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