Home | History | Annotate | Download | only in nci
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2013 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         nfc_ncif_rf_management_status (NFC_START_DEVT, *pp);
    173         break;
    174 
    175     case NCI_MSG_RF_DISCOVER_SELECT:
    176         nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp);
    177         break;
    178 
    179     case NCI_MSG_RF_T3T_POLLING:
    180         break;
    181 
    182     case NCI_MSG_RF_DISCOVER_MAP:
    183         nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp);
    184         break;
    185 
    186     case NCI_MSG_RF_DEACTIVATE:
    187         nfc_ncif_proc_deactivate (*pp, *p_old, FALSE);
    188         break;
    189 
    190 #if (NFC_NFCEE_INCLUDED == TRUE)
    191 #if (NFC_RW_ONLY == FALSE)
    192 
    193     case NCI_MSG_RF_SET_ROUTING:
    194         nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp);
    195         break;
    196 
    197     case NCI_MSG_RF_GET_ROUTING:
    198         if (*pp != NFC_STATUS_OK)
    199             nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp);
    200         break;
    201 #endif
    202 #endif
    203 
    204     case NCI_MSG_RF_PARAMETER_UPDATE:
    205         nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
    206         break;
    207 
    208     default:
    209         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    210         break;
    211     }
    212 }
    213 
    214 /*******************************************************************************
    215 **
    216 ** Function         nci_proc_rf_management_ntf
    217 **
    218 ** Description      Process NCI notifications in the RF Management group
    219 **
    220 ** Returns          void
    221 **
    222 *******************************************************************************/
    223 void nci_proc_rf_management_ntf (BT_HDR *p_msg)
    224 {
    225     UINT8   *p;
    226     UINT8   *pp, len, op_code;
    227 
    228     /* find the start of the NCI message and parse the NCI header */
    229     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    230     pp  = p+1;
    231     NCI_MSG_PRS_HDR1 (pp, op_code);
    232     len = *pp++;
    233 
    234     switch (op_code)
    235     {
    236     case NCI_MSG_RF_DISCOVER :
    237         nfc_ncif_proc_discover_ntf (p, p_msg->len);
    238         break;
    239 
    240     case NCI_MSG_RF_DEACTIVATE:
    241         nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
    242         break;
    243 
    244     case NCI_MSG_RF_INTF_ACTIVATED:
    245         nfc_ncif_proc_activate (pp, len);
    246         break;
    247 
    248     case NCI_MSG_RF_FIELD:
    249         nfc_ncif_proc_rf_field_ntf (*pp);
    250         break;
    251 
    252     case NCI_MSG_RF_T3T_POLLING:
    253         nfc_ncif_proc_t3t_polling_ntf (pp, len);
    254         break;
    255 
    256 #if (NFC_NFCEE_INCLUDED == TRUE)
    257 #if (NFC_RW_ONLY == FALSE)
    258 
    259     case NCI_MSG_RF_GET_ROUTING:
    260         nfc_ncif_proc_get_routing (pp, len);
    261         break;
    262 
    263     case NCI_MSG_RF_EE_ACTION:
    264         nfc_ncif_proc_ee_action (pp, len);
    265         break;
    266 
    267     case NCI_MSG_RF_EE_DISCOVERY_REQ:
    268         nfc_ncif_proc_ee_discover_req (pp, len);
    269         break;
    270 #endif
    271 #endif
    272 
    273     default:
    274         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    275         break;
    276     }
    277 }
    278 
    279 #if (NFC_NFCEE_INCLUDED == TRUE)
    280 #if (NFC_RW_ONLY == FALSE)
    281 
    282 /*******************************************************************************
    283 **
    284 ** Function         nci_proc_ee_management_rsp
    285 **
    286 ** Description      Process NCI responses in the NFCEE Management group
    287 **
    288 ** Returns          void
    289 **
    290 *******************************************************************************/
    291 void nci_proc_ee_management_rsp (BT_HDR *p_msg)
    292 {
    293     UINT8   *p;
    294     UINT8   *pp, len, op_code;
    295     tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
    296     tNFC_NFCEE_DISCOVER_REVT    nfcee_discover;
    297     tNFC_NFCEE_INFO_REVT        nfcee_info;
    298     tNFC_NFCEE_MODE_SET_REVT    mode_set;
    299     tNFC_RESPONSE   *p_evt = (tNFC_RESPONSE *) &nfcee_info;
    300     tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
    301     UINT8   *p_old = nfc_cb.last_cmd;
    302 
    303     /* find the start of the NCI message and parse the NCI header */
    304     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    305     pp  = p+1;
    306     NCI_MSG_PRS_HDR1 (pp, op_code);
    307     NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
    308     len = *pp++;
    309 
    310     switch (op_code)
    311     {
    312     case NCI_MSG_NFCEE_DISCOVER:
    313         p_evt                       = (tNFC_RESPONSE *) &nfcee_discover;
    314         nfcee_discover.status       = *pp++;
    315         nfcee_discover.num_nfcee    = *pp++;
    316 
    317         if (nfcee_discover.status != NFC_STATUS_OK)
    318             nfcee_discover.num_nfcee    = 0;
    319 
    320         event                       = NFC_NFCEE_DISCOVER_REVT;
    321         break;
    322 
    323     case NCI_MSG_NFCEE_MODE_SET:
    324         p_evt                   = (tNFC_RESPONSE *) &mode_set;
    325         mode_set.status         = *pp;
    326         mode_set.nfcee_id       = 0;
    327         event                   = NFC_NFCEE_MODE_SET_REVT;
    328         mode_set.nfcee_id       = *p_old++;
    329         mode_set.mode           = *p_old++;
    330         break;
    331 
    332     default:
    333         p_cback = NULL;
    334         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    335         break;
    336     }
    337 
    338     if (p_cback)
    339         (*p_cback) (event, p_evt);
    340 }
    341 
    342 /*******************************************************************************
    343 **
    344 ** Function         nci_proc_ee_management_ntf
    345 **
    346 ** Description      Process NCI notifications in the NFCEE Management group
    347 **
    348 ** Returns          void
    349 **
    350 *******************************************************************************/
    351 void nci_proc_ee_management_ntf (BT_HDR *p_msg)
    352 {
    353     UINT8                 *p;
    354     UINT8                 *pp, len, op_code;
    355     tNFC_RESPONSE_CBACK   *p_cback = nfc_cb.p_resp_cback;
    356     tNFC_NFCEE_INFO_REVT  nfcee_info;
    357     tNFC_RESPONSE         *p_evt   = (tNFC_RESPONSE *) &nfcee_info;
    358     tNFC_RESPONSE_EVT     event    = NFC_NFCEE_INFO_REVT;
    359     UINT8                 xx;
    360     UINT8                 yy;
    361     UINT8                 ee_status;
    362     tNFC_NFCEE_TLV        *p_tlv;
    363 
    364     /* find the start of the NCI message and parse the NCI header */
    365     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
    366     pp  = p+1;
    367     NCI_MSG_PRS_HDR1 (pp, op_code);
    368     NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
    369     len = *pp++;
    370 
    371     if (op_code == NCI_MSG_NFCEE_DISCOVER)
    372     {
    373         nfcee_info.nfcee_id    = *pp++;
    374         ee_status                   = *pp++;
    375 
    376         nfcee_info.ee_status        = ee_status;
    377         yy                          = *pp;
    378         nfcee_info.num_interface    = *pp++;
    379         p                           = pp;
    380 
    381         if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
    382             nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
    383 
    384         for (xx = 0; xx < nfcee_info.num_interface; xx++)
    385         {
    386             nfcee_info.ee_interface[xx] = *pp++;
    387         }
    388 
    389         pp                              = p + yy;
    390         nfcee_info.num_tlvs             = *pp++;
    391         NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
    392             nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
    393 
    394         if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
    395             nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
    396 
    397         p_tlv = &nfcee_info.ee_tlv[0];
    398 
    399         for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
    400         {
    401             p_tlv->tag  = *pp++;
    402             p_tlv->len  = yy = *pp++;
    403             NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
    404             if (p_tlv->len > NFC_MAX_EE_INFO)
    405                 p_tlv->len = NFC_MAX_EE_INFO;
    406             p   = pp;
    407             STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len);
    408             pp  = p += yy;
    409         }
    410     }
    411     else
    412     {
    413         p_cback = NULL;
    414         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
    415     }
    416 
    417     if (p_cback)
    418         (*p_cback) (event, p_evt);
    419 }
    420 
    421 #endif
    422 #endif
    423 
    424 /*******************************************************************************
    425 **
    426 ** Function         nci_proc_prop_rsp
    427 **
    428 ** Description      Process NCI responses in the Proprietary group
    429 **
    430 ** Returns          void
    431 **
    432 *******************************************************************************/
    433 void nci_proc_prop_rsp (BT_HDR *p_msg)
    434 {
    435     UINT8   *p;
    436     UINT8   *p_evt;
    437     UINT8   *pp, len, op_code;
    438     tNFC_VS_CBACK   *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
    439 
    440     /* find the start of the NCI message and parse the NCI header */
    441     p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
    442     pp  = p+1;
    443     NCI_MSG_PRS_HDR1 (pp, op_code);
    444     len = *pp++;
    445 
    446     /*If there's a pending/stored command, restore the associated address of the callback function */
    447     if (p_cback)
    448         (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
    449 }
    450 
    451 /*******************************************************************************
    452 **
    453 ** Function         nci_proc_prop_ntf
    454 **
    455 ** Description      Process NCI notifications in the Proprietary group
    456 **
    457 ** Returns          void
    458 **
    459 *******************************************************************************/
    460 void nci_proc_prop_ntf (BT_HDR *p_msg)
    461 {
    462     UINT8   *p;
    463     UINT8   *p_evt;
    464     UINT8   *pp, len, op_code;
    465     int i;
    466 
    467     /* find the start of the NCI message and parse the NCI header */
    468     p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
    469     pp  = p+1;
    470     NCI_MSG_PRS_HDR1 (pp, op_code);
    471     len = *pp++;
    472 
    473     for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
    474     {
    475         if (nfc_cb.p_vs_cb[i])
    476         {
    477             (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt);
    478         }
    479     }
    480 }
    481 
    482 #endif /* NFC_INCLUDED == TRUE*/
    483