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