Home | History | Annotate | Download | only in hci
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2014 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 
     20 /******************************************************************************
     21  *
     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         else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE  && pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE  && pp->pipe_id && pp->local_gate >= NFA_HCI_FIRST_PROP_GATE && pp->local_gate <= NFA_HCI_LAST_PROP_GATE)
    454         {
    455             for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    456             {
    457                 if (pp->local_gate == pg->gate_id)
    458                 {
    459                     if (!pg->gate_owner)
    460                         memcpy (&evt_data.gates_pipes.uicc_created_pipe [evt_data.gates_pipes.num_uicc_created_pipes++], pp, sizeof (tNFA_HCI_PIPE_INFO));
    461                     break;
    462                 }
    463             }
    464         }
    465     }
    466 
    467     evt_data.gates_pipes.status = NFA_STATUS_OK;
    468 
    469     /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
    470     nfa_hciu_send_to_app (NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data, p_evt_data->get_gate_pipe_list.hci_handle);
    471 }
    472 
    473 /*******************************************************************************
    474 **
    475 ** Function         nfa_hci_api_alloc_gate
    476 **
    477 ** Description      action function to allocate gate
    478 **
    479 ** Returns          None
    480 **
    481 *******************************************************************************/
    482 static void nfa_hci_api_alloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
    483 {
    484     tNFA_HANDLE         app_handle = p_evt_data->comm.hci_handle;
    485     tNFA_HCI_EVT_DATA   evt_data;
    486     tNFA_HCI_DYN_GATE   *p_gate;
    487 
    488     p_gate = nfa_hciu_alloc_gate (p_evt_data->gate_info.gate, app_handle);
    489 
    490     if (p_gate)
    491     {
    492         if (!p_gate->gate_owner)
    493         {
    494             /* No app owns the gate yet */
    495             p_gate->gate_owner = app_handle;
    496         }
    497         else if (p_gate->gate_owner != app_handle)
    498         {
    499             /* Some other app owns the gate */
    500             p_gate = NULL;
    501             NFA_TRACE_ERROR1 ("nfa_hci_api_alloc_gate (): The Gate (0X%02x) already taken!", p_evt_data->gate_info.gate);
    502         }
    503     }
    504 
    505     evt_data.allocated.gate   = p_gate ? p_gate->gate_id : 0;
    506     evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
    507 
    508     /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
    509     nfa_hciu_send_to_app (NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
    510 }
    511 
    512 /*******************************************************************************
    513 **
    514 ** Function         nfa_hci_api_dealloc_gate
    515 **
    516 ** Description      action function to deallocate the given generic gate
    517 **
    518 ** Returns          None
    519 **
    520 *******************************************************************************/
    521 void nfa_hci_api_dealloc_gate (tNFA_HCI_EVENT_DATA *p_evt_data)
    522 {
    523     tNFA_HCI_EVT_DATA   evt_data;
    524     UINT8               gate_id;
    525     tNFA_HCI_DYN_GATE   *p_gate;
    526     tNFA_HCI_DYN_PIPE   *p_pipe;
    527     tNFA_HANDLE         app_handle;
    528 
    529     /* p_evt_data may be NULL if we are recursively deleting pipes */
    530     if (p_evt_data)
    531     {
    532         gate_id    = p_evt_data->gate_dealloc.gate;
    533         app_handle = p_evt_data->gate_dealloc.hci_handle;
    534 
    535     }
    536     else
    537     {
    538         nfa_sys_stop_timer (&nfa_hci_cb.timer);
    539         gate_id    = nfa_hci_cb.local_gate_in_use;
    540         app_handle = nfa_hci_cb.app_in_use;
    541     }
    542 
    543     evt_data.deallocated.gate = gate_id;;
    544 
    545     p_gate = nfa_hciu_find_gate_by_gid (gate_id);
    546 
    547     if (p_gate == NULL)
    548     {
    549         evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
    550     }
    551     else if (p_gate->gate_owner != app_handle)
    552     {
    553         evt_data.deallocated.status = NFA_STATUS_FAILED;
    554     }
    555     else
    556     {
    557         /* See if any pipe is owned by this app */
    558         if (nfa_hciu_find_pipe_on_gate (p_gate->gate_id) == NULL)
    559         {
    560             nfa_hciu_release_gate (p_gate->gate_id);
    561 
    562             nfa_hci_cb.nv_write_needed  = TRUE;
    563             evt_data.deallocated.status = NFA_STATUS_OK;
    564 
    565             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
    566                 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    567         }
    568         else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate (p_gate->gate_id)) == NULL)
    569         {
    570             /* UICC is not active at the moment and cannot delete the pipe */
    571             nfa_hci_cb.nv_write_needed  = TRUE;
    572             evt_data.deallocated.status = NFA_STATUS_FAILED;
    573 
    574             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
    575                 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
    576         }
    577         else
    578         {
    579             /* Delete pipes on the gate */
    580             nfa_hci_cb.local_gate_in_use = gate_id;
    581             nfa_hci_cb.app_in_use        = app_handle;
    582             nfa_hci_cb.hci_state         = NFA_HCI_STATE_REMOVE_GATE;
    583 
    584             nfa_hciu_send_delete_pipe_cmd (p_pipe->pipe_id);
    585             return;
    586         }
    587     }
    588 
    589     nfa_hciu_send_to_app (NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
    590 }
    591 
    592 /*******************************************************************************
    593 **
    594 ** Function         nfa_hci_api_get_host_list
    595 **
    596 ** Description      action function to get the host list from HCI network
    597 **
    598 ** Returns          None
    599 **
    600 *******************************************************************************/
    601 static void nfa_hci_api_get_host_list (tNFA_HCI_EVENT_DATA *p_evt_data)
    602 {
    603     UINT8               app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
    604 
    605     nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
    606 
    607     /* Send Get Host List command on "Internal request" or requested by registered application with valid handle and callback function */
    608     if (  (nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID)
    609         ||((app_inx < NFA_HCI_MAX_APP_CB) && (nfa_hci_cb.p_app_cback[app_inx] != NULL))  )
    610     {
    611         nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
    612     }
    613 }
    614 
    615 /*******************************************************************************
    616 **
    617 ** Function         nfa_hci_api_create_pipe
    618 **
    619 ** Description      action function to create a pipe
    620 **
    621 ** Returns          TRUE, if the command is processed
    622 **                  FALSE, if command is queued for processing later
    623 **
    624 *******************************************************************************/
    625 static BOOLEAN nfa_hci_api_create_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    626 {
    627     tNFA_HCI_DYN_GATE   *p_gate = nfa_hciu_find_gate_by_gid (p_evt_data->create_pipe.source_gate);
    628     tNFA_HCI_EVT_DATA   evt_data;
    629     BOOLEAN             report_failed = FALSE;
    630 
    631     /* Verify that the app owns the gate that the pipe is being created on */
    632     if (  (p_gate == NULL)
    633         ||(p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)  )
    634     {
    635         report_failed = TRUE;
    636         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);
    637     }
    638     else if (nfa_hciu_check_pipe_between_gates (p_evt_data->create_pipe.source_gate, p_evt_data->create_pipe.dest_host, p_evt_data->create_pipe.dest_gate))
    639     {
    640         report_failed = TRUE;
    641         NFA_TRACE_ERROR0 ("nfa_hci_api_create_pipe : Cannot create multiple pipe between the same two gates!");
    642     }
    643 
    644     if (report_failed)
    645     {
    646         evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
    647         evt_data.created.status = NFA_STATUS_FAILED;
    648 
    649         nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
    650     }
    651     else
    652     {
    653         if (nfa_hciu_is_host_reseting (p_evt_data->create_pipe.dest_gate))
    654         {
    655             GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    656             return FALSE;
    657         }
    658 
    659         nfa_hci_cb.local_gate_in_use  = p_evt_data->create_pipe.source_gate;
    660         nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
    661         nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
    662         nfa_hci_cb.app_in_use         = p_evt_data->create_pipe.hci_handle;
    663 
    664         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);
    665     }
    666     return TRUE;
    667 }
    668 
    669 /*******************************************************************************
    670 **
    671 ** Function         nfa_hci_api_open_pipe
    672 **
    673 ** Description      action function to open a pipe
    674 **
    675 ** Returns          None
    676 **
    677 *******************************************************************************/
    678 static void nfa_hci_api_open_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    679 {
    680     tNFA_HCI_EVT_DATA   evt_data;
    681     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->open_pipe.pipe);
    682     tNFA_HCI_DYN_GATE   *p_gate = NULL;
    683 
    684     if (p_pipe != NULL)
    685         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    686 
    687     if (  (p_pipe != NULL)
    688         &&(p_gate != NULL)
    689         &&(nfa_hciu_is_active_host (p_pipe->dest_host))
    690         &&(p_gate->gate_owner == p_evt_data->open_pipe.hci_handle))
    691     {
    692         if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
    693         {
    694             nfa_hciu_send_open_pipe_cmd (p_evt_data->open_pipe.pipe);
    695         }
    696         else
    697         {
    698             evt_data.opened.pipe   = p_evt_data->open_pipe.pipe;
    699             evt_data.opened.status = NFA_STATUS_OK;
    700 
    701             nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
    702         }
    703     }
    704     else
    705     {
    706         evt_data.opened.pipe   = p_evt_data->open_pipe.pipe;
    707         evt_data.opened.status = NFA_STATUS_FAILED;
    708 
    709         nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, p_evt_data->open_pipe.hci_handle);
    710     }
    711 }
    712 
    713 /*******************************************************************************
    714 **
    715 ** Function         nfa_hci_api_get_reg_value
    716 **
    717 ** Description      action function to get the reg value of the specified index
    718 **
    719 ** Returns          TRUE, if the command is processed
    720 **                  FALSE, if command is queued for processing later
    721 **
    722 *******************************************************************************/
    723 static BOOLEAN nfa_hci_api_get_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
    724 {
    725     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->get_registry.pipe);
    726     tNFA_HCI_DYN_GATE   *p_gate;
    727     tNFA_STATUS         status = NFA_STATUS_FAILED;
    728     tNFA_HCI_EVT_DATA   evt_data;
    729 
    730     if (p_pipe != NULL)
    731     {
    732         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    733 
    734         if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->get_registry.hci_handle))
    735         {
    736             nfa_hci_cb.app_in_use        = p_evt_data->get_registry.hci_handle;
    737 
    738             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    739             {
    740                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    741                 return FALSE;
    742             }
    743 
    744             if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
    745             {
    746                 NFA_TRACE_WARNING1 ("nfa_hci_api_get_reg_value pipe:%d not open", p_evt_data->get_registry.pipe);
    747             }
    748             else
    749             {
    750                 if ((status = nfa_hciu_send_get_param_cmd (p_evt_data->get_registry.pipe, p_evt_data->get_registry.reg_inx)) == NFA_STATUS_OK)
    751                     return TRUE;
    752             }
    753         }
    754     }
    755 
    756     evt_data.cmd_sent.status = status;
    757 
    758     /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
    759     nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->get_registry.hci_handle);
    760     return TRUE;
    761 }
    762 
    763 /*******************************************************************************
    764 **
    765 ** Function         nfa_hci_api_set_reg_value
    766 **
    767 ** Description      action function to set the reg value at specified index
    768 **
    769 ** Returns          TRUE, if the command is processed
    770 **                  FALSE, if command is queued for processing later
    771 **
    772 *******************************************************************************/
    773 static BOOLEAN nfa_hci_api_set_reg_value (tNFA_HCI_EVENT_DATA *p_evt_data)
    774 {
    775     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->set_registry.pipe);
    776     tNFA_HCI_DYN_GATE   *p_gate;
    777     tNFA_STATUS         status = NFA_STATUS_FAILED;
    778     tNFA_HCI_EVT_DATA   evt_data;
    779 
    780     if (p_pipe != NULL)
    781     {
    782         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    783 
    784         if ((p_gate != NULL) && (nfa_hciu_is_active_host (p_pipe->dest_host)) && (p_gate->gate_owner == p_evt_data->set_registry.hci_handle))
    785         {
    786             nfa_hci_cb.app_in_use        = p_evt_data->set_registry.hci_handle;
    787 
    788             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    789             {
    790                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    791                 return FALSE;
    792             }
    793 
    794             if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED)
    795             {
    796                 NFA_TRACE_WARNING1 ("nfa_hci_api_set_reg_value pipe:%d not open", p_evt_data->set_registry.pipe);
    797             }
    798             else
    799             {
    800                 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)
    801                     return TRUE;
    802             }
    803         }
    804     }
    805     evt_data.cmd_sent.status = status;
    806 
    807     /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
    808     nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->set_registry.hci_handle);
    809     return TRUE;
    810 
    811 }
    812 
    813 /*******************************************************************************
    814 **
    815 ** Function         nfa_hci_api_close_pipe
    816 **
    817 ** Description      action function to close a pipe
    818 **
    819 ** Returns          None
    820 **
    821 *******************************************************************************/
    822 static void nfa_hci_api_close_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    823 {
    824     tNFA_HCI_EVT_DATA   evt_data;
    825     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->close_pipe.pipe);
    826     tNFA_HCI_DYN_GATE   *p_gate = NULL;
    827 
    828     if (p_pipe != NULL)
    829         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    830 
    831     if (  (p_pipe != NULL)
    832         &&(p_gate != NULL)
    833         &&(nfa_hciu_is_active_host (p_pipe->dest_host))
    834         &&(p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)  )
    835     {
    836         if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    837         {
    838             nfa_hciu_send_close_pipe_cmd (p_evt_data->close_pipe.pipe);
    839         }
    840         else
    841         {
    842             evt_data.closed.status = NFA_STATUS_OK;
    843             evt_data.closed.pipe   = p_evt_data->close_pipe.pipe;
    844 
    845             nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
    846         }
    847     }
    848     else
    849     {
    850         evt_data.closed.status = NFA_STATUS_FAILED;
    851         evt_data.closed.pipe   = 0x00;
    852 
    853         nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
    854     }
    855 }
    856 
    857 /*******************************************************************************
    858 **
    859 ** Function         nfa_hci_api_delete_pipe
    860 **
    861 ** Description      action function to delete a pipe
    862 **
    863 ** Returns          None
    864 **
    865 *******************************************************************************/
    866 static void nfa_hci_api_delete_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
    867 {
    868     tNFA_HCI_EVT_DATA   evt_data;
    869     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->delete_pipe.pipe);
    870     tNFA_HCI_DYN_GATE   *p_gate = NULL;
    871 
    872     if (p_pipe != NULL)
    873     {
    874         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
    875         if (  (p_gate != NULL)
    876             &&(p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle)
    877             &&(nfa_hciu_is_active_host (p_pipe->dest_host))  )
    878         {
    879             nfa_hciu_send_delete_pipe_cmd (p_evt_data->delete_pipe.pipe);
    880             return;
    881         }
    882     }
    883 
    884     evt_data.deleted.status = NFA_STATUS_FAILED;
    885     evt_data.deleted.pipe   = 0x00;
    886     nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, p_evt_data->close_pipe.hci_handle);
    887 }
    888 
    889 /*******************************************************************************
    890 **
    891 ** Function         nfa_hci_api_send_cmd
    892 **
    893 ** Description      action function to send command on the given pipe
    894 **
    895 ** Returns          TRUE, if the command is processed
    896 **                  FALSE, if command is queued for processing later
    897 **
    898 *******************************************************************************/
    899 static BOOLEAN nfa_hci_api_send_cmd (tNFA_HCI_EVENT_DATA *p_evt_data)
    900 {
    901     tNFA_STATUS         status = NFA_STATUS_FAILED;
    902     tNFA_HCI_DYN_PIPE   *p_pipe;
    903     tNFA_HCI_EVT_DATA   evt_data;
    904     tNFA_HANDLE         app_handle;
    905 
    906     if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_cmd.pipe)) != NULL)
    907     {
    908         app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_cmd.pipe);
    909 
    910         if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
    911             &&((app_handle == p_evt_data->send_cmd.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))  )
    912         {
    913             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
    914             {
    915                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
    916                 return FALSE;
    917             }
    918 
    919             if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    920             {
    921                 nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
    922                 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE, p_evt_data->send_cmd.cmd_code,
    923                                             p_evt_data->send_cmd.cmd_len, p_evt_data->send_cmd.data)) == NFA_STATUS_OK)
    924                     return TRUE;
    925             }
    926             else
    927             {
    928                 NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not open", p_pipe->pipe_id);
    929             }
    930         }
    931         else
    932         {
    933             NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d Owned by different application or Destination host is not active",
    934                                 p_pipe->pipe_id);
    935         }
    936     }
    937     else
    938     {
    939         NFA_TRACE_WARNING1 ("nfa_hci_api_send_cmd pipe:%d not found", p_evt_data->send_cmd.pipe);
    940     }
    941 
    942     evt_data.cmd_sent.status = status;
    943 
    944     /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
    945     nfa_hciu_send_to_app (NFA_HCI_CMD_SENT_EVT, &evt_data, p_evt_data->send_cmd.hci_handle);
    946     return TRUE;
    947 }
    948 
    949 /*******************************************************************************
    950 **
    951 ** Function         nfa_hci_api_send_rsp
    952 **
    953 ** Description      action function to send response on the given pipe
    954 **
    955 ** Returns          None
    956 **
    957 *******************************************************************************/
    958 static void nfa_hci_api_send_rsp (tNFA_HCI_EVENT_DATA *p_evt_data)
    959 {
    960     tNFA_STATUS         status = NFA_STATUS_FAILED;
    961     tNFA_HCI_DYN_PIPE   *p_pipe;
    962     tNFA_HCI_EVT_DATA   evt_data;
    963     tNFA_HANDLE         app_handle;
    964 
    965     if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_rsp.pipe)) != NULL)
    966     {
    967         app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_rsp.pipe);
    968 
    969         if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
    970             &&((app_handle == p_evt_data->send_rsp.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))  )
    971         {
    972             if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
    973             {
    974                 if ((status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, p_evt_data->send_rsp.response,
    975                                             p_evt_data->send_rsp.size, p_evt_data->send_rsp.data)) == NFA_STATUS_OK)
    976                     return;
    977             }
    978             else
    979             {
    980                 NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not open", p_pipe->pipe_id);
    981             }
    982         }
    983         else
    984         {
    985             NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d Owned by different application or Destination host is not active",
    986                                 p_pipe->pipe_id);
    987         }
    988     }
    989     else
    990     {
    991         NFA_TRACE_WARNING1 ("nfa_hci_api_send_rsp pipe:%d not found", p_evt_data->send_rsp.pipe);
    992     }
    993 
    994     evt_data.rsp_sent.status = status;
    995 
    996     /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
    997     nfa_hciu_send_to_app (NFA_HCI_RSP_SENT_EVT, &evt_data, p_evt_data->send_rsp.hci_handle);
    998 }
    999 
   1000 /*******************************************************************************
   1001 **
   1002 ** Function         nfa_hci_api_send_event
   1003 **
   1004 ** Description      action function to send an event to the given pipe
   1005 **
   1006 ** Returns          TRUE, if the event is processed
   1007 **                  FALSE, if event is queued for processing later
   1008 **
   1009 *******************************************************************************/
   1010 static BOOLEAN nfa_hci_api_send_event (tNFA_HCI_EVENT_DATA *p_evt_data)
   1011 {
   1012     tNFA_STATUS         status = NFA_STATUS_FAILED;
   1013     tNFA_HCI_DYN_PIPE   *p_pipe;
   1014     tNFA_HCI_EVT_DATA   evt_data;
   1015     tNFA_HANDLE         app_handle;
   1016 
   1017     if ((p_pipe = nfa_hciu_find_pipe_by_pid (p_evt_data->send_evt.pipe)) != NULL)
   1018     {
   1019         app_handle = nfa_hciu_get_pipe_owner (p_evt_data->send_evt.pipe);
   1020 
   1021         if (  (nfa_hciu_is_active_host (p_pipe->dest_host))
   1022             &&((app_handle == p_evt_data->send_evt.hci_handle || p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))  )
   1023         {
   1024             if (nfa_hciu_is_host_reseting (p_pipe->dest_host))
   1025             {
   1026                 GKI_enqueue (&nfa_hci_cb.hci_host_reset_api_q, (BT_HDR *) p_evt_data);
   1027                 return FALSE;
   1028             }
   1029 
   1030             if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
   1031             {
   1032                 status = nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
   1033                                             p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
   1034 
   1035                 if (status == NFA_STATUS_OK)
   1036                 {
   1037                     if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1038                     {
   1039                         nfa_hci_cb.w4_rsp_evt   = TRUE;
   1040                         nfa_hci_cb.hci_state    = NFA_HCI_STATE_WAIT_RSP;
   1041                     }
   1042 
   1043                     if (p_evt_data->send_evt.rsp_len)
   1044                     {
   1045                         nfa_hci_cb.pipe_in_use  = p_evt_data->send_evt.pipe;
   1046                         nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
   1047                         nfa_hci_cb.p_rsp_buf    = p_evt_data->send_evt.p_rsp_buf;
   1048                         if (p_evt_data->send_evt.rsp_timeout)
   1049                         {
   1050                             nfa_hci_cb.w4_rsp_evt   = TRUE;
   1051                             nfa_hci_cb.hci_state    = NFA_HCI_STATE_WAIT_RSP;
   1052                             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_evt_data->send_evt.rsp_timeout);
   1053                         }
   1054                         else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1055                         {
   1056                             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
   1057                         }
   1058                     }
   1059                     else
   1060                     {
   1061                         if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1062                         {
   1063                             nfa_hci_cb.pipe_in_use  = p_evt_data->send_evt.pipe;
   1064                             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hcp_response_timeout);
   1065                         }
   1066                         nfa_hci_cb.rsp_buf_size = 0;
   1067                         nfa_hci_cb.p_rsp_buf    = NULL;
   1068                     }
   1069                 }
   1070             }
   1071             else
   1072             {
   1073                 NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not open", p_pipe->pipe_id);
   1074             }
   1075         }
   1076         else
   1077         {
   1078             NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d Owned by different application or Destination host is not active",
   1079                                 p_pipe->pipe_id);
   1080         }
   1081     }
   1082     else
   1083     {
   1084         NFA_TRACE_WARNING1 ("nfa_hci_api_send_event pipe:%d not found", p_evt_data->send_evt.pipe);
   1085     }
   1086 
   1087     evt_data.evt_sent.status = status;
   1088 
   1089     /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
   1090     nfa_hciu_send_to_app (NFA_HCI_EVENT_SENT_EVT, &evt_data, p_evt_data->send_evt.hci_handle);
   1091     return TRUE;
   1092 }
   1093 
   1094 /*******************************************************************************
   1095 **
   1096 ** Function         nfa_hci_api_add_static_pipe
   1097 **
   1098 ** Description      action function to add static pipe
   1099 **
   1100 ** Returns          None
   1101 **
   1102 *******************************************************************************/
   1103 static void nfa_hci_api_add_static_pipe (tNFA_HCI_EVENT_DATA *p_evt_data)
   1104 {
   1105     tNFA_HCI_DYN_GATE   *pg;
   1106     tNFA_HCI_DYN_PIPE   *pp;
   1107     tNFA_HCI_EVT_DATA   evt_data;
   1108 
   1109     /* Allocate a proprietary gate */
   1110     if ((pg = nfa_hciu_alloc_gate (p_evt_data->add_static_pipe.gate, p_evt_data->add_static_pipe.hci_handle)) != NULL)
   1111     {
   1112         /* Assign new owner to the gate */
   1113         pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
   1114 
   1115         /* Add the dynamic pipe to the proprietary gate */
   1116         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)
   1117         {
   1118             /* Unable to add the dynamic pipe, so release the gate */
   1119             nfa_hciu_release_gate (pg->gate_id);
   1120             evt_data.pipe_added.status = NFA_STATUS_FAILED;
   1121             nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
   1122             return;
   1123         }
   1124         if ((pp = nfa_hciu_find_pipe_by_pid (p_evt_data->add_static_pipe.pipe)) != NULL)
   1125         {
   1126             /* This pipe is always opened */
   1127             pp->pipe_state = NFA_HCI_PIPE_OPENED;
   1128             evt_data.pipe_added.status = NFA_STATUS_OK;
   1129             nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
   1130             return;
   1131         }
   1132     }
   1133     /* Unable to add static pipe */
   1134     evt_data.pipe_added.status = NFA_STATUS_FAILED;
   1135     nfa_hciu_send_to_app (NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data, p_evt_data->add_static_pipe.hci_handle);
   1136 
   1137 }
   1138 
   1139 /*******************************************************************************
   1140 **
   1141 ** Function         nfa_hci_handle_link_mgm_gate_cmd
   1142 **
   1143 ** Description      This function handles incoming link management gate hci
   1144 **                  commands
   1145 **
   1146 ** Returns          none
   1147 **
   1148 *******************************************************************************/
   1149 void nfa_hci_handle_link_mgm_gate_cmd (UINT8 *p_data)
   1150 {
   1151     UINT8       index;
   1152     UINT8       data[2];
   1153     UINT8       rsp_len = 0;
   1154     UINT8       response = NFA_HCI_ANY_OK;
   1155 
   1156     if (  (nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED)
   1157         &&(nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE) )
   1158     {
   1159         nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, NULL);
   1160         return;
   1161     }
   1162 
   1163     switch (nfa_hci_cb.inst)
   1164     {
   1165     case NFA_HCI_ANY_SET_PARAMETER:
   1166         STREAM_TO_UINT8 (index, p_data);
   1167 
   1168         if (index == 1)
   1169         {
   1170             STREAM_TO_UINT16 (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
   1171         }
   1172         else
   1173             response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
   1174         break;
   1175 
   1176     case NFA_HCI_ANY_GET_PARAMETER:
   1177         STREAM_TO_UINT8 (index, p_data);
   1178         if (index == 1)
   1179         {
   1180             data[0] = (UINT8) ((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
   1181             data[1] = (UINT8) (nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
   1182             rsp_len = 2;
   1183         }
   1184         else
   1185             response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
   1186         break;
   1187 
   1188     case NFA_HCI_ANY_OPEN_PIPE:
   1189         data[0]  = 0;
   1190         rsp_len  = 1;
   1191         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
   1192         break;
   1193 
   1194     case NFA_HCI_ANY_CLOSE_PIPE:
   1195         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1196         break;
   1197 
   1198     default:
   1199         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   1200         break;
   1201     }
   1202 
   1203     nfa_hciu_send_msg (NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
   1204 }
   1205 
   1206 
   1207 
   1208 /*******************************************************************************
   1209 **
   1210 ** Function         nfa_hci_handle_pipe_open_close_cmd
   1211 **
   1212 ** Description      This function handles all generic gates (excluding
   1213 **                  connectivity gate) commands
   1214 **
   1215 ** Returns          none
   1216 **
   1217 *******************************************************************************/
   1218 void nfa_hci_handle_pipe_open_close_cmd (tNFA_HCI_DYN_PIPE *p_pipe)
   1219 {
   1220     UINT8               data[1];
   1221     UINT8               rsp_len = 0;
   1222     tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
   1223     tNFA_HCI_DYN_GATE   *p_gate;
   1224 
   1225     if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
   1226     {
   1227         if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != NULL)
   1228             data[0] = nfa_hciu_count_open_pipes_on_gate (p_gate);
   1229         else
   1230             data[0] = 0;
   1231 
   1232         p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   1233         rsp_len = 1;
   1234     }
   1235     else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
   1236     {
   1237         p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   1238     }
   1239 
   1240     nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
   1241 }
   1242 
   1243 /*******************************************************************************
   1244 **
   1245 ** Function         nfa_hci_handle_admin_gate_cmd
   1246 **
   1247 ** Description      This function handles incoming commands on ADMIN gate
   1248 **
   1249 ** Returns          none
   1250 **
   1251 *******************************************************************************/
   1252 void nfa_hci_handle_admin_gate_cmd (UINT8 *p_data)
   1253 {
   1254     UINT8               source_host, source_gate, dest_host, dest_gate, pipe;
   1255     UINT8               data = 0;
   1256     UINT8               rsp_len = 0;
   1257     tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
   1258     tNFA_HCI_DYN_GATE   *pgate;
   1259     tNFA_HCI_EVT_DATA   evt_data;
   1260 
   1261     switch (nfa_hci_cb.inst)
   1262     {
   1263     case NFA_HCI_ANY_OPEN_PIPE:
   1264         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
   1265         data    = 0;
   1266         rsp_len = 1;
   1267         break;
   1268 
   1269     case NFA_HCI_ANY_CLOSE_PIPE:
   1270         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
   1271         /* Reopen the pipe immediately */
   1272         nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
   1273         nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
   1274         nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1275         return;
   1276         break;
   1277 
   1278     case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
   1279         STREAM_TO_UINT8 (source_host, p_data);
   1280         STREAM_TO_UINT8 (source_gate, p_data);
   1281         STREAM_TO_UINT8 (dest_host,   p_data);
   1282         STREAM_TO_UINT8 (dest_gate,   p_data);
   1283         STREAM_TO_UINT8 (pipe,        p_data);
   1284 
   1285         if (  (dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
   1286             ||(dest_gate == NFA_HCI_LOOP_BACK_GATE) )
   1287         {
   1288             response = nfa_hciu_add_pipe_to_static_gate (dest_gate, pipe, source_host, source_gate);
   1289         }
   1290         else
   1291         {
   1292             if ((pgate = nfa_hciu_find_gate_by_gid (dest_gate)) != NULL)
   1293             {
   1294                 /* If the gate is valid, add the pipe to it  */
   1295                 if (nfa_hciu_check_pipe_between_gates (dest_gate, source_host, source_gate))
   1296                 {
   1297                     /* Already, there is a pipe between these two gates, so will reject */
   1298                     response = NFA_HCI_ANY_E_NOK;
   1299                 }
   1300                 else if ((response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate)) == NFA_HCI_ANY_OK)
   1301                 {
   1302                     /* Tell the application a pipe was created with its gate */
   1303 
   1304                     evt_data.created.status       = NFA_STATUS_OK;
   1305                     evt_data.created.pipe         = pipe;
   1306                     evt_data.created.source_gate  = dest_gate;
   1307                     evt_data.created.dest_host    = source_host;
   1308                     evt_data.created.dest_gate    = source_gate;
   1309 
   1310                     nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, pgate->gate_owner);
   1311                 }
   1312             }
   1313             else
   1314             {
   1315                 response = NFA_HCI_ANY_E_NOK;
   1316                 if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) && (dest_gate <= NFA_HCI_LAST_PROP_GATE))
   1317                 {
   1318                     if (nfa_hciu_alloc_gate (dest_gate, 0))
   1319                         response = nfa_hciu_add_pipe_to_gate (pipe, dest_gate, source_host, source_gate);
   1320                 }
   1321             }
   1322         }
   1323         break;
   1324 
   1325     case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
   1326         STREAM_TO_UINT8 (pipe, p_data);
   1327         response = nfa_hciu_release_pipe (pipe);
   1328         break;
   1329 
   1330     case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
   1331         STREAM_TO_UINT8 (source_host, p_data);
   1332 
   1333         nfa_hciu_remove_all_pipes_from_host (source_host);
   1334 
   1335         if (source_host == NFA_HCI_HOST_CONTROLLER)
   1336         {
   1337             nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1338             nfa_hci_cb.cfg.admin_gate.pipe01_state     = NFA_HCI_PIPE_CLOSED;
   1339 
   1340             /* Reopen the admin pipe immediately */
   1341             nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
   1342             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1343             return;
   1344         }
   1345         else
   1346         {
   1347             if (  (source_host >= NFA_HCI_HOST_ID_UICC0)
   1348                 &&(source_host < (NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK))  )
   1349             {
   1350                 nfa_hci_cb.reset_host[source_host - NFA_HCI_HOST_ID_UICC0] = source_host;
   1351             }
   1352         }
   1353         break;
   1354 
   1355     default:
   1356         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   1357         break;
   1358     }
   1359 
   1360     nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response, rsp_len, &data);
   1361 }
   1362 
   1363 /*******************************************************************************
   1364 **
   1365 ** Function         nfa_hci_handle_admin_gate_rsp
   1366 **
   1367 ** Description      This function handles response received on admin gate
   1368 **
   1369 ** Returns          none
   1370 **
   1371 *******************************************************************************/
   1372 void nfa_hci_handle_admin_gate_rsp (UINT8 *p_data, UINT8 data_len)
   1373 {
   1374     UINT8               source_host;
   1375     UINT8               source_gate = nfa_hci_cb.local_gate_in_use;
   1376     UINT8               dest_host   = nfa_hci_cb.remote_host_in_use;
   1377     UINT8               dest_gate   = nfa_hci_cb.remote_gate_in_use;
   1378     UINT8               pipe        = 0;
   1379     tNFA_STATUS         status;
   1380     tNFA_HCI_EVT_DATA   evt_data;
   1381     UINT8               default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
   1382     UINT8               host_count  = 0;
   1383     UINT8               host_id     = 0;
   1384     UINT32              os_tick;
   1385 
   1386 #if (BT_TRACE_VERBOSE == TRUE)
   1387     NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s  App: 0x%04x  Gate: 0x%02x  Pipe: 0x%02x",
   1388                        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);
   1389 #else
   1390     NFA_TRACE_DEBUG4 ("nfa_hci_handle_admin_gate_rsp LastCmdSent: %u  App: 0x%04x  Gate: 0x%02x  Pipe: 0x%02x",
   1391                        nfa_hci_cb.cmd_sent, nfa_hci_cb.app_in_use, nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
   1392 #endif
   1393 
   1394     /* If starting up, handle events here */
   1395     if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
   1396         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)
   1397         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
   1398         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE))
   1399     {
   1400         if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED)
   1401         {
   1402             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1403             return;
   1404         }
   1405 
   1406         if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
   1407         {
   1408             NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_rsp - Initialization failed");
   1409             nfa_hci_startup_complete (NFA_STATUS_FAILED);
   1410             return;
   1411         }
   1412 
   1413         switch (nfa_hci_cb.cmd_sent)
   1414         {
   1415         case NFA_HCI_ANY_SET_PARAMETER:
   1416             if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
   1417             {
   1418                 /* Set WHITELIST */
   1419                 nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
   1420             }
   1421             else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX)
   1422             {
   1423                 if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
   1424                     ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)  )
   1425                     nfa_hci_dh_startup_complete ();
   1426             }
   1427             break;
   1428 
   1429         case NFA_HCI_ANY_GET_PARAMETER:
   1430             if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
   1431             {
   1432                 host_count = 0;
   1433                 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
   1434                 {
   1435                     nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
   1436                     host_count++;
   1437                 }
   1438 
   1439                 host_count = 0;
   1440                 /* Collect active host in the Host Network */
   1441                 while (host_count < data_len)
   1442                 {
   1443                     host_id = (UINT8) *p_data++;
   1444 
   1445                     if (  (host_id >= NFA_HCI_HOST_ID_UICC0)
   1446                         &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)  )
   1447                     {
   1448                         nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1449                         nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1450                     }
   1451 
   1452                     host_count++;
   1453                 }
   1454                 nfa_hci_startup_complete (NFA_STATUS_OK);
   1455             }
   1456             else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
   1457             {
   1458                 /* The only parameter we get when initializing is the session ID. Check for match. */
   1459                 if (!memcmp ((UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, p_data, NFA_HCI_SESSION_ID_LEN) )
   1460                 {
   1461                     /* Session has not changed, Set WHITELIST */
   1462                     nfa_hciu_send_set_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX, p_nfa_hci_cfg->num_whitelist_host, p_nfa_hci_cfg->p_whitelist);
   1463                 }
   1464                 else
   1465                 {
   1466                     /* Something wrong, NVRAM data could be corrupt or first start with default session id */
   1467                     nfa_hciu_send_clear_all_pipe_cmd ();
   1468                     nfa_hci_cb.b_hci_netwk_reset = TRUE;
   1469                 }
   1470             }
   1471             break;
   1472 
   1473         case NFA_HCI_ANY_OPEN_PIPE:
   1474             nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
   1475 
   1476             if (nfa_hci_cb.b_hci_netwk_reset)
   1477             {
   1478                 nfa_hci_cb.b_hci_netwk_reset = FALSE;
   1479                /* Session ID is reset, Set New session id */
   1480                 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));
   1481                 os_tick = GKI_get_os_tick_count ();
   1482                 memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *)&os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
   1483                 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);
   1484             }
   1485             else
   1486             {
   1487                 /* First thing is to get the session ID */
   1488                 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
   1489             }
   1490             break;
   1491 
   1492         case NFA_HCI_ADM_CLEAR_ALL_PIPE:
   1493             nfa_hciu_remove_all_pipes_from_host (0);
   1494             nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
   1495             nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1496             nfa_hci_cb.nv_write_needed = TRUE;
   1497 
   1498             /* Open admin */
   1499             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1500             break;
   1501         }
   1502     }
   1503     else
   1504     {
   1505         status = (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
   1506 
   1507         switch (nfa_hci_cb.cmd_sent)
   1508         {
   1509         case NFA_HCI_ANY_SET_PARAMETER:
   1510             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1511                 nfa_hci_api_deregister (NULL);
   1512             else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1513                 nfa_hci_api_dealloc_gate (NULL);
   1514             break;
   1515 
   1516         case NFA_HCI_ANY_GET_PARAMETER:
   1517             if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX)
   1518             {
   1519                 if (!memcmp ((UINT8 *) default_session, p_data , NFA_HCI_SESSION_ID_LEN))
   1520                 {
   1521                     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));
   1522                     os_tick = GKI_get_os_tick_count ();
   1523                     memcpy (nfa_hci_cb.cfg.admin_gate.session_id, (UINT8 *) &os_tick, (NFA_HCI_SESSION_ID_LEN / 2));
   1524                     nfa_hci_cb.nv_write_needed = TRUE;
   1525                     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);
   1526                 }
   1527                 else
   1528                 {
   1529                     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1530                         nfa_hci_api_deregister (NULL);
   1531                     else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1532                         nfa_hci_api_dealloc_gate (NULL);
   1533                 }
   1534             }
   1535             else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX)
   1536             {
   1537                 evt_data.hosts.status    = status;
   1538                 evt_data.hosts.num_hosts = data_len;
   1539                 memcpy (evt_data.hosts.host, p_data, data_len);
   1540 
   1541                 host_count = 0;
   1542                 while (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)
   1543                 {
   1544                     nfa_hci_cb.inactive_host[host_count] = NFA_HCI_HOST_ID_UICC0 + host_count;
   1545                     host_count++;
   1546                 }
   1547 
   1548                 host_count = 0;
   1549                 /* Collect active host in the Host Network */
   1550                 while (host_count < data_len)
   1551                 {
   1552                     host_id = (UINT8) *p_data++;
   1553 
   1554                     if (  (host_id >= NFA_HCI_HOST_ID_UICC0)
   1555                         &&(host_id < NFA_HCI_HOST_ID_UICC0 + NFA_HCI_MAX_HOST_IN_NETWORK)  )
   1556                     {
   1557                         nfa_hci_cb.inactive_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1558                         nfa_hci_cb.reset_host[host_id - NFA_HCI_HOST_ID_UICC0] = 0x00;
   1559                     }
   1560                     host_count++;
   1561                 }
   1562                 if (nfa_hciu_is_no_host_resetting ())
   1563                     nfa_hci_check_pending_api_requests ();
   1564                 nfa_hciu_send_to_app (NFA_HCI_HOST_LIST_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1565             }
   1566             break;
   1567 
   1568         case NFA_HCI_ADM_CREATE_PIPE:
   1569             if (status == NFA_STATUS_OK)
   1570             {
   1571                 STREAM_TO_UINT8 (source_host, p_data);
   1572                 STREAM_TO_UINT8 (source_gate, p_data);
   1573                 STREAM_TO_UINT8 (dest_host,   p_data);
   1574                 STREAM_TO_UINT8 (dest_gate,   p_data);
   1575                 STREAM_TO_UINT8 (pipe,        p_data);
   1576 
   1577                 /* Sanity check */
   1578                 if (source_gate != nfa_hci_cb.local_gate_in_use)
   1579                 {
   1580                     NFA_TRACE_WARNING2 ("nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u got back: %u",
   1581                                         nfa_hci_cb.local_gate_in_use, source_gate);
   1582                     break;
   1583                 }
   1584 
   1585                 nfa_hciu_add_pipe_to_gate (pipe, source_gate, dest_host, dest_gate);
   1586 
   1587             }
   1588 
   1589             /* Tell the application his pipe was created or not */
   1590             evt_data.created.status       = status;
   1591             evt_data.created.pipe         = pipe;
   1592             evt_data.created.source_gate  = source_gate;
   1593             evt_data.created.dest_host    = dest_host;
   1594             evt_data.created.dest_gate    = dest_gate;
   1595 
   1596             nfa_hciu_send_to_app (NFA_HCI_CREATE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1597             break;
   1598 
   1599         case NFA_HCI_ADM_DELETE_PIPE:
   1600             if (status == NFA_STATUS_OK)
   1601             {
   1602                 nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
   1603 
   1604                 /* If only deleting one pipe, tell the app we are done */
   1605                 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
   1606                 {
   1607                     evt_data.deleted.status         = status;
   1608                     evt_data.deleted.pipe           = nfa_hci_cb.pipe_in_use;
   1609 
   1610                     nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1611                 }
   1612                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1613                     nfa_hci_api_deregister (NULL);
   1614                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1615                     nfa_hci_api_dealloc_gate (NULL);
   1616             }
   1617             else
   1618             {
   1619                 /* If only deleting one pipe, tell the app we are done */
   1620                 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
   1621                 {
   1622                     evt_data.deleted.status         = status;
   1623                     evt_data.deleted.pipe           = nfa_hci_cb.pipe_in_use;
   1624 
   1625                     nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1626                 }
   1627                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
   1628                 {
   1629                     nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
   1630                     nfa_hci_api_deregister (NULL);
   1631                 }
   1632                 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
   1633                 {
   1634                     nfa_hciu_release_pipe (nfa_hci_cb.pipe_in_use);
   1635                     nfa_hci_api_dealloc_gate (NULL);
   1636                 }
   1637             }
   1638             break;
   1639 
   1640         case NFA_HCI_ANY_OPEN_PIPE:
   1641             nfa_hci_cb.cfg.admin_gate.pipe01_state = status ? NFA_HCI_PIPE_CLOSED:NFA_HCI_PIPE_OPENED;
   1642             nfa_hci_cb.nv_write_needed = TRUE;
   1643             if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED)
   1644             {
   1645                 /* First thing is to get the session ID */
   1646                 nfa_hciu_send_get_param_cmd (NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX);
   1647             }
   1648             break;
   1649 
   1650         case NFA_HCI_ADM_CLEAR_ALL_PIPE:
   1651             nfa_hciu_remove_all_pipes_from_host (0);
   1652             nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
   1653             nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
   1654             nfa_hci_cb.nv_write_needed = TRUE;
   1655             /* Open admin */
   1656             nfa_hciu_send_open_pipe_cmd (NFA_HCI_ADMIN_PIPE);
   1657             break;
   1658 
   1659         }
   1660     }
   1661 }
   1662 
   1663 /*******************************************************************************
   1664 **
   1665 ** Function         nfa_hci_handle_admin_gate_evt
   1666 **
   1667 ** Description      This function handles events received on admin gate
   1668 **
   1669 ** Returns          none
   1670 **
   1671 *******************************************************************************/
   1672 void nfa_hci_handle_admin_gate_evt (UINT8 *p_data)
   1673 {
   1674     tNFA_HCI_EVT_DATA           evt_data;
   1675     tNFA_HCI_API_GET_HOST_LIST  *p_msg;
   1676 
   1677     if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG)
   1678     {
   1679         NFA_TRACE_ERROR0 ("nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
   1680         return;
   1681     }
   1682 
   1683     NFA_TRACE_DEBUG0 ("nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
   1684     nfa_hci_cb.num_hot_plug_evts++;
   1685 
   1686     if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE)
   1687         ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)  )
   1688     {
   1689         /* Received Hot Plug evt while waiting for other Host in the network to bootup after DH host bootup is complete */
   1690         if (  (nfa_hci_cb.ee_disable_disc)
   1691             &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))
   1692             &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))  )
   1693         {
   1694             /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */
   1695             nfa_sys_stop_timer (&nfa_hci_cb.timer);
   1696             /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ Ntf(s) */
   1697             nfa_sys_start_timer (&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT, p_nfa_hci_cfg->hci_netwk_enable_timeout);
   1698         }
   1699     }
   1700     else if (  (nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP)
   1701              ||(nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)  )
   1702     {
   1703         /* Received Hot Plug evt during DH host bootup */
   1704         if (  (nfa_hci_cb.ee_disable_disc)
   1705             &&(nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1))
   1706             &&(nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))  )
   1707         {
   1708             /* Received expected number of Hot Plug event(s) before as many number of EE DISC REQ Ntf(s) are received */
   1709             nfa_hci_cb.w4_hci_netwk_init = FALSE;
   1710         }
   1711     }
   1712     else
   1713     {
   1714         /* Received Hot Plug evt on UICC self reset */
   1715         evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
   1716         /* Notify all registered application with the HOT_PLUG_EVT */
   1717         nfa_hciu_send_to_all_apps (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
   1718 
   1719         /* Send Get Host List after receiving any pending response */
   1720         if ((p_msg = (tNFA_HCI_API_GET_HOST_LIST *) GKI_getbuf (sizeof (tNFA_HCI_API_GET_HOST_LIST))) != NULL)
   1721         {
   1722             p_msg->hdr.event    = NFA_HCI_API_GET_HOST_LIST_EVT;
   1723             /* Set Invalid handle to identify this Get Host List command is internal */
   1724             p_msg->hci_handle   = NFA_HANDLE_INVALID;
   1725 
   1726             nfa_sys_sendmsg (p_msg);
   1727         }
   1728     }
   1729 }
   1730 
   1731 /*******************************************************************************
   1732 **
   1733 ** Function         nfa_hci_handle_dyn_pipe_pkt
   1734 **
   1735 ** Description      This function handles data received via dynamic pipe
   1736 **
   1737 ** Returns          none
   1738 **
   1739 *******************************************************************************/
   1740 void nfa_hci_handle_dyn_pipe_pkt (UINT8 pipe_id, UINT8 *p_data, UINT16 data_len)
   1741 {
   1742     tNFA_HCI_DYN_PIPE   *p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id);
   1743     tNFA_HCI_DYN_GATE   *p_gate;
   1744 
   1745     if (p_pipe == NULL)
   1746     {
   1747         /* Invalid pipe ID */
   1748         NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",pipe_id);
   1749         if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   1750             nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
   1751         return;
   1752     }
   1753 
   1754     if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
   1755     {
   1756         nfa_hci_handle_identity_mgmt_gate_pkt (p_data, p_pipe);
   1757     }
   1758     else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE)
   1759     {
   1760         nfa_hci_handle_loopback_gate_pkt (p_data, data_len, p_pipe);
   1761     }
   1762     else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
   1763     {
   1764         nfa_hci_handle_connectivity_gate_pkt (p_data, data_len, p_pipe);
   1765     }
   1766     else
   1767     {
   1768         p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate);
   1769         if (p_gate == NULL)
   1770         {
   1771             NFA_TRACE_ERROR1 ("nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",p_pipe->local_gate);
   1772             if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   1773                 nfa_hciu_send_msg (pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0, NULL);
   1774             return;
   1775         }
   1776 
   1777         /* Check if data packet is a command, response or event */
   1778         switch (nfa_hci_cb.type)
   1779         {
   1780         case NFA_HCI_COMMAND_TYPE:
   1781             nfa_hci_handle_generic_gate_cmd (p_data, (UINT8) data_len, p_gate, p_pipe);
   1782             break;
   1783 
   1784         case NFA_HCI_RESPONSE_TYPE:
   1785             nfa_hci_handle_generic_gate_rsp (p_data, (UINT8) data_len, p_gate, p_pipe);
   1786             break;
   1787 
   1788         case NFA_HCI_EVENT_TYPE:
   1789             nfa_hci_handle_generic_gate_evt (p_data, data_len, p_gate, p_pipe);
   1790             break;
   1791         }
   1792     }
   1793 }
   1794 
   1795 /*******************************************************************************
   1796 **
   1797 ** Function         nfa_hci_handle_identity_mgmt_gate_pkt
   1798 **
   1799 ** Description      This function handles incoming Identity Management gate hci
   1800 **                  commands
   1801 **
   1802 ** Returns          none
   1803 **
   1804 *******************************************************************************/
   1805 static void nfa_hci_handle_identity_mgmt_gate_pkt (UINT8 *p_data, tNFA_HCI_DYN_PIPE *p_pipe)
   1806 {
   1807     UINT8       data[20];
   1808     UINT8       index;
   1809     UINT8       gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
   1810     UINT16      rsp_len = 0;
   1811     UINT8       *p_rsp = data;
   1812     tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
   1813 
   1814     /* We never send commands on a pipe where the local gate is the identity management
   1815      * gate, so only commands should be processed.
   1816      */
   1817     if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE)
   1818         return;
   1819 
   1820     switch (nfa_hci_cb.inst)
   1821     {
   1822     case  NFA_HCI_ANY_GET_PARAMETER:
   1823         index = *(p_data++);
   1824         if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED)
   1825         {
   1826             switch (index)
   1827             {
   1828             case NFA_HCI_VERSION_SW_INDEX:
   1829                 data[0] = (UINT8) ((NFA_HCI_VERSION_SW >> 16 ) & 0xFF);
   1830                 data[1] = (UINT8) ((NFA_HCI_VERSION_SW >> 8 ) & 0xFF);
   1831                 data[2] = (UINT8) ((NFA_HCI_VERSION_SW ) & 0xFF);
   1832                 rsp_len = 3;
   1833                 break;
   1834 
   1835             case NFA_HCI_HCI_VERSION_INDEX:
   1836                 data[0] = NFA_HCI_VERSION;
   1837                 rsp_len = 1;
   1838                 break;
   1839 
   1840             case NFA_HCI_VERSION_HW_INDEX:
   1841                 data[0] = (UINT8) ((NFA_HCI_VERSION_HW >> 16 ) & 0xFF);
   1842                 data[1] = (UINT8) ((NFA_HCI_VERSION_HW >> 8 ) & 0xFF);
   1843                 data[2] = (UINT8) ((NFA_HCI_VERSION_HW ) & 0xFF);
   1844                 rsp_len = 3;
   1845                 break;
   1846 
   1847             case NFA_HCI_VENDOR_NAME_INDEX:
   1848                 memcpy (data,NFA_HCI_VENDOR_NAME,strlen (NFA_HCI_VENDOR_NAME));
   1849                 rsp_len = (UINT8) strlen (NFA_HCI_VENDOR_NAME);
   1850                 break;
   1851 
   1852             case NFA_HCI_MODEL_ID_INDEX:
   1853                 data[0] = NFA_HCI_MODEL_ID;
   1854                 rsp_len = 1;
   1855                 break;
   1856 
   1857             case NFA_HCI_GATES_LIST_INDEX:
   1858                 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
   1859                 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
   1860                 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
   1861                 num_gates   = nfa_hciu_get_allocated_gate_list (&gate_rsp[3]);
   1862                 rsp_len     = num_gates + 3;
   1863                 p_rsp       = gate_rsp;
   1864                 break;
   1865 
   1866             default:
   1867                 response = NFA_HCI_ANY_E_NOK;
   1868                 break;
   1869             }
   1870         }
   1871         else
   1872         {
   1873             response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
   1874         }
   1875         break;
   1876 
   1877     case NFA_HCI_ANY_OPEN_PIPE:
   1878         data[0] = 0;
   1879         rsp_len = 1;
   1880         p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   1881         break;
   1882 
   1883     case NFA_HCI_ANY_CLOSE_PIPE:
   1884         p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   1885         break;
   1886 
   1887     default:
   1888         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   1889         break;
   1890     }
   1891 
   1892     nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, p_rsp);
   1893 }
   1894 
   1895 /*******************************************************************************
   1896 **
   1897 ** Function         nfa_hci_handle_generic_gate_cmd
   1898 **
   1899 ** Description      This function handles all generic gates (excluding
   1900 **                  connectivity gate) commands
   1901 **
   1902 ** Returns          none
   1903 **
   1904 *******************************************************************************/
   1905 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)
   1906 {
   1907     tNFA_HCI_EVT_DATA   evt_data;
   1908     tNFA_HANDLE         app_handle = nfa_hciu_get_pipe_owner (p_pipe->pipe_id);
   1909 
   1910     switch (nfa_hci_cb.inst)
   1911     {
   1912     case NFA_HCI_ANY_SET_PARAMETER:
   1913         evt_data.registry.pipe     = p_pipe->pipe_id;
   1914         evt_data.registry.index    = *p_data++;
   1915         if (data_len > 0)
   1916             data_len--;
   1917         evt_data.registry.data_len = data_len;
   1918 
   1919         memcpy (evt_data.registry.reg_data, p_data, data_len);
   1920 
   1921         nfa_hciu_send_to_app (NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
   1922         break;
   1923 
   1924     case NFA_HCI_ANY_GET_PARAMETER:
   1925         evt_data.registry.pipe     = p_pipe->pipe_id;
   1926         evt_data.registry.index    = *p_data;
   1927         evt_data.registry.data_len = 0;
   1928 
   1929         nfa_hciu_send_to_app (NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
   1930         break;
   1931 
   1932     case NFA_HCI_ANY_OPEN_PIPE:
   1933         nfa_hci_handle_pipe_open_close_cmd (p_pipe);
   1934 
   1935         evt_data.opened.pipe   = p_pipe->pipe_id;
   1936         evt_data.opened.status = NFA_STATUS_OK;
   1937 
   1938         nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
   1939         break;
   1940 
   1941     case NFA_HCI_ANY_CLOSE_PIPE:
   1942         nfa_hci_handle_pipe_open_close_cmd (p_pipe);
   1943 
   1944         evt_data.closed.pipe   = p_pipe->pipe_id;
   1945         evt_data.opened.status = NFA_STATUS_OK;
   1946 
   1947         nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
   1948         break;
   1949 
   1950     default:
   1951         /* Could be application specific command, pass it on */
   1952         evt_data.cmd_rcvd.status   = NFA_STATUS_OK;
   1953         evt_data.cmd_rcvd.pipe     = p_pipe->pipe_id;;
   1954         evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
   1955         evt_data.cmd_rcvd.cmd_len  = data_len;
   1956 
   1957         if (data_len <= NFA_MAX_HCI_CMD_LEN)
   1958             memcpy (evt_data.cmd_rcvd.cmd_data, p_data, data_len);
   1959 
   1960         nfa_hciu_send_to_app (NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
   1961         break;
   1962     }
   1963 }
   1964 
   1965 /*******************************************************************************
   1966 **
   1967 ** Function         nfa_hci_handle_generic_gate_rsp
   1968 **
   1969 ** Description      This function handles all generic gates (excluding
   1970 **                  connectivity) response
   1971 **
   1972 ** Returns          none
   1973 **
   1974 *******************************************************************************/
   1975 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)
   1976 {
   1977     tNFA_HCI_EVT_DATA   evt_data;
   1978     tNFA_STATUS         status = NFA_STATUS_OK;
   1979 
   1980     if (nfa_hci_cb.inst != NFA_HCI_ANY_OK)
   1981         status = NFA_STATUS_FAILED;
   1982 
   1983     if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE)
   1984     {
   1985         if (status == NFA_STATUS_OK)
   1986             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   1987 
   1988         nfa_hci_cb.nv_write_needed = TRUE;
   1989         /* Tell application */
   1990         evt_data.opened.status  = status;
   1991         evt_data.opened.pipe    = p_pipe->pipe_id;
   1992 
   1993         nfa_hciu_send_to_app (NFA_HCI_OPEN_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   1994     }
   1995     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
   1996     {
   1997         p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   1998 
   1999         nfa_hci_cb.nv_write_needed = TRUE;
   2000         /* Tell application */
   2001         evt_data.opened.status = status;;
   2002         evt_data.opened.pipe   = p_pipe->pipe_id;
   2003 
   2004         nfa_hciu_send_to_app (NFA_HCI_CLOSE_PIPE_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2005     }
   2006     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER)
   2007     {
   2008         /* Tell application */
   2009         evt_data.registry.status   = status;
   2010         evt_data.registry.pipe     = p_pipe->pipe_id;
   2011         evt_data.registry.data_len = data_len;
   2012         evt_data.registry.index    = nfa_hci_cb.param_in_use;
   2013 
   2014         memcpy (evt_data.registry.reg_data, p_data, data_len);
   2015 
   2016         nfa_hciu_send_to_app (NFA_HCI_GET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2017     }
   2018     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER)
   2019     {
   2020         /* Tell application */
   2021         evt_data.registry.status = status;;
   2022         evt_data.registry.pipe   = p_pipe->pipe_id;
   2023 
   2024         nfa_hciu_send_to_app (NFA_HCI_SET_REG_RSP_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2025     }
   2026     else
   2027     {
   2028         /* Could be a response to application specific command sent, pass it on */
   2029         evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
   2030         evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
   2031         evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
   2032         evt_data.rsp_rcvd.rsp_len  = data_len;
   2033 
   2034         if (data_len <= NFA_MAX_HCI_RSP_LEN)
   2035             memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
   2036 
   2037         nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2038     }
   2039 
   2040 }
   2041 
   2042 /*******************************************************************************
   2043 **
   2044 ** Function         nfa_hci_handle_connectivity_gate_pkt
   2045 **
   2046 ** Description      This function handles incoming connectivity gate packets
   2047 **
   2048 ** Returns          none
   2049 **
   2050 *******************************************************************************/
   2051 static void nfa_hci_handle_connectivity_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
   2052 {
   2053     tNFA_HCI_EVT_DATA   evt_data;
   2054 
   2055     if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   2056     {
   2057         switch (nfa_hci_cb.inst)
   2058         {
   2059         case NFA_HCI_ANY_OPEN_PIPE:
   2060         case NFA_HCI_ANY_CLOSE_PIPE:
   2061             nfa_hci_handle_pipe_open_close_cmd (p_pipe);
   2062             break;
   2063 
   2064         case NFA_HCI_CON_PRO_HOST_REQUEST:
   2065             /* A request to the DH to activate another host. This is not supported for */
   2066             /* now, we will implement it when the spec is clearer and UICCs need it.   */
   2067             nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
   2068             break;
   2069 
   2070         default:
   2071             nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, NULL);
   2072             break;
   2073         }
   2074     }
   2075     else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
   2076     {
   2077         if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
   2078             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   2079         else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
   2080             p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   2081 
   2082         /* Could be a response to application specific command sent, pass it on */
   2083         evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
   2084         evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
   2085         evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
   2086         evt_data.rsp_rcvd.rsp_len  = data_len;
   2087 
   2088         if (data_len <= NFA_MAX_HCI_RSP_LEN)
   2089             memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
   2090 
   2091         nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2092     }
   2093     else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
   2094     {
   2095         evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
   2096         evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
   2097         evt_data.rcvd_evt.evt_len   = data_len;
   2098         evt_data.rcvd_evt.p_evt_buf = p_data;
   2099 
   2100         /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
   2101         nfa_hciu_send_to_apps_handling_connectivity_evts (NFA_HCI_EVENT_RCVD_EVT, &evt_data);
   2102     }
   2103 }
   2104 
   2105 /*******************************************************************************
   2106 **
   2107 ** Function         nfa_hci_handle_loopback_gate_pkt
   2108 **
   2109 ** Description      This function handles incoming loopback gate hci events
   2110 **
   2111 ** Returns          none
   2112 **
   2113 *******************************************************************************/
   2114 static void nfa_hci_handle_loopback_gate_pkt (UINT8 *p_data, UINT16 data_len, tNFA_HCI_DYN_PIPE *p_pipe)
   2115 {
   2116     UINT8               data[1];
   2117     UINT8               rsp_len = 0;
   2118     tNFA_HCI_RESPONSE   response = NFA_HCI_ANY_OK;
   2119     tNFA_HCI_EVT_DATA   evt_data;
   2120 
   2121     /* Check if data packet is a command, response or event */
   2122     if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
   2123     {
   2124         if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE)
   2125         {
   2126             data[0] = 0;
   2127             rsp_len = 1;
   2128             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   2129         }
   2130         else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE)
   2131         {
   2132             p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   2133         }
   2134         else
   2135             response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
   2136 
   2137         nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len, data);
   2138     }
   2139     else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE)
   2140     {
   2141         if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) && (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
   2142             p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
   2143         else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
   2144             p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
   2145 
   2146         /* Could be a response to application specific command sent, pass it on */
   2147         evt_data.rsp_rcvd.status   = NFA_STATUS_OK;
   2148         evt_data.rsp_rcvd.pipe     = p_pipe->pipe_id;;
   2149         evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
   2150         evt_data.rsp_rcvd.rsp_len  = data_len;
   2151 
   2152         if (data_len <= NFA_MAX_HCI_RSP_LEN)
   2153             memcpy (evt_data.rsp_rcvd.rsp_data, p_data, data_len);
   2154 
   2155         nfa_hciu_send_to_app (NFA_HCI_RSP_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2156     }
   2157     else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE)
   2158     {
   2159         if (nfa_hci_cb.w4_rsp_evt)
   2160         {
   2161             evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
   2162             evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
   2163             evt_data.rcvd_evt.evt_len   = data_len;
   2164             evt_data.rcvd_evt.p_evt_buf = p_data;
   2165 
   2166             nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, nfa_hci_cb.app_in_use);
   2167         }
   2168         else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA)
   2169         {
   2170             /* Send back the same data we got */
   2171             nfa_hciu_send_msg (p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, NFA_HCI_EVT_POST_DATA, data_len, p_data);
   2172         }
   2173     }
   2174 }
   2175 
   2176 /*******************************************************************************
   2177 **
   2178 ** Function         nfa_hci_handle_generic_gate_evt
   2179 **
   2180 ** Description      This function handles incoming Generic gate hci events
   2181 **
   2182 ** Returns          none
   2183 **
   2184 *******************************************************************************/
   2185 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)
   2186 {
   2187     tNFA_HCI_EVT_DATA   evt_data;
   2188 
   2189     evt_data.rcvd_evt.pipe      = p_pipe->pipe_id;
   2190     evt_data.rcvd_evt.evt_code  = nfa_hci_cb.inst;
   2191     evt_data.rcvd_evt.evt_len   = data_len;
   2192 
   2193     if (nfa_hci_cb.assembly_failed)
   2194         evt_data.rcvd_evt.status    = NFA_STATUS_BUFFER_FULL;
   2195     else
   2196         evt_data.rcvd_evt.status    = NFA_STATUS_OK;
   2197 
   2198     evt_data.rcvd_evt.p_evt_buf = p_data;
   2199     nfa_hci_cb.rsp_buf_size     = 0;
   2200     nfa_hci_cb.p_rsp_buf        = NULL;
   2201 
   2202     /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
   2203     nfa_hciu_send_to_app (NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
   2204 }
   2205 
   2206