/******************************************************************************* ** ** Function rw_t4t_handle_error ** ** Description notify error to application and clean up ** ** Returns none ** *******************************************************************************/ static void rw_t4t_handle_error (tNFC_STATUS status, UINT8 sw1, UINT8 sw2) { tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t; tRW_DATA rw_data; tRW_EVENT event; RW_TRACE_DEBUG4 ("rw_t4t_handle_error (): status:0%02X, sw1:0x%02X, sw2:0x%02X, state:0x%X", status, sw1, sw2, p_t4t->state); nfc_stop_quick_timer (&p_t4t->timer); if (rw_cb.p_cback) { rw_data.status = status; rw_data.t4t_sw.sw1 = sw1; rw_data.t4t_sw.sw2 = sw2; switch (p_t4t->state) { case RW_T4T_STATE_DETECT_NDEF: rw_data.ndef.flags = RW_NDEF_FL_UNKNOWN; event = RW_T4T_NDEF_DETECT_EVT; break; case RW_T4T_STATE_READ_NDEF: event = RW_T4T_NDEF_READ_FAIL_EVT; break; case RW_T4T_STATE_UPDATE_NDEF: event = RW_T4T_NDEF_UPDATE_FAIL_EVT; break; case RW_T4T_STATE_PRESENCE_CHECK: event = RW_T4T_PRESENCE_CHECK_EVT; rw_data.status = NFC_STATUS_FAILED; break; default: event = RW_T4T_MAX_EVT; break; } p_t4t->state = RW_T4T_STATE_IDLE; if (event != RW_T4T_MAX_EVT) { (*(rw_cb.p_cback)) (event, &rw_data); } } else { p_t4t->state = RW_T4T_STATE_IDLE; } }
/******************************************************************************* ** ** Function llcp_cleanup ** ** Description This function is called once at closing to clean up ** ** Returns void ** *******************************************************************************/ void llcp_cleanup (void) { UINT8 sap; tLLCP_APP_CB *p_app_cb; LLCP_TRACE_DEBUG0 ("LLCP - llcp_cleanup ()"); for (sap = LLCP_SAP_SDP; sap < LLCP_NUM_SAPS; sap++) { p_app_cb = llcp_util_get_app_cb (sap); if ( (p_app_cb) &&(p_app_cb->p_app_cback) ) { LLCP_Deregister (sap); } } nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer); nfc_stop_quick_timer (&llcp_cb.lcb.timer); }
/******************************************************************************* ** ** Function ce_select_t4t ** ** Description Select Type 4 Tag ** ** Returns NFC_STATUS_OK if success ** *******************************************************************************/ tNFC_STATUS ce_select_t4t (void) { tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t; CE_TRACE_DEBUG0 ("ce_select_t4t ()"); nfc_stop_quick_timer (&p_t4t->timer); /* clear other than read-only flag */ p_t4t->status &= CE_T4T_STATUS_NDEF_FILE_READ_ONLY; NFC_SetStaticRfCback (ce_t4t_data_cback); return NFC_STATUS_OK; }
/******************************************************************************* ** ** Function llcp_util_deallocate_data_link ** ** Description Deallocate tLLCP_DLCB ** ** Returns void ** ******************************************************************************/ void llcp_util_deallocate_data_link (tLLCP_DLCB *p_dlcb) { if (p_dlcb) { LLCP_TRACE_DEBUG1 ("llcp_util_deallocate_data_link (): local_sap = 0x%x", p_dlcb->local_sap); if (p_dlcb->state != LLCP_DLC_STATE_IDLE) { nfc_stop_quick_timer (&p_dlcb->timer); llcp_dlc_flush_q (p_dlcb); p_dlcb->state = LLCP_DLC_STATE_IDLE; if (llcp_cb.num_data_link_connection > 0) { llcp_cb.num_data_link_connection--; } LLCP_TRACE_DEBUG1 ("llcp_util_deallocate_data_link (): num_data_link_connection = %d", llcp_cb.num_data_link_connection); } } }
/******************************************************************************* ** ** Function ce_t4t_update_binary ** ** Description Update file and send R-APDU to peer ** ** Returns TRUE if success ** *******************************************************************************/ static BOOLEAN ce_t4t_update_binary (UINT16 offset, UINT8 length, UINT8 *p_data) { tCE_T4T_MEM *p_t4t = &ce_cb.mem.t4t; UINT8 *p; UINT8 file_length[2]; UINT16 starting_offset; tCE_DATA ce_data; CE_TRACE_DEBUG3 ("ce_t4t_update_binary (): Offset:0x%04X, Length:0x%04X, selected status = 0x%02X", offset, length, p_t4t->status); starting_offset = offset; /* update file size (NLEN) */ if ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0)) { p = file_length; UINT16_TO_BE_STREAM (p, p_t4t->nlen); while ((offset < T4T_FILE_LENGTH_SIZE) && (length > 0)) { *(file_length + offset++) = *(p_data++); length--; } p = file_length; BE_STREAM_TO_UINT16 (p_t4t->nlen, p); } if (length > 0) memcpy (p_t4t->p_scratch_buf + offset - T4T_FILE_LENGTH_SIZE, p_data, length); /* if this is the last step: writing non-zero length in NLEN */ if ((starting_offset == 0) && (p_t4t->nlen > 0)) { nfc_stop_quick_timer (&p_t4t->timer); if (ce_cb.p_cback) { ce_data.update_info.status = NFC_STATUS_OK; ce_data.update_info.length = p_t4t->nlen; ce_data.update_info.p_data = p_t4t->p_scratch_buf; (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_CPLT_EVT, &ce_data); CE_TRACE_DEBUG0 ("ce_t4t_update_binary (): Sent CE_T4T_NDEF_UPDATE_CPLT_EVT"); } p_t4t->status &= ~ (CE_T4T_STATUS_NDEF_FILE_UPDATING); } else if (!(p_t4t->status & CE_T4T_STATUS_NDEF_FILE_UPDATING)) { /* starting of updating */ p_t4t->status |= CE_T4T_STATUS_NDEF_FILE_UPDATING; nfc_start_quick_timer (&p_t4t->timer, NFC_TTYPE_CE_T4T_UPDATE, (CE_T4T_TOUT_UPDATE * QUICK_TIMER_TICKS_PER_SEC) / 1000); if (ce_cb.p_cback) (*ce_cb.p_cback) (CE_T4T_NDEF_UPDATE_START_EVT, NULL); } if (!ce_t4t_send_status (T4T_RSP_CMD_CMPLTED)) { return FALSE; } else { return TRUE; } }
/******************************************************************************* ** ** Function rw_t2t_proc_data ** ** Description This function handles data evt received from NFC Controller. ** ** Returns none ** *******************************************************************************/ static void rw_t2t_proc_data (UINT8 conn_id, tNFC_DATA_CEVT *p_data) { tRW_EVENT rw_event = RW_RAW_FRAME_EVT; tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; BT_HDR *p_pkt = p_data->p_data; BOOLEAN b_notify = TRUE; BOOLEAN b_release = TRUE; UINT8 *p; tRW_READ_DATA evt_data = {0}; tT2T_CMD_RSP_INFO *p_cmd_rsp_info = (tT2T_CMD_RSP_INFO *) rw_cb.tcb.t2t.p_cmd_rsp_info; tRW_DETECT_NDEF_DATA ndef_data; #if (BT_TRACE_VERBOSE == TRUE) UINT8 begin_state = p_t2t->state; #endif if ( (p_t2t->state == RW_T2T_STATE_IDLE) ||(p_cmd_rsp_info == NULL) ) { #if (BT_TRACE_VERBOSE == TRUE) RW_TRACE_DEBUG2 ("RW T2T Raw Frame: Len [0x%X] Status [%s]", p_pkt->len, NFC_GetStatusName (p_data->status)); #else RW_TRACE_DEBUG2 ("RW T2T Raw Frame: Len [0x%X] Status [0x%X]", p_pkt->len, p_data->status); #endif evt_data.status = p_data->status; evt_data.p_data = p_pkt; (*rw_cb.p_cback) (RW_T2T_RAW_FRAME_EVT, (tRW_DATA *)&evt_data); return; } #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Update rx stats */ rw_main_update_rx_stats (p_pkt->len); #endif /* Stop timer as response is received */ nfc_stop_quick_timer (&p_t2t->t2_timer); RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t2t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode); if ( ( (p_pkt->len != p_cmd_rsp_info->rsp_len) &&(p_pkt->len != p_cmd_rsp_info->nack_rsp_len) &&(p_t2t->substate != RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) ) ||(p_t2t->state == RW_T2T_STATE_HALT) ) { #if (BT_TRACE_VERBOSE == TRUE) RW_TRACE_ERROR1 ("T2T Frame error. state=%s ", rw_t2t_get_state_name (p_t2t->state)); #else RW_TRACE_ERROR1 ("T2T Frame error. state=0x%02X command=0x%02X ", p_t2t->state); #endif if (p_t2t->state != RW_T2T_STATE_HALT) { /* Retrasmit the last sent command if retry-count < max retry */ rw_t2t_process_frame_error (); p_t2t->check_tag_halt = FALSE; } GKI_freebuf (p_pkt); return; } rw_cb.cur_retry = 0; /* Assume the data is just the response byte sequence */ p = (UINT8 *) (p_pkt + 1) + p_pkt->offset; RW_TRACE_EVENT4 ("rw_t2t_proc_data State: %u conn_id: %u len: %u data[0]: 0x%02x", p_t2t->state, conn_id, p_pkt->len, *p); evt_data.p_data = NULL; if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR_SUPPORT) { /* The select process happens in two steps */ if ((*p & 0x0f) == T2T_RSP_ACK) { if (rw_t2t_sector_change (p_t2t->select_sector) == NFC_STATUS_OK) b_notify = FALSE; else evt_data.status = NFC_STATUS_FAILED; } else { RW_TRACE_EVENT1 ("rw_t2t_proc_data - Received NACK response(0x%x) to SEC-SELCT CMD", (*p & 0x0f)); evt_data.status = NFC_STATUS_REJECTED; } } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_SELECT_SECTOR) { evt_data.status = NFC_STATUS_FAILED; } else if ( (p_pkt->len != p_cmd_rsp_info->rsp_len) ||((p_cmd_rsp_info->opcode == T2T_CMD_WRITE) && ((*p & 0x0f) != T2T_RSP_ACK)) ) { /* Received NACK response */ evt_data.p_data = p_pkt; if (p_t2t->state == RW_T2T_STATE_READ) b_release = FALSE; RW_TRACE_EVENT1 ("rw_t2t_proc_data - Received NACK response(0x%x)", (*p & 0x0f)); if (!p_t2t->check_tag_halt) { /* Just received first NACK. Retry just one time to find if tag went in to HALT State */ b_notify = FALSE; rw_t2t_process_error (); /* Assume Tag is in HALT State, untill we get response to retry command */ p_t2t->check_tag_halt = TRUE; } else { p_t2t->check_tag_halt = FALSE; /* Got consecutive NACK so tag not really halt after first NACK, but current operation failed */ evt_data.status = NFC_STATUS_FAILED; } } else { /* If the response length indicates positive response or cannot be known from length then assume success */ evt_data.status = NFC_STATUS_OK; p_t2t->check_tag_halt = FALSE; /* The response data depends on what the current operation was */ switch (p_t2t->state) { case RW_T2T_STATE_CHECK_PRESENCE: b_notify = FALSE; rw_t2t_handle_presence_check_rsp (NFC_STATUS_OK); break; case RW_T2T_STATE_READ: evt_data.p_data = p_pkt; b_release = FALSE; if (p_t2t->block_read == 0) { p_t2t->b_read_hdr = TRUE; memcpy (p_t2t->tag_hdr, p, T2T_READ_DATA_LEN); #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) /* On Ultralight - C tag, if CC is corrupt, correct it */ if ( (p_t2t->tag_hdr[0] == TAG_MIFARE_MID) &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] >= T2T_INVALID_CC_TMS_VAL0) &&(p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] <= T2T_INVALID_CC_TMS_VAL1) ) { p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] = T2T_CC2_TMS_MULC; } #endif } break; case RW_T2T_STATE_WRITE: /* Write operation completed successfully */ break; default: /* NDEF/other Tlv Operation/Format-Tag/Config Tag as Read only */ b_notify = FALSE; rw_t2t_handle_rsp (p); break; } } if (b_notify) { rw_event = rw_t2t_info_to_event (p_cmd_rsp_info); if (rw_event == RW_T2T_NDEF_DETECT_EVT) { ndef_data.status = evt_data.status; ndef_data.protocol = NFC_PROTOCOL_T2T; ndef_data.flags = RW_NDEF_FL_UNKNOWN; if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) ndef_data.flags = RW_NDEF_FL_FORMATED; ndef_data.max_size = 0; ndef_data.cur_size = 0; /* Move back to idle state */ rw_t2t_handle_op_complete (); (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &ndef_data); } else { /* Move back to idle state */ rw_t2t_handle_op_complete (); (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data); } } if (b_release) GKI_freebuf (p_pkt); #if (BT_TRACE_VERBOSE == TRUE) if (begin_state != p_t2t->state) { RW_TRACE_DEBUG2 ("RW T2T state changed:<%s> -> <%s>", rw_t2t_get_state_name (begin_state), rw_t2t_get_state_name (p_t2t->state)); } #endif }
/******************************************************************************* ** ** Function rw_t2t_conn_cback ** ** Description This callback function receives events/data from NFCC. ** ** Returns none ** *******************************************************************************/ void rw_t2t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) { tRW_T2T_CB *p_t2t = &rw_cb.tcb.t2t; tRW_READ_DATA evt_data; RW_TRACE_DEBUG2 ("rw_t2t_conn_cback: conn_id=%i, evt=%i", conn_id, event); /* Only handle static conn_id */ if (conn_id != NFC_RF_CONN_ID) { return; } switch (event) { case NFC_CONN_CREATE_CEVT: case NFC_CONN_CLOSE_CEVT: break; case NFC_DEACTIVATE_CEVT: #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Display stats */ rw_main_log_stats (); #endif /* Stop t2t timer (if started) */ nfc_stop_quick_timer (&p_t2t->t2_timer); /* Free cmd buf for retransmissions */ if (p_t2t->p_cur_cmd_buf) { GKI_freebuf (p_t2t->p_cur_cmd_buf); p_t2t->p_cur_cmd_buf = NULL; } /* Free cmd buf used to hold command before sector change */ if (p_t2t->p_sec_cmd_buf) { GKI_freebuf (p_t2t->p_sec_cmd_buf); p_t2t->p_sec_cmd_buf = NULL; } p_t2t->state = RW_T2T_STATE_NOT_ACTIVATED; NFC_SetStaticRfCback (NULL); break; case NFC_DATA_CEVT: if ( (p_data != NULL) &&( (p_data->data.status == NFC_STATUS_OK) ||(p_data->data.status == NFC_STATUS_CONTINUE) ) ) { rw_t2t_proc_data (conn_id, &(p_data->data)); break; } /* Data event with error status...fall through to NFC_ERROR_CEVT case */ case NFC_ERROR_CEVT: if ( (p_t2t->state == RW_T2T_STATE_NOT_ACTIVATED) ||(p_t2t->state == RW_T2T_STATE_IDLE) ||(p_t2t->state == RW_T2T_STATE_HALT) ) { #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) rw_main_update_trans_error_stats (); #endif /* RW_STATS_INCLUDED */ if (event == NFC_ERROR_CEVT) evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data); else if (p_data) evt_data.status = p_data->status; else evt_data.status = NFC_STATUS_FAILED; evt_data.p_data = NULL; (*rw_cb.p_cback) (RW_T2T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data); break; } nfc_stop_quick_timer (&p_t2t->t2_timer); #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) rw_main_update_trans_error_stats (); #endif if (p_t2t->state == RW_T2T_STATE_CHECK_PRESENCE) { if (p_t2t->check_tag_halt) { p_t2t->state = RW_T2T_STATE_HALT; rw_t2t_handle_presence_check_rsp (NFC_STATUS_REJECTED); } else { /* Move back to idle state */ rw_t2t_handle_presence_check_rsp (NFC_STATUS_FAILED); } } else { rw_t2t_process_error (); } #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) /* Free the response buffer in case of invalid response*/ if (p_data != NULL) { GKI_freebuf((BT_HDR *) (p_data->data.p_data)); } #endif break; default: break; } }
/******************************************************************************* ** ** Function rw_t1t_data_cback ** ** Description This callback function handles data from NFCC. ** ** Returns none ** *******************************************************************************/ static void rw_t1t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) { tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; tRW_EVENT rw_event = RW_RAW_FRAME_EVT; BOOLEAN b_notify = TRUE; tRW_DATA evt_data; BT_HDR *p_pkt; UINT8 *p; tT1T_CMD_RSP_INFO *p_cmd_rsp_info = (tT1T_CMD_RSP_INFO *) rw_cb.tcb.t1t.p_cmd_rsp_info; #if (BT_TRACE_VERBOSE == TRUE) UINT8 begin_state = p_t1t->state; #endif p_pkt = (BT_HDR *) (p_data->data.p_data); if (p_pkt == NULL) return; /* Assume the data is just the response byte sequence */ p = (UINT8 *) (p_pkt + 1) + p_pkt->offset; #if (BT_TRACE_VERBOSE == TRUE) RW_TRACE_DEBUG2 ("rw_t1t_data_cback (): state:%s (%d)", rw_t1t_get_state_name (p_t1t->state), p_t1t->state); #else RW_TRACE_DEBUG1 ("rw_t1t_data_cback (): state=%d", p_t1t->state); #endif evt_data.status = NFC_STATUS_OK; if( (p_t1t->state == RW_T1T_STATE_IDLE) ||(!p_cmd_rsp_info) ) { /* If previous command was retransmitted and if response is pending to previous command retransmission, * check if lenght and ADD/ADD8/ADDS field matches the expected value of previous * retransmited command response. However, ignore ADD field if the command was RALL/RID */ if ( (p_t1t->prev_cmd_rsp_info.pend_retx_rsp) &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len) &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p)) ) { /* Response to previous command retransmission */ RW_TRACE_ERROR2 ("T1T Response to previous command in Idle state. command=0x%02x, Remaining max retx rsp:0x%02x ", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1); p_t1t->prev_cmd_rsp_info.pend_retx_rsp--; GKI_freebuf (p_pkt); } else { /* Raw frame event */ evt_data.data.p_data = p_pkt; (*rw_cb.p_cback) (RW_T1T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data); } return; } #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Update rx stats */ rw_main_update_rx_stats (p_pkt->len); #endif /* RW_STATS_INCLUDED */ if ( (p_pkt->len != p_cmd_rsp_info->rsp_len) ||((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID) && (*p != p_t1t->addr)) ) { /* If previous command was retransmitted and if response is pending to previous command retransmission, * then check if lenght and ADD/ADD8/ADDS field matches the expected value of previous * retransmited command response. However, ignore ADD field if the command was RALL/RID */ if ( (p_t1t->prev_cmd_rsp_info.pend_retx_rsp) &&(p_t1t->prev_cmd_rsp_info.rsp_len == p_pkt->len) &&((p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RID) || (p_t1t->prev_cmd_rsp_info.op_code == T1T_CMD_RALL) || (p_t1t->prev_cmd_rsp_info.addr == *p)) ) { RW_TRACE_ERROR2 ("T1T Response to previous command. command=0x%02x, Remaining max retx rsp:0x%02x", p_t1t->prev_cmd_rsp_info.op_code, p_t1t->prev_cmd_rsp_info.pend_retx_rsp - 1); p_t1t->prev_cmd_rsp_info.pend_retx_rsp--; } else { /* Stop timer as some response to current command is received */ nfc_stop_quick_timer (&p_t1t->timer); /* Retrasmit the last sent command if retry-count < max retry */ #if (BT_TRACE_VERBOSE == TRUE) RW_TRACE_ERROR2 ("T1T Frame error. state=%s command (opcode) = 0x%02x", rw_t1t_get_state_name (p_t1t->state), p_cmd_rsp_info->opcode); #else RW_TRACE_ERROR2 ("T1T Frame error. state=0x%02x command = 0x%02x ", p_t1t->state, p_cmd_rsp_info->opcode); #endif rw_t1t_process_frame_error (); } GKI_freebuf (p_pkt); return; } /* Stop timer as response to current command is received */ nfc_stop_quick_timer (&p_t1t->timer); RW_TRACE_EVENT2 ("RW RECV [%s]:0x%x RSP", t1t_info_to_str (p_cmd_rsp_info), p_cmd_rsp_info->opcode); /* If we did not receive response to all retransmitted previous command, * dont expect that as response have come for the current command itself. */ if (p_t1t->prev_cmd_rsp_info.pend_retx_rsp) memset (&(p_t1t->prev_cmd_rsp_info), 0, sizeof (tRW_T1T_PREV_CMD_RSP_INFO)); if (rw_cb.cur_retry) { /* If the current command was retransmitted to get this response, we might get response later to all or some of the retrasnmission of the current command */ p_t1t->prev_cmd_rsp_info.addr = ((p_cmd_rsp_info->opcode != T1T_CMD_RALL) && (p_cmd_rsp_info->opcode != T1T_CMD_RID))? p_t1t->addr:0; p_t1t->prev_cmd_rsp_info.rsp_len = p_cmd_rsp_info->rsp_len; p_t1t->prev_cmd_rsp_info.op_code = p_cmd_rsp_info->opcode; p_t1t->prev_cmd_rsp_info.pend_retx_rsp = (UINT8) rw_cb.cur_retry; } rw_cb.cur_retry = 0; if (p_cmd_rsp_info->opcode == T1T_CMD_RID) { rw_event = rw_t1t_handle_rid_rsp (p_pkt); } else { rw_event = rw_t1t_handle_rsp (p_cmd_rsp_info, &b_notify, p, &evt_data.status); } if (b_notify) { if( (p_t1t->state != RW_T1T_STATE_READ) &&(p_t1t->state != RW_T1T_STATE_WRITE) ) { GKI_freebuf (p_pkt); evt_data.data.p_data = NULL; } else { evt_data.data.p_data = p_pkt; } rw_t1t_handle_op_complete (); (*rw_cb.p_cback) (rw_event, (tRW_DATA *) &evt_data); } else GKI_freebuf (p_pkt); #if (BT_TRACE_VERBOSE == TRUE) if (begin_state != p_t1t->state) { RW_TRACE_DEBUG2 ("RW T1T state changed:<%s> -> <%s>", rw_t1t_get_state_name (begin_state), rw_t1t_get_state_name (p_t1t->state)); } #endif }
/******************************************************************************* ** ** Function rw_t1t_conn_cback ** ** Description This callback function receives the events/data from NFCC. ** ** Returns none ** *******************************************************************************/ void rw_t1t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) { tRW_T1T_CB *p_t1t = &rw_cb.tcb.t1t; tRW_READ_DATA evt_data; RW_TRACE_DEBUG2 ("rw_t1t_conn_cback: conn_id=%i, evt=0x%x", conn_id, event); /* Only handle static conn_id */ if (conn_id != NFC_RF_CONN_ID) { RW_TRACE_WARNING1 ("rw_t1t_conn_cback - Not static connection id: =%i", conn_id); return; } switch (event) { case NFC_CONN_CREATE_CEVT: case NFC_CONN_CLOSE_CEVT: break; case NFC_DEACTIVATE_CEVT: #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) /* Display stats */ rw_main_log_stats (); #endif /* RW_STATS_INCLUDED */ /* Stop t1t timer (if started) */ nfc_stop_quick_timer (&p_t1t->timer); /* Free cmd buf for retransmissions */ if (p_t1t->p_cur_cmd_buf) { GKI_freebuf (p_t1t->p_cur_cmd_buf); p_t1t->p_cur_cmd_buf = NULL; } p_t1t->state = RW_T1T_STATE_NOT_ACTIVATED; NFC_SetStaticRfCback (NULL); break; case NFC_DATA_CEVT: if ( (p_data != NULL) &&(p_data->data.status == NFC_STATUS_OK) ) { rw_t1t_data_cback (conn_id, event, p_data); break; } /* Data event with error status...fall through to NFC_ERROR_CEVT case */ case NFC_ERROR_CEVT: if ( (p_t1t->state == RW_T1T_STATE_NOT_ACTIVATED) ||(p_t1t->state == RW_T1T_STATE_IDLE) ) { #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) rw_main_update_trans_error_stats (); #endif /* RW_STATS_INCLUDED */ if (event == NFC_ERROR_CEVT) evt_data.status = (tNFC_STATUS) (*(UINT8*) p_data); else if (p_data) evt_data.status = p_data->status; else evt_data.status = NFC_STATUS_FAILED; evt_data.p_data = NULL; (*rw_cb.p_cback) (RW_T1T_INTF_ERROR_EVT, (tRW_DATA *) &evt_data); break; } nfc_stop_quick_timer (&p_t1t->timer); #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE)) rw_main_update_trans_error_stats (); #endif /* RW_STATS_INCLUDED */ if (p_t1t->state == RW_T1T_STATE_CHECK_PRESENCE) { rw_t1t_handle_presence_check_rsp (NFC_STATUS_FAILED); } else { rw_t1t_process_error (); } break; default: break; } }
/******************************************************************************* ** ** Function rw_t4t_data_cback ** ** Description This callback function receives the data from NFCC. ** ** Returns none ** *******************************************************************************/ static void rw_t4t_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) { tRW_T4T_CB *p_t4t = &rw_cb.tcb.t4t; BT_HDR *p_r_apdu = (BT_HDR *) p_data->data.p_data; tRW_DATA rw_data; #if (BT_TRACE_VERBOSE == TRUE) UINT8 begin_state = p_t4t->state; #endif RW_TRACE_DEBUG1 ("rw_t4t_data_cback () event = 0x%X", event); nfc_stop_quick_timer (&p_t4t->timer); switch (event) { case NFC_DEACTIVATE_CEVT: NFC_SetStaticRfCback (NULL); p_t4t->state = RW_T4T_STATE_NOT_ACTIVATED; return; case NFC_ERROR_CEVT: if (p_t4t->state == RW_T4T_STATE_PRESENCE_CHECK) { p_t4t->state = RW_T4T_STATE_IDLE; rw_data.status = NFC_STATUS_FAILED; (*(rw_cb.p_cback)) (RW_T4T_PRESENCE_CHECK_EVT, &rw_data); } else { p_t4t->state = RW_T4T_STATE_IDLE; rw_data.status = (tNFC_STATUS) (*(UINT8*) p_data); (*(rw_cb.p_cback)) (RW_T4T_INTF_ERROR_EVT, &rw_data); } return; case NFC_DATA_CEVT: break; default: return; } #if (BT_TRACE_PROTOCOL == TRUE) DispRWT4Tags (p_r_apdu, TRUE); #endif #if (BT_TRACE_VERBOSE == TRUE) RW_TRACE_DEBUG2 ("RW T4T state: <%s (%d)>", rw_t4t_get_state_name (p_t4t->state), p_t4t->state); #else RW_TRACE_DEBUG1 ("RW T4T state: %d", p_t4t->state); #endif switch (p_t4t->state) { case RW_T4T_STATE_IDLE: /* Unexpected R-APDU, it should be raw frame response */ /* forward to upper layer without parsing */ if (rw_cb.p_cback) { rw_data.raw_frame.status = NFC_STATUS_OK; rw_data.raw_frame.p_data = p_r_apdu; (*(rw_cb.p_cback)) (RW_T4T_RAW_FRAME_EVT, &rw_data); p_r_apdu = NULL; } else { GKI_freebuf (p_r_apdu); } break; case RW_T4T_STATE_DETECT_NDEF: rw_t4t_sm_detect_ndef (p_r_apdu); GKI_freebuf (p_r_apdu); break; case RW_T4T_STATE_READ_NDEF: rw_t4t_sm_read_ndef (p_r_apdu); /* p_r_apdu may send upper lyaer */ break; case RW_T4T_STATE_UPDATE_NDEF: rw_t4t_sm_update_ndef (p_r_apdu); GKI_freebuf (p_r_apdu); break; case RW_T4T_STATE_PRESENCE_CHECK: /* if any response, send presence check with ok */ rw_data.status = NFC_STATUS_OK; p_t4t->state = RW_T4T_STATE_IDLE; (*(rw_cb.p_cback)) (RW_T4T_PRESENCE_CHECK_EVT, &rw_data); GKI_freebuf (p_r_apdu); break; default: RW_TRACE_ERROR1 ("rw_t4t_data_cback (): invalid state=%d", p_t4t->state); GKI_freebuf (p_r_apdu); break; } #if (BT_TRACE_VERBOSE == TRUE) if (begin_state != p_t4t->state) { RW_TRACE_DEBUG2 ("RW T4T state changed:<%s> -> <%s>", rw_t4t_get_state_name (begin_state), rw_t4t_get_state_name (p_t4t->state)); } #endif }