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 file contains the action functions for the NFA HCI.
     23  *
     24  ******************************************************************************/
     25 #include <string.h>
     26 #include "trace_api.h"
     27 #include "nfc_api.h"
     28 #include "nfa_sys.h"
     29 #include "nfa_sys_int.h"
     30 #include "nfa_hci_api.h"
     31 #include "nfa_hci_int.h"
     32 #include "nfa_dm_int.h"
     33 #include "nfa_nv_co.h"
     34 #include "nfa_mem_co.h"
     35 #include "nfa_hci_defs.h"
     36 
     37 
     38 /* Static local functions       */
     39 static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data);
     40 static void nfa_hci_api_get_gate_pipe_list (tNFA_HCI_EVENT_DATA *p_evt_data);
     41 static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data);
     42 static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data);
     43 static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data);
     44 static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data);
     45 static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
     46 static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
     47 static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
     48 static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
     49 static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data);
     50 static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data);
     51 static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data);
     52 static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data);
     53 
     54 static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe);
     55 static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe);
     56 static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe);
     57 static void nfa_hci_handle_generic_gate_cmd (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
     58 static void nfa_hci_handle_generic_gate_rsp (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
     59 static void nfa_hci_handle_generic_gate_evt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe);
     60 
     61 
     62 /*******************************************************************************
     63 **
     64 ** Function         nfa_hci_check_pending_api_requests
     65 **
     66 ** Description      This function handles pending API requests
     67 **
     68 ** Returns          none
     69 **
     70 *******************************************************************************/
     71 void nfa_hci_check_pending_api_requests (void)
     72 {
     73     BT_HDR              *p_msg;
     74     tNFA_HCI_EVENT_DATA *p_evt_data;
     75     BOOLEAN             b_free;
     76 
     77     /* If busy, or API queue is empty, then exit */
     78     if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE)
     79         ||((p_msg = (BT_HDR *) GKI_dequeue (&nfa_hci_cb.hci_host_reset_api_q)) == NULL) )
     80         return;
     81 
     82     /* Process API request */
     83     p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
     84 
     85     /* Save the application handle */
     86     nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
     87 
     88     b_free = TRUE;
     89     switch (p_msg->event)
     90     {
     91     case NFA_HCI_API_CREATE_PIPE_EVT:
     92         if (nfa_hci_api_create_pipe (p_evt_data) == FALSE)
     93             b_free = FALSE;
     94         break;
     95 
     96     case NFA_HCI_API_GET_REGISTRY_EVT:
     97         if (nfa_hci_api_get_reg_value (p_evt_data) == FALSE)
     98             b_free = FALSE;
     99         break;
    100 
    101     case NFA_HCI_API_SET_REGISTRY_EVT:
    102         if (nfa_hci_api_set_reg_value (p_evt_data) == FALSE)
    103             b_free = FALSE;
    104         break;
    105 
    106     case NFA_HCI_API_SEND_CMD_EVT:
    107         if (nfa_hci_api_send_cmd (p_evt_data) == FALSE)
    108             b_free = FALSE;
    109         break;
    110     case NFA_HCI_API_SEND_EVENT_EVT:
    111         if (nfa_hci_api_send_event (p_evt_data) == FALSE)
    112             b_free = FALSE;
    113         break;
    114     }
    115 
    116     if (b_free)
    117         GKI_freebuf (p_msg);
    118 }
    119 
    120 /*******************************************************************************
    121 **
    122 ** Function         nfa_hci_check_api_requests
    123 **
    124 ** Description      This function handles API requests
    125 **
    126 ** Returns          none
    127 **
    128 *******************************************************************************/
    129 void nfa_hci_check_api_requests (void)
    130 {
    131     BT_HDR              *p_msg;
    132     tNFA_HCI_EVENT_DATA *p_evt_data;
    133 
    134     for ( ; ; )
    135     {
    136         /* If busy, or API queue is empty, then exit */
    137         if (  (nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE)
    138             ||((p_msg = (BT_HDR *) GKI_dequeue (&nfa_hci_cb.hci_api_q)) == NULL) )
    139             break;
    140 
    141         /* Process API request */
    142         p_evt_data = (tNFA_HCI_EVENT_DATA *)p_msg;
    143 
    144         /* Save the application handle */
    145         nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
    146 
    147         switch (p_msg->event)
    148         {
    149         case NFA_HCI_API_REGISTER_APP_EVT:
    150             nfa_hci_api_register (p_evt_data);
    151             break;
    152 
    153         case NFA_HCI_API_DEREGISTER_APP_EVT:
    154             nfa_hci_api_deregister (p_evt_data);
    155             break;
    156 
    157         case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
    158             nfa_hci_api_get_gate_pipe_list (p_evt_data);
    159             break;
    160 
    161         case NFA_HCI_API_ALLOC_GATE_EVT:
    162             nfa_hci_api_alloc_gate (p_evt_data);
    163             break;
    164 
    165         case NFA_HCI_API_DEALLOC_GATE_EVT:
    166             nfa_hci_api_dealloc_gate (p_evt_data);
    167             break;
    168 
    169         case NFA_HCI_API_GET_HOST_LIST_EVT:
    170             nfa_hci_api_get_host_list (p_evt_data);
    171             break;
    172 
    173         case NFA_HCI_API_GET_REGISTRY_EVT:
    174             if (nfa_hci_api_get_reg_value (p_evt_data) == FALSE)
    175                 continue;
    176             break;
    177 
    178         case NFA_HCI_API_SET_REGISTRY_EVT:
    179             if (nfa_hci_api_set_reg_value (p_evt_data) == FALSE)
    180                 continue;
    181             break;
    182 
    183         case NFA_HCI_API_CREATE_PIPE_EVT:
    184            if (nfa_hci_api_create_pipe (p_evt_data) == FALSE)
    185                continue;
    186             break;
    187 
    188         case NFA_HCI_API_OPEN_PIPE_EVT:
    189             nfa_hci_api_open_pipe (p_evt_data);
    190             break;
    191 
    192         case NFA_HCI_API_CLOSE_PIPE_EVT:
    193             nfa_hci_api_close_pipe (p_evt_data);
    194             break;
    195 
    196         case NFA_HCI_API_DELETE_PIPE_EVT:
    197             nfa_hci_api_delete_pipe (p_evt_data);
    198             break;
    199 
    200         case NFA_HCI_API_SEND_CMD_EVT:
    201             if (nfa_hci_api_send_cmd (p_evt_data) == FALSE)
    202                 continue;
    203             break;
    204 
    205         case NFA_HCI_API_SEND_RSP_EVT:
    206             nfa_hci_api_send_rsp (p_evt_data);
    207             break;
    208 
    209         case NFA_HCI_API_SEND_EVENT_EVT:
    210             if (nfa_hci_api_send_event (p_evt_data) == FALSE)
    211                 continue;
    212             break;
    213 
    214         case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
    215             nfa_hci_api_add_static_pipe (p_evt_data);
    216             break;
    217 
    218         default:
    219             NFA_TRACE_ERROR1 ("nfa_hci_check_api_requests ()  Unknown event: 0x%04x", p_msg->event);
    220             break;
    221         }
    222 
    223         GKI_freebuf (p_msg);
    224     }
    225 }
    226 
    227 /*******************************************************************************
    228 **
    229 ** Function         nfa_hci_api_register
    230 **
    231 ** Description      action function to register the events for the given AID
    232 **
    233 ** Returns          None
    234 **
    235 *******************************************************************************/
    236 static void nfa_hci_api_register (tNFA_HCI_EVENT_DATA *p_evt_data)
    237 {
    238     tNFA_HCI_EVT_DATA   evt_data;
    239     char                *p_app_name  = p_evt_data->app_info.app_name;
    240     tNFA_HCI_CBACK      *p_cback     = p_evt_data->app_info.p_cback;
    241     int                 xx,yy;
    242     UINT8               num_gates    = 0,num_pipes = 0;
    243     tNFA_HCI_DYN_GATE   *pg = nfa_hci_cb.cfg.dyn_gates;
    244 
    245     /* First, see if the application was already registered */
    246     for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
    247     {
    248         if (  (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
    249             && !strncmp (p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], strlen (p_app_name)) )
    250         {
    251             NFA_TRACE_EVENT2 ("nfa_hci_api_register (%s)  Reusing: %u", p_app_name, xx);
    252             break;
    253         }
    254     }
    255 
    256     if (xx != NFA_HCI_MAX_APP_CB)
    257     {
    258         nfa_hci_cb.app_in_use = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
    259         /* The app was registered, find the number of gates and pipes associated to the app */
    260 
    261         for ( yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++)
    262         {
    263             if (pg->gate_owner == nfa_hci_cb.app_in_use)
    264             {
    265                 num_gates++;
    266                 num_pipes += nfa_hciu_count_pipes_on_gate (pg);
    267             }
    268         }
    269     }
    270     else
    271     {
    272         /* Not registered, look for a free entry */
    273         for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
    274         {
    275             if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0)
    276             {
    277                 memset (&nfa_hci_cb.cfg.reg_app_names[xx][0], 0, sizeof (nfa_hci_cb.cfg.reg_app_names[xx]));
    278                 BCM_STRNCPY_S (&nfa_hci_cb.cfg.reg_app_names[xx][0], sizeof (nfa_hci_cb.cfg.reg_app_names[xx]), p_app_name, NFA_MAX_HCI_APP_NAME_LEN);
    279                 nfa_hci_cb.nv_write_needed = TRUE;
    280                 NFA_TRACE_EVENT2 ("nfa_hci_api_register (%s)  Allocated: %u", p_app_name, xx);
    281                 break;
    282             }
    283         }
    284 
    285         if (xx == NFA_HCI_MAX_APP_CB)
    286         {
    287             NFA_TRACE_ERROR1 ("nfa_hci_api_register (%s)  NO ENTRIES", p_app_name);
    288 
    289             evt_data.hci_register.status = NFA_STATUS_FAILED;
    290             p_evt_data->app_info.p_cback (NFA_HCI_REGISTER_EVT, &evt_data);
    291             return;
    292         }
    293     }
    294 
    295     evt_data.hci_register.num_pipes = num_pipes;
    296     evt_data.hci_register.num_gates = num_gates;
    297     nfa_hci_cb.p_app_cback[xx]      = p_cback;
    298 
    299     nfa_hci_cb.cfg.b_send_conn_evts[xx]  = p_evt_data->app_info.b_send_conn_evts;
    300 
    301     evt_data.hci_register.hci_handle = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
    302 
    303     evt_data.hci_register.status = NFA_STATUS_OK;
    304 
    305     /* notify NFA_HCI_REGISTER_EVT to the application */
    306     p_evt_data->app_info.p_cback (NFA_HCI_REGISTER_EVT, &evt_data);
    307 }
    308 
    309 /*******************************************************************************
    310 **
    311 ** Function         nfa_hci_api_deregister
    312 **
    313 ** Description      action function to deregister the given application
    314 **
    315 ** Returns          None
    316 **
    317 *******************************************************************************/
    318 void nfa_hci_api_deregister (tNFA_HCI_EVENT_DATA *p_evt_data)
    319 {
    320     tNFA_HCI_EVT_DATA   evt_data;
    321     tNFA_HCI_CBACK      *p_cback = NULL;
    322     int                 xx;
    323     tNFA_HCI_DYN_PIPE   *p_pipe;
    324     tNFA_HCI_DYN_GATE   *p_gate;
    325 
    326     /* If needed, find the application registration handle */
    327     if (p_evt_data != NULL)
    328     {
    329         for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++)
    330         {
    331             if (  (nfa_hci_cb.cfg.reg_app_names[xx][0] != 0)
    332                 && !strncmp (p_evt_data->app_info.app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0], strlen (p_evt_data->app_info.app_name)) )
    333             {
    334                 NFA_TRACE_EVENT2 ("nfa_hci_api_deregister (%s) inx: %u", p_evt_data->app_info.app_name, xx);
    335                 break;
    336             }
    337         }
    338 
    339         if (xx == NFA_HCI_MAX_APP_CB)
    340         {
    341             NFA_TRACE_WARNING1 ("nfa_hci_api_deregister () Unknown app: %s", p_evt_data->app_info.app_name);
    342             return;
    343         }
    344         nfa_hci_cb.app_in_use = (tNFA_HANDLE) (xx | NFA_HANDLE_GROUP_HCI);
    345         p_cback               = nfa_hci_cb.p_app_cback[xx];
    346     }
    347     else
    348     {
    349         nfa_sys_stop_timer (&nfa_hci_cb.timer);
    350         /* We are recursing through deleting all the app's pipes and gates */
    351         p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
    352     }
    353 
    354     /* See if any pipe is owned by this app */
    355     if (nfa_hciu_find_pipe_by_owner (nfa_hci_cb.app_in_use) == NULL)
    356     {
    357         /* No pipes, release all gates owned by this app */
    358         while ((p_gate = nfa_hciu_find_gate_by_owner (nfa_hci_cb.app_in_use)) != NULL)
    359             nfa_hciu_release_gate (p_gate->gate_id);
    360 
    361         memset (&nfa_hci_cb.cfg.reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0], 0, NFA_MAX_HCI_APP_NAME_LEN + 1);
    362         nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK]  = NULL;
    363 
    364         nfa_hci_cb.nv_write_needed = TRUE;
    365 
    366         evt_data.hci_deregister.status = NFC_STATUS_OK;
    367 
    368         if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
    369             nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    370 
    371         /* notify NFA_HCI_DEREGISTER_EVT to the application */
    372         if (p_cback)
    373             p_cback (NFA_HCI_DEREGISTER_EVT, &evt_data);
    374     }
    375     else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner (nfa_hci_cb.app_in_use)) == NULL)
    376     {
    377         /* No pipes, release all gates owned by this app */
    378         while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner (nfa_hci_cb.app_in_use)) != NULL)
    379             nfa_hciu_release_gate (p_gate->gate_id);
    380 
    381         nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK]  = NULL;
    382 
    383         nfa_hci_cb.nv_write_needed = TRUE;
    384 
    385         evt_data.hci_deregister.status = NFC_STATUS_FAILED;
    386 
    387         if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
    388             nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    389 
    390         /* notify NFA_HCI_DEREGISTER_EVT to the application */
    391         if (p_cback)
    392             p_cback (NFA_HCI_DEREGISTER_EVT, &evt_data);
    393     }
    394     else
    395     {
    396         /* Delete all active pipes created for the application before de registering
    397         **/
    398         nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;
    399 
    400         nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id);
    401     }
    402 }
    403 
    404 /*******************************************************************************
    405 **
    406 ** Function         nfa_hci_api_get_gate_pipe_list
    407 **
    408 ** Description      action function to get application allocated gates and
    409 **                  application created pipes
    410 **
    411 ** Returns          None
    412 **
    413 *******************************************************************************/
    414 static void nfa_hci_api_get_gate_pipe_list (tNFA_HCI_EVENT_DATA *p_evt_data)
    415 {
    416     tNFA_HCI_EVT_DATA   evt_data;
    417     int                 xx,yy;
    418     tNFA_HCI_DYN_GATE   *pg = nfa_hci_cb.cfg.dyn_gates;
    419     tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
    420 
    421     evt_data.gates_pipes.num_gates = 0;
    422     evt_data.gates_pipes.num_pipes = 0;
    423 
    424     for ( xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    425     {
    426         if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle)
    427         {
    428             evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;
    429 
    430             pp = nfa_hci_cb.cfg.dyn_pipes;
    431 
    432             /* Loop through looking for a match */
    433             for ( yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++)
    434             {
    435                 if (pp->local_gate == pg->gate_id)
    436                     evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] = *(tNFA_HCI_PIPE_INFO*)pp;
    437             }
    438         }
    439     }
    440 
    441     evt_data.gates_pipes.num_uicc_created_pipes = 0;
    442     /* Loop through all pipes that are connected to connectivity gate */
    443     for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    444     {
    445         if (pp->pipe_id != 0  && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE)
    446         {
    447             memcpy (&evt_data.gates_pipes.uicc_created_pipe [evt_data.gates_pipes.num_uicc_created_pipes++], pp, sizeof (tNFA_HCI_PIPE_INFO));
    448         }
    449         else if (pp->pipe_id != 0  && pp->local_gate == NFA_HCI_LOOP_BACK_GATE)
    450         {
    451             memcpy (&evt_data.gates_pipes.uicc_created_pipe [evt_data.gates_pipes.num_uicc_created_pipes++], pp, sizeof (tNFA_HCI_PIPE_INFO));
    452         }
    453     }
    454 
    455     evt_data.gates_pipes.status = NFA_STATUS_OK;
    456 
    457     /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
    458     nfa_hciu_send_to_app (NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, p_evt_data->get_gate_pipe_list.hci_handle);
    459 }
    460 
    461 /*******************************************************************************
    462 **
    463 ** Function         nfa_hci_api_alloc_gate
    464 **
    465 ** Description      action function to allocate a generic gate
    466 **
    467 ** Returns          None
    468 **
    469 *******************************************************************************/
    470 static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
    471 {
    472     tNFA_HANDLE         app_handle = p_evt_data->comm.hci_handle;
    473     tNFA_HCI_EVT_DATA   evt_data;
    474     tNFA_HCI_DYN_GATE   *p_gate;
    475 
    476     p_gate = nfa_hciu_alloc_gate (0, app_handle);
    477 
    478     evt_data.allocated.gate   = p_gate ? p_gate->gate_id : 0;
    479     evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
    480 
    481     /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
    482     nfa_hciu_send_to_app (NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
    483 }
    484 
    485 /*******************************************************************************
    486 **
    487 ** Function         nfa_hci_api_dealloc_gate
    488 **
    489 ** Description      action function to deallocate the given generic gate
    490 **
    491 ** Returns          None
    492 **
    493 *******************************************************************************/
    494 void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
    495 {
    496     tNFA_HCI_EVT_DATA   evt_data;
    497     UINT8               gate_id;
    498     tNFA_HCI_DYN_GATE   *p_gate;
    499     tNFA_HCI_DYN_PIPE   *p_pipe;
    500     tNFA_HANDLE         app_handle;
    501 
    502     /* p_evt_data may be NULL if we are recursively deleting pipes */
    503     if (p_evt_data)
    504     {
    505         gate_id    = p_evt_data->gate_dealloc.gate;
    506         app_handle = p_evt_data->gate_dealloc.hci_handle;
    507 
    508     }
    509     else
    510     {
    511         nfa_sys_stop_timer (&nfa_hci_cb.timer);
    512         gate_id    = nfa_hci_cb.local_gate_in_use;
    513         app_handle = nfa_hci_cb.app_in_use;
    514     }
    515 
    516     evt_data.deallocated.gate = gate_id;;
    517 
    518     p_gate = nfa_hciu_find_gate_by_gid (gate_id);
    519 
    520     if (p_gate == NULL)
    521     {
    522         evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
    523     }
    524     else if (p_gate->gate_owner != app_handle)
    525     {
    526         evt_data.deallocated.status = NFA_STATUS_FAILED;
    527     }
    528     else
    529     {
    530         /* See if any pipe is owned by this app */
    531         if (nfa_hciu_find_pipe_on_gate (p_gate->gate_id) == NULL)
    532         {
    533             nfa_hciu_release_gate (p_gate->gate_id);
    534 
    535             nfa_hci_cb.nv_write_needed  = TRUE;
    536             evt_data.deallocated.status = NFA_STATUS_OK;
    537 
    538             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
    539                 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    540         }
    541         else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate (p_gate->gate_id)) == NULL)
    542         {
    543             /* UICC is not active at the moment and cannot delete the pipe */
    544             nfa_hci_cb.nv_write_needed  = TRUE;
    545             evt_data.deallocated.status = NFA_STATUS_FAILED;
    546 
    547             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
    548                 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    549         }
    550         else
    551         {
    552             /* Delete pipes on the gate */
    553             nfa_hci_cb.local_gate_in_use = gate_id;
    554             nfa_hci_cb.app_in_use        = app_handle;
    555             nfa_hci_cb.hci_state         = NFA_HCI_STATE_REMOVE_GATE;
    556 
    557             nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id);
    558             return;
    559         }
    560     }
    561 
    562     nfa_hciu_send_to_app (NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
    563 }
    564 
    565 /*******************************************************************************
    566 **
    567 ** Function         nfa_hci_api_get_host_list
    568 **
    569 ** Description      action function to get the host list from HCI network
    570 **
    571 ** Returns          None
    572 **
    573 *******************************************************************************/
    574 static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data)
    575 {
    576     UINT8               app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
    577 
    578     nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
    579 
    580     /* Send Get Host List command on "Internal request" or requested by registered application with valid handle and callback function */
    581     if (  (nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID)
    582         ||((app_inx < NFA_HCI_MAX_APP_CB) && (nfa_hci_cb.p_app_cback[app_inx] != NULL))  )
    583     {
    584         nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
    585     }
    586 }
    587 
    588 /*******************************************************************************
    589 **
    590 ** Function         nfa_hci_api_create_pipe
    591 **
    592 ** Description      action function to create a pipe
    593 **
    594 ** Returns          TRUE, if the command is processed
    595 **                  FALSE, if command is queued for processing later
    596 **
    597 *******************************************************************************/
    598 static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    599 {
    600     tNFA_HCI_DYN_GATE   *p_gate = nfa_hciu_find_gate_by_gid (p_evt_data->create_pipe.source_gate);
    601     tNFA_HCI_EVT_DATA   evt_data;
    602 
    603     /* Verify that the app owns the gate that the pipe is being created on */
    604     if ((p_gate == NULL) || (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle))
    605     {
    606         evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
    607         evt_data.created.status = NFA_STATUS_FAILED;
    608 
    609         NFA_TRACE_ERROR2 ("nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own the gate:0x%x", p_evt_data->create_pipe.hci_handle, p_evt_data->create_pipe.source_gate);
    610         nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
    611     }
    612     else
    613     {
    614         if (nfa_hciu_is_host_reseting (p_evt_data->create_pipe.dest_gate))
    615         {
    616             GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    617             return FALSE;
    618         }
    619 
    620         nfa_hci_cb.local_gate_in_use  = p_evt_data->create_pipe.source_gate;
    621         nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
    622         nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
    623         nfa_hci_cb.app_in_use         = p_evt_data->create_pipe.hci_handle;
    624 
    625         nfa_hciu_send_create_pipe_cmd (p_evt_data->create_pipe.source_gate, p_evt_data->create_pipe.dest_host, p_evt_data->create_pipe.dest_gate);
    626     }
    627     return TRUE;
    628 }
    629 
    630 /*******************************************************************************
    631 **
    632 ** Function         nfa_hci_api_open_pipe
    633 **
    634 ** Description      action function to open a pipe
    635 **
    636 ** Returns          None
    637 **
    638 *******************************************************************************/
    639 static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    640 {
    641     tNFA_HCI_EVT_DATA   evt_data;
    642     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->open_pipe.pipe);
    643     tNFA_HCI_DYN_GATE   *p_gate = NULL;
    644 
    645     if (p_pipe != NULL)
    646         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    647 
    648     if (  (p_pipe != NULL)
    649         &&(p_gate != NULL)
    650         &&(nfa_hciu_is_active_host (p_pipe->dest_host))
    651         &&(p_gate->gate_owner == p_evt_data->open_pipe.hci_handle))
    652     {
    653         if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
    654         {
    655             nfa_hciu_send_open_pipe_cmd (p_evt_data->open_pipe.pipe);
    656         }
    657         else
    658         {
    659             evt_data.opened.pipe   = p_evt_data->open_pipe.pipe;
    660             evt_data.opened.status = NFA_STATUS_OK;
    661 
    662             nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
    663         }
    664     }
    665     else
    666     {
    667         evt_data.opened.pipe   = p_evt_data->open_pipe.pipe;
    668         evt_data.opened.status = NFA_STATUS_FAILED;
    669 
    670         nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
    671     }
    672 }
    673 
    674 /*******************************************************************************
    675 **
    676 ** Function         nfa_hci_api_get_reg_value
    677 **
    678 ** Description      action function to get the reg value of the specified index
    679 **
    680 ** Returns          TRUE, if the command is processed
    681 **                  FALSE, if command is queued for processing later
    682 **
    683 *******************************************************************************/
    684 static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
    685 {
    686     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->get_registry.pipe);
    687     tNFA_HCI_DYN_GATE   *p_gate;
    688     tNFA_STATUS         status = NFA_STATUS_FAILED;
    689     tNFA_HCI_EVT_DATA   evt_data;
    690 
    691     if (p_pipe != NULL)
    692     {
    693         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    694 
    695         if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->get_registry.hci_handle))
    696         {
    697             nfa_hci_cb.app_in_use        = p_evt_data->get_registry.hci_handle;
    698 
    699             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    700             {
    701                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    702                 return FALSE;
    703             }
    704 
    705             if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
    706             {
    707                 NFA_TRACE_WARNING1 ("nfa_hci_api_get_reg_value pipe:%d not open", p_evt_data->get_registry.pipe);
    708             }
    709             else
    710             {
    711                 if ((status = nfa_hciu_send_get_param_cmd (p_evt_data->get_registry.pipe, p_evt_data->get_registry.reg_inx)) == NFA_STATUS_OK)
    712                     return TRUE;
    713             }
    714         }
    715     }
    716 
    717     evt_data.cmd_sent.status = status;
    718 
    719     /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
    720     nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->get_registry.hci_handle);
    721     return TRUE;
    722 }
    723 
    724 /*******************************************************************************
    725 **
    726 ** Function         nfa_hci_api_set_reg_value
    727 **
    728 ** Description      action function to set the reg value at specified index
    729 **
    730 ** Returns          TRUE, if the command is processed
    731 **                  FALSE, if command is queued for processing later
    732 **
    733 *******************************************************************************/
    734 static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
    735 {
    736     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->set_registry.pipe);
    737     tNFA_HCI_DYN_GATE   *p_gate;
    738     tNFA_STATUS         status = NFA_STATUS_FAILED;
    739     tNFA_HCI_EVT_DATA   evt_data;
    740 
    741     if (p_pipe != NULL)
    742     {
    743         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    744 
    745         if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->set_registry.hci_handle))
    746         {
    747             nfa_hci_cb.app_in_use        = p_evt_data->set_registry.hci_handle;
    748 
    749             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    750             {
    751                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    752                 return FALSE;
    753             }
    754 
    755             if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
    756             {
    757                 NFA_TRACE_WARNING1 ("nfa_hci_api_set_reg_value pipe:%d not open", p_evt_data->set_registry.pipe);
    758             }
    759             else
    760             {
    761                 if ((status = nfa_hciu_send_set_param_cmd (p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx, p_evt_data->set_registry.size, p_evt_data->set_registry.data)) == NFA_STATUS_OK)
    762                     return TRUE;
    763             }
    764         }
    765     }
    766     evt_data.cmd_sent.status = status;
    767 
    768     /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
    769     nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->set_registry.hci_handle);
    770     return TRUE;
    771 
    772 }
    773 
    774 /*******************************************************************************
    775 **
    776 ** Function         nfa_hci_api_close_pipe
    777 **
    778 ** Description      action function to close a pipe
    779 **
    780 ** Returns          None
    781 **
    782 *******************************************************************************/
    783 static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    784 {
    785     tNFA_HCI_EVT_DATA   evt_data;
    786     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->close_pipe.pipe);
    787     tNFA_HCI_DYN_GATE   *p_gate = NULL;
    788 
    789     if (p_pipe != NULL)
    790         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    791 
    792     if (  (p_pipe != NULL)
    793         &&(p_gate != NULL)
    794         &&(nfa_hciu_is_active_host (p_pipe->dest_host))
    795         &&(p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)  )
    796     {
    797         if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    798         {
    799             nfa_hciu_send_close_pipe_cmd (p_evt_data->close_pipe.pipe);
    800         }
    801         else
    802         {
    803             evt_data.closed.status = NFA_STATUS_OK;
    804             evt_data.closed.pipe   = p_evt_data->close_pipe.pipe;
    805 
    806             nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
    807         }
    808     }
    809     else
    810     {
    811         evt_data.closed.status = NFA_STATUS_FAILED;
    812         evt_data.closed.pipe   = 0x00;
    813 
    814         nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
    815     }
    816 }
    817 
    818 /*******************************************************************************
    819 **
    820 ** Function         nfa_hci_api_delete_pipe
    821 **
    822 ** Description      action function to delete a pipe
    823 **
    824 ** Returns          None
    825 **
    826 *******************************************************************************/
    827 static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    828 {
    829     tNFA_HCI_EVT_DATA   evt_data;
    830     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->delete_pipe.pipe);
    831     tNFA_HCI_DYN_GATE   *p_gate = NULL;
    832 
    833     if (p_pipe != NULL)
    834     {
    835         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    836         if (  (p_gate != NULL)
    837             &&(p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle)
    838             &&(nfa_hciu_is_active_host (p_pipe->dest_host))  )
    839         {
    840             nfa_hciu_send_delete_pipe_cmd (p_evt_data->delete_pipe.pipe);
    841             return;
    842         }
    843     }
    844 
    845     evt_data.deleted.status = NFA_STATUS_FAILED;
    846     evt_data.deleted.pipe   = 0x00;
    847     nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
    848 }
    849 
    850 /*******************************************************************************
    851 **
    852 ** Function         nfa_hci_api_send_cmd
    853 **
    854 ** Description      action function to send command on the given pipe
    855 **
    856 ** Returns          TRUE, if the command is processed
    857 **                  FALSE, if command is queued for processing later
    858 **
    859 *******************************************************************************/
    860 static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data)
    861 {
    862     tNFA_STATUS         status = NFA_STATUS_FAILED;
    863     tNFA_HCI_DYN_PIPE   *p_pipe;
    864     tNFA_HCI_EVT_DATA   evt_data;
    865     tNFA_HANDLE         app_handle;
    866 
    867     if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_cmd.pipe)) != NULL)
    868     {
    869         app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_cmd.pipe);
    870 
    871         if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
    872             &&((app_handle == p_evt_data->send_cmd.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))  )
    873         {
    874             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    875             {
    876                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    877                 return FALSE;
    878             }
    879 
    880             if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    881             {
    882                 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
    883                 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, p_evt_data->send_cmd.cmd_code,
    884                                             p_evt_data->send_cmd.cmd_len, p_evt_data->send_cmd.data)) == NFA_STATUS_OK)
    885                     return TRUE;
    886             }
    887             else
    888             {
    889                 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not open", p_pipe->pipe_id);
    890             }
    891         }
    892         else
    893         {
    894             NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d Owned by different application or Destination host is not active",
    895                                 p_pipe->pipe_id);
    896         }
    897     }
    898     else
    899     {
    900         NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not found", p_evt_data->send_cmd.pipe);
    901     }
    902 
    903     evt_data.cmd_sent.status = status;
    904 
    905     /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
    906     nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->send_cmd.hci_handle);
    907     return TRUE;
    908 }
    909 
    910 /*******************************************************************************
    911 **
    912 ** Function         nfa_hci_api_send_rsp
    913 **
    914 ** Description      action function to send response on the given pipe
    915 **
    916 ** Returns          None
    917 **
    918 *******************************************************************************/
    919 static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data)
    920 {
    921     tNFA_STATUS         status = NFA_STATUS_FAILED;
    922     tNFA_HCI_DYN_PIPE   *p_pipe;
    923     tNFA_HCI_EVT_DATA   evt_data;
    924     tNFA_HANDLE         app_handle;
    925 
    926     if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_rsp.pipe)) != NULL)
    927     {
    928         app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_rsp.pipe);
    929 
    930         if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
    931             &&((app_handle == p_evt_data->send_rsp.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))  )
    932         {
    933             if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    934             {
    935                 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, p_evt_data->send_rsp.response,
    936                                             p_evt_data->send_rsp.size, p_evt_data->send_rsp.data)) == NFA_STATUS_OK)
    937                     return;
    938             }
    939             else
    940             {
    941                 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not open", p_pipe->pipe_id);
    942             }
    943         }
    944         else
    945         {
    946             NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d Owned by different application or Destination host is not active",
    947                                 p_pipe->pipe_id);
    948         }
    949     }
    950     else
    951     {
    952         NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not found", p_evt_data->send_rsp.pipe);
    953     }
    954 
    955     evt_data.rsp_sent.status = status;
    956 
    957     /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
    958     nfa_hciu_send_to_app (NFA_HCI_RSP_SENT_EVT, &evt_data, p_evt_data->send_rsp.hci_handle);
    959 }
    960 
    961 /*******************************************************************************
    962 **
    963 ** Function         nfa_hci_api_send_event
    964 **
    965 ** Description      action function to send an event to the given pipe
    966 **
    967 ** Returns          TRUE, if the event is processed
    968 **                  FALSE, if event is queued for processing later
    969 **
    970 *******************************************************************************/
    971 static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data)
    972 {
    973     tNFA_STATUS         status = NFA_STATUS_FAILED;
    974     tNFA_HCI_DYN_PIPE   *p_pipe;
    975     tNFA_HCI_EVT_DATA   evt_data;
    976     tNFA_HANDLE         app_handle;
    977 
    978     if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_evt.pipe)) != NULL)
    979     {
    980         app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_evt.pipe);
    981 
    982         if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
    983             &&((app_handle == p_evt_data->send_evt.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))  )
    984         {
    985             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    986             {
    987                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    988                 return FALSE;
    989             }
    990 
    991             if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    992             {
    993                 status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
    994                                             p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
    995 
    996                 if (status == NFA_STATUS_OK)
    997                 {
    998                     if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
    999                     {
   1000                         nfa_hci_cb.w4_rsp_evt   = TRUE;
   1001                         nfa_hci_cb.hci_state    = NFA_HCI_STATE_WAIT_RSP;
   1002                     }
   1003 
   1004                     if (p_evt_data->send_evt.rsp_len)
   1005                     {
   1006                         nfa_hci_cb.pipe_in_use  = p_evt_data->send_evt.pipe;
   1007                         nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
   1008                         nfa_hci_cb.p_rsp_buf    = p_evt_data->send_evt.p_rsp_buf;
   1009                         if (p_evt_data->send_evt.rsp_timeout)
   1010                         {
   1011                             nfa_hci_cb.w4_rsp_evt   = TRUE;
   1012                             nfa_hci_cb.hci_state    = NFA_HCI_STATE_WAIT_RSP;
   1013                             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_evt_data->send_evt.rsp_timeout);
   1014                         }
   1015                         else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1016                         {
   1017                             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
   1018                         }
   1019                     }
   1020                     else
   1021                     {
   1022                         if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1023                         {
   1024                             nfa_hci_cb.pipe_in_use  = p_evt_data->send_evt.pipe;
   1025                             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
   1026                         }
   1027                         nfa_hci_cb.rsp_buf_size = 0;
   1028                         nfa_hci_cb.p_rsp_buf    = NULL;
   1029                     }
   1030                 }
   1031             }
   1032             else
   1033             {
   1034                 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not open", p_pipe->pipe_id);
   1035             }
   1036         }
   1037         else
   1038         {
   1039             NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d Owned by different application or Destination host is not active",
   1040                                 p_pipe->pipe_id);
   1041         }
   1042     }
   1043     else
   1044     {
   1045         NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not found", p_evt_data->send_evt.pipe);
   1046     }
   1047 
   1048     evt_data.evt_sent.status = status;
   1049 
   1050     /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
   1051     nfa_hciu_send_to_app (NFA_HCI_EVENT_SENT_EVT, &evt_data, p_evt_data->send_evt.hci_handle);
   1052     return TRUE;
   1053 }
   1054 
   1055 /*******************************************************************************
   1056 **
   1057 ** Function         nfa_hci_api_add_static_pipe
   1058 **
   1059 ** Description      action function to add static pipe
   1060 **
   1061 ** Returns          None
   1062 **
   1063 *******************************************************************************/
   1064 static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
   1065 {
   1066     tNFA_HCI_DYN_GATE   *pg;
   1067     tNFA_HCI_DYN_PIPE   *pp;
   1068     tNFA_HCI_EVT_DATA   evt_data;
   1069 
   1070     /* Allocate a proprietary gate */
   1071     if ((pg = nfa_hciu_alloc_gate (p_evt_data->add_static_pipe.gate, p_evt_data->add_static_pipe.hci_handle)) != NULL)
   1072     {
   1073         /* Assign new owner to the gate */
   1074         pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
   1075 
   1076         /* Add the dynamic pipe to the proprietary gate */
   1077         if (nfa_hciu_add_pipe_to_gate (p_evt_data->add_static_pipe.pipe,pg->gate_id, p_evt_data->add_static_pipe.host, p_evt_data->add_static_pipe.gate) != NFA_HCI_ANY_OK)
   1078         {
   1079             /* Unable to add the dynamic pipe, so release the gate */
   1080             nfa_hciu_release_gate (pg->gate_id);
   1081             evt_data.pipe_added.status = NFA_STATUS_FAILED;
   1082             nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
   1083             return;
   1084         }
   1085         if ((pp = nfa_hciu_find_pipe_by_pid (p_evt_data->add_static_pipe.pipe)) != NULL)
   1086         {
   1087             /* This pipe is always opened */
   1088             pp->pipe_state = NFA_HCI_PIPE_OPENED;
   1089             evt_data.pipe_added.status = NFA_STATUS_OK;
   1090             nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
   1091             return;
   1092         }
   1093     }
   1094     /* Unable to add static pipe */
   1095     evt_data.pipe_added.status = NFA_STATUS_FAILED;
   1096     nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
   1097 
   1098 }
   1099 
   1100 /*******************************************************************************
   1101 **
   1102 ** Function         nfa_hci_handle_link_mgm_gate_cmd
   1103 **
   1104 ** Description      This function handles incoming link management gate hci
   1105 **                  commands
   1106 **
   1107 ** Returns          none
   1108 **
   1109 *******************************************************************************/
   1110 void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data)
   1111 {
   1112     UINT8       index;
   1113     UINT8       data[2];
   1114     UINT8       rsp_len = 0;
   1115     UINT8       response = NFA_HCI_ANY_OK;
   1116 
   1117     if (  (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED)
   1118         &&(nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE) )
   1119     {
   1120         nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
   1121         return;
   1122     }
   1123 
   1124     switch (nfa_hci_cb.inst)
   1125     {
   1126     case NFA_HCI_ANY_SET_PARAMETER:
   1127         STREAM_TO_UINT8 (index, p_data);
   1128 
   1129         if (index == 1)
   1130         {
   1131             STREAM_TO_UINT16 (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
   1132         }
   1133         else
   1134             response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
   1135         break;
   1136 
   1137     case NFA_HCI_ANY_GET_PARAMETER:
   1138         STREAM_TO_UINT8 (index, p_data);
   1139         if (index == 1)
   1140         {
   1141             data[0] = (UINT8) ((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
   1142             data[1] = (UINT8) (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
   1143             rsp_len = 2;
   1144         }
   1145         else
   1146             response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
   1147         break;
   1148 
   1149     case NFA_HCI_ANY_OPEN_PIPE:
   1150         data[0]  = 0;
   1151         rsp_len  = 1;
   1152         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
   1153         break;
   1154 
   1155     case NFA_HCI_ANY_CLOSE_PIPE:
   1156         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1157         break;
   1158 
   1159     default:
   1160         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   1161         break;
   1162     }
   1163 
   1164     nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
   1165 }
   1166 
   1167 
   1168 
   1169 /*******************************************************************************
   1170 **
   1171 ** Function         nfa_hci_handle_pipe_open_close_cmd
   1172 **
   1173 ** Description      This function handles all generic gates (excluding
   1174 **                  connectivity gate) commands
   1175 **
   1176 ** Returns          none
   1177 **
   1178 *******************************************************************************/
   1179 void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe)
   1180 {
   1181     UINT8               data[1];
   1182     UINT8               rsp_len = 0;
   1183     tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
   1184     tNFA_HCI_DYN_GATE   *p_gate;
   1185 
   1186     if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
   1187     {
   1188         if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
   1189             data[0] = nfa_hciu_count_open_pipes_on_gate (p_gate);
   1190         else
   1191             data[0] = 0;
   1192 
   1193         p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   1194         rsp_len = 1;
   1195     }
   1196     else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
   1197     {
   1198         p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   1199     }
   1200 
   1201     nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
   1202 }
   1203 
   1204 /*******************************************************************************
   1205 **
   1206 ** Function         nfa_hci_handle_admin_gate_cmd
   1207 **
   1208 ** Description      This function handles incoming commands on ADMIN gate
   1209 **
   1210 ** Returns          none
   1211 **
   1212 *******************************************************************************/
   1213 void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data)
   1214 {
   1215     UINT8               source_host, source_gate, dest_host, dest_gate, pipe;
   1216     UINT8               data = 0;
   1217     UINT8               rsp_len = 0;
   1218     tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
   1219     tNFA_HCI_DYN_GATE   *pgate;
   1220     tNFA_HCI_EVT_DATA   evt_data;
   1221 
   1222     switch (nfa_hci_cb.inst)
   1223     {
   1224     case NFA_HCI_ANY_OPEN_PIPE:
   1225         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
   1226         data    = 0;
   1227         rsp_len = 1;
   1228         break;
   1229 
   1230     case NFA_HCI_ANY_CLOSE_PIPE:
   1231         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
   1232         /* Reopen the pipe immediately */
   1233         nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
   1234         nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
   1235         nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1236         return;
   1237         break;
   1238 
   1239     case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
   1240         STREAM_TO_UINT8 (source_host, p_data);
   1241         STREAM_TO_UINT8 (source_gate, p_data);
   1242         STREAM_TO_UINT8 (dest_host,   p_data);
   1243         STREAM_TO_UINT8 (dest_gate,   p_data);
   1244         STREAM_TO_UINT8 (pipe,        p_data);
   1245 
   1246         if (  (dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
   1247             ||(dest_gate == NFA_HCI_LOOP_BACK_GATE) )
   1248         {
   1249             response = nfa_hciu_add_pipe_to_static_gate (dest_gate, pipe, source_host, source_gate);
   1250         }
   1251         else
   1252         {
   1253             if ((pgate = nfa_hciu_find_gate_by_gid (dest_gate)) != NULL)
   1254             {
   1255                 /* If the gate is valid, add the pipe to it  */
   1256                 if ((response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate)) == NFA_HCI_ANY_OK)
   1257                 {
   1258                     /* Tell the application a pipe was created with its gate */
   1259 
   1260                     evt_data.created.status       = NFA_STATUS_OK;
   1261                     evt_data.created.pipe         = pipe;
   1262                     evt_data.created.source_gate  = dest_gate;
   1263                     evt_data.created.dest_host    = source_host;
   1264                     evt_data.created.dest_gate    = source_gate;
   1265 
   1266                     nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, pgate->gate_owner);
   1267                 }
   1268             }
   1269             else
   1270                 response = NFA_HCI_ANY_E_NOK;
   1271         }
   1272         break;
   1273 
   1274     case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
   1275         STREAM_TO_UINT8 (pipe, p_data);
   1276         response = nfa_hciu_release_pipe (pipe);
   1277         break;
   1278 
   1279     case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
   1280         STREAM_TO_UINT8 (source_host, p_data);
   1281 
   1282         nfa_hciu_remove_all_pipes_from_host (source_host);
   1283 
   1284         if (source_host == NFA_HCI_HOST_CONTROLLER)
   1285         {
   1286             nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1287             nfa_hci_cb.cfg.admin_gate.pipe01_state     = NFA_HCI_PIPE_CLOSED;
   1288 
   1289             /* Reopen the admin pipe immediately */
   1290             nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
   1291             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1292             return;
   1293         }
   1294         else
   1295         {
   1296             if (  (source_host >= NFA_HCI_HOST_ID_UICC0)
   1297                 &&(source_host < (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))  )
   1298             {
   1299                 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = source_host;
   1300             }
   1301         }
   1302         break;
   1303 
   1304     default:
   1305         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   1306         break;
   1307     }
   1308 
   1309     nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
   1310 }
   1311 
   1312 /*******************************************************************************
   1313 **
   1314 ** Function         nfa_hci_handle_admin_gate_rsp
   1315 **
   1316 ** Description      This function handles response received on admin gate
   1317 **
   1318 ** Returns          none
   1319 **
   1320 *******************************************************************************/
   1321 void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len)
   1322 {
   1323     UINT8               hosts[2] = {NFA_HCI_HOST_ID_UICC0, (NFA_HCI_HOST_ID_UICC0 + 1)};
   1324     UINT8               source_host;
   1325     UINT8               source_gate = nfa_hci_cb.local_gate_in_use;
   1326     UINT8               dest_host   = nfa_hci_cb.remote_host_in_use;
   1327     UINT8               dest_gate   = nfa_hci_cb.remote_gate_in_use;
   1328     UINT8               pipe        = 0;
   1329     tNFA_STATUS         status;
   1330     tNFA_HCI_EVT_DATA   evt_data;
   1331     UINT8               default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
   1332     UINT8               host_count  = 0;
   1333     UINT8               host_id     = 0;
   1334     UINT32              os_tick;
   1335 
   1336 #if (BT_TRACE_VERBOSE == TRUE)
   1337     NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s  App: 0x%04x  Gate: 0x%02x  Pipe: 0x%02x",
   1338                        nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent), nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
   1339 #else
   1340     NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp LastCmdSent: %u  App: 0x%04x  Gate: 0x%02x  Pipe: 0x%02x",
   1341                        nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
   1342 #endif
   1343 
   1344     if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED)
   1345     {
   1346         nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1347         return;
   1348     }
   1349 
   1350     /* If starting up, handle events here */
   1351     if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
   1352         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
   1353         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
   1354         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE))
   1355     {
   1356         if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
   1357         {
   1358             NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_rsp - Initialization failed");
   1359             nfa_hci_startup_complete (NFA_STATUS_FAILED);
   1360             return;
   1361         }
   1362 
   1363         switch (nfa_hci_cb.cmd_sent)
   1364         {
   1365         case NFA_HCI_ANY_SET_PARAMETER:
   1366             if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
   1367             {
   1368                 /* Set WHITELIST */
   1369                 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 0x02, hosts);
   1370             }
   1371             else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX)
   1372             {
   1373                 if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
   1374                     ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)  )
   1375                     nfa_hci_dh_startup_complete ();
   1376             }
   1377             break;
   1378 
   1379         case NFA_HCI_ANY_GET_PARAMETER:
   1380             if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
   1381             {
   1382                 host_count = 0;
   1383                 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
   1384                 {
   1385                     nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
   1386                     host_count++;
   1387                 }
   1388 
   1389                 host_count = 0;
   1390                 /* Collect active host in the Host Network */
   1391                 while (host_count < data_len)
   1392                 {
   1393                     host_id = (UINT8) *p_data++;
   1394 
   1395                     if (  (host_id >= NFA_HCI_HOST_ID_UICC0)
   1396                         &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)  )
   1397                     {
   1398                         nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1399                         nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1400                     }
   1401 
   1402                     host_count++;
   1403                 }
   1404                 nfa_hci_startup_complete (NFA_STATUS_OK);
   1405             }
   1406             else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
   1407             {
   1408                 /* The only parameter we get when initializing is the session ID. Check for match. */
   1409                 if (!memcmp ((UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, p_data, NFA_HCI_SESSION_ID_LEN) )
   1410                 {
   1411                     /* Session has not changed. Set the WHITELIST */
   1412                     nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, 0x02, hosts);
   1413                 }
   1414                 else
   1415                 {
   1416                     /* Something wrong, NVRAM data could be corrupt or first start with default session id */
   1417                     nfa_hciu_send_clear_all_pipe_cmd ();
   1418                     nfa_hci_cb.b_hci_netwk_reset = TRUE;
   1419                 }
   1420             }
   1421             break;
   1422 
   1423         case NFA_HCI_ANY_OPEN_PIPE:
   1424             nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
   1425 
   1426             if (nfa_hci_cb.b_hci_netwk_reset)
   1427             {
   1428                 nfa_hci_cb.b_hci_netwk_reset = FALSE;
   1429                /* Session ID is reset, Set New session id */
   1430                 memcpy (&nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
   1431                 os_tick = GKI_get_os_tick_count ();
   1432                 memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
   1433                 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
   1434             }
   1435             else
   1436             {
   1437                 /* First thing is to get the session ID */
   1438                 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
   1439             }
   1440             break;
   1441 
   1442         case NFA_HCI_ADM_CLEAR_ALL_PIPE:
   1443             nfa_hciu_remove_all_pipes_from_host (0);
   1444             nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
   1445             nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1446             nfa_hci_cb.nv_write_needed = TRUE;
   1447 
   1448             /* Open admin */
   1449             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1450             break;
   1451         }
   1452     }
   1453     else
   1454     {
   1455         status = (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
   1456 
   1457         switch (nfa_hci_cb.cmd_sent)
   1458         {
   1459         case NFA_HCI_ANY_SET_PARAMETER:
   1460             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1461                 nfa_hci_api_deregister (NULL);
   1462             else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1463                 nfa_hci_api_dealloc_gate (NULL);
   1464             break;
   1465 
   1466         case NFA_HCI_ANY_GET_PARAMETER:
   1467             if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
   1468             {
   1469                 if (!memcmp ((UINT8 *) default_session, p_data , NFA_HCI_SESSION_ID_LEN))
   1470                 {
   1471                     memcpy (&nfa_hci_cb.cfg.admin_gate.session_id[(NFA_HCI_SESSION_ID_LEN / 2)], nfa_hci_cb.cfg.admin_gate.session_id, (NFA_HCI_SESSION_ID_LEN / 2));
   1472                     os_tick = GKI_get_os_tick_count ();
   1473                     memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *) &os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
   1474                     nfa_hci_cb.nv_write_needed = TRUE;
   1475                     nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX, NFA_HCI_SESSION_ID_LEN, (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id);
   1476                 }
   1477                 else
   1478                 {
   1479                     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1480                         nfa_hci_api_deregister (NULL);
   1481                     else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1482                         nfa_hci_api_dealloc_gate (NULL);
   1483                 }
   1484             }
   1485             else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
   1486             {
   1487                 evt_data.hosts.status    = status;
   1488                 evt_data.hosts.num_hosts = data_len;
   1489                 memcpy (evt_data.hosts.host, p_data, data_len);
   1490 
   1491                 host_count = 0;
   1492                 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
   1493                 {
   1494                     nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
   1495                     host_count++;
   1496                 }
   1497 
   1498                 host_count = 0;
   1499                 /* Collect active host in the Host Network */
   1500                 while (host_count < data_len)
   1501                 {
   1502                     host_id = (UINT8) *p_data++;
   1503 
   1504                     if (  (host_id >= NFA_HCI_HOST_ID_UICC0)
   1505                         &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)  )
   1506                     {
   1507                         nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1508                         nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1509                     }
   1510                     host_count++;
   1511                 }
   1512                 if (nfa_hciu_is_no_host_resetting ())
   1513                     nfa_hci_check_pending_api_requests ();
   1514                 nfa_hciu_send_to_app (NFA_HCI_HOST_LIST_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1515             }
   1516             break;
   1517 
   1518         case NFA_HCI_ADM_CREATE_PIPE:
   1519             if (status == NFA_STATUS_OK)
   1520             {
   1521                 STREAM_TO_UINT8 (source_host, p_data);
   1522                 STREAM_TO_UINT8 (source_gate, p_data);
   1523                 STREAM_TO_UINT8 (dest_host,   p_data);
   1524                 STREAM_TO_UINT8 (dest_gate,   p_data);
   1525                 STREAM_TO_UINT8 (pipe,        p_data);
   1526 
   1527                 /* Sanity check */
   1528                 if (source_gate != nfa_hci_cb.local_gate_in_use)
   1529                 {
   1530                     NFA_TRACE_WARNING2 ("nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u got back: %u",
   1531                                         nfa_hci_cb.local_gate_in_use, source_gate);
   1532                     break;
   1533                 }
   1534 
   1535                 nfa_hciu_add_pipe_to_gate (pipe, source_gate, dest_host, dest_gate);
   1536 
   1537             }
   1538 
   1539             /* Tell the application his pipe was created or not */
   1540             evt_data.created.status       = status;
   1541             evt_data.created.pipe         = pipe;
   1542             evt_data.created.source_gate  = source_gate;
   1543             evt_data.created.dest_host    = dest_host;
   1544             evt_data.created.dest_gate    = dest_gate;
   1545 
   1546             nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1547             break;
   1548 
   1549         case NFA_HCI_ADM_DELETE_PIPE:
   1550             if (status == NFA_STATUS_OK)
   1551             {
   1552                 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
   1553 
   1554                 /* If only deleting one pipe, tell the app we are done */
   1555                 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
   1556                 {
   1557                     evt_data.deleted.status         = status;
   1558                     evt_data.deleted.pipe           = nfa_hci_cb.pipe_in_use;
   1559 
   1560                     nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1561                 }
   1562                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1563                     nfa_hci_api_deregister (NULL);
   1564                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1565                     nfa_hci_api_dealloc_gate (NULL);
   1566             }
   1567             else
   1568             {
   1569                 /* If only deleting one pipe, tell the app we are done */
   1570                 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
   1571                 {
   1572                     evt_data.deleted.status         = status;
   1573                     evt_data.deleted.pipe           = nfa_hci_cb.pipe_in_use;
   1574 
   1575                     nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1576                 }
   1577                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1578                 {
   1579                     nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
   1580                     nfa_hci_api_deregister (NULL);
   1581                 }
   1582                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1583                 {
   1584                     nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
   1585                     nfa_hci_api_dealloc_gate (NULL);
   1586                 }
   1587             }
   1588             break;
   1589 
   1590         case NFA_HCI_ANY_OPEN_PIPE:
   1591             nfa_hci_cb.cfg.admin_gate.pipe01_state = status ? NFA_HCI_PIPE_CLOSED:NFA_HCI_PIPE_OPENED;
   1592             nfa_hci_cb.nv_write_needed = TRUE;
   1593             if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED)
   1594             {
   1595                 /* First thing is to get the session ID */
   1596                 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
   1597             }
   1598             break;
   1599 
   1600         case NFA_HCI_ADM_CLEAR_ALL_PIPE:
   1601             nfa_hciu_remove_all_pipes_from_host (0);
   1602             nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
   1603             nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1604             nfa_hci_cb.nv_write_needed = TRUE;
   1605             /* Open admin */
   1606             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1607             break;
   1608 
   1609         }
   1610     }
   1611 }
   1612 
   1613 /*******************************************************************************
   1614 **
   1615 ** Function         nfa_hci_handle_admin_gate_evt
   1616 **
   1617 ** Description      This function handles events received on admin gate
   1618 **
   1619 ** Returns          none
   1620 **
   1621 *******************************************************************************/
   1622 void nfa_hci_handle_admin_gate_evt (UINT8 *p_data)
   1623 {
   1624     tNFA_HCI_EVT_DATA           evt_data;
   1625     tNFA_HCI_API_GET_HOST_LIST  *p_msg;
   1626 
   1627     if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG)
   1628     {
   1629         NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
   1630         return;
   1631     }
   1632 
   1633     NFA_TRACE_DEBUG0 ("nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
   1634     nfa_hci_cb.num_hot_plug_evts++;
   1635 
   1636     if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
   1637         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)  )
   1638     {
   1639         /* Received Hot Plug evt while waiting for other Host in the network to bootup after DH host bootup is complete */
   1640         if (  (nfa_hci_cb.ee_disable_disc)
   1641             &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))
   1642             &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))  )
   1643         {
   1644             /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */
   1645             nfa_sys_stop_timer (&nfa_hci_cb.timer);
   1646             /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ Ntf(s) */
   1647             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hci_netwk_enable_timeout);
   1648         }
   1649     }
   1650     else if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
   1651              ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)  )
   1652     {
   1653         /* Received Hot Plug evt during DH host bootup */
   1654         if (  (nfa_hci_cb.ee_disable_disc)
   1655             &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))
   1656             &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))  )
   1657         {
   1658             /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */
   1659             nfa_hci_cb.w4_hci_netwk_init = FALSE;
   1660         }
   1661     }
   1662     else
   1663     {
   1664         /* Received Hot Plug evt on UICC self reset */
   1665         evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
   1666         /* Notify all registered application with the HOT_PLUG_EVT */
   1667         nfa_hciu_send_to_all_apps (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
   1668 
   1669         /* Send Get Host List after receiving any pending response */
   1670         if ((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL)
   1671         {
   1672             p_msg->hdr.event    = NFA_HCI_API_GET_HOST_LIST_EVT;
   1673             /* Set Invalid handle to identify this Get Host List command is internal */
   1674             p_msg->hci_handle   = NFA_HANDLE_INVALID;
   1675 
   1676             nfa_sys_sendmsg (p_msg);
   1677         }
   1678     }
   1679 }
   1680 
   1681 /*******************************************************************************
   1682 **
   1683 ** Function         nfa_hci_handle_dyn_pipe_pkt
   1684 **
   1685 ** Description      This function handles data received via dynamic pipe
   1686 **
   1687 ** Returns          none
   1688 **
   1689 *******************************************************************************/
   1690 void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe_id, UINT8 *p_data, UINT16 data_len)
   1691 {
   1692     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id);
   1693     tNFA_HCI_DYN_GATE   *p_gate;
   1694 
   1695     if (p_pipe == NULL)
   1696     {
   1697         /* Invalid pipe ID */
   1698         NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",pipe_id);
   1699         if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   1700             nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
   1701         return;
   1702     }
   1703 
   1704     if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
   1705     {
   1706         nfa_hci_handle_identity_mgmt_gate_pkt (p_data, p_pipe);
   1707     }
   1708     else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1709     {
   1710         nfa_hci_handle_loopback_gate_pkt (p_data, data_len, p_pipe);
   1711     }
   1712     else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
   1713     {
   1714         nfa_hci_handle_connectivity_gate_pkt (p_data, data_len, p_pipe);
   1715     }
   1716     else
   1717     {
   1718         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
   1719         if (p_gate == NULL)
   1720         {
   1721             NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",p_pipe->local_gate);
   1722             if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   1723                 nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
   1724             return;
   1725         }
   1726 
   1727         /* Check if data packet is a command, response or event */
   1728         switch (nfa_hci_cb.type)
   1729         {
   1730         case NFA_HCI_COMMAND_TYPE:
   1731             nfa_hci_handle_generic_gate_cmd (p_data, (UINT8) data_len, p_gate, p_pipe);
   1732             break;
   1733 
   1734         case NFA_HCI_RESPONSE_TYPE:
   1735             nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe);
   1736             break;
   1737 
   1738         case NFA_HCI_EVENT_TYPE:
   1739             nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe);
   1740             break;
   1741         }
   1742     }
   1743 }
   1744 
   1745 /*******************************************************************************
   1746 **
   1747 ** Function         nfa_hci_handle_identity_mgmt_gate_pkt
   1748 **
   1749 ** Description      This function handles incoming Identity Management gate hci
   1750 **                  commands
   1751 **
   1752 ** Returns          none
   1753 **
   1754 *******************************************************************************/
   1755 static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe)
   1756 {
   1757     UINT8       data[20];
   1758     UINT8       index;
   1759     UINT8       gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
   1760     UINT16      rsp_len = 0;
   1761     UINT8       *p_rsp = data;
   1762     tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
   1763 
   1764     /* We never send commands on a pipe where the local gate is the identity management
   1765      * gate, so only commands should be processed.
   1766      */
   1767     if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE)
   1768         return;
   1769 
   1770     switch (nfa_hci_cb.inst)
   1771     {
   1772     case  NFA_HCI_ANY_GET_PARAMETER:
   1773         index = *(p_data++);
   1774         if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
   1775         {
   1776             switch (index)
   1777             {
   1778             case NFA_HCI_VERSION_SW_INDEX:
   1779                 data[0] = (UINT8) ((NFA_HCI_VERSION_SW >> 16 ) & 0xFF);
   1780                 data[1] = (UINT8) ((NFA_HCI_VERSION_SW >> 8 ) & 0xFF);
   1781                 data[2] = (UINT8) ((NFA_HCI_VERSION_SW ) & 0xFF);
   1782                 rsp_len = 3;
   1783                 break;
   1784 
   1785             case NFA_HCI_HCI_VERSION_INDEX:
   1786                 data[0] = NFA_HCI_VERSION;
   1787                 rsp_len = 1;
   1788                 break;
   1789 
   1790             case NFA_HCI_VERSION_HW_INDEX:
   1791                 data[0] = (UINT8) ((NFA_HCI_VERSION_HW >> 16 ) & 0xFF);
   1792                 data[1] = (UINT8) ((NFA_HCI_VERSION_HW >> 8 ) & 0xFF);
   1793                 data[2] = (UINT8) ((NFA_HCI_VERSION_HW ) & 0xFF);
   1794                 rsp_len = 3;
   1795                 break;
   1796 
   1797             case NFA_HCI_VENDOR_NAME_INDEX:
   1798                 memcpy (data,NFA_HCI_VENDOR_NAME,strlen (NFA_HCI_VENDOR_NAME));
   1799                 rsp_len = (UINT8) strlen (NFA_HCI_VENDOR_NAME);
   1800                 break;
   1801 
   1802             case NFA_HCI_MODEL_ID_INDEX:
   1803                 data[0] = NFA_HCI_MODEL_ID;
   1804                 rsp_len = 1;
   1805                 break;
   1806 
   1807             case NFA_HCI_GATES_LIST_INDEX:
   1808                 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
   1809                 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
   1810                 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
   1811                 num_gates   = nfa_hciu_get_allocated_gate_list (&gate_rsp[3]);
   1812                 rsp_len     = num_gates + 3;
   1813                 p_rsp       = gate_rsp;
   1814                 break;
   1815 
   1816             default:
   1817                 response = NFA_HCI_ANY_E_NOK;
   1818                 break;
   1819             }
   1820         }
   1821         else
   1822         {
   1823             response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
   1824         }
   1825         break;
   1826 
   1827     case NFA_HCI_ANY_OPEN_PIPE:
   1828         data[0] = 0;
   1829         rsp_len = 1;
   1830         p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   1831         break;
   1832 
   1833     case NFA_HCI_ANY_CLOSE_PIPE:
   1834         p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   1835         break;
   1836 
   1837     default:
   1838         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   1839         break;
   1840     }
   1841 
   1842     nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, p_rsp);
   1843 }
   1844 
   1845 /*******************************************************************************
   1846 **
   1847 ** Function         nfa_hci_handle_generic_gate_cmd
   1848 **
   1849 ** Description      This function handles all generic gates (excluding
   1850 **                  connectivity gate) commands
   1851 **
   1852 ** Returns          none
   1853 **
   1854 *******************************************************************************/
   1855 static void nfa_hci_handle_generic_gate_cmd (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
   1856 {
   1857     tNFA_HCI_EVT_DATA   evt_data;
   1858     tNFA_HANDLE         app_handle = nfa_hciu_get_pipe_owner (p_pipe->pipe_id);
   1859 
   1860     switch (nfa_hci_cb.inst)
   1861     {
   1862     case NFA_HCI_ANY_SET_PARAMETER:
   1863         evt_data.registry.pipe     = p_pipe->pipe_id;
   1864         evt_data.registry.index    = *p_data++;
   1865         if (data_len > 0)
   1866             data_len--;
   1867         evt_data.registry.data_len = data_len;
   1868 
   1869         memcpy (evt_data.registry.reg_data, p_data, data_len);
   1870 
   1871         nfa_hciu_send_to_app (NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
   1872         break;
   1873 
   1874     case NFA_HCI_ANY_GET_PARAMETER:
   1875         evt_data.registry.pipe     = p_pipe->pipe_id;
   1876         evt_data.registry.index    = *p_data;
   1877         evt_data.registry.data_len = 0;
   1878 
   1879         nfa_hciu_send_to_app (NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
   1880         break;
   1881 
   1882     case NFA_HCI_ANY_OPEN_PIPE:
   1883         nfa_hci_handle_pipe_open_close_cmd (p_pipe);
   1884 
   1885         evt_data.opened.pipe   = p_pipe->pipe_id;
   1886         evt_data.opened.status = NFA_STATUS_OK;
   1887 
   1888         nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
   1889         break;
   1890 
   1891     case NFA_HCI_ANY_CLOSE_PIPE:
   1892         nfa_hci_handle_pipe_open_close_cmd (p_pipe);
   1893 
   1894         evt_data.closed.pipe   = p_pipe->pipe_id;
   1895         evt_data.opened.status = NFA_STATUS_OK;
   1896 
   1897         nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
   1898         break;
   1899 
   1900     default:
   1901         /* Could be application specific command, pass it on */
   1902         evt_data.cmd_rcvd.status   = NFA_STATUS_OK;
   1903         evt_data.cmd_rcvd.pipe     = p_pipe->pipe_id;;
   1904         evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
   1905         evt_data.cmd_rcvd.cmd_len  = data_len;
   1906 
   1907         if (data_len <= NFA_MAX_HCI_CMD_LEN)
   1908             memcpy (evt_data.cmd_rcvd.cmd_data, p_data, data_len);
   1909 
   1910         nfa_hciu_send_to_app (NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
   1911         break;
   1912     }
   1913 }
   1914 
   1915 /*******************************************************************************
   1916 **
   1917 ** Function         nfa_hci_handle_generic_gate_rsp
   1918 **
   1919 ** Description      This function handles all generic gates (excluding
   1920 **                  connectivity) response
   1921 **
   1922 ** Returns          none
   1923 **
   1924 *******************************************************************************/
   1925 static void nfa_hci_handle_generic_gate_rsp (UINT8 *p_data, UINT8 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
   1926 {
   1927     tNFA_HCI_EVT_DATA   evt_data;
   1928     tNFA_STATUS         status = NFA_STATUS_OK;
   1929 
   1930     if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
   1931         status = NFA_STATUS_FAILED;
   1932 
   1933     if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE)
   1934     {
   1935         if (status == NFA_STATUS_OK)
   1936             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   1937 
   1938         nfa_hci_cb.nv_write_needed = TRUE;
   1939         /* Tell application */
   1940         evt_data.opened.status  = status;
   1941         evt_data.opened.pipe    = p_pipe->pipe_id;
   1942 
   1943         nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1944     }
   1945     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
   1946     {
   1947         p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   1948 
   1949         nfa_hci_cb.nv_write_needed = TRUE;
   1950         /* Tell application */
   1951         evt_data.opened.status = status;;
   1952         evt_data.opened.pipe   = p_pipe->pipe_id;
   1953 
   1954         nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1955     }
   1956     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER)
   1957     {
   1958         /* Tell application */
   1959         evt_data.registry.status   = status;
   1960         evt_data.registry.pipe     = p_pipe->pipe_id;
   1961         evt_data.registry.data_len = data_len;
   1962         evt_data.registry.index    = nfa_hci_cb.param_in_use;
   1963 
   1964         memcpy (evt_data.registry.reg_data, p_data, data_len);
   1965 
   1966         nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1967     }
   1968     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER)
   1969     {
   1970         /* Tell application */
   1971         evt_data.registry.status = status;;
   1972         evt_data.registry.pipe   = p_pipe->pipe_id;
   1973 
   1974         nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1975     }
   1976     else
   1977     {
   1978         /* Could be a response to application specific command sent, pass it on */
   1979         evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
   1980         evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
   1981         evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
   1982         evt_data.rsp_rcvd.rsp_len  = data_len;
   1983 
   1984         if (data_len <= NFA_MAX_HCI_RSP_LEN)
   1985             memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
   1986 
   1987         nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1988     }
   1989 
   1990 }
   1991 
   1992 /*******************************************************************************
   1993 **
   1994 ** Function         nfa_hci_handle_connectivity_gate_pkt
   1995 **
   1996 ** Description      This function handles incoming connectivity gate packets
   1997 **
   1998 ** Returns          none
   1999 **
   2000 *******************************************************************************/
   2001 static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
   2002 {
   2003     tNFA_HCI_EVT_DATA   evt_data;
   2004 
   2005     if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   2006     {
   2007         switch (nfa_hci_cb.inst)
   2008         {
   2009         case NFA_HCI_ANY_OPEN_PIPE:
   2010         case NFA_HCI_ANY_CLOSE_PIPE:
   2011             nfa_hci_handle_pipe_open_close_cmd (p_pipe);
   2012             break;
   2013 
   2014         case NFA_HCI_CON_PRO_HOST_REQUEST:
   2015             /* A request to the DH to activate another host. This is not supported for */
   2016             /* now, we will implement it when the spec is clearer and UICCs need it.   */
   2017             nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
   2018             break;
   2019 
   2020         default:
   2021             nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
   2022             break;
   2023         }
   2024     }
   2025     else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
   2026     {
   2027         if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
   2028             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   2029         else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
   2030             p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   2031 
   2032         /* Could be a response to application specific command sent, pass it on */
   2033         evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
   2034         evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
   2035         evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
   2036         evt_data.rsp_rcvd.rsp_len  = data_len;
   2037 
   2038         if (data_len <= NFA_MAX_HCI_RSP_LEN)
   2039             memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
   2040 
   2041         nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2042     }
   2043     else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
   2044     {
   2045         evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
   2046         evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
   2047         evt_data.rcvd_evt.evt_len   = data_len;
   2048         evt_data.rcvd_evt.p_evt_buf = p_data;
   2049 
   2050         /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
   2051         nfa_hciu_send_to_apps_handling_connectivity_evts (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
   2052     }
   2053 }
   2054 
   2055 /*******************************************************************************
   2056 **
   2057 ** Function         nfa_hci_handle_loopback_gate_pkt
   2058 **
   2059 ** Description      This function handles incoming loopback gate hci events
   2060 **
   2061 ** Returns          none
   2062 **
   2063 *******************************************************************************/
   2064 static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
   2065 {
   2066     UINT8               data[1];
   2067     UINT8               rsp_len = 0;
   2068     tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
   2069     tNFA_HCI_EVT_DATA   evt_data;
   2070 
   2071     /* Check if data packet is a command, response or event */
   2072     if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   2073     {
   2074         if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
   2075         {
   2076             data[0] = 0;
   2077             rsp_len = 1;
   2078             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   2079         }
   2080         else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
   2081         {
   2082             p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   2083         }
   2084         else
   2085             response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   2086 
   2087         nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
   2088     }
   2089     else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
   2090     {
   2091         if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
   2092             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   2093         else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
   2094             p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   2095 
   2096         /* Could be a response to application specific command sent, pass it on */
   2097         evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
   2098         evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
   2099         evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
   2100         evt_data.rsp_rcvd.rsp_len  = data_len;
   2101 
   2102         if (data_len <= NFA_MAX_HCI_RSP_LEN)
   2103             memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
   2104 
   2105         nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2106     }
   2107     else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
   2108     {
   2109         if (nfa_hci_cb.w4_rsp_evt)
   2110         {
   2111             evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
   2112             evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
   2113             evt_data.rcvd_evt.evt_len   = data_len;
   2114             evt_data.rcvd_evt.p_evt_buf = p_data;
   2115 
   2116             nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2117         }
   2118         else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA)
   2119         {
   2120             /* Send back the same data we got */
   2121             nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, NFA_HCI_EVT_POST_DATA, data_len, p_data);
   2122         }
   2123     }
   2124 }
   2125 
   2126 /*******************************************************************************
   2127 **
   2128 ** Function         nfa_hci_handle_generic_gate_evt
   2129 **
   2130 ** Description      This function handles incoming Generic gate hci events
   2131 **
   2132 ** Returns          none
   2133 **
   2134 *******************************************************************************/
   2135 static void nfa_hci_handle_generic_gate_evt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_GATE *p_gate, tNFA_HCI_DYN_PIPE *p_pipe)
   2136 {
   2137     tNFA_HCI_EVT_DATA   evt_data;
   2138 
   2139     evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
   2140     evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
   2141     evt_data.rcvd_evt.evt_len   = data_len;
   2142 
   2143     if (nfa_hci_cb.assembly_failed)
   2144         evt_data.rcvd_evt.status    = NFA_STATUS_BUFFER_FULL;
   2145     else
   2146         evt_data.rcvd_evt.status    = NFA_STATUS_OK;
   2147 
   2148     evt_data.rcvd_evt.p_evt_buf = p_data;
   2149     nfa_hci_cb.rsp_buf_size     = 0;
   2150     nfa_hci_cb.p_rsp_buf        = NULL;
   2151 
   2152     /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
   2153     nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
   2154 }
   2155 
   2156