/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <rw_int.h>
#include <stdlib.h>
#include "../includes/common.h"

bool testInProgress = false;
struct sigaction new_action, old_action;
void sigabrt_handler(int signum, siginfo_t *info, void *context) {
    if (testInProgress && info->si_signo == SIGABRT) {
        (*old_action.sa_sigaction)(signum, info, context);
        return;
    }
    exit(EXIT_FAILURE);
}

uint8_t *p_data = nullptr;
extern tRW_CB rw_cb;

extern void rw_t2t_handle_rsp(uint8_t *p_data);

void poc_cback(uint8_t, tRW_DATA *) {}

void exit_handler(void) {
    if (p_data) {
        free(p_data);
        p_data = nullptr;
    }
}

int main() {
    atexit(exit_handler);
    sigemptyset(&new_action.sa_mask);
    new_action.sa_flags = SA_SIGINFO;
    new_action.sa_sigaction = sigabrt_handler;
    sigaction(SIGABRT, &new_action, &old_action);

    tNFC_ACTIVATE_DEVT p_activate_params = {};
    p_activate_params.protocol = NFC_PROTOCOL_ISO_DEP;
    p_activate_params.rf_tech_param.mode = NFC_DISCOVERY_TYPE_POLL_A;
    FAIL_CHECK(RW_SetActivatedTagType(&p_activate_params, &poc_cback) == NFC_STATUS_OK);
    FAIL_CHECK(rw_cb.p_cback == &poc_cback);
    tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t;
    p_t2t->state = RW_T2T_STATE_DETECT_TLV;
    p_t2t->tlv_detect = TAG_LOCK_CTRL_TLV;
    p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
    p_t2t->found_tlv = TAG_LOCK_CTRL_TLV;
    p_t2t->bytes_count = 0;
    p_t2t->p_cur_cmd_buf = (NFC_HDR *)GKI_getpoolbuf(NFC_RW_POOL_ID);
    rw_cb.p_cback = &poc_cback;
    p_data = (uint8_t *)malloc(sizeof(uint8_t));
    FAIL_CHECK(p_data);

    testInProgress = true;
    rw_t2t_handle_rsp(p_data);
    testInProgress = false;

    return EXIT_SUCCESS;
}
