/******************************************************************************* ** ** Function nfa_ee_find_ecb ** ** Description Return the ecb associated with the given nfcee_id ** ** Returns tNFA_EE_ECB ** *******************************************************************************/ tNFA_EE_ECB * nfa_ee_find_ecb (UINT8 nfcee_id) { UINT32 xx; tNFA_EE_ECB *p_ret = NULL, *p_cb; NFA_TRACE_DEBUG0 ("nfa_ee_find_ecb ()"); if (nfcee_id == NFC_DH_ID) { p_ret = &nfa_ee_cb.ecb[NFA_EE_CB_4_DH]; } else { p_cb = nfa_ee_cb.ecb; for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) { if (nfcee_id == p_cb->nfcee_id) { p_ret = p_cb; break; } } } return p_ret; }
/******************************************************************************* ** ** Function nfa_ee_sys_disable ** ** Description Deregister NFA EE from NFA SYS/DM ** ** ** Returns None ** *******************************************************************************/ void nfa_ee_sys_disable (void) { UINT32 xx; tNFA_EE_ECB *p_cb; tNFA_EE_MSG msg; NFA_TRACE_DEBUG0 ("nfa_ee_sys_disable ()"); nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLED; /* report NFA_EE_DEREGISTER_EVT to all registered to EE */ for (xx = 0; xx < NFA_EE_MAX_CBACKS; xx++) { if (nfa_ee_cb.p_ee_cback[xx]) { msg.deregister.index = xx; nfa_ee_api_deregister (&msg); } } nfa_ee_cb.num_ee_expecting = 0; p_cb = nfa_ee_cb.ecb; for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) { if (p_cb->conn_st == NFA_EE_CONN_ST_CONN) { if (nfa_sys_is_graceful_disable ()) { /* Disconnect NCI connection on graceful shutdown */ msg.disconnect.p_cb = p_cb; nfa_ee_api_disconnect (&msg); nfa_ee_cb.num_ee_expecting++; } else { /* fake NFA_EE_DISCONNECT_EVT on ungraceful shutdown */ msg.conn.conn_id = p_cb->conn_id; msg.conn.event = NFC_CONN_CLOSE_CEVT; nfa_ee_nci_conn (&msg); } } } if (nfa_ee_cb.num_ee_expecting) { nfa_ee_cb.ee_flags |= NFA_EE_FLAG_WAIT_DISCONN; nfa_ee_cb.em_state = NFA_EE_EM_STATE_DISABLING; } nfa_sys_stop_timer (&nfa_ee_cb.timer); nfa_sys_stop_timer (&nfa_ee_cb.discv_timer); /* If Application initiated NFCEE discovery, fake/report the event */ nfa_ee_report_disc_done (FALSE); /* deregister message handler on NFA SYS */ if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_DISABLED) nfa_sys_deregister (NFA_ID_EE); }
/******************************************************************************* ** ** Function nfa_sys_ptim_timer_update ** ** Description Update the protocol timer list and handle expired timers. ** This function is called from the task running the protocol ** timers when the periodic GKI timer expires. ** ** Returns void ** *******************************************************************************/ void nfa_sys_ptim_timer_update (tPTIM_CB *p_cb) { TIMER_LIST_ENT *p_tle; BT_HDR *p_msg; UINT32 new_ticks_count; INT32 period_in_ticks; /* To handle the case when the function is called less frequently than the period we must convert determine the number of ticks since the last update, then convert back to milliseconds before updating timer list */ new_ticks_count = GKI_get_tick_count (); /* Check for wrapped condition */ if (new_ticks_count >= p_cb->last_gki_ticks) { period_in_ticks = (INT32) (new_ticks_count - p_cb->last_gki_ticks); } else { period_in_ticks = (INT32) (((UINT32) 0xffffffff - p_cb->last_gki_ticks) + new_ticks_count + 1); } /* update timer list */ GKI_update_timer_list (&p_cb->timer_queue, GKI_TICKS_TO_MS (period_in_ticks)); p_cb->last_gki_ticks = new_ticks_count; /* while there are expired timers */ while ((p_cb->timer_queue.p_first) && (p_cb->timer_queue.p_first->ticks <= 0)) { /* removed expired timer from list */ p_tle = p_cb->timer_queue.p_first; NFA_TRACE_DEBUG1 ("nfa_sys_ptim_timer_update expired: %08x", p_tle); GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle); /* call timer callback */ if (p_tle->p_cback) { (*p_tle->p_cback) (p_tle); } else if (p_tle->event) { if ((p_msg = (BT_HDR *) GKI_getbuf (sizeof (BT_HDR))) != NULL) { p_msg->event = p_tle->event; p_msg->layer_specific = 0; nfa_sys_sendmsg (p_msg); } } } /* if timer list is empty stop periodic GKI timer */ if (p_cb->timer_queue.p_first == NULL) { NFA_TRACE_DEBUG0 ("ptim timer stop"); GKI_stop_timer (p_cb->timer_id); } }
/******************************************************************************* ** ** Function nfa_rw_init ** ** Description Initialize NFA RW ** ** Returns None ** *******************************************************************************/ void nfa_rw_init (void) { NFA_TRACE_DEBUG0 ("nfa_rw_init ()"); /* initialize control block */ memset (&nfa_rw_cb, 0, sizeof (tNFA_RW_CB)); /* register message handler on NFA SYS */ nfa_sys_register (NFA_ID_RW, &nfa_rw_sys_reg); }
/******************************************************************************* ** ** Function nfa_dm_init ** ** Description Initialises the NFC device manager ** ** Returns void ** *******************************************************************************/ void nfa_dm_init (void) { NFA_TRACE_DEBUG0 ("nfa_dm_init ()"); memset (&nfa_dm_cb, 0, sizeof (tNFA_DM_CB)); nfa_dm_cb.poll_disc_handle = NFA_HANDLE_INVALID; nfa_dm_cb.disc_cb.disc_duration = NFA_DM_DISC_DURATION_POLL; nfa_dm_cb.nfcc_pwr_mode = NFA_DM_PWR_MODE_FULL; /* register message handler on NFA SYS */ nfa_sys_register (NFA_ID_DM, &nfa_dm_sys_reg); }
/******************************************************************************* ** ** Function nfa_hciu_send_clear_all_pipe_cmd ** ** Description delete all the dynamic pipe connected to device host, ** to close all static pipes connected to device host, ** and to set registry values related to static pipes to ** theri default values. ** ** Returns None ** *******************************************************************************/ tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void) { tNFA_STATUS status; UINT16 id_ref_data = 0x0102; NFA_TRACE_DEBUG0 ("nfa_hciu_send_clear_all_pipe_cmd"); status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (UINT8 *) &id_ref_data); return status; }
/******************************************************************************* ** ** Function nfa_ee_evt_hdlr ** ** Description Processing event for NFA EE ** ** ** Returns TRUE if p_msg needs to be deallocated ** *******************************************************************************/ BOOLEAN nfa_ee_evt_hdlr (BT_HDR *p_msg) { tNFA_EE_MSG *p_evt_data = (tNFA_EE_MSG *) p_msg; UINT16 event = p_msg->event & 0x00ff; BOOLEAN act = FALSE; #if (BT_TRACE_VERBOSE == TRUE) NFA_TRACE_DEBUG4 ("nfa_ee_evt_hdlr (): Event %s(0x%02x), State: %s(%d)", nfa_ee_sm_evt_2_str (p_evt_data->hdr.event), p_evt_data->hdr.event, nfa_ee_sm_st_2_str (nfa_ee_cb.em_state), nfa_ee_cb.em_state); #else NFA_TRACE_DEBUG2 ("nfa_ee_evt_hdlr (): Event 0x%02x, State: %d", p_evt_data->hdr.event, nfa_ee_cb.em_state); #endif #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) /*This is required to receive Reader Over SWP event*/ if(p_evt_data->hdr.event == NFA_EE_NCI_DISC_NTF_EVT) { NFA_TRACE_DEBUG0("recived dis_ntf; stopping timer"); nfa_sys_stop_timer(&nfa_ee_cb.discv_timer); } #endif switch (nfa_ee_cb.em_state) { case NFA_EE_EM_STATE_INIT_DONE: case NFA_EE_EM_STATE_RESTORING: act = TRUE; break; case NFA_EE_EM_STATE_INIT: if ((p_msg->event == NFA_EE_NCI_DISC_NTF_EVT) || (p_msg->event == NFA_EE_NCI_DISC_RSP_EVT)) act = TRUE; break; case NFA_EE_EM_STATE_DISABLING: if (p_msg->event == NFA_EE_NCI_CONN_EVT) act = TRUE; break; } if (act) { if (event < NFA_EE_NUM_ACTIONS) { (*nfa_ee_actions[event]) (p_evt_data); } } else { /* if the data event is not handled by action function, free the data packet */ if (p_msg->event == NFA_EE_NCI_DATA_EVT) GKI_freebuf (p_evt_data->conn.p_data); } return TRUE; }
/******************************************************************************* ** ** Function nfa_sys_ptim_stop_timer ** ** Description Stop a protocol timer. ** ** Returns void ** *******************************************************************************/ void nfa_sys_ptim_stop_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle) { NFA_TRACE_DEBUG1 ("nfa_sys_ptim_stop_timer %08x", p_tle); GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle); /* if timer list is empty stop periodic GKI timer */ if (p_cb->timer_queue.p_first == NULL) { NFA_TRACE_DEBUG0 ("ptim timer stop"); GKI_stop_timer (p_cb->timer_id); } }
/******************************************************************************* ** ** Function nfa_ee_find_ecb_by_conn_id ** ** Description Return the ecb associated with the given connection id ** ** Returns tNFA_EE_ECB ** *******************************************************************************/ tNFA_EE_ECB * nfa_ee_find_ecb_by_conn_id (UINT8 conn_id) { UINT32 xx; tNFA_EE_ECB *p_ret = NULL, *p_cb; NFA_TRACE_DEBUG0 ("nfa_ee_find_ecb_by_conn_id ()"); p_cb = nfa_ee_cb.ecb; for (xx = 0; xx < nfa_ee_cb.cur_ee; xx++, p_cb++) { if (conn_id == p_cb->conn_id) { p_ret = p_cb; break; } } return p_ret; }
/******************************************************************************* ** ** Function nfa_sys_ptim_start_timer ** ** Description Start a protocol timer for the specified amount ** of time in seconds. ** ** Returns void ** *******************************************************************************/ void nfa_sys_ptim_start_timer (tPTIM_CB *p_cb, TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout) { NFA_TRACE_DEBUG1 ("nfa_sys_ptim_start_timer %08x", p_tle); /* if timer list is currently empty, start periodic GKI timer */ if (p_cb->timer_queue.p_first == NULL) { NFA_TRACE_DEBUG0 ("ptim timer start"); p_cb->last_gki_ticks = GKI_get_tick_count (); GKI_start_timer (p_cb->timer_id, GKI_MS_TO_TICKS (p_cb->period), TRUE); } GKI_remove_from_timer_list (&p_cb->timer_queue, p_tle); p_tle->event = type; p_tle->ticks = timeout; GKI_add_to_timer_list (&p_cb->timer_queue, p_tle); }
/******************************************************************************* ** ** Function nfa_ee_init ** ** Description Initialize NFA EE control block ** register to NFA SYS ** ** Returns None ** *******************************************************************************/ void nfa_ee_init (void) { int xx; NFA_TRACE_DEBUG0 ("nfa_ee_init ()"); /* initialize control block */ memset (&nfa_ee_cb, 0, sizeof (tNFA_EE_CB)); for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++) { nfa_ee_cb.ecb[xx].nfcee_id = NFA_EE_INVALID; nfa_ee_cb.ecb[xx].ee_status = NFC_NFCEE_STATUS_INACTIVE; } nfa_ee_cb.ecb[NFA_EE_CB_4_DH].ee_status = NFC_NFCEE_STATUS_ACTIVE; nfa_ee_cb.ecb[NFA_EE_CB_4_DH].nfcee_id = NFC_DH_ID; /* register message handler on NFA SYS */ nfa_sys_register (NFA_ID_EE, &nfa_ee_sys_reg); }
/******************************************************************************* ** ** Function nfa_ee_proc_hci_info_cback ** ** Description HCI initialization complete from power off sleep mode ** ** Returns None ** *******************************************************************************/ void nfa_ee_proc_hci_info_cback (void) { UINT32 xx; tNFA_EE_ECB *p_cb; NFA_TRACE_DEBUG0 ("nfa_ee_proc_hci_info_cback ()"); /* if NFCC power state is change to full power */ nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_HCI; p_cb = nfa_ee_cb.ecb; for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) { /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access" * SHALL NOT contain any other additional Protocol * i.e. check only first supported NFCEE interface is HCI access */ /* NFA_HCI module handles restoring configurations for HCI access */ if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) { nfa_ee_restore_one_ecb (p_cb); } } }
/******************************************************************************* ** ** Function nfa_ee_proc_hci_info_cback ** ** Description HCI initialization complete from power off sleep mode ** ** Returns None ** *******************************************************************************/ void nfa_ee_proc_hci_info_cback (void) { UINT32 xx; tNFA_EE_ECB *p_cb; tNFA_EE_MSG data; NFA_TRACE_DEBUG0 ("nfa_ee_proc_hci_info_cback ()"); /* if NFCC power state is change to full power */ nfa_ee_cb.ee_flags &= ~NFA_EE_FLAG_WAIT_HCI; p_cb = nfa_ee_cb.ecb; for (xx = 0; xx < NFA_EE_MAX_EE_SUPPORTED; xx++, p_cb++) { /* NCI spec says: An NFCEE_DISCOVER_NTF that contains a Protocol type of "HCI Access" * SHALL NOT contain any other additional Protocol * i.e. check only first supported NFCEE interface is HCI access */ /* NFA_HCI module handles restoring configurations for HCI access */ if (p_cb->ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) { nfa_ee_restore_one_ecb (p_cb); } } if (nfa_ee_restore_ntf_done()) { nfa_ee_check_restore_complete(); if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT_DONE) { if (nfa_ee_cb.discv_timer.in_use) { nfa_sys_stop_timer (&nfa_ee_cb.discv_timer); data.hdr.event = NFA_EE_DISCV_TIMEOUT_EVT; nfa_ee_evt_hdlr((BT_HDR *)&data); } } } }
/******************************************************************************* ** ** Function nfa_dm_check_set_config ** ** Description Update config parameters only if it's different from NFCC ** ** ** Returns tNFA_STATUS ** *******************************************************************************/ tNFA_STATUS nfa_dm_check_set_config (UINT8 tlv_list_len, UINT8 *p_tlv_list, BOOLEAN app_init) { UINT8 type, len, *p_value, *p_stored = NULL, max_len = 0; UINT8 xx = 0, updated_len = 0, *p_cur_len; BOOLEAN update; tNFC_STATUS nfc_status; UINT32 cur_bit; NFA_TRACE_DEBUG0 ("nfa_dm_check_set_config ()"); /* We only allow 32 pending SET_CONFIGs */ if (nfa_dm_cb.setcfg_pending_num >= NFA_DM_SETCONFIG_PENDING_MAX) { NFA_TRACE_ERROR0 ("nfa_dm_check_set_config () error: pending number of SET_CONFIG exceeded"); return NFA_STATUS_FAILED; } while (tlv_list_len - xx >= 2) /* at least type and len */ { update = FALSE; type = *(p_tlv_list + xx); len = *(p_tlv_list + xx + 1); p_value = p_tlv_list + xx + 2; p_cur_len = NULL; switch (type) { case NFC_PMID_TOTAL_DURATION: p_stored = nfa_dm_cb.params.total_duration; max_len = NCI_PARAM_LEN_TOTAL_DURATION; break; /* ** Listen A Configuration */ case NFC_PMID_LA_BIT_FRAME_SDD: p_stored = nfa_dm_cb.params.la_bit_frame_sdd; max_len = NCI_PARAM_LEN_LA_BIT_FRAME_SDD; p_cur_len = &nfa_dm_cb.params.la_bit_frame_sdd_len; break; case NFC_PMID_LA_PLATFORM_CONFIG: p_stored = nfa_dm_cb.params.la_platform_config; max_len = NCI_PARAM_LEN_LA_PLATFORM_CONFIG; p_cur_len = &nfa_dm_cb.params.la_platform_config_len; break; case NFC_PMID_LA_SEL_INFO: p_stored = nfa_dm_cb.params.la_sel_info; max_len = NCI_PARAM_LEN_LA_SEL_INFO; p_cur_len = &nfa_dm_cb.params.la_sel_info_len; break; case NFC_PMID_LA_NFCID1: p_stored = nfa_dm_cb.params.la_nfcid1; max_len = NCI_NFCID1_MAX_LEN; p_cur_len = &nfa_dm_cb.params.la_nfcid1_len; break; case NFC_PMID_LA_HIST_BY: p_stored = nfa_dm_cb.params.la_hist_by; max_len = NCI_MAX_HIS_BYTES_LEN; p_cur_len = &nfa_dm_cb.params.la_hist_by_len; break; /* ** Listen B Configuration */ case NFC_PMID_LB_SENSB_INFO: #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) if(app_init == TRUE) { #endif p_stored = nfa_dm_cb.params.lb_sensb_info; max_len = NCI_PARAM_LEN_LB_SENSB_INFO; p_cur_len = &nfa_dm_cb.params.lb_sensb_info_len; #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) } else { update = FALSE; } #endif break; case NFC_PMID_LB_NFCID0: p_stored = nfa_dm_cb.params.lb_nfcid0; max_len = NCI_PARAM_LEN_LB_NFCID0; p_cur_len = &nfa_dm_cb.params.lb_nfcid0_len; break; case NFC_PMID_LB_APPDATA: p_stored = nfa_dm_cb.params.lb_appdata; max_len = NCI_PARAM_LEN_LB_APPDATA; p_cur_len = &nfa_dm_cb.params.lb_appdata_len; break; case NFC_PMID_LB_ADC_FO: p_stored = nfa_dm_cb.params.lb_adc_fo; max_len = NCI_PARAM_LEN_LB_ADC_FO; p_cur_len = &nfa_dm_cb.params.lb_adc_fo_len; break; case NFC_PMID_LB_H_INFO: p_stored = nfa_dm_cb.params.lb_h_info; max_len = NCI_MAX_ATTRIB_LEN; p_cur_len = &nfa_dm_cb.params.lb_h_info_len; break; /* ** Listen F Configuration */ case NFC_PMID_LF_PROTOCOL: p_stored = nfa_dm_cb.params.lf_protocol; max_len = NCI_PARAM_LEN_LF_PROTOCOL; p_cur_len = &nfa_dm_cb.params.lf_protocol_len; break; case NFC_PMID_LF_T3T_FLAGS2: p_stored = nfa_dm_cb.params.lf_t3t_flags2; max_len = NCI_PARAM_LEN_LF_T3T_FLAGS2; p_cur_len = &nfa_dm_cb.params.lf_t3t_flags2_len; break; // LF_T3T_PMM is not supported. /* case NFC_PMID_LF_T3T_PMM: p_stored = nfa_dm_cb.params.lf_t3t_pmm; max_len = NCI_PARAM_LEN_LF_T3T_PMM; break;*/ /* ** ISO-DEP and NFC-DEP Configuration */ #if(NFC_NXP_NOT_OPEN_INCLUDED != TRUE) case NFC_PMID_FWI: p_stored = nfa_dm_cb.params.fwi; max_len = NCI_PARAM_LEN_FWI; break; #endif case NFC_PMID_WT: p_stored = nfa_dm_cb.params.wt; max_len = NCI_PARAM_LEN_WT; break; case NFC_PMID_ATR_REQ_GEN_BYTES: p_stored = nfa_dm_cb.params.atr_req_gen_bytes; max_len = NCI_MAX_GEN_BYTES_LEN; p_cur_len = &nfa_dm_cb.params.atr_req_gen_bytes_len; break; case NFC_PMID_ATR_RES_GEN_BYTES: p_stored = nfa_dm_cb.params.atr_res_gen_bytes; max_len = NCI_MAX_GEN_BYTES_LEN; p_cur_len = &nfa_dm_cb.params.atr_res_gen_bytes_len; break; default: /* ** Listen F Configuration */ if ((type >= NFC_PMID_LF_T3T_ID1) && (type < NFC_PMID_LF_T3T_ID1 + NFA_CE_LISTEN_INFO_MAX)) { p_stored = nfa_dm_cb.params.lf_t3t_id[type - NFC_PMID_LF_T3T_ID1]; max_len = NCI_PARAM_LEN_LF_T3T_ID; } else { /* we don't stored this config items */ update = TRUE; p_stored = NULL; } break; } if ((p_stored)&&(len <= max_len)) { if (p_cur_len) { if (*p_cur_len != len) { *p_cur_len = len; update = TRUE; } else if (memcmp (p_value, p_stored, len)) { update = TRUE; } } else if (len == max_len) /* fixed length */ { if (memcmp (p_value, p_stored, len)) { update = TRUE; } } } if (update) { /* we don't store this type */ if (p_stored) { memcpy (p_stored, p_value, len); } /* If need to change TLV in the original list. (Do not modify list if app_init) */ if ((updated_len != xx) && (!app_init)) { memcpy (p_tlv_list + updated_len, p_tlv_list + xx, (len + 2)); } updated_len += (len + 2); } xx += len + 2; /* move to next TLV */ } /* If any TVLs to update, or if the SetConfig was initiated by the application, then send the SET_CONFIG command */ //if (updated_len || app_init) /*Commented to fix the hack*/ if #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) (( #endif (updated_len || app_init) #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) && (appl_dta_mode_flag == 0x00 )) || ((appl_dta_mode_flag) && (app_init))) #endif { if ((nfc_status = NFC_SetConfig (updated_len, p_tlv_list)) == NFC_STATUS_OK) { /* Keep track of whether we will need to notify NFA_DM_SET_CONFIG_EVT on NFC_SET_CONFIG_REVT */ /* Get the next available bit offset for this setconfig (based on how many SetConfigs are outstanding) */ cur_bit = (UINT32) (1 << nfa_dm_cb.setcfg_pending_num); /* If setconfig is due to NFA_SetConfig: then set the bit (NFA_DM_SET_CONFIG_EVT needed on NFC_SET_CONFIG_REVT) */ if (app_init) { nfa_dm_cb.setcfg_pending_mask |= cur_bit; } /* Otherwise setconfig is internal: clear the bit (NFA_DM_SET_CONFIG_EVT not needed on NFC_SET_CONFIG_REVT) */ else { nfa_dm_cb.setcfg_pending_mask &= ~cur_bit; } /* Increment setcfg_pending counter */ nfa_dm_cb.setcfg_pending_num++; } return (nfc_status); } else { return NFA_STATUS_OK; } }