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