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