Home | History | Annotate | Download | only in nfc
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 1999-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  *  This file contains functions that interface with the NFC NCI transport.
     22  *  On the receive side, it routes events to the appropriate handler
     23  *  (callback). On the transmit side, it manages the command transmission.
     24  *
     25  ******************************************************************************/
     26 #include <stdlib.h>
     27 #include <string.h>
     28 #include "nfc_target.h"
     29 
     30 #include "nci_defs.h"
     31 #include "nci_hmsgs.h"
     32 #include "nfc_api.h"
     33 #include "nfc_hal_api.h"
     34 #include "nfc_int.h"
     35 #include "rw_api.h"
     36 #include "rw_int.h"
     37 
     38 #if (NFC_RW_ONLY == FALSE)
     39 static const uint8_t nfc_mpl_code_to_size[] = {64, 128, 192, 254};
     40 
     41 #endif /* NFC_RW_ONLY */
     42 
     43 #define NFC_PB_ATTRIB_REQ_FIXED_BYTES 1
     44 #define NFC_LB_ATTRIB_REQ_FIXED_BYTES 8
     45 
     46 /*******************************************************************************
     47 **
     48 ** Function         nfc_ncif_update_window
     49 **
     50 ** Description      Update tx cmd window to indicate that NFCC can received
     51 **
     52 ** Returns          void
     53 **
     54 *******************************************************************************/
     55 void nfc_ncif_update_window(void) {
     56   /* Sanity check - see if we were expecting a update_window */
     57   if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW) {
     58     if (nfc_cb.nfc_state != NFC_STATE_W4_HAL_CLOSE) {
     59       NFC_TRACE_ERROR0("nfc_ncif_update_window: Unexpected call");
     60     }
     61     return;
     62   }
     63 
     64   /* Stop command-pending timer */
     65   nfc_stop_timer(&nfc_cb.nci_wait_rsp_timer);
     66 
     67   nfc_cb.p_vsc_cback = NULL;
     68   nfc_cb.nci_cmd_window++;
     69 
     70   /* Check if there were any commands waiting to be sent */
     71   nfc_ncif_check_cmd_queue(NULL);
     72 }
     73 
     74 /*******************************************************************************
     75 **
     76 ** Function         nfc_ncif_cmd_timeout
     77 **
     78 ** Description      Handle a command timeout
     79 **
     80 ** Returns          void
     81 **
     82 *******************************************************************************/
     83 void nfc_ncif_cmd_timeout(void) {
     84   NFC_TRACE_ERROR0("nfc_ncif_cmd_timeout");
     85 
     86   /* report an error */
     87   nfc_ncif_event_status(NFC_GEN_ERROR_REVT, NFC_STATUS_HW_TIMEOUT);
     88   nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
     89 
     90   /* if enabling NFC, notify upper layer of failure */
     91   if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT) {
     92     nfc_enabled(NFC_STATUS_FAILED, NULL);
     93   }
     94 
     95   /* XXX maco since this failure is unrecoverable, abort the process */
     96   abort();
     97 }
     98 
     99 /*******************************************************************************
    100 **
    101 ** Function         nfc_wait_2_deactivate_timeout
    102 **
    103 ** Description      Handle a command timeout
    104 **
    105 ** Returns          void
    106 **
    107 *******************************************************************************/
    108 void nfc_wait_2_deactivate_timeout(void) {
    109   NFC_TRACE_ERROR0("nfc_wait_2_deactivate_timeout");
    110   nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
    111   nci_snd_deactivate_cmd((uint8_t)nfc_cb.deactivate_timer.param);
    112 }
    113 
    114 /*******************************************************************************
    115 **
    116 ** Function         nfc_ncif_send_data
    117 **
    118 ** Description      This function is called to add the NCI data header
    119 **                  and send it to NCIT task for sending it to transport
    120 **                  as credits are available.
    121 **
    122 ** Returns          void
    123 **
    124 *******************************************************************************/
    125 uint8_t nfc_ncif_send_data(tNFC_CONN_CB* p_cb, NFC_HDR* p_data) {
    126   uint8_t* pp;
    127   uint8_t* ps;
    128   uint8_t ulen = NCI_MAX_PAYLOAD_SIZE;
    129   NFC_HDR* p;
    130   uint8_t pbf = 1;
    131   uint8_t buffer_size = p_cb->buff_size;
    132   uint8_t hdr0 = p_cb->conn_id;
    133   bool fragmented = false;
    134 
    135   NFC_TRACE_DEBUG3("nfc_ncif_send_data :%d, num_buff:%d qc:%d", p_cb->conn_id,
    136                    p_cb->num_buff, p_cb->tx_q.count);
    137   if (p_cb->id == NFC_RF_CONN_ID) {
    138     if (nfc_cb.nfc_state != NFC_STATE_OPEN) {
    139       if (nfc_cb.nfc_state == NFC_STATE_CLOSING) {
    140         if ((p_data == NULL) && /* called because credit from NFCC */
    141             (nfc_cb.flags & NFC_FL_DEACTIVATING)) {
    142           if (p_cb->init_credits == p_cb->num_buff) {
    143             /* all the credits are back */
    144             nfc_cb.flags &= ~NFC_FL_DEACTIVATING;
    145             NFC_TRACE_DEBUG2(
    146                 "deactivating NFC-DEP init_credits:%d, num_buff:%d",
    147                 p_cb->init_credits, p_cb->num_buff);
    148             nfc_stop_timer(&nfc_cb.deactivate_timer);
    149             nci_snd_deactivate_cmd((uint8_t)nfc_cb.deactivate_timer.param);
    150           }
    151         }
    152       }
    153       return NCI_STATUS_FAILED;
    154     }
    155   }
    156 
    157   if (p_data) {
    158     /* always enqueue the data to the tx queue */
    159     GKI_enqueue(&p_cb->tx_q, p_data);
    160   }
    161 
    162   /* try to send the first data packet in the tx queue  */
    163   p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q);
    164 
    165   /* post data fragment to NCIT task as credits are available */
    166   while (p_data && (p_data->len >= 0) && (p_cb->num_buff > 0)) {
    167     if (p_data->len <= buffer_size) {
    168       pbf = 0; /* last fragment */
    169       ulen = (uint8_t)(p_data->len);
    170       fragmented = false;
    171     } else {
    172       fragmented = true;
    173       ulen = buffer_size;
    174     }
    175 
    176     if (!fragmented) {
    177       /* if data packet is not fragmented, use the original buffer */
    178       p = p_data;
    179       p_data = (NFC_HDR*)GKI_dequeue(&p_cb->tx_q);
    180     } else {
    181       /* the data packet is too big and need to be fragmented
    182        * prepare a new GKI buffer
    183        * (even the last fragment to avoid issues) */
    184       p = NCI_GET_CMD_BUF(ulen);
    185       if (p == NULL) return (NCI_STATUS_BUFFER_FULL);
    186       p->len = ulen;
    187       p->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
    188       if (p->len) {
    189         pp = (uint8_t*)(p + 1) + p->offset;
    190         ps = (uint8_t*)(p_data + 1) + p_data->offset;
    191         memcpy(pp, ps, ulen);
    192       }
    193       /* adjust the NFC_HDR on the old fragment */
    194       p_data->len -= ulen;
    195       p_data->offset += ulen;
    196     }
    197 
    198     p->event = BT_EVT_TO_NFC_NCI;
    199     p->layer_specific = pbf;
    200     p->len += NCI_DATA_HDR_SIZE;
    201     p->offset -= NCI_DATA_HDR_SIZE;
    202     pp = (uint8_t*)(p + 1) + p->offset;
    203     /* build NCI Data packet header */
    204     NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen);
    205 
    206     if (p_cb->num_buff != NFC_CONN_NO_FC) p_cb->num_buff--;
    207 
    208     /* send to HAL */
    209     HAL_WRITE(p);
    210 
    211     if (!fragmented) {
    212       /* check if there are more data to send */
    213       p_data = (NFC_HDR*)GKI_getfirst(&p_cb->tx_q);
    214     }
    215   }
    216 
    217   return (NCI_STATUS_OK);
    218 }
    219 
    220 /*******************************************************************************
    221 **
    222 ** Function         nfc_ncif_check_cmd_queue
    223 **
    224 ** Description      Send NCI command to the transport
    225 **
    226 ** Returns          void
    227 **
    228 *******************************************************************************/
    229 void nfc_ncif_check_cmd_queue(NFC_HDR* p_buf) {
    230   uint8_t* ps;
    231   /* If there are commands waiting in the xmit queue, or if the controller
    232    * cannot accept any more commands, */
    233   /* then enqueue this command */
    234   if (p_buf) {
    235     if ((nfc_cb.nci_cmd_xmit_q.count) || (nfc_cb.nci_cmd_window == 0)) {
    236       GKI_enqueue(&nfc_cb.nci_cmd_xmit_q, p_buf);
    237       p_buf = NULL;
    238     }
    239   }
    240 
    241   /* If controller can accept another command, then send the next command */
    242   if (nfc_cb.nci_cmd_window > 0) {
    243     /* If no command was provided, or if older commands were in the queue, then
    244      * get cmd from the queue */
    245     if (!p_buf) p_buf = (NFC_HDR*)GKI_dequeue(&nfc_cb.nci_cmd_xmit_q);
    246 
    247     if (p_buf) {
    248       /* save the message header to double check the response */
    249       ps = (uint8_t*)(p_buf + 1) + p_buf->offset;
    250       memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE);
    251       memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE);
    252       if (p_buf->layer_specific == NFC_WAIT_RSP_VSC) {
    253         /* save the callback for NCI VSCs)  */
    254         nfc_cb.p_vsc_cback = (void*)((tNFC_NCI_VS_MSG*)p_buf)->p_cback;
    255       }
    256 
    257       /* send to HAL */
    258       HAL_WRITE(p_buf);
    259 
    260       /* Indicate command is pending */
    261       nfc_cb.nci_cmd_window--;
    262 
    263       /* start NFC command-timeout timer */
    264       nfc_start_timer(&nfc_cb.nci_wait_rsp_timer,
    265                       (uint16_t)(NFC_TTYPE_NCI_WAIT_RSP),
    266                       nfc_cb.nci_wait_rsp_tout);
    267     }
    268   }
    269 
    270   if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW) {
    271     /* the command queue must be empty now */
    272     if (nfc_cb.flags & NFC_FL_CONTROL_REQUESTED) {
    273       /* HAL requested control or stack needs to handle pre-discover */
    274       nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
    275       if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING) {
    276         if (nfc_cb.p_hal->prediscover()) {
    277           /* HAL has the command window now */
    278           nfc_cb.flags |= NFC_FL_CONTROL_GRANTED;
    279           nfc_cb.nci_cmd_window = 0;
    280         } else {
    281           /* HAL does not need to send command,
    282            * - restore the command window and issue the discovery command now */
    283           nfc_cb.flags &= ~NFC_FL_DISCOVER_PENDING;
    284           ps = (uint8_t*)nfc_cb.p_disc_pending;
    285           nci_snd_discover_cmd(*ps, (tNFC_DISCOVER_PARAMS*)(ps + 1));
    286           GKI_freebuf(nfc_cb.p_disc_pending);
    287           nfc_cb.p_disc_pending = NULL;
    288         }
    289       } else if (nfc_cb.flags & NFC_FL_HAL_REQUESTED) {
    290         /* grant the control to HAL */
    291         nfc_cb.flags &= ~NFC_FL_HAL_REQUESTED;
    292         nfc_cb.flags |= NFC_FL_CONTROL_GRANTED;
    293         nfc_cb.nci_cmd_window = 0;
    294         nfc_cb.p_hal->control_granted();
    295       }
    296     }
    297   }
    298 }
    299 
    300 /*******************************************************************************
    301 **
    302 ** Function         nfc_ncif_send_cmd
    303 **
    304 ** Description      Send NCI command to the NCIT task
    305 **
    306 ** Returns          void
    307 **
    308 *******************************************************************************/
    309 void nfc_ncif_send_cmd(NFC_HDR* p_buf) {
    310   /* post the p_buf to NCIT task */
    311   p_buf->event = BT_EVT_TO_NFC_NCI;
    312   p_buf->layer_specific = 0;
    313   nfc_ncif_check_cmd_queue(p_buf);
    314 }
    315 
    316 /*******************************************************************************
    317 **
    318 ** Function         nfc_ncif_process_event
    319 **
    320 ** Description      This function is called to process the
    321 **                  data/response/notification from NFCC
    322 **
    323 ** Returns          TRUE if need to free buffer
    324 **
    325 *******************************************************************************/
    326 bool nfc_ncif_process_event(NFC_HDR* p_msg) {
    327   uint8_t mt, pbf, gid, *p, *pp;
    328   bool free = true;
    329   uint8_t oid;
    330   uint8_t *p_old, old_gid, old_oid, old_mt;
    331 
    332   p = (uint8_t*)(p_msg + 1) + p_msg->offset;
    333 
    334   pp = p;
    335   NCI_MSG_PRS_HDR0(pp, mt, pbf, gid);
    336 
    337   switch (mt) {
    338     case NCI_MT_DATA:
    339       NFC_TRACE_DEBUG0("NFC received data");
    340       nfc_ncif_proc_data(p_msg);
    341       free = false;
    342       break;
    343 
    344     case NCI_MT_RSP:
    345       NFC_TRACE_DEBUG1("NFC received rsp gid:%d", gid);
    346       oid = ((*pp) & NCI_OID_MASK);
    347       p_old = nfc_cb.last_hdr;
    348       NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid);
    349       old_oid = ((*p_old) & NCI_OID_MASK);
    350       /* make sure this is the RSP we are waiting for before updating the
    351        * command window */
    352       if ((old_gid != gid) || (old_oid != oid)) {
    353         NFC_TRACE_ERROR2(
    354             "nfc_ncif_process_event unexpected rsp: gid:0x%x, oid:0x%x", gid,
    355             oid);
    356         return true;
    357       }
    358 
    359       switch (gid) {
    360         case NCI_GID_CORE: /* 0000b NCI Core group */
    361           free = nci_proc_core_rsp(p_msg);
    362           break;
    363         case NCI_GID_RF_MANAGE: /* 0001b NCI Discovery group */
    364           nci_proc_rf_management_rsp(p_msg);
    365           break;
    366 #if (NFC_NFCEE_INCLUDED == TRUE)
    367 #if (NFC_RW_ONLY == FALSE)
    368         case NCI_GID_EE_MANAGE: /* 0x02 0010b NFCEE Discovery group */
    369           nci_proc_ee_management_rsp(p_msg);
    370           break;
    371 #endif
    372 #endif
    373         case NCI_GID_PROP: /* 1111b Proprietary */
    374           nci_proc_prop_rsp(p_msg);
    375           break;
    376         default:
    377           NFC_TRACE_ERROR1("NFC: Unknown gid:%d", gid);
    378           break;
    379       }
    380 
    381       nfc_ncif_update_window();
    382       break;
    383 
    384     case NCI_MT_NTF:
    385       NFC_TRACE_DEBUG1("NFC received ntf gid:%d", gid);
    386       switch (gid) {
    387         case NCI_GID_CORE: /* 0000b NCI Core group */
    388           nci_proc_core_ntf(p_msg);
    389           break;
    390         case NCI_GID_RF_MANAGE: /* 0001b NCI Discovery group */
    391           nci_proc_rf_management_ntf(p_msg);
    392           break;
    393 #if (NFC_NFCEE_INCLUDED == TRUE)
    394 #if (NFC_RW_ONLY == FALSE)
    395         case NCI_GID_EE_MANAGE: /* 0x02 0010b NFCEE Discovery group */
    396           nci_proc_ee_management_ntf(p_msg);
    397           break;
    398 #endif
    399 #endif
    400         case NCI_GID_PROP: /* 1111b Proprietary */
    401           nci_proc_prop_ntf(p_msg);
    402           break;
    403         default:
    404           NFC_TRACE_ERROR1("NFC: Unknown gid:%d", gid);
    405           break;
    406       }
    407       break;
    408 
    409     default:
    410       NFC_TRACE_DEBUG2("NFC received unknown mt:0x%x, gid:%d", mt, gid);
    411   }
    412 
    413   return (free);
    414 }
    415 
    416 /*******************************************************************************
    417 **
    418 ** Function         nfc_ncif_rf_management_status
    419 **
    420 ** Description      This function is called to report an event
    421 **
    422 ** Returns          void
    423 **
    424 *******************************************************************************/
    425 void nfc_ncif_rf_management_status(tNFC_DISCOVER_EVT event, uint8_t status) {
    426   tNFC_DISCOVER evt_data;
    427   if (nfc_cb.p_discv_cback) {
    428     evt_data.status = (tNFC_STATUS)status;
    429     (*nfc_cb.p_discv_cback)(event, &evt_data);
    430   }
    431 }
    432 
    433 /*******************************************************************************
    434 **
    435 ** Function         nfc_ncif_set_config_status
    436 **
    437 ** Description      This function is called to report NFC_SET_CONFIG_REVT
    438 **
    439 ** Returns          void
    440 **
    441 *******************************************************************************/
    442 void nfc_ncif_set_config_status(uint8_t* p, uint8_t len) {
    443   tNFC_RESPONSE evt_data;
    444   if (nfc_cb.p_resp_cback) {
    445     evt_data.set_config.status = (tNFC_STATUS)*p++;
    446     evt_data.set_config.num_param_id = NFC_STATUS_OK;
    447     if (evt_data.set_config.status != NFC_STATUS_OK) {
    448       evt_data.set_config.num_param_id = *p++;
    449       STREAM_TO_ARRAY(evt_data.set_config.param_ids, p,
    450                       evt_data.set_config.num_param_id);
    451     }
    452 
    453     (*nfc_cb.p_resp_cback)(NFC_SET_CONFIG_REVT, &evt_data);
    454   }
    455 }
    456 
    457 /*******************************************************************************
    458 **
    459 ** Function         nfc_ncif_event_status
    460 **
    461 ** Description      This function is called to report an event
    462 **
    463 ** Returns          void
    464 **
    465 *******************************************************************************/
    466 void nfc_ncif_event_status(tNFC_RESPONSE_EVT event, uint8_t status) {
    467   tNFC_RESPONSE evt_data;
    468   if (nfc_cb.p_resp_cback) {
    469     evt_data.status = (tNFC_STATUS)status;
    470     (*nfc_cb.p_resp_cback)(event, &evt_data);
    471   }
    472 }
    473 
    474 /*******************************************************************************
    475 **
    476 ** Function         nfc_ncif_error_status
    477 **
    478 ** Description      This function is called to report an error event to data
    479 **                  cback
    480 **
    481 ** Returns          void
    482 **
    483 *******************************************************************************/
    484 void nfc_ncif_error_status(uint8_t conn_id, uint8_t status) {
    485   tNFC_CONN_CB* p_cb;
    486   p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
    487   if (p_cb && p_cb->p_cback) {
    488     (*p_cb->p_cback)(conn_id, NFC_ERROR_CEVT, (tNFC_CONN*)&status);
    489   }
    490 }
    491 
    492 /*******************************************************************************
    493 **
    494 ** Function         nfc_ncif_proc_rf_field_ntf
    495 **
    496 ** Description      This function is called to process RF field notification
    497 **
    498 ** Returns          void
    499 **
    500 *******************************************************************************/
    501 #if (NFC_RW_ONLY == FALSE)
    502 void nfc_ncif_proc_rf_field_ntf(uint8_t rf_status) {
    503   tNFC_RESPONSE evt_data;
    504   if (nfc_cb.p_resp_cback) {
    505     evt_data.status = (tNFC_STATUS)NFC_STATUS_OK;
    506     evt_data.rf_field.rf_field = rf_status;
    507     (*nfc_cb.p_resp_cback)(NFC_RF_FIELD_REVT, &evt_data);
    508   }
    509 }
    510 #endif
    511 
    512 /*******************************************************************************
    513 **
    514 ** Function         nfc_ncif_proc_credits
    515 **
    516 ** Description      This function is called to process data credits
    517 **
    518 ** Returns          void
    519 **
    520 *******************************************************************************/
    521 void nfc_ncif_proc_credits(uint8_t* p, uint16_t plen) {
    522   uint8_t num, xx;
    523   tNFC_CONN_CB* p_cb;
    524 
    525   num = *p++;
    526   for (xx = 0; xx < num; xx++) {
    527     p_cb = nfc_find_conn_cb_by_conn_id(*p++);
    528     if (p_cb && p_cb->num_buff != NFC_CONN_NO_FC) {
    529       p_cb->num_buff += (*p);
    530 #if (BT_USE_TRACES == TRUE)
    531       if (p_cb->num_buff > p_cb->init_credits) {
    532         if (nfc_cb.nfc_state == NFC_STATE_OPEN) {
    533           /* if this happens in activated state, it's very likely that our NFCC
    534            * has issues */
    535           /* However, credit may be returned after deactivation */
    536           NFC_TRACE_ERROR2("num_buff:0x%x, init_credits:0x%x", p_cb->num_buff,
    537                            p_cb->init_credits);
    538         }
    539         p_cb->num_buff = p_cb->init_credits;
    540       }
    541 #endif
    542       /* check if there's nay data in tx q to be sent */
    543       nfc_ncif_send_data(p_cb, NULL);
    544     }
    545     p++;
    546   }
    547 }
    548 /*******************************************************************************
    549 **
    550 ** Function         nfc_ncif_decode_rf_params
    551 **
    552 ** Description      This function is called to process the detected technology
    553 **                  and mode and the associated parameters for DISCOVER_NTF and
    554 **                  ACTIVATE_NTF
    555 **
    556 ** Returns          void
    557 **
    558 *******************************************************************************/
    559 uint8_t* nfc_ncif_decode_rf_params(tNFC_RF_TECH_PARAMS* p_param, uint8_t* p) {
    560   tNFC_RF_PA_PARAMS* p_pa;
    561   uint8_t len, *p_start, u8;
    562   tNFC_RF_PB_PARAMS* p_pb;
    563   tNFC_RF_LF_PARAMS* p_lf;
    564   tNFC_RF_PF_PARAMS* p_pf;
    565   tNFC_RF_PISO15693_PARAMS* p_i93;
    566 
    567   len = *p++;
    568   p_start = p;
    569   memset(&p_param->param, 0, sizeof(tNFC_RF_TECH_PARAMU));
    570 
    571   if (NCI_DISCOVERY_TYPE_POLL_A == p_param->mode ||
    572       NCI_DISCOVERY_TYPE_POLL_A_ACTIVE == p_param->mode) {
    573     p_pa = &p_param->param.pa;
    574     /*
    575 SENS_RES Response   2 bytes Defined in [DIGPROT] Available after Technology
    576 Detection
    577 NFCID1 length   1 byte  Length of NFCID1 Available after Collision Resolution
    578 NFCID1  4, 7, or 10 bytes   Defined in [DIGPROT]Available after Collision
    579 Resolution
    580 SEL_RES Response    1 byte  Defined in [DIGPROT]Available after Collision
    581 Resolution
    582 HRx Length  1 Octets    Length of HRx Parameters collected from the response to
    583 the T1T RID command.
    584 HRx 0 or 2 Octets   If present, the first byte SHALL contain HR0 and the second
    585 byte SHALL contain HR1 as defined in [DIGITAL].
    586     */
    587     STREAM_TO_ARRAY(p_pa->sens_res, p, 2);
    588     p_pa->nfcid1_len = *p++;
    589     if (p_pa->nfcid1_len > NCI_NFCID1_MAX_LEN)
    590       p_pa->nfcid1_len = NCI_NFCID1_MAX_LEN;
    591     STREAM_TO_ARRAY(p_pa->nfcid1, p, p_pa->nfcid1_len);
    592     u8 = *p++;
    593     if (u8) p_pa->sel_rsp = *p++;
    594     if (len ==
    595         (7 + p_pa->nfcid1_len + u8)) /* 2(sens_res) + 1(len) +
    596                                         p_pa->nfcid1_len + 1(len) + u8 + hr
    597                                         (1:len + 2) */
    598     {
    599       p_pa->hr_len = *p++;
    600       if (p_pa->hr_len == NCI_T1T_HR_LEN) {
    601         p_pa->hr[0] = *p++;
    602         p_pa->hr[1] = *p;
    603       }
    604     }
    605   } else if (NCI_DISCOVERY_TYPE_POLL_B == p_param->mode) {
    606     /*
    607 SENSB_RES Response length (n)   1 byte  Length of SENSB_RES Response (Byte 2 -
    608 Byte 12 or 13)Available after Technology Detection
    609 SENSB_RES Response Byte 2 - Byte 12 or 13   11 or 12 bytes  Defined in [DIGPROT]
    610 Available after Technology Detection
    611     */
    612     p_pb = &p_param->param.pb;
    613     p_pb->sensb_res_len = *p++;
    614     if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN)
    615       p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN;
    616     STREAM_TO_ARRAY(p_pb->sensb_res, p, p_pb->sensb_res_len);
    617     memcpy(p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN);
    618   } else if (NCI_DISCOVERY_TYPE_POLL_F == p_param->mode ||
    619              NCI_DISCOVERY_TYPE_POLL_F_ACTIVE == p_param->mode) {
    620     /*
    621 Bit Rate    1 byte  1   212 kbps/2   424 kbps/0 and 3 to 255  RFU
    622 SENSF_RES Response length.(n) 1 byte  Length of SENSF_RES (Byte 2 - Byte 17 or
    623 19).Available after Technology Detection
    624 SENSF_RES Response Byte 2 - Byte 17 or 19  n bytes Defined in [DIGPROT]
    625 Available after Technology Detection
    626     */
    627     p_pf = &p_param->param.pf;
    628     p_pf->bit_rate = *p++;
    629     p_pf->sensf_res_len = *p++;
    630     if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN)
    631       p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN;
    632     STREAM_TO_ARRAY(p_pf->sensf_res, p, p_pf->sensf_res_len);
    633     memcpy(p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN);
    634     p_pf->mrti_check = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX];
    635     p_pf->mrti_update = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX];
    636   } else if (NCI_DISCOVERY_TYPE_LISTEN_F == p_param->mode ||
    637              NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE == p_param->mode) {
    638     p_lf = &p_param->param.lf;
    639     u8 = *p++;
    640     if (u8) {
    641       STREAM_TO_ARRAY(p_lf->nfcid2, p, NCI_NFCID2_LEN);
    642     }
    643   } else if (NCI_DISCOVERY_TYPE_POLL_ISO15693 == p_param->mode) {
    644     p_i93 = &p_param->param.pi93;
    645     p_i93->flag = *p++;
    646     p_i93->dsfid = *p++;
    647     STREAM_TO_ARRAY(p_i93->uid, p, NFC_ISO15693_UID_LEN);
    648   } else if (NCI_DISCOVERY_TYPE_POLL_KOVIO == p_param->mode) {
    649     p_param->param.pk.uid_len = *p++;
    650     if (p_param->param.pk.uid_len > NFC_KOVIO_MAX_LEN) {
    651       NFC_TRACE_ERROR2("Kovio UID len:0x%x exceeds max(0x%x)",
    652                        p_param->param.pk.uid_len, NFC_KOVIO_MAX_LEN);
    653       p_param->param.pk.uid_len = NFC_KOVIO_MAX_LEN;
    654     }
    655     STREAM_TO_ARRAY(p_param->param.pk.uid, p, p_param->param.pk.uid_len);
    656   }
    657 
    658   return (p_start + len);
    659 }
    660 
    661 /*******************************************************************************
    662 **
    663 ** Function         nfc_ncif_proc_discover_ntf
    664 **
    665 ** Description      This function is called to process discover notification
    666 **
    667 ** Returns          void
    668 **
    669 *******************************************************************************/
    670 void nfc_ncif_proc_discover_ntf(uint8_t* p, uint16_t plen) {
    671   tNFC_DISCOVER evt_data;
    672 
    673   if (nfc_cb.p_discv_cback) {
    674     p += NCI_MSG_HDR_SIZE;
    675     evt_data.status = NCI_STATUS_OK;
    676     evt_data.result.rf_disc_id = *p++;
    677     evt_data.result.protocol = *p++;
    678 
    679     /* fill in tNFC_RESULT_DEVT */
    680     evt_data.result.rf_tech_param.mode = *p++;
    681     p = nfc_ncif_decode_rf_params(&evt_data.result.rf_tech_param, p);
    682 
    683     evt_data.result.more = *p++;
    684     (*nfc_cb.p_discv_cback)(NFC_RESULT_DEVT, &evt_data);
    685   }
    686 }
    687 
    688 /*******************************************************************************
    689 **
    690 ** Function         nfc_ncif_proc_activate
    691 **
    692 ** Description      This function is called to process de-activate
    693 **                  response and notification
    694 **
    695 ** Returns          void
    696 **
    697 *******************************************************************************/
    698 void nfc_ncif_proc_activate(uint8_t* p, uint8_t len) {
    699   tNFC_DISCOVER evt_data;
    700   tNFC_INTF_PARAMS* p_intf = &evt_data.activate.intf_param;
    701   tNFC_INTF_PA_ISO_DEP* p_pa_iso;
    702   tNFC_INTF_LB_ISO_DEP* p_lb_iso;
    703   tNFC_INTF_PB_ISO_DEP* p_pb_iso;
    704 #if (NFC_RW_ONLY == FALSE)
    705   tNFC_INTF_PA_NFC_DEP* p_pa_nfc;
    706   int mpl_idx = 0;
    707   uint8_t gb_idx = 0, mpl;
    708 #endif
    709   uint8_t t0;
    710   tNCI_DISCOVERY_TYPE mode;
    711   tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
    712   uint8_t *pp, len_act;
    713   uint8_t buff_size, num_buff;
    714   tNFC_RF_PA_PARAMS* p_pa;
    715 
    716   nfc_set_state(NFC_STATE_OPEN);
    717 
    718   memset(p_intf, 0, sizeof(tNFC_INTF_PARAMS));
    719   evt_data.activate.rf_disc_id = *p++;
    720   p_intf->type = *p++;
    721   evt_data.activate.protocol = *p++;
    722 
    723   if (evt_data.activate.protocol == NCI_PROTOCOL_18092_ACTIVE)
    724     evt_data.activate.protocol = NCI_PROTOCOL_NFC_DEP;
    725 
    726   evt_data.activate.rf_tech_param.mode = *p++;
    727   buff_size = *p++;
    728   num_buff = *p++;
    729   /* fill in tNFC_activate_DEVT */
    730   p = nfc_ncif_decode_rf_params(&evt_data.activate.rf_tech_param, p);
    731 
    732   evt_data.activate.data_mode = *p++;
    733   evt_data.activate.tx_bitrate = *p++;
    734   evt_data.activate.rx_bitrate = *p++;
    735   mode = evt_data.activate.rf_tech_param.mode;
    736   len_act = *p++;
    737   NFC_TRACE_DEBUG3("nfc_ncif_proc_activate:%d %d, mode:0x%02x", len, len_act,
    738                    mode);
    739   /* just in case the interface reports activation parameters not defined in the
    740    * NCI spec */
    741   p_intf->intf_param.frame.param_len = len_act;
    742   if (p_intf->intf_param.frame.param_len > NFC_MAX_RAW_PARAMS)
    743     p_intf->intf_param.frame.param_len = NFC_MAX_RAW_PARAMS;
    744   pp = p;
    745   STREAM_TO_ARRAY(p_intf->intf_param.frame.param, pp,
    746                   p_intf->intf_param.frame.param_len);
    747   if (evt_data.activate.intf_param.type == NCI_INTERFACE_ISO_DEP) {
    748     /* Make max payload of NCI aligned to max payload of ISO-DEP for better
    749      * performance */
    750     if (buff_size > NCI_ISO_DEP_MAX_INFO) buff_size = NCI_ISO_DEP_MAX_INFO;
    751 
    752     switch (mode) {
    753       case NCI_DISCOVERY_TYPE_POLL_A:
    754         p_pa_iso = &p_intf->intf_param.pa_iso;
    755         p_pa_iso->ats_res_len = *p++;
    756 
    757         if (p_pa_iso->ats_res_len == 0) break;
    758 
    759         if (p_pa_iso->ats_res_len > NFC_MAX_ATS_LEN)
    760           p_pa_iso->ats_res_len = NFC_MAX_ATS_LEN;
    761         STREAM_TO_ARRAY(p_pa_iso->ats_res, p, p_pa_iso->ats_res_len);
    762         pp = &p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
    763         t0 = p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
    764         pp++;                           /* T0 */
    765         if (t0 & NCI_ATS_TA_MASK) pp++; /* TA */
    766         if (t0 & NCI_ATS_TB_MASK) {
    767           /* FWI (Frame Waiting time Integer) & SPGI (Start-up Frame Guard time
    768            * Integer) */
    769           p_pa_iso->fwi = (((*pp) >> 4) & 0x0F);
    770           p_pa_iso->sfgi = ((*pp) & 0x0F);
    771           pp++; /* TB */
    772         }
    773         if (t0 & NCI_ATS_TC_MASK) {
    774           p_pa_iso->nad_used = ((*pp) & 0x01);
    775           pp++; /* TC */
    776         }
    777         p_pa_iso->his_byte_len =
    778             (uint8_t)(p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res));
    779         if (p_pa_iso->his_byte_len > NFC_MAX_HIS_BYTES_LEN)
    780           p_pa_iso->his_byte_len = NFC_MAX_HIS_BYTES_LEN;
    781         memcpy(p_pa_iso->his_byte, pp, p_pa_iso->his_byte_len);
    782         break;
    783 
    784       case NCI_DISCOVERY_TYPE_LISTEN_A:
    785         p_intf->intf_param.la_iso.rats = *p++;
    786         break;
    787 
    788       case NCI_DISCOVERY_TYPE_POLL_B:
    789         /* ATTRIB RSP
    790         Byte 1   Byte 2 ~ 2+n-1
    791         MBLI/DID Higher layer - Response
    792         */
    793         p_pb_iso = &p_intf->intf_param.pb_iso;
    794         p_pb_iso->attrib_res_len = *p++;
    795 
    796         if (p_pb_iso->attrib_res_len == 0) break;
    797 
    798         if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN)
    799           p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN;
    800         STREAM_TO_ARRAY(p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len);
    801         p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4;
    802         if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES) {
    803           p_pb_iso->hi_info_len =
    804               p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES;
    805           if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
    806             p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
    807           memcpy(p_pb_iso->hi_info,
    808                  &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES],
    809                  p_pb_iso->hi_info_len);
    810         }
    811         break;
    812 
    813       case NCI_DISCOVERY_TYPE_LISTEN_B:
    814         /* ATTRIB CMD
    815         Byte 2~5 Byte 6  Byte 7  Byte 8  Byte 9  Byte 10 ~ 10+k-1
    816         NFCID0   Param 1 Param 2 Param 3 Param 4 Higher layer - INF
    817         */
    818         p_lb_iso = &p_intf->intf_param.lb_iso;
    819         p_lb_iso->attrib_req_len = *p++;
    820 
    821         if (p_lb_iso->attrib_req_len == 0) break;
    822 
    823         if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN)
    824           p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN;
    825         STREAM_TO_ARRAY(p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len);
    826         memcpy(p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN);
    827         if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES) {
    828           p_lb_iso->hi_info_len =
    829               p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES;
    830           if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
    831             p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
    832           memcpy(p_lb_iso->hi_info,
    833                  &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES],
    834                  p_lb_iso->hi_info_len);
    835         }
    836         break;
    837     }
    838 
    839   }
    840 #if (NFC_RW_ONLY == FALSE)
    841   else if (evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP) {
    842     /* Make max payload of NCI aligned to max payload of NFC-DEP for better
    843      * performance */
    844     if (buff_size > NCI_NFC_DEP_MAX_DATA) buff_size = NCI_NFC_DEP_MAX_DATA;
    845 
    846     p_pa_nfc = &p_intf->intf_param.pa_nfc;
    847     p_pa_nfc->atr_res_len = *p++;
    848 
    849     if (p_pa_nfc->atr_res_len > 0) {
    850       if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN)
    851         p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN;
    852       STREAM_TO_ARRAY(p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len);
    853       if ((mode == NCI_DISCOVERY_TYPE_POLL_A) ||
    854           (mode == NCI_DISCOVERY_TYPE_POLL_F) ||
    855           (mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
    856           (mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE)) {
    857         /* ATR_RES
    858         Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n
    859         NFCID3T   DIDT    BST     BRT     TO      PPT     [GT0 ... GTn] */
    860         mpl_idx = 14;
    861         gb_idx = NCI_P_GEN_BYTE_INDEX;
    862         p_pa_nfc->waiting_time =
    863             p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F;
    864       } else if ((mode == NCI_DISCOVERY_TYPE_LISTEN_A) ||
    865                  (mode == NCI_DISCOVERY_TYPE_LISTEN_F) ||
    866                  (mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ||
    867                  (mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE)) {
    868         /* ATR_REQ
    869         Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n
    870         NFCID3I   DIDI    BSI     BRI     PPI     [GI0 ... GIn] */
    871         mpl_idx = 13;
    872         gb_idx = NCI_L_GEN_BYTE_INDEX;
    873       }
    874 
    875       mpl = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03;
    876       p_pa_nfc->max_payload_size = nfc_mpl_code_to_size[mpl];
    877       if (p_pa_nfc->atr_res_len > gb_idx) {
    878         p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx;
    879         if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN)
    880           p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN;
    881         memcpy(p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx],
    882                p_pa_nfc->gen_bytes_len);
    883       }
    884     }
    885   }
    886 #endif
    887   else if ((evt_data.activate.intf_param.type == NCI_INTERFACE_FRAME) &&
    888            (evt_data.activate.protocol == NCI_PROTOCOL_T1T)) {
    889     p_pa = &evt_data.activate.rf_tech_param.param.pa;
    890     if ((len_act == NCI_T1T_HR_LEN) && (p_pa->hr_len == 0)) {
    891       p_pa->hr_len = NCI_T1T_HR_LEN;
    892       p_pa->hr[0] = *p++;
    893       p_pa->hr[1] = *p++;
    894     }
    895   }
    896 
    897   p_cb->act_protocol = evt_data.activate.protocol;
    898   p_cb->buff_size = buff_size;
    899   p_cb->num_buff = num_buff;
    900   p_cb->init_credits = num_buff;
    901 
    902   if (nfc_cb.p_discv_cback) {
    903     (*nfc_cb.p_discv_cback)(NFC_ACTIVATE_DEVT, &evt_data);
    904   }
    905 }
    906 
    907 /*******************************************************************************
    908 **
    909 ** Function         nfc_ncif_proc_deactivate
    910 **
    911 ** Description      This function is called to process de-activate
    912 **                  response and notification
    913 **
    914 ** Returns          void
    915 **
    916 *******************************************************************************/
    917 void nfc_ncif_proc_deactivate(uint8_t status, uint8_t deact_type, bool is_ntf) {
    918   tNFC_DISCOVER evt_data;
    919   tNFC_DEACTIVATE_DEVT* p_deact;
    920   tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
    921   void* p_data;
    922 
    923   nfc_set_state(NFC_STATE_IDLE);
    924   p_deact = &evt_data.deactivate;
    925   p_deact->status = status;
    926   p_deact->type = deact_type;
    927   p_deact->is_ntf = is_ntf;
    928 
    929   while ((p_data = GKI_dequeue(&p_cb->rx_q)) != NULL) {
    930     GKI_freebuf(p_data);
    931   }
    932 
    933   while ((p_data = GKI_dequeue(&p_cb->tx_q)) != NULL) {
    934     GKI_freebuf(p_data);
    935   }
    936 
    937   if (p_cb->p_cback)
    938     (*p_cb->p_cback)(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN*)p_deact);
    939 
    940   if (nfc_cb.p_discv_cback) {
    941     (*nfc_cb.p_discv_cback)(NFC_DEACTIVATE_DEVT, &evt_data);
    942   }
    943 }
    944 /*******************************************************************************
    945 **
    946 ** Function         nfc_ncif_proc_ee_action
    947 **
    948 ** Description      This function is called to process NFCEE ACTION NTF
    949 **
    950 ** Returns          void
    951 **
    952 *******************************************************************************/
    953 #if (NFC_NFCEE_INCLUDED == TRUE && NFC_RW_ONLY == FALSE)
    954 void nfc_ncif_proc_ee_action(uint8_t* p, uint16_t plen) {
    955   tNFC_EE_ACTION_REVT evt_data;
    956   tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
    957   uint8_t data_len, ulen, tag, *p_data;
    958   uint8_t max_len;
    959 
    960   if (p_cback) {
    961     memset(&evt_data.act_data, 0, sizeof(tNFC_ACTION_DATA));
    962     evt_data.status = NFC_STATUS_OK;
    963     evt_data.nfcee_id = *p++;
    964     evt_data.act_data.trigger = *p++;
    965     data_len = *p++;
    966     if (plen >= 3) plen -= 3;
    967     if (data_len > plen) data_len = (uint8_t)plen;
    968 
    969     switch (evt_data.act_data.trigger) {
    970       case NCI_EE_TRIG_7816_SELECT:
    971         if (data_len > NFC_MAX_AID_LEN) data_len = NFC_MAX_AID_LEN;
    972         evt_data.act_data.param.aid.len_aid = data_len;
    973         STREAM_TO_ARRAY(evt_data.act_data.param.aid.aid, p, data_len);
    974         break;
    975       case NCI_EE_TRIG_RF_PROTOCOL:
    976         evt_data.act_data.param.protocol = *p++;
    977         break;
    978       case NCI_EE_TRIG_RF_TECHNOLOGY:
    979         evt_data.act_data.param.technology = *p++;
    980         break;
    981       case NCI_EE_TRIG_APP_INIT:
    982         while (data_len > NFC_TL_SIZE) {
    983           data_len -= NFC_TL_SIZE;
    984           tag = *p++;
    985           ulen = *p++;
    986           if (ulen > data_len) ulen = data_len;
    987           p_data = NULL;
    988           max_len = ulen;
    989           switch (tag) {
    990             case NCI_EE_ACT_TAG_AID: /* AID                 */
    991               if (max_len > NFC_MAX_AID_LEN) max_len = NFC_MAX_AID_LEN;
    992               evt_data.act_data.param.app_init.len_aid = max_len;
    993               p_data = evt_data.act_data.param.app_init.aid;
    994               break;
    995             case NCI_EE_ACT_TAG_DATA: /* hex data for app    */
    996               if (max_len > NFC_MAX_APP_DATA_LEN)
    997                 max_len = NFC_MAX_APP_DATA_LEN;
    998               evt_data.act_data.param.app_init.len_data = max_len;
    999               p_data = evt_data.act_data.param.app_init.data;
   1000               break;
   1001           }
   1002           if (p_data) {
   1003             STREAM_TO_ARRAY(p_data, p, max_len);
   1004           }
   1005           data_len -= ulen;
   1006         }
   1007         break;
   1008     }
   1009     (*p_cback)(NFC_EE_ACTION_REVT, (tNFC_RESPONSE*)&evt_data);
   1010   }
   1011 }
   1012 
   1013 /*******************************************************************************
   1014 **
   1015 ** Function         nfc_ncif_proc_ee_discover_req
   1016 **
   1017 ** Description      This function is called to process NFCEE DISCOVER REQ NTF
   1018 **
   1019 ** Returns          void
   1020 **
   1021 *******************************************************************************/
   1022 void nfc_ncif_proc_ee_discover_req(uint8_t* p, uint16_t plen) {
   1023   tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
   1024   tNFC_EE_DISCOVER_REQ_REVT ee_disc_req;
   1025   tNFC_EE_DISCOVER_INFO* p_info;
   1026   uint8_t u8;
   1027 
   1028   NFC_TRACE_DEBUG2("nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen);
   1029   if (p_cback) {
   1030     u8 = *p;
   1031     ee_disc_req.status = NFC_STATUS_OK;
   1032     ee_disc_req.num_info = *p++;
   1033     p_info = ee_disc_req.info;
   1034     if (plen) plen--;
   1035     while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN)) {
   1036       p_info->op = *p++;                  /* T */
   1037       if (*p != NFC_EE_DISCOVER_INFO_LEN) /* L */
   1038       {
   1039         NFC_TRACE_DEBUG1("bad entry len:%d", *p);
   1040         return;
   1041       }
   1042       p++;
   1043       /* V */
   1044       p_info->nfcee_id = *p++;
   1045       p_info->tech_n_mode = *p++;
   1046       p_info->protocol = *p++;
   1047       u8--;
   1048       plen -= NFC_EE_DISCOVER_ENTRY_LEN;
   1049       p_info++;
   1050     }
   1051     (*p_cback)(NFC_EE_DISCOVER_REQ_REVT, (tNFC_RESPONSE*)&ee_disc_req);
   1052   }
   1053 }
   1054 
   1055 /*******************************************************************************
   1056 **
   1057 ** Function         nfc_ncif_proc_get_routing
   1058 **
   1059 ** Description      This function is called to process get routing notification
   1060 **
   1061 ** Returns          void
   1062 **
   1063 *******************************************************************************/
   1064 void nfc_ncif_proc_get_routing(uint8_t* p, uint8_t len) {
   1065   tNFC_GET_ROUTING_REVT evt_data;
   1066   uint8_t more, num_entries, xx, yy, *pn, tl;
   1067   tNFC_STATUS status = NFC_STATUS_CONTINUE;
   1068 
   1069   if (nfc_cb.p_resp_cback) {
   1070     more = *p++;
   1071     num_entries = *p++;
   1072     for (xx = 0; xx < num_entries; xx++) {
   1073       if ((more == false) && (xx == (num_entries - 1))) status = NFC_STATUS_OK;
   1074       evt_data.status = (tNFC_STATUS)status;
   1075       evt_data.nfcee_id = *p++;
   1076       evt_data.num_tlvs = *p++;
   1077       evt_data.tlv_size = 0;
   1078       pn = evt_data.param_tlvs;
   1079       for (yy = 0; yy < evt_data.num_tlvs; yy++) {
   1080         tl = *(p + 1);
   1081         tl += NFC_TL_SIZE;
   1082         STREAM_TO_ARRAY(pn, p, tl);
   1083         evt_data.tlv_size += tl;
   1084         pn += tl;
   1085       }
   1086       (*nfc_cb.p_resp_cback)(NFC_GET_ROUTING_REVT, (tNFC_RESPONSE*)&evt_data);
   1087     }
   1088   }
   1089 }
   1090 #endif
   1091 
   1092 /*******************************************************************************
   1093 **
   1094 ** Function         nfc_ncif_proc_conn_create_rsp
   1095 **
   1096 ** Description      This function is called to process connection create
   1097 **                  response
   1098 **
   1099 ** Returns          void
   1100 **
   1101 *******************************************************************************/
   1102 void nfc_ncif_proc_conn_create_rsp(uint8_t* p, uint16_t plen,
   1103                                    uint8_t dest_type) {
   1104   tNFC_CONN_CB* p_cb;
   1105   tNFC_STATUS status;
   1106   tNFC_CONN_CBACK* p_cback;
   1107   tNFC_CONN evt_data;
   1108   uint8_t conn_id;
   1109 
   1110   /* find the pending connection control block */
   1111   p_cb = nfc_find_conn_cb_by_conn_id(NFC_PEND_CONN_ID);
   1112   if (p_cb) {
   1113     p += NCI_MSG_HDR_SIZE;
   1114     status = *p++;
   1115     p_cb->buff_size = *p++;
   1116     p_cb->num_buff = p_cb->init_credits = *p++;
   1117     conn_id = *p++;
   1118     evt_data.conn_create.status = status;
   1119     evt_data.conn_create.dest_type = dest_type;
   1120     evt_data.conn_create.id = p_cb->id;
   1121     evt_data.conn_create.buff_size = p_cb->buff_size;
   1122     evt_data.conn_create.num_buffs = p_cb->num_buff;
   1123     p_cback = p_cb->p_cback;
   1124     if (status == NCI_STATUS_OK) {
   1125       nfc_set_conn_id(p_cb, conn_id);
   1126     } else {
   1127       nfc_free_conn_cb(p_cb);
   1128     }
   1129 
   1130     if (p_cback) (*p_cback)(conn_id, NFC_CONN_CREATE_CEVT, &evt_data);
   1131   }
   1132 }
   1133 
   1134 /*******************************************************************************
   1135 **
   1136 ** Function         nfc_ncif_report_conn_close_evt
   1137 **
   1138 ** Description      This function is called to report connection close event
   1139 **
   1140 ** Returns          void
   1141 **
   1142 *******************************************************************************/
   1143 void nfc_ncif_report_conn_close_evt(uint8_t conn_id, tNFC_STATUS status) {
   1144   tNFC_CONN evt_data;
   1145   tNFC_CONN_CBACK* p_cback;
   1146   tNFC_CONN_CB* p_cb;
   1147 
   1148   p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
   1149   if (p_cb) {
   1150     p_cback = p_cb->p_cback;
   1151     nfc_free_conn_cb(p_cb);
   1152     evt_data.status = status;
   1153     if (p_cback) (*p_cback)(conn_id, NFC_CONN_CLOSE_CEVT, &evt_data);
   1154   }
   1155 }
   1156 
   1157 /*******************************************************************************
   1158 **
   1159 ** Function         nfc_ncif_proc_reset_rsp
   1160 **
   1161 ** Description      This function is called to process reset
   1162 **                  response/notification
   1163 **
   1164 ** Returns          void
   1165 **
   1166 *******************************************************************************/
   1167 void nfc_ncif_proc_reset_rsp(uint8_t* p, bool is_ntf) {
   1168   uint8_t status = *p++;
   1169 
   1170   if (is_ntf) {
   1171     NFC_TRACE_ERROR1("reset notification!!:0x%x ", status);
   1172     /* clean up, if the state is OPEN
   1173      * FW does not report reset ntf right now */
   1174     if (nfc_cb.nfc_state == NFC_STATE_OPEN) {
   1175       /*if any conn_cb is connected, close it.
   1176         if any pending outgoing packets are dropped.*/
   1177       nfc_reset_all_conn_cbs();
   1178     }
   1179     status = NCI_STATUS_OK;
   1180   }
   1181 
   1182   if (nfc_cb.flags & (NFC_FL_RESTARTING | NFC_FL_POWER_CYCLE_NFCC)) {
   1183     nfc_reset_all_conn_cbs();
   1184   }
   1185 
   1186   if (!is_ntf && status == NCI_STATUS_OK) {
   1187     if ((*p) != NCI_VERSION) {
   1188       NFC_TRACE_ERROR2("NCI version mismatch!!:0x%02x != 0x%02x ", NCI_VERSION,
   1189                        *p);
   1190       if ((*p) < NCI_VERSION_0_F) {
   1191         NFC_TRACE_ERROR0("NFCC version is too old");
   1192         status = NCI_STATUS_FAILED;
   1193       }
   1194     }
   1195   }
   1196 
   1197   if (status == NCI_STATUS_OK) {
   1198     nci_snd_core_init();
   1199   } else {
   1200     NFC_TRACE_ERROR0("Failed to reset NFCC");
   1201     nfc_enabled(status, NULL);
   1202   }
   1203 }
   1204 
   1205 /*******************************************************************************
   1206 **
   1207 ** Function         nfc_ncif_proc_init_rsp
   1208 **
   1209 ** Description      This function is called to process init response
   1210 **
   1211 ** Returns          void
   1212 **
   1213 *******************************************************************************/
   1214 void nfc_ncif_proc_init_rsp(NFC_HDR* p_msg) {
   1215   uint8_t *p, status;
   1216   tNFC_CONN_CB* p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
   1217 
   1218   p = (uint8_t*)(p_msg + 1) + p_msg->offset;
   1219 
   1220   /* handle init params in nfc_enabled */
   1221   status = *(p + NCI_MSG_HDR_SIZE);
   1222   if (status == NCI_STATUS_OK) {
   1223     p_cb->id = NFC_RF_CONN_ID;
   1224     p_cb->act_protocol = NCI_PROTOCOL_UNKNOWN;
   1225 
   1226     nfc_set_state(NFC_STATE_W4_POST_INIT_CPLT);
   1227 
   1228     nfc_cb.p_nci_init_rsp = p_msg;
   1229     nfc_cb.p_hal->core_initialized(p_msg->len - p_msg->offset, p);
   1230   } else {
   1231     nfc_enabled(status, NULL);
   1232     GKI_freebuf(p_msg);
   1233   }
   1234 }
   1235 
   1236 /*******************************************************************************
   1237 **
   1238 ** Function         nfc_ncif_proc_get_config_rsp
   1239 **
   1240 ** Description      This function is called to process get config response
   1241 **
   1242 ** Returns          void
   1243 **
   1244 *******************************************************************************/
   1245 void nfc_ncif_proc_get_config_rsp(NFC_HDR* p_evt) {
   1246   uint8_t* p;
   1247   tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback;
   1248   tNFC_RESPONSE evt_data;
   1249 
   1250   p_evt->offset += NCI_MSG_HDR_SIZE;
   1251   p_evt->len -= NCI_MSG_HDR_SIZE;
   1252   if (p_cback) {
   1253     p = (uint8_t*)(p_evt + 1) + p_evt->offset;
   1254     evt_data.get_config.status = *p++;
   1255     evt_data.get_config.tlv_size = p_evt->len;
   1256     evt_data.get_config.p_param_tlvs = p;
   1257     (*p_cback)(NFC_GET_CONFIG_REVT, &evt_data);
   1258   }
   1259 }
   1260 
   1261 /*******************************************************************************
   1262 **
   1263 ** Function         nfc_ncif_proc_t3t_polling_ntf
   1264 **
   1265 ** Description      Handle NCI_MSG_RF_T3T_POLLING NTF
   1266 **
   1267 ** Returns          void
   1268 **
   1269 *******************************************************************************/
   1270 void nfc_ncif_proc_t3t_polling_ntf(uint8_t* p, uint16_t plen) {
   1271   uint8_t status;
   1272   uint8_t num_responses;
   1273 
   1274   /* Pass result to RW_T3T for processing */
   1275   STREAM_TO_UINT8(status, p);
   1276   STREAM_TO_UINT8(num_responses, p);
   1277   plen -= NFC_TL_SIZE;
   1278   rw_t3t_handle_nci_poll_ntf(status, num_responses, (uint8_t)plen, p);
   1279 }
   1280 
   1281 /*******************************************************************************
   1282 **
   1283 ** Function         nfc_data_event
   1284 **
   1285 ** Description      Report Data event on the given connection control block
   1286 **
   1287 ** Returns          void
   1288 **
   1289 *******************************************************************************/
   1290 void nfc_data_event(tNFC_CONN_CB* p_cb) {
   1291   NFC_HDR* p_evt;
   1292   tNFC_DATA_CEVT data_cevt;
   1293   uint8_t* p;
   1294 
   1295   if (p_cb->p_cback) {
   1296     while ((p_evt = (NFC_HDR*)GKI_getfirst(&p_cb->rx_q)) != NULL) {
   1297       if (p_evt->layer_specific & NFC_RAS_FRAGMENTED) {
   1298         /* Not the last fragment */
   1299         if (!(p_evt->layer_specific & NFC_RAS_TOO_BIG)) {
   1300           /* buffer can hold more */
   1301           if ((p_cb->conn_id != NFC_RF_CONN_ID) || (nfc_cb.reassembly)) {
   1302             /* If not rf connection or If rf connection and reassembly
   1303              * requested,
   1304              * try to Reassemble next packet */
   1305             break;
   1306           }
   1307         }
   1308       }
   1309 
   1310       p_evt = (NFC_HDR*)GKI_dequeue(&p_cb->rx_q);
   1311       /* report data event */
   1312       p_evt->offset += NCI_MSG_HDR_SIZE;
   1313       p_evt->len -= NCI_MSG_HDR_SIZE;
   1314 
   1315       if (p_evt->layer_specific)
   1316         data_cevt.status = NFC_STATUS_CONTINUE;
   1317       else {
   1318         nfc_cb.reassembly = true;
   1319         data_cevt.status = NFC_STATUS_OK;
   1320       }
   1321 
   1322       data_cevt.p_data = p_evt;
   1323       /* adjust payload, if needed */
   1324       if (p_cb->conn_id == NFC_RF_CONN_ID) {
   1325         /* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status
   1326          * byte needs to be removed
   1327          */
   1328         if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) &&
   1329             (p_cb->act_protocol <= NCI_PROTOCOL_T3T)) {
   1330           p_evt->len--;
   1331           p = (uint8_t*)(p_evt + 1);
   1332           data_cevt.status = *(p + p_evt->offset + p_evt->len);
   1333         }
   1334       }
   1335       (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_CEVT, (tNFC_CONN*)&data_cevt);
   1336       p_evt = NULL;
   1337     }
   1338   }
   1339 }
   1340 
   1341 /*******************************************************************************
   1342 **
   1343 ** Function         nfc_ncif_proc_data
   1344 **
   1345 ** Description      Find the connection control block associated with the data
   1346 **                  packet. Assemble the data packet, if needed.
   1347 **                  Report the Data event.
   1348 **
   1349 ** Returns          void
   1350 **
   1351 *******************************************************************************/
   1352 void nfc_ncif_proc_data(NFC_HDR* p_msg) {
   1353   uint8_t *pp, cid;
   1354   tNFC_CONN_CB* p_cb;
   1355   uint8_t pbf;
   1356   NFC_HDR* p_last;
   1357   uint8_t *ps, *pd;
   1358   uint16_t size;
   1359   NFC_HDR* p_max = NULL;
   1360   uint16_t len;
   1361 
   1362   pp = (uint8_t*)(p_msg + 1) + p_msg->offset;
   1363   NFC_TRACE_DEBUG3("nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]);
   1364   NCI_DATA_PRS_HDR(pp, pbf, cid, len);
   1365   p_cb = nfc_find_conn_cb_by_conn_id(cid);
   1366   if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE)) {
   1367     NFC_TRACE_DEBUG1("nfc_ncif_proc_data len:%d", len);
   1368 
   1369     p_msg->layer_specific = 0;
   1370     if (pbf) p_msg->layer_specific = NFC_RAS_FRAGMENTED;
   1371     p_last = (NFC_HDR*)GKI_getlast(&p_cb->rx_q);
   1372     if (p_last && (p_last->layer_specific & NFC_RAS_FRAGMENTED)) {
   1373       /* last data buffer is not last fragment, append this new packet to the
   1374        * last */
   1375       size = GKI_get_buf_size(p_last);
   1376       if (size < (NFC_HDR_SIZE + p_last->len + p_last->offset + len)) {
   1377         /* the current size of p_last is not big enough to hold the new
   1378          * fragment, p_msg */
   1379         if (size != GKI_MAX_BUF_SIZE) {
   1380           /* try the biggest GKI pool */
   1381           p_max = (NFC_HDR*)GKI_getpoolbuf(GKI_MAX_BUF_SIZE_POOL_ID);
   1382           if (p_max) {
   1383             /* copy the content of last buffer to the new buffer */
   1384             memcpy(p_max, p_last, NFC_HDR_SIZE);
   1385             pd = (uint8_t*)(p_max + 1) + p_max->offset;
   1386             ps = (uint8_t*)(p_last + 1) + p_last->offset;
   1387             memcpy(pd, ps, p_last->len);
   1388 
   1389             /* place the new buffer in the queue instead */
   1390             GKI_remove_from_queue(&p_cb->rx_q, p_last);
   1391             GKI_freebuf(p_last);
   1392             GKI_enqueue(&p_cb->rx_q, p_max);
   1393             p_last = p_max;
   1394           }
   1395         }
   1396         if (p_max == NULL) {
   1397           /* Biggest GKI Pool not available (or)
   1398            * Biggest available GKI Pool is not big enough to hold the new
   1399            * fragment, p_msg */
   1400           p_last->layer_specific |= NFC_RAS_TOO_BIG;
   1401         }
   1402       }
   1403 
   1404       ps = (uint8_t*)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
   1405       len = p_msg->len - NCI_MSG_HDR_SIZE;
   1406 
   1407       if (!(p_last->layer_specific & NFC_RAS_TOO_BIG)) {
   1408         pd = (uint8_t*)(p_last + 1) + p_last->offset + p_last->len;
   1409         memcpy(pd, ps, len);
   1410         p_last->len += len;
   1411         /* do not need to update pbf and len in NCI header.
   1412          * They are stripped off at NFC_DATA_CEVT and len may exceed 255 */
   1413         NFC_TRACE_DEBUG1("nfc_ncif_proc_data len:%d", p_last->len);
   1414         p_last->layer_specific = p_msg->layer_specific;
   1415         GKI_freebuf(p_msg);
   1416 #ifdef DISP_NCI
   1417         if (!(p_last->layer_specific & NFC_RAS_FRAGMENTED)) {
   1418           /* this packet was reassembled. display the complete packet */
   1419           DISP_NCI((uint8_t*)(p_last + 1) + p_last->offset, p_last->len, true);
   1420         }
   1421 #endif
   1422         nfc_data_event(p_cb);
   1423       } else {
   1424         /* Not enough memory to add new buffer
   1425          * Send data already in queue first with status Continue */
   1426         nfc_data_event(p_cb);
   1427         /* now enqueue the new buffer to the rx queue */
   1428         GKI_enqueue(&p_cb->rx_q, p_msg);
   1429       }
   1430     } else {
   1431       /* if this is the first fragment on RF link */
   1432       if ((p_msg->layer_specific & NFC_RAS_FRAGMENTED) &&
   1433           (p_cb->conn_id == NFC_RF_CONN_ID) && (p_cb->p_cback)) {
   1434         /* Indicate upper layer that local device started receiving data */
   1435         (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_START_CEVT, NULL);
   1436       }
   1437       /* enqueue the new buffer to the rx queue */
   1438       GKI_enqueue(&p_cb->rx_q, p_msg);
   1439       nfc_data_event(p_cb);
   1440     }
   1441     return;
   1442   }
   1443   GKI_freebuf(p_msg);
   1444 }
   1445