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