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