/*******************************************************************************
**
** 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);
    }

}
Exemple #5
0
/*******************************************************************************
**
** 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);
}
Exemple #6
0
/*******************************************************************************
**
** 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);
}