• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the action functions for the NFA HCI.
22  *
23  ******************************************************************************/
24 #include <android-base/stringprintf.h>
25 #include <base/logging.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 extern bool nfc_debug_enabled;
37 
38 /* Static local functions       */
39 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data);
40 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data);
41 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data);
42 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data);
43 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
44 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
45 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
46 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
47 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
48 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
49 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data);
50 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data);
51 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data);
52 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
53 
54 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
55                                                   tNFA_HCI_DYN_PIPE* p_pipe);
56 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
57                                              tNFA_HCI_DYN_PIPE* p_pipe);
58 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
59                                                  uint16_t data_len,
60                                                  tNFA_HCI_DYN_PIPE* p_pipe);
61 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
62                                             tNFA_HCI_DYN_PIPE* p_pipe);
63 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
64                                             tNFA_HCI_DYN_PIPE* p_pipe);
65 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
66                                             tNFA_HCI_DYN_GATE* p_gate,
67                                             tNFA_HCI_DYN_PIPE* p_pipe);
68 
69 /*******************************************************************************
70 **
71 ** Function         nfa_hci_check_pending_api_requests
72 **
73 ** Description      This function handles pending API requests
74 **
75 ** Returns          none
76 **
77 *******************************************************************************/
nfa_hci_check_pending_api_requests(void)78 void nfa_hci_check_pending_api_requests(void) {
79   NFC_HDR* p_msg;
80   tNFA_HCI_EVENT_DATA* p_evt_data;
81   bool b_free;
82 
83   /* If busy, or API queue is empty, then exit */
84   if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
85       ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_host_reset_api_q)) ==
86        nullptr))
87     return;
88 
89   /* Process API request */
90   p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
91 
92   /* Save the application handle */
93   nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
94 
95   b_free = true;
96   switch (p_msg->event) {
97     case NFA_HCI_API_CREATE_PIPE_EVT:
98       if (nfa_hci_api_create_pipe(p_evt_data) == false) b_free = false;
99       break;
100 
101     case NFA_HCI_API_GET_REGISTRY_EVT:
102       if (nfa_hci_api_get_reg_value(p_evt_data) == false) b_free = false;
103       break;
104 
105     case NFA_HCI_API_SET_REGISTRY_EVT:
106       if (nfa_hci_api_set_reg_value(p_evt_data) == false) b_free = false;
107       break;
108 
109     case NFA_HCI_API_SEND_CMD_EVT:
110       if (nfa_hci_api_send_cmd(p_evt_data) == false) b_free = false;
111       break;
112     case NFA_HCI_API_SEND_EVENT_EVT:
113       if (nfa_hci_api_send_event(p_evt_data) == false) b_free = false;
114       break;
115   }
116 
117   if (b_free) GKI_freebuf(p_msg);
118 }
119 
120 /*******************************************************************************
121 **
122 ** Function         nfa_hci_check_api_requests
123 **
124 ** Description      This function handles API requests
125 **
126 ** Returns          none
127 **
128 *******************************************************************************/
nfa_hci_check_api_requests(void)129 void nfa_hci_check_api_requests(void) {
130   NFC_HDR* p_msg;
131   tNFA_HCI_EVENT_DATA* p_evt_data;
132 
133   for (;;) {
134     /* If busy, or API queue is empty, then exit */
135     if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
136         ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_api_q)) == nullptr))
137       break;
138 
139     /* Process API request */
140     p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
141 
142     /* Save the application handle */
143     nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
144 
145     switch (p_msg->event) {
146       case NFA_HCI_API_REGISTER_APP_EVT:
147         nfa_hci_api_register(p_evt_data);
148         break;
149 
150       case NFA_HCI_API_DEREGISTER_APP_EVT:
151         nfa_hci_api_deregister(p_evt_data);
152         break;
153 
154       case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
155         nfa_hci_api_get_gate_pipe_list(p_evt_data);
156         break;
157 
158       case NFA_HCI_API_ALLOC_GATE_EVT:
159         nfa_hci_api_alloc_gate(p_evt_data);
160         break;
161 
162       case NFA_HCI_API_DEALLOC_GATE_EVT:
163         nfa_hci_api_dealloc_gate(p_evt_data);
164         break;
165 
166       case NFA_HCI_API_GET_HOST_LIST_EVT:
167         nfa_hci_api_get_host_list(p_evt_data);
168         break;
169 
170       case NFA_HCI_API_GET_REGISTRY_EVT:
171         if (nfa_hci_api_get_reg_value(p_evt_data) == false) continue;
172         break;
173 
174       case NFA_HCI_API_SET_REGISTRY_EVT:
175         if (nfa_hci_api_set_reg_value(p_evt_data) == false) continue;
176         break;
177 
178       case NFA_HCI_API_CREATE_PIPE_EVT:
179         if (nfa_hci_api_create_pipe(p_evt_data) == false) continue;
180         break;
181 
182       case NFA_HCI_API_OPEN_PIPE_EVT:
183         nfa_hci_api_open_pipe(p_evt_data);
184         break;
185 
186       case NFA_HCI_API_CLOSE_PIPE_EVT:
187         nfa_hci_api_close_pipe(p_evt_data);
188         break;
189 
190       case NFA_HCI_API_DELETE_PIPE_EVT:
191         nfa_hci_api_delete_pipe(p_evt_data);
192         break;
193 
194       case NFA_HCI_API_SEND_CMD_EVT:
195         if (nfa_hci_api_send_cmd(p_evt_data) == false) continue;
196         break;
197 
198       case NFA_HCI_API_SEND_RSP_EVT:
199         nfa_hci_api_send_rsp(p_evt_data);
200         break;
201 
202       case NFA_HCI_API_SEND_EVENT_EVT:
203         if (nfa_hci_api_send_event(p_evt_data) == false) continue;
204         break;
205 
206       case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
207         nfa_hci_api_add_static_pipe(p_evt_data);
208         break;
209 
210       default:
211         LOG(ERROR) << StringPrintf("Unknown event: 0x%04x", p_msg->event);
212         break;
213     }
214 
215     GKI_freebuf(p_msg);
216   }
217 }
218 
219 /*******************************************************************************
220 **
221 ** Function         nfa_hci_api_register
222 **
223 ** Description      action function to register the events for the given AID
224 **
225 ** Returns          None
226 **
227 *******************************************************************************/
nfa_hci_api_register(tNFA_HCI_EVENT_DATA * p_evt_data)228 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) {
229   tNFA_HCI_EVT_DATA evt_data;
230   char* p_app_name = p_evt_data->app_info.app_name;
231   tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback;
232   int xx, yy;
233   uint8_t num_gates = 0, num_pipes = 0;
234   tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
235 
236   /* First, see if the application was already registered */
237   for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
238     if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
239         !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0],
240                  strlen(p_app_name))) {
241       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
242           "nfa_hci_api_register (%s)  Reusing: %u", p_app_name, xx);
243       break;
244     }
245   }
246 
247   if (xx != NFA_HCI_MAX_APP_CB) {
248     nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
249     /* The app was registered, find the number of gates and pipes associated to
250      * the app */
251 
252     for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) {
253       if (pg->gate_owner == nfa_hci_cb.app_in_use) {
254         num_gates++;
255         num_pipes += nfa_hciu_count_pipes_on_gate(pg);
256       }
257     }
258   } else {
259     /* Not registered, look for a free entry */
260     for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
261       if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) {
262         memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0,
263                sizeof(nfa_hci_cb.cfg.reg_app_names[xx]));
264         strlcpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
265                 NFA_MAX_HCI_APP_NAME_LEN);
266         nfa_hci_cb.nv_write_needed = true;
267         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
268             "nfa_hci_api_register (%s)  Allocated: %u", p_app_name, xx);
269         break;
270       }
271     }
272 
273     if (xx == NFA_HCI_MAX_APP_CB) {
274       LOG(ERROR) << StringPrintf("nfa_hci_api_register (%s)  NO ENTRIES",
275                                  p_app_name);
276 
277       evt_data.hci_register.status = NFA_STATUS_FAILED;
278       p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
279       return;
280     }
281   }
282 
283   evt_data.hci_register.num_pipes = num_pipes;
284   evt_data.hci_register.num_gates = num_gates;
285   nfa_hci_cb.p_app_cback[xx] = p_cback;
286 
287   nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts;
288 
289   evt_data.hci_register.hci_handle = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
290 
291   evt_data.hci_register.status = NFA_STATUS_OK;
292 
293   /* notify NFA_HCI_REGISTER_EVT to the application */
294   p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
295 }
296 
297 /*******************************************************************************
298 **
299 ** Function         nfa_hci_api_deregister
300 **
301 ** Description      action function to deregister the given application
302 **
303 ** Returns          None
304 **
305 *******************************************************************************/
nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA * p_evt_data)306 void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data) {
307   tNFA_HCI_EVT_DATA evt_data;
308   tNFA_HCI_CBACK* p_cback = nullptr;
309   int xx;
310   tNFA_HCI_DYN_PIPE* p_pipe;
311   tNFA_HCI_DYN_GATE* p_gate;
312 
313   /* If needed, find the application registration handle */
314   if (p_evt_data != nullptr) {
315     for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
316       if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
317           !strncmp(p_evt_data->app_info.app_name,
318                    &nfa_hci_cb.cfg.reg_app_names[xx][0],
319                    strlen(p_evt_data->app_info.app_name))) {
320         DLOG_IF(INFO, nfc_debug_enabled)
321             << StringPrintf("nfa_hci_api_deregister (%s) inx: %u",
322                             p_evt_data->app_info.app_name, xx);
323         break;
324       }
325     }
326 
327     if (xx == NFA_HCI_MAX_APP_CB) {
328       LOG(WARNING) << StringPrintf("Unknown app: %s",
329                                    p_evt_data->app_info.app_name);
330       return;
331     }
332     nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
333     p_cback = nfa_hci_cb.p_app_cback[xx];
334   } else {
335     nfa_sys_stop_timer(&nfa_hci_cb.timer);
336     /* We are recursing through deleting all the app's pipes and gates */
337     p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
338   }
339 
340   /* See if any pipe is owned by this app */
341   if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == nullptr) {
342     /* No pipes, release all gates owned by this app */
343     while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) !=
344            nullptr)
345       nfa_hciu_release_gate(p_gate->gate_id);
346 
347     memset(&nfa_hci_cb.cfg
348                 .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0],
349            0, NFA_MAX_HCI_APP_NAME_LEN + 1);
350     nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = nullptr;
351 
352     nfa_hci_cb.nv_write_needed = true;
353 
354     evt_data.hci_deregister.status = NFC_STATUS_OK;
355 
356     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
357       nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
358 
359     /* notify NFA_HCI_DEREGISTER_EVT to the application */
360     if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
361   } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner(
362                   nfa_hci_cb.app_in_use)) == nullptr) {
363     /* No pipes, release all gates owned by this app */
364     while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner(
365                 nfa_hci_cb.app_in_use)) != nullptr)
366       nfa_hciu_release_gate(p_gate->gate_id);
367 
368     nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = nullptr;
369 
370     nfa_hci_cb.nv_write_needed = true;
371 
372     evt_data.hci_deregister.status = NFC_STATUS_FAILED;
373 
374     if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
375       nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
376 
377     /* notify NFA_HCI_DEREGISTER_EVT to the application */
378     if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
379   } else {
380     /* Delete all active pipes created for the application before de registering
381     **/
382     nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;
383 
384     nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
385   }
386 }
387 
388 /*******************************************************************************
389 **
390 ** Function         nfa_hci_api_get_gate_pipe_list
391 **
392 ** Description      action function to get application allocated gates and
393 **                  application created pipes
394 **
395 ** Returns          None
396 **
397 *******************************************************************************/
nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA * p_evt_data)398 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
399   tNFA_HCI_EVT_DATA evt_data;
400   int xx, yy;
401   tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
402   tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
403 
404   evt_data.gates_pipes.num_gates = 0;
405   evt_data.gates_pipes.num_pipes = 0;
406 
407   for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
408     if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) {
409       evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;
410 
411       pp = nfa_hci_cb.cfg.dyn_pipes;
412 
413       /* Loop through looking for a match */
414       for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) {
415         if (pp->local_gate == pg->gate_id)
416           evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] =
417               *(tNFA_HCI_PIPE_INFO*)pp;
418       }
419     }
420   }
421 
422   evt_data.gates_pipes.num_uicc_created_pipes = 0;
423   /* Loop through all pipes that are connected to connectivity gate */
424   for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
425        xx++, pp++) {
426     if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
427       memcpy(&evt_data.gates_pipes.uicc_created_pipe
428                   [evt_data.gates_pipes.num_uicc_created_pipes++],
429              pp, sizeof(tNFA_HCI_PIPE_INFO));
430     } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_GATE) {
431       memcpy(&evt_data.gates_pipes.uicc_created_pipe
432                   [evt_data.gates_pipes.num_uicc_created_pipes++],
433              pp, sizeof(tNFA_HCI_PIPE_INFO));
434     } else if (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE &&
435                pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id &&
436                pp->local_gate >= NFA_HCI_FIRST_PROP_GATE &&
437                pp->local_gate <= NFA_HCI_LAST_PROP_GATE) {
438       for (yy = 0, pg = nfa_hci_cb.cfg.dyn_gates; yy < NFA_HCI_MAX_GATE_CB;
439            yy++, pg++) {
440         if (pp->local_gate == pg->gate_id) {
441           if (!pg->gate_owner)
442             memcpy(&evt_data.gates_pipes.uicc_created_pipe
443                         [evt_data.gates_pipes.num_uicc_created_pipes++],
444                    pp, sizeof(tNFA_HCI_PIPE_INFO));
445           break;
446         }
447       }
448     }
449   }
450 
451   evt_data.gates_pipes.status = NFA_STATUS_OK;
452 
453   /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
454   nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data,
455                        p_evt_data->get_gate_pipe_list.hci_handle);
456 }
457 
458 /*******************************************************************************
459 **
460 ** Function         nfa_hci_api_alloc_gate
461 **
462 ** Description      action function to allocate gate
463 **
464 ** Returns          None
465 **
466 *******************************************************************************/
nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)467 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
468   tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle;
469   tNFA_HCI_EVT_DATA evt_data;
470   tNFA_HCI_DYN_GATE* p_gate;
471 
472   p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle);
473 
474   if (p_gate) {
475     if (!p_gate->gate_owner) {
476       /* No app owns the gate yet */
477       p_gate->gate_owner = app_handle;
478     } else if (p_gate->gate_owner != app_handle) {
479       /* Some other app owns the gate */
480       p_gate = nullptr;
481       LOG(ERROR) << StringPrintf("The Gate (0X%02x) already taken!",
482                                  p_evt_data->gate_info.gate);
483     }
484   }
485 
486   evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0;
487   evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
488 
489   /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
490   nfa_hciu_send_to_app(NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
491 }
492 
493 /*******************************************************************************
494 **
495 ** Function         nfa_hci_api_dealloc_gate
496 **
497 ** Description      action function to deallocate the given generic gate
498 **
499 ** Returns          None
500 **
501 *******************************************************************************/
nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)502 void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
503   tNFA_HCI_EVT_DATA evt_data;
504   uint8_t gate_id;
505   tNFA_HCI_DYN_GATE* p_gate;
506   tNFA_HCI_DYN_PIPE* p_pipe;
507   tNFA_HANDLE app_handle;
508 
509   /* p_evt_data may be NULL if we are recursively deleting pipes */
510   if (p_evt_data) {
511     gate_id = p_evt_data->gate_dealloc.gate;
512     app_handle = p_evt_data->gate_dealloc.hci_handle;
513 
514   } else {
515     nfa_sys_stop_timer(&nfa_hci_cb.timer);
516     gate_id = nfa_hci_cb.local_gate_in_use;
517     app_handle = nfa_hci_cb.app_in_use;
518   }
519 
520   evt_data.deallocated.gate = gate_id;
521   ;
522 
523   p_gate = nfa_hciu_find_gate_by_gid(gate_id);
524 
525   if (p_gate == nullptr) {
526     evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
527   } else if (p_gate->gate_owner != app_handle) {
528     evt_data.deallocated.status = NFA_STATUS_FAILED;
529   } else {
530     /* See if any pipe is owned by this app */
531     if (nfa_hciu_find_pipe_on_gate(p_gate->gate_id) == nullptr) {
532       nfa_hciu_release_gate(p_gate->gate_id);
533 
534       nfa_hci_cb.nv_write_needed = true;
535       evt_data.deallocated.status = NFA_STATUS_OK;
536 
537       if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
538         nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
539     } else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate(p_gate->gate_id)) ==
540                nullptr) {
541       /* UICC is not active at the moment and cannot delete the pipe */
542       nfa_hci_cb.nv_write_needed = true;
543       evt_data.deallocated.status = NFA_STATUS_FAILED;
544 
545       if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
546         nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
547     } else {
548       /* Delete pipes on the gate */
549       nfa_hci_cb.local_gate_in_use = gate_id;
550       nfa_hci_cb.app_in_use = app_handle;
551       nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE;
552 
553       nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
554       return;
555     }
556   }
557 
558   nfa_hciu_send_to_app(NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
559 }
560 
561 /*******************************************************************************
562 **
563 ** Function         nfa_hci_api_get_host_list
564 **
565 ** Description      action function to get the host list from HCI network
566 **
567 ** Returns          None
568 **
569 *******************************************************************************/
nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA * p_evt_data)570 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
571   uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
572 
573   nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
574 
575   /* Send Get Host List command on "Internal request" or requested by registered
576    * application with valid handle and callback function */
577   if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
578       ((app_inx < NFA_HCI_MAX_APP_CB) &&
579        (nfa_hci_cb.p_app_cback[app_inx] != nullptr))) {
580     nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
581   }
582 }
583 
584 /*******************************************************************************
585 **
586 ** Function         nfa_hci_api_create_pipe
587 **
588 ** Description      action function to create a pipe
589 **
590 ** Returns          TRUE, if the command is processed
591 **                  FALSE, if command is queued for processing later
592 **
593 *******************************************************************************/
nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)594 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
595   tNFA_HCI_DYN_GATE* p_gate =
596       nfa_hciu_find_gate_by_gid(p_evt_data->create_pipe.source_gate);
597   tNFA_HCI_EVT_DATA evt_data;
598   bool report_failed = false;
599 
600   /* Verify that the app owns the gate that the pipe is being created on */
601   if ((p_gate == nullptr) ||
602       (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)) {
603     report_failed = true;
604     LOG(ERROR) << StringPrintf(
605         "nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own "
606         "the gate:0x%x",
607         p_evt_data->create_pipe.hci_handle,
608         p_evt_data->create_pipe.source_gate);
609   } else if (nfa_hciu_check_pipe_between_gates(
610                  p_evt_data->create_pipe.source_gate,
611                  p_evt_data->create_pipe.dest_host,
612                  p_evt_data->create_pipe.dest_gate)) {
613     report_failed = true;
614     LOG(ERROR) << StringPrintf(
615         "nfa_hci_api_create_pipe : Cannot create multiple pipe between the "
616         "same two gates!");
617   }
618 
619   if (report_failed) {
620     evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
621     evt_data.created.status = NFA_STATUS_FAILED;
622 
623     nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
624                          p_evt_data->open_pipe.hci_handle);
625   } else {
626     if (nfa_hciu_is_host_reseting(p_evt_data->create_pipe.dest_gate)) {
627       GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
628       return false;
629     }
630 
631     nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
632     nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
633     nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
634     nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;
635 
636     nfa_hciu_send_create_pipe_cmd(p_evt_data->create_pipe.source_gate,
637                                   p_evt_data->create_pipe.dest_host,
638                                   p_evt_data->create_pipe.dest_gate);
639   }
640   return true;
641 }
642 
643 /*******************************************************************************
644 **
645 ** Function         nfa_hci_api_open_pipe
646 **
647 ** Description      action function to open a pipe
648 **
649 ** Returns          None
650 **
651 *******************************************************************************/
nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)652 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
653   tNFA_HCI_EVT_DATA evt_data;
654   tNFA_HCI_DYN_PIPE* p_pipe =
655       nfa_hciu_find_pipe_by_pid(p_evt_data->open_pipe.pipe);
656   tNFA_HCI_DYN_GATE* p_gate = nullptr;
657 
658   if (p_pipe != nullptr) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
659 
660   if ((p_pipe != nullptr) && (p_gate != nullptr) &&
661       (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
662       (p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) {
663     if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
664       nfa_hciu_send_open_pipe_cmd(p_evt_data->open_pipe.pipe);
665     } else {
666       evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
667       evt_data.opened.status = NFA_STATUS_OK;
668 
669       nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
670                            p_evt_data->open_pipe.hci_handle);
671     }
672   } else {
673     evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
674     evt_data.opened.status = NFA_STATUS_FAILED;
675 
676     nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
677                          p_evt_data->open_pipe.hci_handle);
678   }
679 }
680 
681 /*******************************************************************************
682 **
683 ** Function         nfa_hci_api_get_reg_value
684 **
685 ** Description      action function to get the reg value of the specified index
686 **
687 ** Returns          TRUE, if the command is processed
688 **                  FALSE, if command is queued for processing later
689 **
690 *******************************************************************************/
nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)691 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
692   tNFA_HCI_DYN_PIPE* p_pipe =
693       nfa_hciu_find_pipe_by_pid(p_evt_data->get_registry.pipe);
694   tNFA_HCI_DYN_GATE* p_gate;
695   tNFA_STATUS status = NFA_STATUS_FAILED;
696   tNFA_HCI_EVT_DATA evt_data;
697 
698   if (p_pipe != nullptr) {
699     p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
700 
701     if ((p_gate != nullptr) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
702         (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) {
703       nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;
704 
705       if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
706         GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
707         return false;
708       }
709 
710       if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
711         LOG(WARNING) << StringPrintf(
712             "nfa_hci_api_get_reg_value pipe:%d not open",
713             p_evt_data->get_registry.pipe);
714       } else {
715         status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe,
716                                              p_evt_data->get_registry.reg_inx);
717         if (status == NFA_STATUS_OK) return true;
718       }
719     }
720   }
721 
722   evt_data.cmd_sent.status = status;
723 
724   /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
725   nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
726                        p_evt_data->get_registry.hci_handle);
727   return true;
728 }
729 
730 /*******************************************************************************
731 **
732 ** Function         nfa_hci_api_set_reg_value
733 **
734 ** Description      action function to set the reg value at specified index
735 **
736 ** Returns          TRUE, if the command is processed
737 **                  FALSE, if command is queued for processing later
738 **
739 *******************************************************************************/
nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)740 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
741   tNFA_HCI_DYN_PIPE* p_pipe =
742       nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe);
743   tNFA_HCI_DYN_GATE* p_gate;
744   tNFA_STATUS status = NFA_STATUS_FAILED;
745   tNFA_HCI_EVT_DATA evt_data;
746 
747   if (p_pipe != nullptr) {
748     p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
749 
750     if ((p_gate != nullptr) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
751         (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) {
752       nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;
753 
754       if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
755         GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
756         return false;
757       }
758 
759       if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
760         LOG(WARNING) << StringPrintf(
761             "nfa_hci_api_set_reg_value pipe:%d not open",
762             p_evt_data->set_registry.pipe);
763       } else {
764         status = nfa_hciu_send_set_param_cmd(
765             p_evt_data->set_registry.pipe, p_evt_data->set_registry.reg_inx,
766             p_evt_data->set_registry.size, p_evt_data->set_registry.data);
767         if (status == NFA_STATUS_OK) return true;
768       }
769     }
770   }
771   evt_data.cmd_sent.status = status;
772 
773   /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
774   nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
775                        p_evt_data->set_registry.hci_handle);
776   return true;
777 }
778 
779 /*******************************************************************************
780 **
781 ** Function         nfa_hci_api_close_pipe
782 **
783 ** Description      action function to close a pipe
784 **
785 ** Returns          None
786 **
787 *******************************************************************************/
nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)788 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
789   tNFA_HCI_EVT_DATA evt_data;
790   tNFA_HCI_DYN_PIPE* p_pipe =
791       nfa_hciu_find_pipe_by_pid(p_evt_data->close_pipe.pipe);
792   tNFA_HCI_DYN_GATE* p_gate = nullptr;
793 
794   if (p_pipe != nullptr) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
795 
796   if ((p_pipe != nullptr) && (p_gate != nullptr) &&
797       (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
798       (p_gate->gate_owner == p_evt_data->close_pipe.hci_handle)) {
799     if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
800       nfa_hciu_send_close_pipe_cmd(p_evt_data->close_pipe.pipe);
801     } else {
802       evt_data.closed.status = NFA_STATUS_OK;
803       evt_data.closed.pipe = p_evt_data->close_pipe.pipe;
804 
805       nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
806                            p_evt_data->close_pipe.hci_handle);
807     }
808   } else {
809     evt_data.closed.status = NFA_STATUS_FAILED;
810     evt_data.closed.pipe = 0x00;
811 
812     nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
813                          p_evt_data->close_pipe.hci_handle);
814   }
815 }
816 
817 /*******************************************************************************
818 **
819 ** Function         nfa_hci_api_delete_pipe
820 **
821 ** Description      action function to delete a pipe
822 **
823 ** Returns          None
824 **
825 *******************************************************************************/
nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)826 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
827   tNFA_HCI_EVT_DATA evt_data;
828   tNFA_HCI_DYN_PIPE* p_pipe =
829       nfa_hciu_find_pipe_by_pid(p_evt_data->delete_pipe.pipe);
830   tNFA_HCI_DYN_GATE* p_gate = nullptr;
831 
832   if (p_pipe != nullptr) {
833     p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
834     if ((p_gate != nullptr) &&
835         (p_gate->gate_owner == p_evt_data->delete_pipe.hci_handle) &&
836         (nfa_hciu_is_active_host(p_pipe->dest_host))) {
837       nfa_hciu_send_delete_pipe_cmd(p_evt_data->delete_pipe.pipe);
838       return;
839     }
840   }
841 
842   evt_data.deleted.status = NFA_STATUS_FAILED;
843   evt_data.deleted.pipe = 0x00;
844   nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
845                        p_evt_data->close_pipe.hci_handle);
846 }
847 
848 /*******************************************************************************
849 **
850 ** Function         nfa_hci_api_send_cmd
851 **
852 ** Description      action function to send command on the given pipe
853 **
854 ** Returns          TRUE, if the command is processed
855 **                  FALSE, if command is queued for processing later
856 **
857 *******************************************************************************/
nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA * p_evt_data)858 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data) {
859   tNFA_STATUS status = NFA_STATUS_FAILED;
860   tNFA_HCI_DYN_PIPE* p_pipe;
861   tNFA_HCI_EVT_DATA evt_data;
862   tNFA_HANDLE app_handle;
863 
864   if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_cmd.pipe)) != nullptr) {
865     app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe);
866 
867     if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
868         ((app_handle == p_evt_data->send_cmd.hci_handle ||
869           p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
870       if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
871         GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
872         return false;
873       }
874 
875       if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
876         nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
877         status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE,
878                                    p_evt_data->send_cmd.cmd_code,
879                                    p_evt_data->send_cmd.cmd_len,
880                                    p_evt_data->send_cmd.data);
881         if (status == NFA_STATUS_OK) return true;
882       } else {
883         LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not open",
884                                      p_pipe->pipe_id);
885       }
886     } else {
887       LOG(WARNING) << StringPrintf(
888           "nfa_hci_api_send_cmd pipe:%d Owned by different application or "
889           "Destination host is not active",
890           p_pipe->pipe_id);
891     }
892   } else {
893     LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not found",
894                                  p_evt_data->send_cmd.pipe);
895   }
896 
897   evt_data.cmd_sent.status = status;
898 
899   /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
900   nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
901                        p_evt_data->send_cmd.hci_handle);
902   return true;
903 }
904 
905 /*******************************************************************************
906 **
907 ** Function         nfa_hci_api_send_rsp
908 **
909 ** Description      action function to send response on the given pipe
910 **
911 ** Returns          None
912 **
913 *******************************************************************************/
nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA * p_evt_data)914 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) {
915   tNFA_STATUS status = NFA_STATUS_FAILED;
916   tNFA_HCI_DYN_PIPE* p_pipe;
917   tNFA_HCI_EVT_DATA evt_data;
918   tNFA_HANDLE app_handle;
919 
920   if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) != nullptr) {
921     app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe);
922 
923     if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
924         ((app_handle == p_evt_data->send_rsp.hci_handle ||
925           p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
926       if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
927         status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
928                                    p_evt_data->send_rsp.response,
929                                    p_evt_data->send_rsp.size,
930                                    p_evt_data->send_rsp.data);
931         if (status == NFA_STATUS_OK) return;
932       } else {
933         LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not open",
934                                      p_pipe->pipe_id);
935       }
936     } else {
937       LOG(WARNING) << StringPrintf(
938           "nfa_hci_api_send_rsp pipe:%d Owned by different application or "
939           "Destination host is not active",
940           p_pipe->pipe_id);
941     }
942   } else {
943     LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not found",
944                                  p_evt_data->send_rsp.pipe);
945   }
946 
947   evt_data.rsp_sent.status = status;
948 
949   /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
950   nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data,
951                        p_evt_data->send_rsp.hci_handle);
952 }
953 
954 /*******************************************************************************
955 **
956 ** Function         nfa_hci_api_send_event
957 **
958 ** Description      action function to send an event to the given pipe
959 **
960 ** Returns          TRUE, if the event is processed
961 **                  FALSE, if event is queued for processing later
962 **
963 *******************************************************************************/
nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA * p_evt_data)964 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) {
965   tNFA_STATUS status = NFA_STATUS_FAILED;
966   tNFA_HCI_DYN_PIPE* p_pipe;
967   tNFA_HCI_EVT_DATA evt_data;
968   tNFA_HANDLE app_handle;
969 
970   if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) != 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   DLOG_IF(INFO, nfc_debug_enabled) << 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   DLOG_IF(INFO, nfc_debug_enabled) << 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