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