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