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