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