/******************************************************************************* ** ** Function nfa_hciu_alloc_pipe ** ** Description Allocate a pipe control block ** ** Returns pointer to the pipe control block, or NULL if ** cannot allocate ** *******************************************************************************/ tNFA_HCI_DYN_PIPE *nfa_hciu_alloc_pipe (UINT8 pipe_id) { UINT8 xx; tNFA_HCI_DYN_PIPE *pp; /* If we already have a pipe of the same ID, release it first it */ if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL) { if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) return pp; nfa_hciu_release_pipe (pipe_id); } /* Look for a free pipe control block */ for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) { if (pp->pipe_id == 0) { NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx); pp->pipe_id = pipe_id; nfa_hci_cb.nv_write_needed = TRUE; return (pp); } } NFA_TRACE_DEBUG1 ("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id); return (NULL); }
/******************************************************************************* ** ** 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_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 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_ee_proc_evt ** ** Description Process NFCEE related events from NFC stack ** ** ** Returns None ** *******************************************************************************/ void nfa_ee_proc_evt (tNFC_RESPONSE_EVT event, void *p_data) { tNFA_EE_INT_EVT int_event=0; tNFA_EE_NCI_WAIT_RSP cbk; BT_HDR *p_hdr; switch (event) { case NFC_NFCEE_DISCOVER_REVT: /* 4 NFCEE Discover response */ int_event = NFA_EE_NCI_DISC_RSP_EVT; break; case NFC_NFCEE_INFO_REVT: /* 5 NFCEE Discover Notification */ int_event = NFA_EE_NCI_DISC_NTF_EVT; break; case NFC_NFCEE_MODE_SET_REVT: /* 6 NFCEE Mode Set response */ int_event = NFA_EE_NCI_MODE_SET_RSP_EVT; break; case NFC_EE_ACTION_REVT: int_event = NFA_EE_NCI_ACTION_NTF_EVT; break; case NFC_EE_DISCOVER_REQ_REVT: /* 10 EE Discover Req notification */ int_event = NFA_EE_NCI_DISC_REQ_NTF_EVT; break; case NFC_SET_ROUTING_REVT: int_event = NFA_EE_NCI_WAIT_RSP_EVT; cbk.opcode = NCI_MSG_RF_SET_ROUTING; break; } NFA_TRACE_DEBUG2 ("nfa_ee_proc_evt: event=0x%02x int_event:0x%x", event, int_event); if (int_event) { p_hdr = (BT_HDR *) &cbk; cbk.hdr.event = int_event; cbk.p_data = p_data; nfa_ee_evt_hdlr (p_hdr); } }
/******************************************************************************* ** ** Function NFA_EeGetInfo ** ** Description This function retrieves the NFCEE information from NFA. ** The actual number of NFCEE is returned in p_num_nfcee ** and NFCEE information is returned in p_info ** ** Returns NFA_STATUS_OK if information is retrieved successfully ** NFA_STATUS_FAILED If wrong state (retry later) ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeGetInfo(UINT8 *p_num_nfcee, tNFA_EE_INFO *p_info) { int xx, ret = nfa_ee_cb.cur_ee; tNFA_EE_ECB *p_cb = nfa_ee_cb.ecb; UINT8 max_ret; UINT8 num_ret = 0; NFA_TRACE_DEBUG2 ("NFA_EeGetInfo em_state:%d cur_ee:%d", nfa_ee_cb.em_state, nfa_ee_cb.cur_ee); /* validate parameters */ if (p_info == NULL || p_num_nfcee == NULL) { NFA_TRACE_ERROR0 ("NFA_EeGetInfo bad parameter"); return (NFA_STATUS_INVALID_PARAM); } max_ret = *p_num_nfcee; *p_num_nfcee = 0; if (nfa_ee_cb.em_state == NFA_EE_EM_STATE_INIT) { NFA_TRACE_ERROR1 ("NFA_EeGetInfo bad em state: %d", nfa_ee_cb.em_state); return (NFA_STATUS_FAILED); } /* compose output */ for (xx = 0; (xx < ret) && (num_ret < max_ret); xx++, p_cb++) { NFA_TRACE_DEBUG4 ("xx:%d max_ret:%d, num_ret:%d ee_status:0x%x", xx, max_ret, num_ret, p_cb->ee_status); if ((p_cb->ee_status & NFA_EE_STATUS_INT_MASK) || (p_cb->ee_status == NFA_EE_STATUS_REMOVED)) { continue; } p_info->ee_handle = NFA_HANDLE_GROUP_EE | (tNFA_HANDLE)p_cb->nfcee_id; p_info->ee_status = p_cb->ee_status; p_info->num_interface = p_cb->num_interface; p_info->num_tlvs = p_cb->num_tlvs; memcpy(p_info->ee_interface, p_cb->ee_interface, p_cb->num_interface); memcpy(p_info->ee_tlv, p_cb->ee_tlv, p_cb->num_tlvs * sizeof(tNFA_EE_TLV)); p_info++; num_ret++; } NFA_TRACE_DEBUG1 ("num_ret:%d", num_ret); *p_num_nfcee = num_ret; return (NFA_STATUS_OK); }
/******************************************************************************* ** ** Function NFA_EeAddAidRouting ** ** Description This function is called to add an AID entry in the ** listen mode routing table in NFCC. The status of this ** operation is reported as the NFA_EE_ADD_AID_EVT. ** ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT ** should happen before calling this function ** ** Note: NFA_EeUpdateNow() should be called after last NFA-EE function ** to change the listen mode routing is called. ** ** Returns NFA_STATUS_OK if successfully initiated ** NFA_STATUS_FAILED otherwise ** NFA_STATUS_INVALID_PARAM If bad parameter ** *******************************************************************************/ tNFA_STATUS NFA_EeAddAidRouting(tNFA_HANDLE ee_handle, UINT8 aid_len, UINT8 *p_aid, tNFA_EE_PWR_STATE power_state) { tNFA_EE_API_ADD_AID *p_msg; tNFA_STATUS status = NFA_STATUS_FAILED; UINT16 size = sizeof(tNFA_EE_API_ADD_AID) + aid_len; UINT8 nfcee_id = (UINT8)(ee_handle & 0xFF); tNFA_EE_ECB *p_cb; NFA_TRACE_API1 ("NFA_EeAddAidRouting(): handle:<0x%x>", ee_handle); p_cb = nfa_ee_find_ecb (nfcee_id); /* validate parameters - make sure the AID is in valid length range */ if ((p_cb == NULL) || (aid_len == 0) || (p_aid == NULL) || (aid_len < NFA_MIN_AID_LEN) || (aid_len > NFA_MAX_AID_LEN)) { NFA_TRACE_ERROR1 ("Bad ee_handle or AID (len=%d)", aid_len); status = NFA_STATUS_INVALID_PARAM; } else if ((p_msg = (tNFA_EE_API_ADD_AID *) GKI_getbuf (size)) != NULL) { NFA_TRACE_DEBUG2 ("aid:<%02x%02x>", p_aid[0], p_aid[1]); p_msg->hdr.event = NFA_EE_API_ADD_AID_EVT; p_msg->nfcee_id = nfcee_id; p_msg->p_cb = p_cb; p_msg->aid_len = aid_len; p_msg->power_state = power_state; p_msg->p_aid = (UINT8 *)(p_msg + 1); memcpy(p_msg->p_aid, p_aid, aid_len); nfa_sys_sendmsg (p_msg); status = NFA_STATUS_OK; } return status; }
/******************************************************************************* ** ** Function nfa_hciu_alloc_gate ** ** Description Allocate an gate control block ** ** Returns pointer to the allocated gate, or NULL if cannot allocate ** *******************************************************************************/ tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle) { tNFA_HCI_DYN_GATE *pg; int xx; UINT8 app_inx = app_handle & NFA_HANDLE_MASK; /* First, check if the application handle is valid */ if ( (gate_id != NFA_HCI_CONNECTIVITY_GATE) &&(gate_id < NFA_HCI_FIRST_PROP_GATE) &&(( (app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI) ||(app_inx >= NFA_HCI_MAX_APP_CB) ||(nfa_hci_cb.p_app_cback[app_inx] == NULL)) ) { return (NULL); } if (gate_id != 0) { if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL) return (pg); } else { /* If gate_id is 0, we need to assign a free one */ /* Loop through all possible gate IDs checking if they are already used */ for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id <= NFA_HCI_LAST_PROP_GATE; gate_id++) { /* Skip connectivity gate */ if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++; /* Check if the gate is already allocated */ if (nfa_hciu_find_gate_by_gid (gate_id) == NULL) break; } if (gate_id > NFA_HCI_LAST_PROP_GATE) { NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u App Handle: 0x%04x", gate_id, app_handle); return (NULL); } } /* Now look for a free control block */ for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) { if (pg->gate_id == 0) { /* Found a free gate control block */ pg->gate_id = gate_id; pg->gate_owner = app_handle; pg->pipe_inx_mask = 0; NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d app_handle: 0x%04x", gate_id, app_handle); nfa_hci_cb.nv_write_needed = TRUE; return (pg); } } /* If here, no free gate control block */ NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB Gate ID: %u App Handle: 0x%04x", gate_id, app_handle); return (NULL); }