Home | History | Annotate | Download | only in hci
      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  *  This is the main implementation file for the NFA HCI.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfa_dm_int.h"
     26 #include "nfa_ee_api.h"
     27 #include "nfa_ee_int.h"
     28 #include "nfa_hci_api.h"
     29 #include "nfa_hci_defs.h"
     30 #include "nfa_hci_int.h"
     31 #include "nfa_mem_co.h"
     32 #include "nfa_nv_co.h"
     33 #include "nfa_sys.h"
     34 #include "nfa_sys_int.h"
     35 #include "nfc_api.h"
     36 #include "trace_api.h"
     37 
     38 /*****************************************************************************
     39 **  Global Variables
     40 *****************************************************************************/
     41 
     42 tNFA_HCI_CB nfa_hci_cb;
     43 
     44 #ifndef NFA_HCI_NV_READ_TIMEOUT_VAL
     45 #define NFA_HCI_NV_READ_TIMEOUT_VAL 1000
     46 #endif
     47 
     48 #ifndef NFA_HCI_CON_CREATE_TIMEOUT_VAL
     49 #define NFA_HCI_CON_CREATE_TIMEOUT_VAL 1000
     50 #endif
     51 
     52 /*****************************************************************************
     53 **  Static Functions
     54 *****************************************************************************/
     55 
     56 /* event handler function type */
     57 static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg);
     58 
     59 static void nfa_hci_sys_enable(void);
     60 static void nfa_hci_sys_disable(void);
     61 static void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data);
     62 static void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
     63                                tNFC_CONN* p_data);
     64 static void nfa_hci_set_receive_buf(uint8_t pipe);
     65 static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len);
     66 static void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status);
     67 
     68 /*****************************************************************************
     69 **  Constants
     70 *****************************************************************************/
     71 static const tNFA_SYS_REG nfa_hci_sys_reg = {
     72     nfa_hci_sys_enable, nfa_hci_evt_hdlr, nfa_hci_sys_disable,
     73     nfa_hci_proc_nfcc_power_mode};
     74 
     75 /*******************************************************************************
     76 **
     77 ** Function         nfa_hci_ee_info_cback
     78 **
     79 ** Description      Callback function
     80 **
     81 ** Returns          None
     82 **
     83 *******************************************************************************/
     84 void nfa_hci_ee_info_cback(tNFA_EE_DISC_STS status) {
     85   uint8_t num_nfcee = 3;
     86   tNFA_EE_INFO ee_info[3];
     87 
     88   NFA_TRACE_DEBUG1("nfa_hci_ee_info_cback (): %d", status);
     89 
     90   switch (status) {
     91     case NFA_EE_DISC_STS_ON:
     92       if ((!nfa_hci_cb.ee_disc_cmplt) &&
     93           ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
     94            (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))) {
     95         /* NFCEE Discovery is in progress */
     96         nfa_hci_cb.ee_disc_cmplt = true;
     97         nfa_hci_cb.num_ee_dis_req_ntf = 0;
     98         nfa_hci_cb.num_hot_plug_evts = 0;
     99         nfa_hci_cb.conn_id = 0;
    100         nfa_hci_startup();
    101       }
    102       break;
    103 
    104     case NFA_EE_DISC_STS_OFF:
    105       if (nfa_hci_cb.ee_disable_disc) break;
    106       nfa_hci_cb.ee_disable_disc = true;
    107       /* Discovery operation is complete, retrieve discovery result */
    108       NFA_EeGetInfo(&num_nfcee, ee_info);
    109       nfa_hci_cb.num_nfcee = num_nfcee;
    110 
    111       if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
    112           (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
    113         if ((nfa_hci_cb.num_nfcee <= 1) ||
    114             (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) ||
    115             (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))) {
    116           /* No UICC Host is detected or
    117            * HOT_PLUG_EVT(s) and or EE DISC REQ Ntf(s) are already received
    118            * Get Host list and notify SYS on Initialization complete */
    119           nfa_sys_stop_timer(&nfa_hci_cb.timer);
    120           if ((nfa_hci_cb.num_nfcee > 1) &&
    121               (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
    122             /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s)
    123              */
    124             nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    125                                 p_nfa_hci_cfg->hci_netwk_enable_timeout);
    126           } else {
    127             nfa_hci_cb.w4_hci_netwk_init = false;
    128             nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
    129                                         NFA_HCI_HOST_LIST_INDEX);
    130           }
    131         }
    132       } else if (nfa_hci_cb.num_nfcee <= 1) {
    133         /* No UICC Host is detected, HCI NETWORK is enabled */
    134         nfa_hci_cb.w4_hci_netwk_init = false;
    135       }
    136       break;
    137 
    138     case NFA_EE_DISC_STS_REQ:
    139       nfa_hci_cb.num_ee_dis_req_ntf++;
    140 
    141       if (nfa_hci_cb.ee_disable_disc) {
    142         /* Already received Discovery Ntf */
    143         if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
    144             (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
    145           /* Received DISC REQ Ntf while waiting for other Host in the network
    146            * to bootup after DH host bootup is complete */
    147           if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
    148             /* Received expected number of EE DISC REQ Ntf(s) */
    149             nfa_sys_stop_timer(&nfa_hci_cb.timer);
    150             nfa_hci_cb.w4_hci_netwk_init = false;
    151             nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
    152                                         NFA_HCI_HOST_LIST_INDEX);
    153           }
    154         } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
    155                    (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
    156           /* Received DISC REQ Ntf during DH host bootup */
    157           if (nfa_hci_cb.num_ee_dis_req_ntf == (nfa_hci_cb.num_nfcee - 1)) {
    158             /* Received expected number of EE DISC REQ Ntf(s) */
    159             nfa_hci_cb.w4_hci_netwk_init = false;
    160           }
    161         }
    162       }
    163       break;
    164   }
    165 }
    166 
    167 /*******************************************************************************
    168 **
    169 ** Function         nfa_hci_init
    170 **
    171 ** Description      Initialize NFA HCI
    172 **
    173 ** Returns          None
    174 **
    175 *******************************************************************************/
    176 void nfa_hci_init(void) {
    177   NFA_TRACE_DEBUG0("nfa_hci_init ()");
    178 
    179   /* initialize control block */
    180   memset(&nfa_hci_cb, 0, sizeof(tNFA_HCI_CB));
    181 
    182   nfa_hci_cb.hci_state = NFA_HCI_STATE_STARTUP;
    183 
    184   /* register message handler on NFA SYS */
    185   nfa_sys_register(NFA_ID_HCI, &nfa_hci_sys_reg);
    186 }
    187 
    188 /*******************************************************************************
    189 **
    190 ** Function         nfa_hci_is_valid_cfg
    191 **
    192 ** Description      Validate hci control block config parameters
    193 **
    194 ** Returns          None
    195 **
    196 *******************************************************************************/
    197 bool nfa_hci_is_valid_cfg(void) {
    198   uint8_t xx, yy, zz;
    199   tNFA_HANDLE reg_app[NFA_HCI_MAX_APP_CB];
    200   uint8_t valid_gate[NFA_HCI_MAX_GATE_CB];
    201   uint8_t app_count = 0;
    202   uint8_t gate_count = 0;
    203   uint32_t pipe_inx_mask = 0;
    204 
    205   /* First, see if valid values are stored in app names, send connectivity
    206    * events flag */
    207   for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
    208     /* Check if app name is valid with null terminated string */
    209     if (strlen(&nfa_hci_cb.cfg.reg_app_names[xx][0]) > NFA_MAX_HCI_APP_NAME_LEN)
    210       return false;
    211 
    212     /* Send Connectivity event flag can be either TRUE or FALSE */
    213     if ((nfa_hci_cb.cfg.b_send_conn_evts[xx] != true) &&
    214         (nfa_hci_cb.cfg.b_send_conn_evts[xx] != false))
    215       return false;
    216 
    217     if (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) {
    218       /* Check if the app name is present more than one time in the control
    219        * block */
    220       for (yy = xx + 1; yy < NFA_HCI_MAX_APP_CB; yy++) {
    221         if ((nfa_hci_cb.cfg.reg_app_names[yy][0] != 0) &&
    222             (!strncmp(&nfa_hci_cb.cfg.reg_app_names[xx][0],
    223                       &nfa_hci_cb.cfg.reg_app_names[yy][0],
    224                       strlen(nfa_hci_cb.cfg.reg_app_names[xx])))) {
    225           /* Two app cannot have the same name , NVRAM is corrupted */
    226           NFA_TRACE_EVENT2("nfa_hci_is_valid_cfg (%s)  Reusing: %u",
    227                            &nfa_hci_cb.cfg.reg_app_names[xx][0], xx);
    228           return false;
    229         }
    230       }
    231       /* Collect list of hci handle */
    232       reg_app[app_count++] = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
    233     }
    234   }
    235 
    236   /* Validate Gate Control block */
    237   for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++) {
    238     if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != 0) {
    239       if (((nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_LOOP_BACK_GATE) &&
    240            (nfa_hci_cb.cfg.dyn_gates[xx].gate_id !=
    241             NFA_HCI_IDENTITY_MANAGEMENT_GATE) &&
    242            (nfa_hci_cb.cfg.dyn_gates[xx].gate_id <
    243             NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
    244           (nfa_hci_cb.cfg.dyn_gates[xx].gate_id > NFA_HCI_LAST_PROP_GATE))
    245         return false;
    246 
    247       /* Check if the same gate id is present more than once in the control
    248        * block */
    249       for (yy = xx + 1; yy < NFA_HCI_MAX_GATE_CB; yy++) {
    250         if ((nfa_hci_cb.cfg.dyn_gates[yy].gate_id != 0) &&
    251             (nfa_hci_cb.cfg.dyn_gates[xx].gate_id ==
    252              nfa_hci_cb.cfg.dyn_gates[yy].gate_id)) {
    253           NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Reusing: %u",
    254                            nfa_hci_cb.cfg.dyn_gates[xx].gate_id);
    255           return false;
    256         }
    257       }
    258       if ((nfa_hci_cb.cfg.dyn_gates[xx].gate_owner & (~NFA_HANDLE_GROUP_HCI)) >=
    259           NFA_HCI_MAX_APP_CB) {
    260         NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate owner: %u",
    261                          nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
    262         return false;
    263       }
    264       if (nfa_hci_cb.cfg.dyn_gates[xx].gate_id != NFA_HCI_CONNECTIVITY_GATE) {
    265         /* The gate owner should be one of the registered application */
    266         for (zz = 0; zz < app_count; zz++) {
    267           if (nfa_hci_cb.cfg.dyn_gates[xx].gate_owner == reg_app[zz]) break;
    268         }
    269         if (zz == app_count) {
    270           NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate owner: %u",
    271                            nfa_hci_cb.cfg.dyn_gates[xx].gate_owner);
    272           return false;
    273         }
    274       }
    275       /* Collect list of allocated gates */
    276       valid_gate[gate_count++] = nfa_hci_cb.cfg.dyn_gates[xx].gate_id;
    277 
    278       /* No two gates can own a same pipe */
    279       if ((pipe_inx_mask & nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask) != 0)
    280         return false;
    281       /* Collect the list of pipes on this gate */
    282       pipe_inx_mask |= nfa_hci_cb.cfg.dyn_gates[xx].pipe_inx_mask;
    283     }
    284   }
    285 
    286   for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
    287        xx++, pipe_inx_mask >>= 1) {
    288     /* Every bit set in pipe increment mask indicates a valid pipe */
    289     if (pipe_inx_mask & 1) {
    290       /* Check if the pipe is valid one */
    291       if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
    292         return false;
    293     }
    294   }
    295 
    296   if (xx == NFA_HCI_MAX_PIPE_CB) return false;
    297 
    298   /* Validate Gate Control block */
    299   for (xx = 0; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
    300     if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id != 0) {
    301       /* Check if pipe id is valid */
    302       if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
    303         return false;
    304 
    305       /* Check if pipe state is valid */
    306       if ((nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_OPENED) &&
    307           (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_state != NFA_HCI_PIPE_CLOSED))
    308         return false;
    309 
    310       /* Check if local gate on which the pipe is created is valid */
    311       if ((((nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
    312              NFA_HCI_LOOP_BACK_GATE) &&
    313             (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
    314              NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
    315            (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate <
    316             NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
    317           (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate > NFA_HCI_LAST_PROP_GATE))
    318         return false;
    319 
    320       /* Check if the peer gate on which the pipe is created is valid */
    321       if ((((nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
    322              NFA_HCI_LOOP_BACK_GATE) &&
    323             (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate !=
    324              NFA_HCI_IDENTITY_MANAGEMENT_GATE)) &&
    325            (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate <
    326             NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE)) ||
    327           (nfa_hci_cb.cfg.dyn_pipes[xx].dest_gate > NFA_HCI_LAST_PROP_GATE))
    328         return false;
    329 
    330       /* Check if the same pipe is present more than once in the control block
    331        */
    332       for (yy = xx + 1; yy < NFA_HCI_MAX_PIPE_CB; yy++) {
    333         if ((nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id != 0) &&
    334             (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id ==
    335              nfa_hci_cb.cfg.dyn_pipes[yy].pipe_id)) {
    336           NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Reusing: %u",
    337                            nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id);
    338           return false;
    339         }
    340       }
    341       /* The local gate should be one of the element in gate control block */
    342       for (zz = 0; zz < gate_count; zz++) {
    343         if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate == valid_gate[zz]) break;
    344       }
    345       if (zz == gate_count) {
    346         NFA_TRACE_EVENT1("nfa_hci_is_valid_cfg  Invalid Gate: %u",
    347                          nfa_hci_cb.cfg.dyn_pipes[xx].local_gate);
    348         return false;
    349       }
    350     }
    351   }
    352 
    353   /* Check if admin pipe state is valid */
    354   if ((nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_OPENED) &&
    355       (nfa_hci_cb.cfg.admin_gate.pipe01_state != NFA_HCI_PIPE_CLOSED))
    356     return false;
    357 
    358   /* Check if link management pipe state is valid */
    359   if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
    360       (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_CLOSED))
    361     return false;
    362 
    363   pipe_inx_mask = nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask;
    364   for (xx = 0; (pipe_inx_mask && (xx < NFA_HCI_MAX_PIPE_CB));
    365        xx++, pipe_inx_mask >>= 1) {
    366     /* Every bit set in pipe increment mask indicates a valid pipe */
    367     if (pipe_inx_mask & 1) {
    368       /* Check if the pipe is valid one */
    369       if (nfa_hci_cb.cfg.dyn_pipes[xx].pipe_id < NFA_HCI_FIRST_DYNAMIC_PIPE)
    370         return false;
    371       /* Check if the pipe is connected to Identity management gate */
    372       if (nfa_hci_cb.cfg.dyn_pipes[xx].local_gate !=
    373           NFA_HCI_IDENTITY_MANAGEMENT_GATE)
    374         return false;
    375     }
    376   }
    377   if (xx == NFA_HCI_MAX_PIPE_CB) return false;
    378 
    379   return true;
    380 }
    381 
    382 /*******************************************************************************
    383 **
    384 ** Function         nfa_hci_cfg_default
    385 **
    386 ** Description      Configure default values for hci control block
    387 **
    388 ** Returns          None
    389 **
    390 *******************************************************************************/
    391 void nfa_hci_restore_default_config(uint8_t* p_session_id) {
    392   memset(&nfa_hci_cb.cfg, 0, sizeof(nfa_hci_cb.cfg));
    393   memcpy(nfa_hci_cb.cfg.admin_gate.session_id, p_session_id,
    394          NFA_HCI_SESSION_ID_LEN);
    395   nfa_hci_cb.nv_write_needed = true;
    396 }
    397 
    398 /*******************************************************************************
    399 **
    400 ** Function         nfa_hci_proc_nfcc_power_mode
    401 **
    402 ** Description      Restore NFA HCI sub-module
    403 **
    404 ** Returns          None
    405 **
    406 *******************************************************************************/
    407 void nfa_hci_proc_nfcc_power_mode(uint8_t nfcc_power_mode) {
    408   NFA_TRACE_DEBUG1("nfa_hci_proc_nfcc_power_mode () nfcc_power_mode=%d",
    409                    nfcc_power_mode);
    410 
    411   /* if NFCC power mode is change to full power */
    412   if (nfcc_power_mode == NFA_DM_PWR_MODE_FULL) {
    413     nfa_hci_cb.b_low_power_mode = false;
    414     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
    415       nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE;
    416       nfa_hci_cb.ee_disc_cmplt = false;
    417       nfa_hci_cb.ee_disable_disc = true;
    418       if (nfa_hci_cb.num_nfcee > 1)
    419         nfa_hci_cb.w4_hci_netwk_init = true;
    420       else
    421         nfa_hci_cb.w4_hci_netwk_init = false;
    422       nfa_hci_cb.conn_id = 0;
    423       nfa_hci_cb.num_ee_dis_req_ntf = 0;
    424       nfa_hci_cb.num_hot_plug_evts = 0;
    425     } else {
    426       NFA_TRACE_ERROR0("nfa_hci_proc_nfcc_power_mode (): Cannot restore now");
    427       nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
    428     }
    429   } else {
    430     nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    431     nfa_hci_cb.w4_rsp_evt = false;
    432     nfa_hci_cb.conn_id = 0;
    433     nfa_sys_stop_timer(&nfa_hci_cb.timer);
    434     nfa_hci_cb.b_low_power_mode = true;
    435     nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
    436   }
    437 }
    438 
    439 /*******************************************************************************
    440 **
    441 ** Function         nfa_hci_dh_startup_complete
    442 **
    443 ** Description      Initialization of terminal host in HCI Network is completed
    444 **                  Wait for other host in the network to initialize
    445 **
    446 ** Returns          None
    447 **
    448 *******************************************************************************/
    449 void nfa_hci_dh_startup_complete(void) {
    450   if (nfa_hci_cb.w4_hci_netwk_init) {
    451     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
    452       nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
    453       /* Wait for EE Discovery to complete */
    454       nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    455                           NFA_EE_DISCV_TIMEOUT_VAL);
    456     } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) {
    457       nfa_hci_cb.hci_state = NFA_HCI_STATE_RESTORE_NETWK_ENABLE;
    458       /* No HCP packet to DH for a specified period of time indicates all host
    459        * in the network is initialized */
    460       nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    461                           p_nfa_hci_cfg->hci_netwk_enable_timeout);
    462     }
    463   } else if ((nfa_hci_cb.num_nfcee > 1) &&
    464              (nfa_hci_cb.num_ee_dis_req_ntf != (nfa_hci_cb.num_nfcee - 1))) {
    465     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
    466       nfa_hci_cb.ee_disable_disc = true;
    467     /* Received HOT PLUG EVT, we will also wait for EE DISC REQ Ntf(s) */
    468     nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    469                         p_nfa_hci_cfg->hci_netwk_enable_timeout);
    470   } else {
    471     /* Received EE DISC REQ Ntf(s) */
    472     nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
    473   }
    474 }
    475 
    476 /*******************************************************************************
    477 **
    478 ** Function         nfa_hci_startup_complete
    479 **
    480 ** Description      HCI network initialization is completed
    481 **
    482 ** Returns          None
    483 **
    484 *******************************************************************************/
    485 void nfa_hci_startup_complete(tNFA_STATUS status) {
    486   tNFA_HCI_EVT_DATA evt_data;
    487 
    488   NFA_TRACE_EVENT1("nfa_hci_startup_complete (): Status: %u", status);
    489 
    490   nfa_sys_stop_timer(&nfa_hci_cb.timer);
    491 
    492   if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
    493       (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
    494     nfa_ee_proc_hci_info_cback();
    495     nfa_sys_cback_notify_nfcc_power_mode_proc_complete(NFA_ID_HCI);
    496   } else {
    497     evt_data.hci_init.status = status;
    498 
    499     nfa_hciu_send_to_all_apps(NFA_HCI_INIT_EVT, &evt_data);
    500     nfa_sys_cback_notify_enable_complete(NFA_ID_HCI);
    501   }
    502 
    503   if (status == NFA_STATUS_OK)
    504     nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    505 
    506   else
    507     nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
    508 }
    509 
    510 /*******************************************************************************
    511 **
    512 ** Function         nfa_hci_startup
    513 **
    514 ** Description      Perform HCI startup
    515 **
    516 ** Returns          None
    517 **
    518 *******************************************************************************/
    519 void nfa_hci_startup(void) {
    520   tNFA_STATUS status = NFA_STATUS_FAILED;
    521   tNFA_EE_INFO ee_info[2];
    522   uint8_t num_nfcee = 2;
    523   uint8_t target_handle;
    524   uint8_t count = 0;
    525   bool found = false;
    526 
    527   if (HCI_LOOPBACK_DEBUG) {
    528     /* First step in initialization is to open the admin pipe */
    529     nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
    530     return;
    531   }
    532 
    533   /* We can only start up if NV Ram is read and EE discovery is complete */
    534   if (nfa_hci_cb.nv_read_cmplt && nfa_hci_cb.ee_disc_cmplt &&
    535       (nfa_hci_cb.conn_id == 0)) {
    536     NFA_EeGetInfo(&num_nfcee, ee_info);
    537 
    538     while ((count < num_nfcee) && (!found)) {
    539       target_handle = (uint8_t)ee_info[count].ee_handle;
    540 
    541       if (ee_info[count].ee_interface[0] == NFA_EE_INTERFACE_HCI_ACCESS) {
    542         found = true;
    543 
    544         if (ee_info[count].ee_status == NFA_EE_STATUS_INACTIVE) {
    545           NFC_NfceeModeSet(target_handle, NFC_MODE_ACTIVATE);
    546         }
    547         status =
    548             NFC_ConnCreate(NCI_DEST_TYPE_NFCEE, target_handle,
    549                            NFA_EE_INTERFACE_HCI_ACCESS, nfa_hci_conn_cback);
    550         if (status == NFA_STATUS_OK)
    551           nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    552                               NFA_HCI_CON_CREATE_TIMEOUT_VAL);
    553         else {
    554           nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
    555           NFA_TRACE_ERROR0(
    556               "nfa_hci_startup - Failed to Create Logical connection. HCI "
    557               "Initialization/Restore failed");
    558           nfa_hci_startup_complete(NFA_STATUS_FAILED);
    559         }
    560       }
    561       count++;
    562     }
    563     if (!found) {
    564       NFA_TRACE_ERROR0(
    565           "nfa_hci_startup - HCI ACCESS Interface not discovered. HCI "
    566           "Initialization/Restore failed");
    567       nfa_hci_startup_complete(NFA_STATUS_FAILED);
    568     }
    569   }
    570 }
    571 
    572 /*******************************************************************************
    573 **
    574 ** Function         nfa_hci_sys_enable
    575 **
    576 ** Description      Enable NFA HCI
    577 **
    578 ** Returns          None
    579 **
    580 *******************************************************************************/
    581 static void nfa_hci_sys_enable(void) {
    582   NFA_TRACE_DEBUG0("nfa_hci_sys_enable ()");
    583   nfa_ee_reg_cback_enable_done(&nfa_hci_ee_info_cback);
    584 
    585   nfa_nv_co_read((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
    586                  DH_NV_BLOCK);
    587   nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    588                       NFA_HCI_NV_READ_TIMEOUT_VAL);
    589 }
    590 
    591 /*******************************************************************************
    592 **
    593 ** Function         nfa_hci_sys_disable
    594 **
    595 ** Description      Disable NFA HCI
    596 **
    597 ** Returns          None
    598 **
    599 *******************************************************************************/
    600 static void nfa_hci_sys_disable(void) {
    601   tNFA_HCI_EVT_DATA evt_data;
    602 
    603   nfa_sys_stop_timer(&nfa_hci_cb.timer);
    604 
    605   if (nfa_hci_cb.conn_id) {
    606     if (nfa_sys_is_graceful_disable()) {
    607       /* Tell all applications stack is down */
    608       nfa_hciu_send_to_all_apps(NFA_HCI_EXIT_EVT, &evt_data);
    609       NFC_ConnClose(nfa_hci_cb.conn_id);
    610       return;
    611     }
    612     nfa_hci_cb.conn_id = 0;
    613   }
    614 
    615   nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
    616   /* deregister message handler on NFA SYS */
    617   nfa_sys_deregister(NFA_ID_HCI);
    618 }
    619 
    620 /*******************************************************************************
    621 **
    622 ** Function         nfa_hci_conn_cback
    623 **
    624 ** Description      This function Process event from NCI
    625 **
    626 ** Returns          None
    627 **
    628 *******************************************************************************/
    629 static void nfa_hci_conn_cback(uint8_t conn_id, tNFC_CONN_EVT event,
    630                                tNFC_CONN* p_data) {
    631   uint8_t* p;
    632   NFC_HDR* p_pkt = (NFC_HDR*)p_data->data.p_data;
    633   uint8_t chaining_bit;
    634   uint8_t pipe;
    635   uint16_t pkt_len;
    636 #if (BT_TRACE_VERBOSE == TRUE)
    637   char buff[100];
    638 #endif
    639 
    640   if (event == NFC_CONN_CREATE_CEVT) {
    641     nfa_hci_cb.conn_id = conn_id;
    642     nfa_hci_cb.buff_size = p_data->conn_create.buff_size;
    643 
    644     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) {
    645       nfa_hci_cb.w4_hci_netwk_init = true;
    646       nfa_hciu_alloc_gate(NFA_HCI_CONNECTIVITY_GATE, 0);
    647     }
    648 
    649     if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_CLOSED) {
    650       /* First step in initialization/restore is to open the admin pipe */
    651       nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
    652     } else {
    653       /* Read session id, to know DH session id is correct */
    654       nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
    655                                   NFA_HCI_SESSION_IDENTITY_INDEX);
    656     }
    657   } else if (event == NFC_CONN_CLOSE_CEVT) {
    658     nfa_hci_cb.conn_id = 0;
    659     nfa_hci_cb.hci_state = NFA_HCI_STATE_DISABLED;
    660     /* deregister message handler on NFA SYS */
    661     nfa_sys_deregister(NFA_ID_HCI);
    662   }
    663 
    664   if ((event != NFC_DATA_CEVT) || (p_pkt == NULL)) return;
    665 
    666   if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
    667       (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
    668     /* Received HCP Packet before timeout, Other Host initialization is not
    669      * complete */
    670     nfa_sys_stop_timer(&nfa_hci_cb.timer);
    671     if (nfa_hci_cb.w4_hci_netwk_init)
    672       nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
    673                           p_nfa_hci_cfg->hci_netwk_enable_timeout);
    674   }
    675 
    676   p = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
    677   pkt_len = p_pkt->len;
    678 
    679 #if (BT_TRACE_PROTOCOL == TRUE)
    680   DispHcp(p, pkt_len, true, (bool)!nfa_hci_cb.assembling);
    681 #endif
    682 
    683   chaining_bit = ((*p) >> 0x07) & 0x01;
    684   pipe = (*p++) & 0x7F;
    685   if (pkt_len != 0) pkt_len--;
    686 
    687   if (nfa_hci_cb.assembling == false) {
    688     /* First Segment of a packet */
    689     nfa_hci_cb.type = ((*p) >> 0x06) & 0x03;
    690     nfa_hci_cb.inst = (*p++ & 0x3F);
    691     if (pkt_len != 0) pkt_len--;
    692     nfa_hci_cb.assembly_failed = false;
    693     nfa_hci_cb.msg_len = 0;
    694 
    695     if (chaining_bit == NFA_HCI_MESSAGE_FRAGMENTATION) {
    696       nfa_hci_cb.assembling = true;
    697       nfa_hci_set_receive_buf(pipe);
    698       nfa_hci_assemble_msg(p, pkt_len);
    699     } else {
    700       if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
    701           (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
    702         nfa_hci_set_receive_buf(pipe);
    703         nfa_hci_assemble_msg(p, pkt_len);
    704         p = nfa_hci_cb.p_msg_data;
    705       }
    706     }
    707   } else {
    708     if (nfa_hci_cb.assembly_failed) {
    709       /* If Reassembly failed because of insufficient buffer, just drop the new
    710        * segmented packets */
    711       NFA_TRACE_ERROR1(
    712           "nfa_hci_conn_cback (): Insufficient buffer to Reassemble HCP "
    713           "packet! Dropping :%u bytes",
    714           pkt_len);
    715     } else {
    716       /* Reassemble the packet */
    717       nfa_hci_assemble_msg(p, pkt_len);
    718     }
    719 
    720     if (chaining_bit == NFA_HCI_NO_MESSAGE_FRAGMENTATION) {
    721       /* Just added the last segment in the chain. Reset pointers */
    722       nfa_hci_cb.assembling = false;
    723       p = nfa_hci_cb.p_msg_data;
    724       pkt_len = nfa_hci_cb.msg_len;
    725     }
    726   }
    727 
    728 #if (BT_TRACE_VERBOSE == TRUE)
    729   NFA_TRACE_EVENT5(
    730       "nfa_hci_conn_cback Recvd data pipe:%d  %s  chain:%d  assmbl:%d  len:%d",
    731       (uint8_t)pipe, nfa_hciu_get_type_inst_names(pipe, nfa_hci_cb.type,
    732                                                   nfa_hci_cb.inst, buff),
    733       (uint8_t)chaining_bit, (uint8_t)nfa_hci_cb.assembling, p_pkt->len);
    734 #else
    735   NFA_TRACE_EVENT6(
    736       "nfa_hci_conn_cback Recvd data pipe:%d  Type: %u  Inst: %u  chain:%d "
    737       "reassm:%d len:%d",
    738       pipe, nfa_hci_cb.type, nfa_hci_cb.inst, chaining_bit,
    739       nfa_hci_cb.assembling, p_pkt->len);
    740 #endif
    741 
    742   /* If still reassembling fragments, just return */
    743   if (nfa_hci_cb.assembling) {
    744     /* if not last packet, release GKI buffer */
    745     GKI_freebuf(p_pkt);
    746     return;
    747   }
    748 
    749   /* If we got a response, cancel the response timer. Also, if waiting for */
    750   /* a single response, we can go back to idle state                       */
    751   if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_RSP) &&
    752       ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
    753        (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)))) {
    754     nfa_sys_stop_timer(&nfa_hci_cb.timer);
    755     nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    756   }
    757 
    758   switch (pipe) {
    759     case NFA_HCI_ADMIN_PIPE:
    760       /* Check if data packet is a command, response or event */
    761       if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
    762         nfa_hci_handle_admin_gate_cmd(p);
    763       } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
    764         nfa_hci_handle_admin_gate_rsp(p, (uint8_t)pkt_len);
    765       } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
    766         nfa_hci_handle_admin_gate_evt(p);
    767       }
    768       break;
    769 
    770     case NFA_HCI_LINK_MANAGEMENT_PIPE:
    771       /* We don't send Link Management commands, we only get them */
    772       if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
    773         nfa_hci_handle_link_mgm_gate_cmd(p);
    774       break;
    775 
    776     default:
    777       if (pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE)
    778         nfa_hci_handle_dyn_pipe_pkt(pipe, p, pkt_len);
    779       break;
    780   }
    781 
    782   if ((nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) ||
    783       (nfa_hci_cb.w4_rsp_evt && (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE))) {
    784     nfa_hci_cb.w4_rsp_evt = false;
    785   }
    786 
    787   /* Send a message to ouselves to check for anything to do */
    788   p_pkt->event = NFA_HCI_CHECK_QUEUE_EVT;
    789   p_pkt->len = 0;
    790   nfa_sys_sendmsg(p_pkt);
    791 }
    792 
    793 /*******************************************************************************
    794 **
    795 ** Function         nfa_hci_handle_nv_read
    796 **
    797 ** Description      handler function for nv read complete event
    798 **
    799 ** Returns          None
    800 **
    801 *******************************************************************************/
    802 void nfa_hci_handle_nv_read(uint8_t block, tNFA_STATUS status) {
    803   uint8_t session_id[NFA_HCI_SESSION_ID_LEN];
    804   uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
    805                                                      0xFF, 0xFF, 0xFF, 0xFF};
    806   uint8_t reset_session[NFA_HCI_SESSION_ID_LEN] = {0x00, 0x00, 0x00, 0x00,
    807                                                    0x00, 0x00, 0x00, 0x00};
    808   uint32_t os_tick;
    809 
    810   if (block == DH_NV_BLOCK) {
    811     /* Stop timer as NVDATA Read Completed */
    812     nfa_sys_stop_timer(&nfa_hci_cb.timer);
    813     nfa_hci_cb.nv_read_cmplt = true;
    814     if ((status != NFA_STATUS_OK) || (!nfa_hci_is_valid_cfg()) ||
    815         (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, default_session,
    816                   NFA_HCI_SESSION_ID_LEN))) ||
    817         (!(memcmp(nfa_hci_cb.cfg.admin_gate.session_id, reset_session,
    818                   NFA_HCI_SESSION_ID_LEN)))) {
    819       nfa_hci_cb.b_hci_netwk_reset = true;
    820       /* Set a new session id so that we clear all pipes later after seeing a
    821        * difference with the HC Session ID */
    822       memcpy(&session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
    823              nfa_hci_cb.cfg.admin_gate.session_id,
    824              (NFA_HCI_SESSION_ID_LEN / 2));
    825       os_tick = GKI_get_os_tick_count();
    826       memcpy(session_id, (uint8_t*)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
    827       nfa_hci_restore_default_config(session_id);
    828     }
    829     nfa_hci_startup();
    830   }
    831 }
    832 
    833 /*******************************************************************************
    834 **
    835 ** Function         nfa_hci_rsp_timeout
    836 **
    837 ** Description      action function to process timeout
    838 **
    839 ** Returns          None
    840 **
    841 *******************************************************************************/
    842 void nfa_hci_rsp_timeout(tNFA_HCI_EVENT_DATA* p_evt_data) {
    843   tNFA_HCI_EVT evt = 0;
    844   tNFA_HCI_EVT_DATA evt_data;
    845   uint8_t delete_pipe;
    846 
    847   NFA_TRACE_EVENT2("nfa_hci_rsp_timeout () State: %u  Cmd: %u",
    848                    nfa_hci_cb.hci_state, nfa_hci_cb.cmd_sent);
    849 
    850   evt_data.status = NFA_STATUS_FAILED;
    851 
    852   switch (nfa_hci_cb.hci_state) {
    853     case NFA_HCI_STATE_STARTUP:
    854     case NFA_HCI_STATE_RESTORE:
    855       NFA_TRACE_ERROR0("nfa_hci_rsp_timeout - Initialization failed!");
    856       nfa_hci_startup_complete(NFA_STATUS_TIMEOUT);
    857       break;
    858 
    859     case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
    860     case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
    861 
    862       if (nfa_hci_cb.w4_hci_netwk_init) {
    863         /* HCI Network is enabled */
    864         nfa_hci_cb.w4_hci_netwk_init = false;
    865         nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
    866                                     NFA_HCI_HOST_LIST_INDEX);
    867       } else {
    868         nfa_hci_startup_complete(NFA_STATUS_FAILED);
    869       }
    870       break;
    871 
    872     case NFA_HCI_STATE_REMOVE_GATE:
    873       /* Something wrong, NVRAM data could be corrupt */
    874       if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
    875         nfa_hciu_send_clear_all_pipe_cmd();
    876       } else {
    877         nfa_hciu_remove_all_pipes_from_host(0);
    878         nfa_hci_api_dealloc_gate(NULL);
    879       }
    880       break;
    881 
    882     case NFA_HCI_STATE_APP_DEREGISTER:
    883       /* Something wrong, NVRAM data could be corrupt */
    884       if (nfa_hci_cb.cmd_sent == NFA_HCI_ADM_DELETE_PIPE) {
    885         nfa_hciu_send_clear_all_pipe_cmd();
    886       } else {
    887         nfa_hciu_remove_all_pipes_from_host(0);
    888         nfa_hci_api_deregister(NULL);
    889       }
    890       break;
    891 
    892     case NFA_HCI_STATE_WAIT_RSP:
    893       nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    894 
    895       if (nfa_hci_cb.w4_rsp_evt) {
    896         nfa_hci_cb.w4_rsp_evt = false;
    897         evt = NFA_HCI_EVENT_RCVD_EVT;
    898         evt_data.rcvd_evt.pipe = nfa_hci_cb.pipe_in_use;
    899         evt_data.rcvd_evt.evt_code = 0;
    900         evt_data.rcvd_evt.evt_len = 0;
    901         evt_data.rcvd_evt.p_evt_buf = NULL;
    902         nfa_hci_cb.rsp_buf_size = 0;
    903         nfa_hci_cb.p_rsp_buf = NULL;
    904 
    905         break;
    906       }
    907 
    908       delete_pipe = 0;
    909       switch (nfa_hci_cb.cmd_sent) {
    910         case NFA_HCI_ANY_SET_PARAMETER:
    911           /*
    912            * As no response to the command sent on this pipe, we may assume the
    913            * pipe is
    914            * deleted already and release the pipe. But still send delete pipe
    915            * command to be safe.
    916            */
    917           delete_pipe = nfa_hci_cb.pipe_in_use;
    918           evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
    919           evt_data.registry.data_len = 0;
    920           evt_data.registry.index = nfa_hci_cb.param_in_use;
    921           evt = NFA_HCI_SET_REG_RSP_EVT;
    922           break;
    923 
    924         case NFA_HCI_ANY_GET_PARAMETER:
    925           /*
    926            * As no response to the command sent on this pipe, we may assume the
    927            * pipe is
    928            * deleted already and release the pipe. But still send delete pipe
    929            * command to be safe.
    930            */
    931           delete_pipe = nfa_hci_cb.pipe_in_use;
    932           evt_data.registry.pipe = nfa_hci_cb.pipe_in_use;
    933           evt_data.registry.data_len = 0;
    934           evt_data.registry.index = nfa_hci_cb.param_in_use;
    935           evt = NFA_HCI_GET_REG_RSP_EVT;
    936           break;
    937 
    938         case NFA_HCI_ANY_OPEN_PIPE:
    939           /*
    940            * As no response to the command sent on this pipe, we may assume the
    941            * pipe is
    942            * deleted already and release the pipe. But still send delete pipe
    943            * command to be safe.
    944            */
    945           delete_pipe = nfa_hci_cb.pipe_in_use;
    946           evt_data.opened.pipe = nfa_hci_cb.pipe_in_use;
    947           evt = NFA_HCI_OPEN_PIPE_EVT;
    948           break;
    949 
    950         case NFA_HCI_ANY_CLOSE_PIPE:
    951           /*
    952            * As no response to the command sent on this pipe, we may assume the
    953            * pipe is
    954            * deleted already and release the pipe. But still send delete pipe
    955            * command to be safe.
    956            */
    957           delete_pipe = nfa_hci_cb.pipe_in_use;
    958           evt_data.closed.pipe = nfa_hci_cb.pipe_in_use;
    959           evt = NFA_HCI_CLOSE_PIPE_EVT;
    960           break;
    961 
    962         case NFA_HCI_ADM_CREATE_PIPE:
    963           evt_data.created.pipe = nfa_hci_cb.pipe_in_use;
    964           evt_data.created.source_gate = nfa_hci_cb.local_gate_in_use;
    965           evt_data.created.dest_host = nfa_hci_cb.remote_host_in_use;
    966           evt_data.created.dest_gate = nfa_hci_cb.remote_gate_in_use;
    967           evt = NFA_HCI_CREATE_PIPE_EVT;
    968           break;
    969 
    970         case NFA_HCI_ADM_DELETE_PIPE:
    971           /*
    972            * As no response to the command sent on this pipe, we may assume the
    973            * pipe is
    974            * deleted already. Just release the pipe.
    975            */
    976           if (nfa_hci_cb.pipe_in_use <= NFA_HCI_LAST_DYNAMIC_PIPE)
    977             nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
    978           evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
    979           evt = NFA_HCI_DELETE_PIPE_EVT;
    980           break;
    981 
    982         default:
    983           /*
    984            * As no response to the command sent on this pipe, we may assume the
    985            * pipe is
    986            * deleted already and release the pipe. But still send delete pipe
    987            * command to be safe.
    988            */
    989           delete_pipe = nfa_hci_cb.pipe_in_use;
    990           break;
    991       }
    992       if (delete_pipe && (delete_pipe <= NFA_HCI_LAST_DYNAMIC_PIPE)) {
    993         nfa_hciu_send_delete_pipe_cmd(delete_pipe);
    994         nfa_hciu_release_pipe(delete_pipe);
    995       }
    996       break;
    997     case NFA_HCI_STATE_DISABLED:
    998     default:
    999       NFA_TRACE_DEBUG0(
   1000           "nfa_hci_rsp_timeout () Timeout in DISABLED/ Invalid state");
   1001       break;
   1002   }
   1003   if (evt != 0) nfa_hciu_send_to_app(evt, &evt_data, nfa_hci_cb.app_in_use);
   1004 }
   1005 
   1006 /*******************************************************************************
   1007 **
   1008 ** Function         nfa_hci_set_receive_buf
   1009 **
   1010 ** Description      Set reassembly buffer for incoming message
   1011 **
   1012 ** Returns          status
   1013 **
   1014 *******************************************************************************/
   1015 static void nfa_hci_set_receive_buf(uint8_t pipe) {
   1016   if ((pipe >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
   1017       (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)) {
   1018     if ((nfa_hci_cb.rsp_buf_size) && (nfa_hci_cb.p_rsp_buf != NULL)) {
   1019       nfa_hci_cb.p_msg_data = nfa_hci_cb.p_rsp_buf;
   1020       nfa_hci_cb.max_msg_len = nfa_hci_cb.rsp_buf_size;
   1021       return;
   1022     }
   1023   }
   1024   nfa_hci_cb.p_msg_data = nfa_hci_cb.msg_data;
   1025   nfa_hci_cb.max_msg_len = NFA_MAX_HCI_EVENT_LEN;
   1026 }
   1027 
   1028 /*******************************************************************************
   1029 **
   1030 ** Function         nfa_hci_assemble_msg
   1031 **
   1032 ** Description      Reassemble the incoming message
   1033 **
   1034 ** Returns          None
   1035 **
   1036 *******************************************************************************/
   1037 static void nfa_hci_assemble_msg(uint8_t* p_data, uint16_t data_len) {
   1038   if ((nfa_hci_cb.msg_len + data_len) > nfa_hci_cb.max_msg_len) {
   1039     /* Fill the buffer as much it can hold */
   1040     memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data,
   1041            (nfa_hci_cb.max_msg_len - nfa_hci_cb.msg_len));
   1042     nfa_hci_cb.msg_len = nfa_hci_cb.max_msg_len;
   1043     /* Set Reassembly failed */
   1044     nfa_hci_cb.assembly_failed = true;
   1045     NFA_TRACE_ERROR1(
   1046         "nfa_hci_assemble_msg (): Insufficient buffer to Reassemble HCP "
   1047         "packet! Dropping :%u bytes",
   1048         ((nfa_hci_cb.msg_len + data_len) - nfa_hci_cb.max_msg_len));
   1049   } else {
   1050     memcpy(&nfa_hci_cb.p_msg_data[nfa_hci_cb.msg_len], p_data, data_len);
   1051     nfa_hci_cb.msg_len += data_len;
   1052   }
   1053 }
   1054 
   1055 /*******************************************************************************
   1056 **
   1057 ** Function         nfa_hci_evt_hdlr
   1058 **
   1059 ** Description      Processing all event for NFA HCI
   1060 **
   1061 ** Returns          TRUE if p_msg needs to be deallocated
   1062 **
   1063 *******************************************************************************/
   1064 static bool nfa_hci_evt_hdlr(NFC_HDR* p_msg) {
   1065   tNFA_HCI_EVENT_DATA* p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
   1066 
   1067 #if (BT_TRACE_VERBOSE == TRUE)
   1068   NFA_TRACE_EVENT4(
   1069       "nfa_hci_evt_hdlr state: %s (%d) event: %s (0x%04x)",
   1070       nfa_hciu_get_state_name(nfa_hci_cb.hci_state), nfa_hci_cb.hci_state,
   1071       nfa_hciu_get_event_name(p_evt_data->hdr.event), p_evt_data->hdr.event);
   1072 #else
   1073   NFA_TRACE_EVENT2("nfa_hci_evt_hdlr state: %d event: 0x%04x",
   1074                    nfa_hci_cb.hci_state, p_evt_data->hdr.event);
   1075 #endif
   1076 
   1077   /* If this is an API request, queue it up */
   1078   if ((p_msg->event >= NFA_HCI_FIRST_API_EVENT) &&
   1079       (p_msg->event <= NFA_HCI_LAST_API_EVENT)) {
   1080     GKI_enqueue(&nfa_hci_cb.hci_api_q, p_msg);
   1081   } else {
   1082     switch (p_msg->event) {
   1083       case NFA_HCI_RSP_NV_READ_EVT:
   1084         nfa_hci_handle_nv_read(p_evt_data->nv_read.block,
   1085                                p_evt_data->nv_read.status);
   1086         break;
   1087 
   1088       case NFA_HCI_RSP_NV_WRITE_EVT:
   1089         /* NV Ram write completed - nothing to do... */
   1090         break;
   1091 
   1092       case NFA_HCI_RSP_TIMEOUT_EVT:
   1093         nfa_hci_rsp_timeout((tNFA_HCI_EVENT_DATA*)p_msg);
   1094         break;
   1095 
   1096       case NFA_HCI_CHECK_QUEUE_EVT:
   1097         if (HCI_LOOPBACK_DEBUG) {
   1098           if (p_msg->len != 0) {
   1099             tNFC_DATA_CEVT xx;
   1100             xx.p_data = p_msg;
   1101             nfa_hci_conn_cback(0, NFC_DATA_CEVT, (tNFC_CONN*)&xx);
   1102             return false;
   1103           }
   1104         }
   1105         break;
   1106     }
   1107   }
   1108 
   1109   if ((p_msg->event > NFA_HCI_LAST_API_EVENT)) GKI_freebuf(p_msg);
   1110 
   1111   nfa_hci_check_api_requests();
   1112 
   1113   if (nfa_hciu_is_no_host_resetting()) nfa_hci_check_pending_api_requests();
   1114 
   1115   if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) &&
   1116       (nfa_hci_cb.nv_write_needed)) {
   1117     nfa_hci_cb.nv_write_needed = false;
   1118     nfa_nv_co_write((uint8_t*)&nfa_hci_cb.cfg, sizeof(nfa_hci_cb.cfg),
   1119                     DH_NV_BLOCK);
   1120   }
   1121 
   1122   return false;
   1123 }
   1124