Home | History | Annotate | Download | only in nci
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2014 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 
     20 /******************************************************************************
     21  *
     22  *  This file contains function of the NFC unit to receive/process NCI
     23  *  commands.
     24  *
     25  ******************************************************************************/
     26 #include <string.h>
     27 #include "nfc_target.h"
     28 #include "bt_types.h"
     29 #include "gki.h"
     30 
     31 #if NFC_INCLUDED == TRUE
     32 #include "nci_defs.h"
     33 #include "nci_hmsgs.h"
     34 #include "nfc_api.h"
     35 #include "nfc_int.h"
     36 
     37 /*******************************************************************************
     38 **
     39 ** Function         nci_proc_core_rsp
     40 **
     41 ** Description      Process NCI responses in the CORE group
     42 **
     43 ** Returns          TRUE-caller of this function to free the GKI buffer p_msg
     44 **
     45 *******************************************************************************/
     46 BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg)
     47 {
     48     UINT8   *p;
     49     UINT8   *pp, len, op_code;
     50     BOOLEAN free = TRUE;
     51     UINT8   *p_old = nfc_cb.last_cmd;
     52 
     53     /* find the start of the NCI message and parse the NCI header */
     54     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
     55     pp  = p+1;
     56     NCI_MSG_PRS_HDR1 (pp, op_code);
     57     NFC_TRACE_DEBUG1 ("nci_proc_core_rsp opcode:0x%x", op_code);
     58     len = *pp++;
     59 
     60     /* process the message based on the opcode and message type */
     61     switch (op_code)
     62     {
     63     case NCI_MSG_CORE_RESET:
     64         nfc_ncif_proc_reset_rsp (pp, FALSE);
     65         break;
     66 
     67     case NCI_MSG_CORE_INIT:
     68         nfc_ncif_proc_init_rsp (p_msg);
     69         free = FALSE;
     70         break;
     71 
     72     case NCI_MSG_CORE_GET_CONFIG:
     73         nfc_ncif_proc_get_config_rsp (p_msg);
     74         break;
     75 
     76     case NCI_MSG_CORE_SET_CONFIG:
     77         nfc_ncif_set_config_status (pp, len);
     78         break;
     79 
     80     case NCI_MSG_CORE_CONN_CREATE:
     81         nfc_ncif_proc_conn_create_rsp (p, p_msg->len, *p_old);
     82         break;
     83 
     84     case NCI_MSG_CORE_CONN_CLOSE:
     85         nfc_ncif_report_conn_close_evt (*p_old, *pp);
     86         break;
     87 
     88     default:
     89         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
     90         break;
     91     }
     92 
     93     return free;
     94 }
     95 
     96 /*******************************************************************************
     97 **
     98 ** Function         nci_proc_core_ntf
     99 **
    100 ** Description      Process NCI notifications in the CORE group
    101 **
    102 ** Returns          void
    103 **
    104 *******************************************************************************/
    105 void nci_proc_core_ntf (BT_HDR *p_msg)
    106 {
    107     UINT8   *p;
    108     UINT8   *pp, len, op_code;
    109     UINT8   conn_id;
    110 
    111     /* find the start of the NCI message and parse the NCI header */
    112     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    113     pp  = p+1;
    114     NCI_MSG_PRS_HDR1 (pp, op_code);
    115     NFC_TRACE_DEBUG1 ("nci_proc_core_ntf opcode:0x%x", op_code);
    116     len = *pp++;
    117 
    118     /* process the message based on the opcode and message type */
    119     switch (op_code)
    120     {
    121     case NCI_MSG_CORE_RESET:
    122         nfc_ncif_proc_reset_rsp (pp, TRUE);
    123         break;
    124 
    125     case NCI_MSG_CORE_GEN_ERR_STATUS:
    126         /* process the error ntf */
    127         /* in case of timeout: notify the static connection callback */
    128         nfc_ncif_event_status (NFC_GEN_ERROR_REVT, *pp);
    129         nfc_ncif_error_status (NFC_RF_CONN_ID, *pp);
    130         break;
    131 
    132     case NCI_MSG_CORE_INTF_ERR_STATUS:
    133         conn_id = *(pp+1);
    134         nfc_ncif_error_status (conn_id, *pp);
    135         break;
    136 
    137     case NCI_MSG_CORE_CONN_CREDITS:
    138         nfc_ncif_proc_credits(pp, len);
    139         break;
    140 
    141     default:
    142         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    143         break;
    144     }
    145 }
    146 
    147 
    148 /*******************************************************************************
    149 **
    150 ** Function         nci_proc_rf_management_rsp
    151 **
    152 ** Description      Process NCI responses in the RF Management group
    153 **
    154 ** Returns          void
    155 **
    156 *******************************************************************************/
    157 void nci_proc_rf_management_rsp (BT_HDR *p_msg)
    158 {
    159     UINT8   *p;
    160     UINT8   *pp, len, op_code;
    161     UINT8   *p_old = nfc_cb.last_cmd;
    162 
    163     /* find the start of the NCI message and parse the NCI header */
    164     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    165     pp  = p+1;
    166     NCI_MSG_PRS_HDR1 (pp, op_code);
    167     len = *pp++;
    168 
    169     switch (op_code)
    170     {
    171     case NCI_MSG_RF_DISCOVER:
    172         nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_RSP);
    173         nfc_ncif_rf_management_status (NFC_START_DEVT, *pp);
    174         break;
    175 
    176     case NCI_MSG_RF_DISCOVER_SELECT:
    177         nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp);
    178         break;
    179 
    180     case NCI_MSG_RF_T3T_POLLING:
    181         break;
    182 
    183     case NCI_MSG_RF_DISCOVER_MAP:
    184         nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp);
    185         break;
    186 
    187     case NCI_MSG_RF_DEACTIVATE:
    188         if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_RSP))
    189         {
    190             return;
    191         }
    192         nfc_ncif_proc_deactivate (*pp, *p_old, FALSE);
    193         break;
    194 
    195 #if (NFC_NFCEE_INCLUDED == TRUE)
    196 #if (NFC_RW_ONLY == FALSE)
    197 
    198     case NCI_MSG_RF_SET_ROUTING:
    199         nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp);
    200         break;
    201 
    202     case NCI_MSG_RF_GET_ROUTING:
    203         if (*pp != NFC_STATUS_OK)
    204             nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp);
    205         break;
    206 #endif
    207 #endif
    208 
    209     case NCI_MSG_RF_PARAMETER_UPDATE:
    210         nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
    211         break;
    212 
    213     default:
    214         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    215         break;
    216     }
    217 }
    218 
    219 /*******************************************************************************
    220 **
    221 ** Function         nci_proc_rf_management_ntf
    222 **
    223 ** Description      Process NCI notifications in the RF Management group
    224 **
    225 ** Returns          void
    226 **
    227 *******************************************************************************/
    228 void nci_proc_rf_management_ntf (BT_HDR *p_msg)
    229 {
    230     UINT8   *p;
    231     UINT8   *pp, len, op_code;
    232 
    233     /* find the start of the NCI message and parse the NCI header */
    234     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    235     pp  = p+1;
    236     NCI_MSG_PRS_HDR1 (pp, op_code);
    237     len = *pp++;
    238 
    239     switch (op_code)
    240     {
    241     case NCI_MSG_RF_DISCOVER :
    242         nfc_ncif_proc_discover_ntf (p, p_msg->len);
    243         break;
    244 
    245     case NCI_MSG_RF_DEACTIVATE:
    246         if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_NTF))
    247         {
    248             return;
    249         }
    250         nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
    251         break;
    252 
    253     case NCI_MSG_RF_INTF_ACTIVATED:
    254         if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_NTF))
    255         {
    256             return;
    257         }
    258         nfc_ncif_proc_activate (pp, len);
    259         break;
    260 
    261     case NCI_MSG_RF_FIELD:
    262         nfc_ncif_proc_rf_field_ntf (*pp);
    263         break;
    264 
    265     case NCI_MSG_RF_T3T_POLLING:
    266         nfc_ncif_proc_t3t_polling_ntf (pp, len);
    267         break;
    268 
    269 #if (NFC_NFCEE_INCLUDED == TRUE)
    270 #if (NFC_RW_ONLY == FALSE)
    271 
    272     case NCI_MSG_RF_GET_ROUTING:
    273         nfc_ncif_proc_get_routing (pp, len);
    274         break;
    275 
    276     case NCI_MSG_RF_EE_ACTION:
    277         nfc_ncif_proc_ee_action (pp, len);
    278         break;
    279 
    280     case NCI_MSG_RF_EE_DISCOVERY_REQ:
    281         nfc_ncif_proc_ee_discover_req (pp, len);
    282         break;
    283 #endif
    284 #endif
    285 
    286     default:
    287         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    288         break;
    289     }
    290 }
    291 
    292 #if (NFC_NFCEE_INCLUDED == TRUE)
    293 #if (NFC_RW_ONLY == FALSE)
    294 
    295 /*******************************************************************************
    296 **
    297 ** Function         nci_proc_ee_management_rsp
    298 **
    299 ** Description      Process NCI responses in the NFCEE Management group
    300 **
    301 ** Returns          void
    302 **
    303 *******************************************************************************/
    304 void nci_proc_ee_management_rsp (BT_HDR *p_msg)
    305 {
    306     UINT8   *p;
    307     UINT8   *pp, len, op_code;
    308     tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
    309     tNFC_NFCEE_DISCOVER_REVT    nfcee_discover;
    310     tNFC_NFCEE_INFO_REVT        nfcee_info;
    311     tNFC_NFCEE_MODE_SET_REVT    mode_set;
    312     tNFC_RESPONSE   *p_evt = (tNFC_RESPONSE *) &nfcee_info;
    313     tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
    314     UINT8   *p_old = nfc_cb.last_cmd;
    315 
    316     /* find the start of the NCI message and parse the NCI header */
    317     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    318     pp  = p+1;
    319     NCI_MSG_PRS_HDR1 (pp, op_code);
    320     NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
    321     len = *pp++;
    322 
    323     switch (op_code)
    324     {
    325     case NCI_MSG_NFCEE_DISCOVER:
    326         p_evt                       = (tNFC_RESPONSE *) &nfcee_discover;
    327         nfcee_discover.status       = *pp++;
    328         nfcee_discover.num_nfcee    = *pp++;
    329 
    330         if (nfcee_discover.status != NFC_STATUS_OK)
    331             nfcee_discover.num_nfcee    = 0;
    332 
    333         event                       = NFC_NFCEE_DISCOVER_REVT;
    334         break;
    335 
    336     case NCI_MSG_NFCEE_MODE_SET:
    337         p_evt                   = (tNFC_RESPONSE *) &mode_set;
    338         mode_set.status         = *pp;
    339         mode_set.nfcee_id       = 0;
    340         event                   = NFC_NFCEE_MODE_SET_REVT;
    341         mode_set.nfcee_id       = *p_old++;
    342         mode_set.mode           = *p_old++;
    343         break;
    344 
    345     default:
    346         p_cback = NULL;
    347         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    348         break;
    349     }
    350 
    351     if (p_cback)
    352         (*p_cback) (event, p_evt);
    353 }
    354 
    355 /*******************************************************************************
    356 **
    357 ** Function         nci_proc_ee_management_ntf
    358 **
    359 ** Description      Process NCI notifications in the NFCEE Management group
    360 **
    361 ** Returns          void
    362 **
    363 *******************************************************************************/
    364 void nci_proc_ee_management_ntf (BT_HDR *p_msg)
    365 {
    366     UINT8                 *p;
    367     UINT8                 *pp, len, op_code;
    368     tNFC_RESPONSE_CBACK   *p_cback = nfc_cb.p_resp_cback;
    369     tNFC_NFCEE_INFO_REVT  nfcee_info;
    370     tNFC_RESPONSE         *p_evt   = (tNFC_RESPONSE *) &nfcee_info;
    371     tNFC_RESPONSE_EVT     event    = NFC_NFCEE_INFO_REVT;
    372     UINT8                 xx;
    373     UINT8                 yy;
    374     UINT8                 ee_status;
    375     tNFC_NFCEE_TLV        *p_tlv;
    376 
    377     /* find the start of the NCI message and parse the NCI header */
    378     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    379     pp  = p+1;
    380     NCI_MSG_PRS_HDR1 (pp, op_code);
    381     NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
    382     len = *pp++;
    383 
    384     if (op_code == NCI_MSG_NFCEE_DISCOVER)
    385     {
    386         nfcee_info.nfcee_id    = *pp++;
    387         ee_status                   = *pp++;
    388 
    389         nfcee_info.ee_status        = ee_status;
    390         yy                          = *pp;
    391         nfcee_info.num_interface    = *pp++;
    392         p                           = pp;
    393 
    394         if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
    395             nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
    396 
    397         for (xx = 0; xx < nfcee_info.num_interface; xx++)
    398         {
    399             nfcee_info.ee_interface[xx] = *pp++;
    400         }
    401 
    402         pp                              = p + yy;
    403         nfcee_info.num_tlvs             = *pp++;
    404         NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
    405             nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
    406 
    407         if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
    408             nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
    409 
    410         p_tlv = &nfcee_info.ee_tlv[0];
    411 
    412         for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
    413         {
    414             p_tlv->tag  = *pp++;
    415             p_tlv->len  = yy = *pp++;
    416             NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
    417             if (p_tlv->len > NFC_MAX_EE_INFO)
    418                 p_tlv->len = NFC_MAX_EE_INFO;
    419             p   = pp;
    420             STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len);
    421             pp  = p += yy;
    422         }
    423     }
    424     else
    425     {
    426         p_cback = NULL;
    427         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    428     }
    429 
    430     if (p_cback)
    431         (*p_cback) (event, p_evt);
    432 }
    433 
    434 #endif
    435 #endif
    436 
    437 /*******************************************************************************
    438 **
    439 ** Function         nci_proc_prop_rsp
    440 **
    441 ** Description      Process NCI responses in the Proprietary group
    442 **
    443 ** Returns          void
    444 **
    445 *******************************************************************************/
    446 void nci_proc_prop_rsp (BT_HDR *p_msg)
    447 {
    448     UINT8   *p;
    449     UINT8   *p_evt;
    450     UINT8   *pp, len, op_code;
    451     tNFC_VS_CBACK   *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
    452 
    453     /* find the start of the NCI message and parse the NCI header */
    454     p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
    455     pp  = p+1;
    456     NCI_MSG_PRS_HDR1 (pp, op_code);
    457     len = *pp++;
    458 
    459     /*If there's a pending/stored command, restore the associated address of the callback function */
    460     if (p_cback)
    461         (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
    462 }
    463 
    464 /*******************************************************************************
    465 **
    466 ** Function         nci_proc_prop_ntf
    467 **
    468 ** Description      Process NCI notifications in the Proprietary group
    469 **
    470 ** Returns          void
    471 **
    472 *******************************************************************************/
    473 void nci_proc_prop_ntf (BT_HDR *p_msg)
    474 {
    475     UINT8   *p;
    476     UINT8   *p_evt;
    477     UINT8   *pp, len, op_code;
    478     int i;
    479 
    480     /* find the start of the NCI message and parse the NCI header */
    481     p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
    482     pp  = p+1;
    483     NCI_MSG_PRS_HDR1 (pp, op_code);
    484     len = *pp++;
    485 
    486     for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
    487     {
    488         if (nfc_cb.p_vs_cb[i])
    489         {
    490             (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt);
    491         }
    492     }
    493 }
    494 
    495 #endif /* NFC_INCLUDED == TRUE*/
    496