• 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)) !=
865       nullptr) {
866     app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_cmd.pipe);
867 
868     if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
869         ((app_handle == p_evt_data->send_cmd.hci_handle ||
870           p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
871       if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
872         GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
873         return false;
874       }
875 
876       if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
877         nfa_hci_cb.pipe_in_use = p_evt_data->send_cmd.pipe;
878         status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_COMMAND_TYPE,
879                                    p_evt_data->send_cmd.cmd_code,
880                                    p_evt_data->send_cmd.cmd_len,
881                                    p_evt_data->send_cmd.data);
882         if (status == NFA_STATUS_OK) return true;
883       } else {
884         LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not open",
885                                      p_pipe->pipe_id);
886       }
887     } else {
888       LOG(WARNING) << StringPrintf(
889           "nfa_hci_api_send_cmd pipe:%d Owned by different application or "
890           "Destination host is not active",
891           p_pipe->pipe_id);
892     }
893   } else {
894     LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not found",
895                                  p_evt_data->send_cmd.pipe);
896   }
897 
898   evt_data.cmd_sent.status = status;
899 
900   /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
901   nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
902                        p_evt_data->send_cmd.hci_handle);
903   return true;
904 }
905 
906 /*******************************************************************************
907 **
908 ** Function         nfa_hci_api_send_rsp
909 **
910 ** Description      action function to send response on the given pipe
911 **
912 ** Returns          None
913 **
914 *******************************************************************************/
nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA * p_evt_data)915 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data) {
916   tNFA_STATUS status = NFA_STATUS_FAILED;
917   tNFA_HCI_DYN_PIPE* p_pipe;
918   tNFA_HCI_EVT_DATA evt_data;
919   tNFA_HANDLE app_handle;
920 
921   if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_rsp.pipe)) !=
922       nullptr) {
923     app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_rsp.pipe);
924 
925     if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
926         ((app_handle == p_evt_data->send_rsp.hci_handle ||
927           p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
928       if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
929         status = nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
930                                    p_evt_data->send_rsp.response,
931                                    p_evt_data->send_rsp.size,
932                                    p_evt_data->send_rsp.data);
933         if (status == NFA_STATUS_OK) return;
934       } else {
935         LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not open",
936                                      p_pipe->pipe_id);
937       }
938     } else {
939       LOG(WARNING) << StringPrintf(
940           "nfa_hci_api_send_rsp pipe:%d Owned by different application or "
941           "Destination host is not active",
942           p_pipe->pipe_id);
943     }
944   } else {
945     LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not found",
946                                  p_evt_data->send_rsp.pipe);
947   }
948 
949   evt_data.rsp_sent.status = status;
950 
951   /* Send NFA_HCI_RSP_SENT_EVT to notify failure */
952   nfa_hciu_send_to_app(NFA_HCI_RSP_SENT_EVT, &evt_data,
953                        p_evt_data->send_rsp.hci_handle);
954 }
955 
956 /*******************************************************************************
957 **
958 ** Function         nfa_hci_api_send_event
959 **
960 ** Description      action function to send an event to the given pipe
961 **
962 ** Returns          TRUE, if the event is processed
963 **                  FALSE, if event is queued for processing later
964 **
965 *******************************************************************************/
nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA * p_evt_data)966 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data) {
967   tNFA_STATUS status = NFA_STATUS_FAILED;
968   tNFA_HCI_DYN_PIPE* p_pipe;
969   tNFA_HCI_EVT_DATA evt_data;
970   tNFA_HANDLE app_handle;
971 
972   if ((p_pipe = nfa_hciu_find_pipe_by_pid(p_evt_data->send_evt.pipe)) !=
973       nullptr) {
974     app_handle = nfa_hciu_get_pipe_owner(p_evt_data->send_evt.pipe);
975 
976     if ((nfa_hciu_is_active_host(p_pipe->dest_host)) &&
977         ((app_handle == p_evt_data->send_evt.hci_handle ||
978           p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE))) {
979       if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
980         GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
981         return false;
982       }
983 
984       if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
985         status = nfa_hciu_send_msg(
986             p_pipe->pipe_id, NFA_HCI_EVENT_TYPE, p_evt_data->send_evt.evt_code,
987             p_evt_data->send_evt.evt_len, p_evt_data->send_evt.p_evt_buf);
988 
989         if (status == NFA_STATUS_OK) {
990           if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
991             nfa_hci_cb.w4_rsp_evt = true;
992             nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
993           }
994 
995           if (p_evt_data->send_evt.rsp_len) {
996             nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
997             nfa_hci_cb.rsp_buf_size = p_evt_data->send_evt.rsp_len;
998             nfa_hci_cb.p_rsp_buf = p_evt_data->send_evt.p_rsp_buf;
999             if (p_evt_data->send_evt.rsp_timeout) {
1000               nfa_hci_cb.w4_rsp_evt = true;
1001               nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
1002               nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1003                                   p_evt_data->send_evt.rsp_timeout);
1004             } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1005               nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1006                                   p_nfa_hci_cfg->hcp_response_timeout);
1007             }
1008           } else {
1009             if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1010               nfa_hci_cb.pipe_in_use = p_evt_data->send_evt.pipe;
1011               nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1012                                   p_nfa_hci_cfg->hcp_response_timeout);
1013             }
1014             nfa_hci_cb.rsp_buf_size = 0;
1015             nfa_hci_cb.p_rsp_buf = nullptr;
1016           }
1017         }
1018       } else {
1019         LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not open",
1020                                      p_pipe->pipe_id);
1021       }
1022     } else {
1023       LOG(WARNING) << StringPrintf(
1024           "nfa_hci_api_send_event pipe:%d Owned by different application or "
1025           "Destination host is not active",
1026           p_pipe->pipe_id);
1027     }
1028   } else {
1029     LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not found",
1030                                  p_evt_data->send_evt.pipe);
1031   }
1032 
1033   evt_data.evt_sent.status = status;
1034 
1035   /* Send NFC_HCI_EVENT_SENT_EVT to notify status */
1036   nfa_hciu_send_to_app(NFA_HCI_EVENT_SENT_EVT, &evt_data,
1037                        p_evt_data->send_evt.hci_handle);
1038   return true;
1039 }
1040 
1041 /*******************************************************************************
1042 **
1043 ** Function         nfa_hci_api_add_static_pipe
1044 **
1045 ** Description      action function to add static pipe
1046 **
1047 ** Returns          None
1048 **
1049 *******************************************************************************/
nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)1050 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
1051   tNFA_HCI_DYN_GATE* pg;
1052   tNFA_HCI_DYN_PIPE* pp;
1053   tNFA_HCI_EVT_DATA evt_data;
1054 
1055   /* Allocate a proprietary gate */
1056   pg = nfa_hciu_alloc_gate(p_evt_data->add_static_pipe.gate,
1057                            p_evt_data->add_static_pipe.hci_handle);
1058   if (pg != nullptr) {
1059     /* Assign new owner to the gate */
1060     pg->gate_owner = p_evt_data->add_static_pipe.hci_handle;
1061 
1062     /* Add the dynamic pipe to the proprietary gate */
1063     if (nfa_hciu_add_pipe_to_gate(p_evt_data->add_static_pipe.pipe, pg->gate_id,
1064                                   p_evt_data->add_static_pipe.host,
1065                                   p_evt_data->add_static_pipe.gate) !=
1066         NFA_HCI_ANY_OK) {
1067       /* Unable to add the dynamic pipe, so release the gate */
1068       nfa_hciu_release_gate(pg->gate_id);
1069       evt_data.pipe_added.status = NFA_STATUS_FAILED;
1070       nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
1071                            p_evt_data->add_static_pipe.hci_handle);
1072       return;
1073     }
1074     pp = nfa_hciu_find_pipe_by_pid(p_evt_data->add_static_pipe.pipe);
1075     if (pp != nullptr) {
1076       /* This pipe is always opened */
1077       pp->pipe_state = NFA_HCI_PIPE_OPENED;
1078       evt_data.pipe_added.status = NFA_STATUS_OK;
1079       nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
1080                            p_evt_data->add_static_pipe.hci_handle);
1081       return;
1082     }
1083   }
1084   /* Unable to add static pipe */
1085   evt_data.pipe_added.status = NFA_STATUS_FAILED;
1086   nfa_hciu_send_to_app(NFA_HCI_ADD_STATIC_PIPE_EVT, &evt_data,
1087                        p_evt_data->add_static_pipe.hci_handle);
1088 }
1089 
1090 /*******************************************************************************
1091 **
1092 ** Function         nfa_hci_handle_link_mgm_gate_cmd
1093 **
1094 ** Description      This function handles incoming link management gate hci
1095 **                  commands
1096 **
1097 ** Returns          none
1098 **
1099 *******************************************************************************/
nfa_hci_handle_link_mgm_gate_cmd(uint8_t * p_data,uint16_t data_len)1100 void nfa_hci_handle_link_mgm_gate_cmd(uint8_t* p_data, uint16_t data_len) {
1101   uint8_t index;
1102   uint8_t data[2];
1103   uint8_t rsp_len = 0;
1104   uint8_t response = NFA_HCI_ANY_OK;
1105 
1106   if ((nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state != NFA_HCI_PIPE_OPENED) &&
1107       (nfa_hci_cb.inst != NFA_HCI_ANY_OPEN_PIPE)) {
1108     nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
1109                       NFA_HCI_ANY_E_PIPE_NOT_OPENED, 0, nullptr);
1110     return;
1111   }
1112 
1113   switch (nfa_hci_cb.inst) {
1114     case NFA_HCI_ANY_SET_PARAMETER:
1115       if (data_len < 1) {
1116         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1117         break;
1118       }
1119       STREAM_TO_UINT8(index, p_data);
1120 
1121       if (index == 1 && data_len > 2) {
1122         STREAM_TO_UINT16(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors, p_data);
1123       } else
1124         response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
1125       break;
1126 
1127     case NFA_HCI_ANY_GET_PARAMETER:
1128       if (data_len < 1) {
1129         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1130         break;
1131       }
1132       STREAM_TO_UINT8(index, p_data);
1133       if (index == 1) {
1134         data[0] =
1135             (uint8_t)((nfa_hci_cb.cfg.link_mgmt_gate.rec_errors >> 8) & 0x00FF);
1136         data[1] = (uint8_t)(nfa_hci_cb.cfg.link_mgmt_gate.rec_errors & 0x000F);
1137         rsp_len = 2;
1138       } else
1139         response = NFA_HCI_ANY_E_REG_PAR_UNKNOWN;
1140       break;
1141 
1142     case NFA_HCI_ANY_OPEN_PIPE:
1143       data[0] = 0;
1144       rsp_len = 1;
1145       nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_OPENED;
1146       break;
1147 
1148     case NFA_HCI_ANY_CLOSE_PIPE:
1149       nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1150       break;
1151 
1152     default:
1153       response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1154       break;
1155   }
1156 
1157   nfa_hciu_send_msg(NFA_HCI_LINK_MANAGEMENT_PIPE, NFA_HCI_RESPONSE_TYPE,
1158                     response, rsp_len, data);
1159 }
1160 
1161 /*******************************************************************************
1162 **
1163 ** Function         nfa_hci_handle_pipe_open_close_cmd
1164 **
1165 ** Description      This function handles all generic gates (excluding
1166 **                  connectivity gate) commands
1167 **
1168 ** Returns          none
1169 **
1170 *******************************************************************************/
nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE * p_pipe)1171 void nfa_hci_handle_pipe_open_close_cmd(tNFA_HCI_DYN_PIPE* p_pipe) {
1172   uint8_t data[1];
1173   uint8_t rsp_len = 0;
1174   tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1175   tNFA_HCI_DYN_GATE* p_gate;
1176 
1177   if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
1178     if ((p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate)) != nullptr)
1179       data[0] = nfa_hciu_count_open_pipes_on_gate(p_gate);
1180     else
1181       data[0] = 0;
1182 
1183     p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1184     rsp_len = 1;
1185   } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
1186     p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1187   }
1188 
1189   nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
1190                     data);
1191 }
1192 
1193 /*******************************************************************************
1194 **
1195 ** Function         nfa_hci_handle_admin_gate_cmd
1196 **
1197 ** Description      This function handles incoming commands on ADMIN gate
1198 **
1199 ** Returns          none
1200 **
1201 *******************************************************************************/
nfa_hci_handle_admin_gate_cmd(uint8_t * p_data,uint16_t data_len)1202 void nfa_hci_handle_admin_gate_cmd(uint8_t* p_data, uint16_t data_len) {
1203   uint8_t source_host, source_gate, dest_host, dest_gate, pipe;
1204   uint8_t data = 0;
1205   uint8_t rsp_len = 0;
1206   tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1207   tNFA_HCI_DYN_GATE* pgate;
1208   tNFA_HCI_EVT_DATA evt_data;
1209 
1210   switch (nfa_hci_cb.inst) {
1211     case NFA_HCI_ANY_OPEN_PIPE:
1212       nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1213       data = 0;
1214       rsp_len = 1;
1215       break;
1216 
1217     case NFA_HCI_ANY_CLOSE_PIPE:
1218       nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1219       /* Reopen the pipe immediately */
1220       nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
1221                         rsp_len, &data);
1222       nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
1223       nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1224       return;
1225       break;
1226 
1227     case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1228       if (data_len < 5) {
1229         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1230         break;
1231       }
1232       STREAM_TO_UINT8(source_host, p_data);
1233       STREAM_TO_UINT8(source_gate, p_data);
1234       STREAM_TO_UINT8(dest_host, p_data);
1235       STREAM_TO_UINT8(dest_gate, p_data);
1236       STREAM_TO_UINT8(pipe, p_data);
1237 
1238       if ((dest_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) ||
1239           (dest_gate == NFA_HCI_LOOP_BACK_GATE)) {
1240         response = nfa_hciu_add_pipe_to_static_gate(dest_gate, pipe,
1241                                                     source_host, source_gate);
1242       } else {
1243         if ((pgate = nfa_hciu_find_gate_by_gid(dest_gate)) != nullptr) {
1244           /* If the gate is valid, add the pipe to it  */
1245           if (nfa_hciu_check_pipe_between_gates(dest_gate, source_host,
1246                                                 source_gate)) {
1247             /* Already, there is a pipe between these two gates, so will reject
1248              */
1249             response = NFA_HCI_ANY_E_NOK;
1250           } else {
1251             response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
1252                                                  source_gate);
1253             if (response == NFA_HCI_ANY_OK) {
1254               /* Tell the application a pipe was created with its gate */
1255 
1256               evt_data.created.status = NFA_STATUS_OK;
1257               evt_data.created.pipe = pipe;
1258               evt_data.created.source_gate = dest_gate;
1259               evt_data.created.dest_host = source_host;
1260               evt_data.created.dest_gate = source_gate;
1261 
1262               nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
1263                                    pgate->gate_owner);
1264             }
1265           }
1266         } else {
1267           response = NFA_HCI_ANY_E_NOK;
1268           if ((dest_gate >= NFA_HCI_FIRST_PROP_GATE) &&
1269               (dest_gate <= NFA_HCI_LAST_PROP_GATE)) {
1270             if (nfa_hciu_alloc_gate(dest_gate, 0))
1271               response = nfa_hciu_add_pipe_to_gate(pipe, dest_gate, source_host,
1272                                                    source_gate);
1273           }
1274         }
1275       }
1276       break;
1277 
1278     case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1279       if (data_len < 1) {
1280         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1281         break;
1282       }
1283       STREAM_TO_UINT8(pipe, p_data);
1284       response = nfa_hciu_release_pipe(pipe);
1285       break;
1286 
1287     case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1288       if (data_len < 1) {
1289         response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1290         break;
1291       }
1292       STREAM_TO_UINT8(source_host, p_data);
1293 
1294       nfa_hciu_remove_all_pipes_from_host(source_host);
1295 
1296       if (source_host == NFA_HCI_HOST_CONTROLLER) {
1297         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1298         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1299 
1300         /* Reopen the admin pipe immediately */
1301         nfa_hci_cb.app_in_use = NFA_HANDLE_INVALID;
1302         nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1303         return;
1304       } else {
1305         uint8_t host_index = 0;
1306 
1307         if ((source_host == NFA_HCI_HOST_ID_UICC0) ||
1308             (source_host >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
1309           while (host_index < NFA_HCI_MAX_HOST_IN_NETWORK) {
1310             if (nfa_hci_cb.reset_host[host_index] == 0x0) {
1311               nfa_hci_cb.reset_host[host_index] = source_host;
1312               break;
1313             }
1314             host_index++;
1315           }
1316         }
1317       }
1318       break;
1319 
1320     default:
1321       response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1322       break;
1323   }
1324 
1325   nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_RESPONSE_TYPE, response,
1326                     rsp_len, &data);
1327 }
1328 
1329 /*******************************************************************************
1330 **
1331 ** Function         nfa_hci_handle_admin_gate_rsp
1332 **
1333 ** Description      This function handles response received on admin gate
1334 **
1335 ** Returns          none
1336 **
1337 *******************************************************************************/
nfa_hci_handle_admin_gate_rsp(uint8_t * p_data,uint8_t data_len)1338 void nfa_hci_handle_admin_gate_rsp(uint8_t* p_data, uint8_t data_len) {
1339   uint8_t source_host;
1340   uint8_t source_gate = nfa_hci_cb.local_gate_in_use;
1341   uint8_t dest_host = nfa_hci_cb.remote_host_in_use;
1342   uint8_t dest_gate = nfa_hci_cb.remote_gate_in_use;
1343   uint8_t pipe = 0;
1344   tNFA_STATUS status;
1345   tNFA_HCI_EVT_DATA evt_data;
1346   uint8_t default_session[NFA_HCI_SESSION_ID_LEN] = {0xFF, 0xFF, 0xFF, 0xFF,
1347                                                      0xFF, 0xFF, 0xFF, 0xFF};
1348   uint8_t host_count = 0;
1349   uint8_t host_id = 0;
1350   uint32_t os_tick;
1351 
1352   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1353       "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s  App: 0x%04x  Gate: "
1354       "0x%02x  Pipe: 0x%02x",
1355       nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent).c_str(), nfa_hci_cb.app_in_use,
1356       nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
1357 
1358   /* If starting up, handle events here */
1359   if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1360       (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
1361       (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1362       (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1363     if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) {
1364       nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1365       return;
1366     }
1367 
1368     if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
1369       LOG(ERROR) << StringPrintf(
1370           "nfa_hci_handle_admin_gate_rsp - Initialization failed");
1371       nfa_hci_startup_complete(NFA_STATUS_FAILED);
1372       return;
1373     }
1374 
1375     switch (nfa_hci_cb.cmd_sent) {
1376       case NFA_HCI_ANY_SET_PARAMETER:
1377         if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1378           /* Set WHITELIST */
1379           nfa_hciu_send_set_param_cmd(
1380               NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
1381               p_nfa_hci_cfg->num_allowlist_host, p_nfa_hci_cfg->p_allowlist);
1382         } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) {
1383           if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1384               (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
1385             nfa_hci_dh_startup_complete();
1386           if (NFA_GetNCIVersion() == NCI_VERSION_2_0) {
1387             nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
1388             NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
1389             nfa_hci_enable_one_nfcee();
1390           }
1391         }
1392         break;
1393 
1394       case NFA_HCI_ANY_GET_PARAMETER:
1395         if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1396           uint8_t host_index = 0;
1397 
1398           memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);
1399 
1400           host_count = 0;
1401 
1402           /* Collect active host in the Host Network */
1403           while ((host_count < data_len) &&
1404                  (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
1405             host_id = (uint8_t)*p_data++;
1406 
1407             if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
1408                 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
1409               nfa_hci_cb.active_host[host_index] = host_id;
1410               uint8_t index = 0;
1411               while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
1412                 if (nfa_hci_cb.reset_host[index] == host_id) {
1413                   nfa_hci_cb.reset_host[index] = 0x0;
1414                   break;
1415                 }
1416                 index++;
1417               }
1418               host_index++;
1419             }
1420             host_count++;
1421           }
1422 
1423           nfa_hci_startup_complete(NFA_STATUS_OK);
1424         } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1425           /* The only parameter we get when initializing is the session ID.
1426            * Check for match. */
1427           if (data_len >= NFA_HCI_SESSION_ID_LEN &&
1428               !memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
1429                       NFA_HCI_SESSION_ID_LEN)) {
1430             /* Session has not changed, Set WHITELIST */
1431             nfa_hciu_send_set_param_cmd(
1432                 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
1433                 p_nfa_hci_cfg->num_allowlist_host, p_nfa_hci_cfg->p_allowlist);
1434           } else {
1435             /* Something wrong, NVRAM data could be corrupt or first start with
1436              * default session id */
1437             nfa_hciu_send_clear_all_pipe_cmd();
1438             nfa_hci_cb.b_hci_new_sessionId = true;
1439             if (data_len < NFA_HCI_SESSION_ID_LEN) {
1440               android_errorWriteLog(0x534e4554, "124524315");
1441             }
1442           }
1443         }
1444         break;
1445 
1446       case NFA_HCI_ANY_OPEN_PIPE:
1447         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1448         if (nfa_hci_cb.b_hci_netwk_reset) {
1449           /* Something wrong, NVRAM data could be corrupt or first start with
1450            * default session id */
1451           nfa_hciu_send_clear_all_pipe_cmd();
1452           nfa_hci_cb.b_hci_netwk_reset = false;
1453           nfa_hci_cb.b_hci_new_sessionId = true;
1454         } else if (nfa_hci_cb.b_hci_new_sessionId) {
1455           nfa_hci_cb.b_hci_new_sessionId = false;
1456 
1457           /* Session ID is reset, Set New session id */
1458           memcpy(
1459               &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2],
1460               nfa_hci_cb.cfg.admin_gate.session_id,
1461               (NFA_HCI_SESSION_ID_LEN / 2));
1462           os_tick = GKI_get_os_tick_count();
1463           memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1464                  (NFA_HCI_SESSION_ID_LEN / 2));
1465           nfa_hciu_send_set_param_cmd(
1466               NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1467               NFA_HCI_SESSION_ID_LEN,
1468               (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1469         } else {
1470           /* First thing is to get the session ID */
1471           nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1472                                       NFA_HCI_SESSION_IDENTITY_INDEX);
1473         }
1474         break;
1475 
1476       case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1477         nfa_hciu_remove_all_pipes_from_host(0);
1478         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1479         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1480         nfa_hci_cb.nv_write_needed = true;
1481 
1482         /* Open admin */
1483         nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1484         break;
1485     }
1486   } else {
1487     status =
1488         (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
1489 
1490     switch (nfa_hci_cb.cmd_sent) {
1491       case NFA_HCI_ANY_SET_PARAMETER:
1492         if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1493           nfa_hci_api_deregister(nullptr);
1494         else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1495           nfa_hci_api_dealloc_gate(nullptr);
1496         break;
1497 
1498       case NFA_HCI_ANY_GET_PARAMETER:
1499         if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1500           if (data_len >= NFA_HCI_SESSION_ID_LEN &&
1501               !memcmp((uint8_t*)default_session, p_data,
1502                       NFA_HCI_SESSION_ID_LEN)) {
1503             memcpy(&nfa_hci_cb.cfg.admin_gate
1504                         .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
1505                    nfa_hci_cb.cfg.admin_gate.session_id,
1506                    (NFA_HCI_SESSION_ID_LEN / 2));
1507             os_tick = GKI_get_os_tick_count();
1508             memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1509                    (NFA_HCI_SESSION_ID_LEN / 2));
1510             nfa_hci_cb.nv_write_needed = true;
1511             nfa_hciu_send_set_param_cmd(
1512                 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1513                 NFA_HCI_SESSION_ID_LEN,
1514                 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1515           } else {
1516             if (data_len < NFA_HCI_SESSION_ID_LEN) {
1517               android_errorWriteLog(0x534e4554, "124524315");
1518             }
1519             if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1520               nfa_hci_api_deregister(nullptr);
1521             else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1522               nfa_hci_api_dealloc_gate(nullptr);
1523           }
1524         } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1525           evt_data.hosts.status = status;
1526           if (data_len > NFA_HCI_MAX_HOST_IN_NETWORK) {
1527             data_len = NFA_HCI_MAX_HOST_IN_NETWORK;
1528             android_errorWriteLog(0x534e4554, "124524315");
1529           }
1530           evt_data.hosts.num_hosts = data_len;
1531           memcpy(evt_data.hosts.host, p_data, data_len);
1532 
1533           uint8_t host_index = 0;
1534 
1535           memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);
1536 
1537           host_count = 0;
1538           /* Collect active host in the Host Network */
1539           while ((host_count < data_len) &&
1540                  (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
1541             host_id = (uint8_t)*p_data++;
1542 
1543             if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
1544                 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
1545               nfa_hci_cb.active_host[host_index] = host_id;
1546               uint8_t index = 0;
1547               while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
1548                 if (nfa_hci_cb.reset_host[index] == host_id) {
1549                   nfa_hci_cb.reset_host[index] = 0x0;
1550                   break;
1551                 }
1552                 index++;
1553               }
1554               host_index++;
1555             }
1556             host_count++;
1557           }
1558 
1559           if (nfa_hciu_is_no_host_resetting())
1560             nfa_hci_check_pending_api_requests();
1561           nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data,
1562                                nfa_hci_cb.app_in_use);
1563         }
1564         break;
1565 
1566       case NFA_HCI_ADM_CREATE_PIPE:
1567         // p_data should have at least 5 bytes length for pipe info
1568         if (data_len >= 5 && status == NFA_STATUS_OK) {
1569           STREAM_TO_UINT8(source_host, p_data);
1570           STREAM_TO_UINT8(source_gate, p_data);
1571           STREAM_TO_UINT8(dest_host, p_data);
1572           STREAM_TO_UINT8(dest_gate, p_data);
1573           STREAM_TO_UINT8(pipe, p_data);
1574 
1575           /* Sanity check */
1576           if (source_gate != nfa_hci_cb.local_gate_in_use) {
1577             LOG(WARNING) << StringPrintf(
1578                 "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u "
1579                 "got back: %u",
1580                 nfa_hci_cb.local_gate_in_use, source_gate);
1581             break;
1582           }
1583 
1584           nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
1585         } else if (data_len < 5 && status == NFA_STATUS_OK) {
1586           android_errorWriteLog(0x534e4554, "124524315");
1587           status = NFA_STATUS_FAILED;
1588         }
1589 
1590         /* Tell the application his pipe was created or not */
1591         evt_data.created.status = status;
1592         evt_data.created.pipe = pipe;
1593         evt_data.created.source_gate = source_gate;
1594         evt_data.created.dest_host = dest_host;
1595         evt_data.created.dest_gate = dest_gate;
1596 
1597         nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
1598                              nfa_hci_cb.app_in_use);
1599         break;
1600 
1601       case NFA_HCI_ADM_DELETE_PIPE:
1602         if (status == NFA_STATUS_OK) {
1603           nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1604 
1605           /* If only deleting one pipe, tell the app we are done */
1606           if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1607             evt_data.deleted.status = status;
1608             evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1609 
1610             nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1611                                  nfa_hci_cb.app_in_use);
1612           } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1613             nfa_hci_api_deregister(nullptr);
1614           else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1615             nfa_hci_api_dealloc_gate(nullptr);
1616         } else {
1617           /* If only deleting one pipe, tell the app we are done */
1618           if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1619             evt_data.deleted.status = status;
1620             evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1621 
1622             nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1623                                  nfa_hci_cb.app_in_use);
1624           } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) {
1625             nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1626             nfa_hci_api_deregister(nullptr);
1627           } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) {
1628             nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1629             nfa_hci_api_dealloc_gate(nullptr);
1630           }
1631         }
1632         break;
1633 
1634       case NFA_HCI_ANY_OPEN_PIPE:
1635         nfa_hci_cb.cfg.admin_gate.pipe01_state =
1636             status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED;
1637         nfa_hci_cb.nv_write_needed = true;
1638         if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
1639           /* First thing is to get the session ID */
1640           nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1641                                       NFA_HCI_SESSION_IDENTITY_INDEX);
1642         }
1643         break;
1644 
1645       case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1646         nfa_hciu_remove_all_pipes_from_host(0);
1647         nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1648         nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1649         nfa_hci_cb.nv_write_needed = true;
1650         /* Open admin */
1651         nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1652         break;
1653     }
1654   }
1655 }
1656 
1657 /*******************************************************************************
1658 **
1659 ** Function         nfa_hci_handle_admin_gate_evt
1660 **
1661 ** Description      This function handles events received on admin gate
1662 **
1663 ** Returns          none
1664 **
1665 *******************************************************************************/
nfa_hci_handle_admin_gate_evt()1666 void nfa_hci_handle_admin_gate_evt() {
1667   tNFA_HCI_EVT_DATA evt_data;
1668   tNFA_HCI_API_GET_HOST_LIST* p_msg;
1669 
1670   if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) {
1671     LOG(ERROR) << StringPrintf(
1672         "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
1673     return;
1674   }
1675 
1676   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1677       "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
1678   nfa_hci_cb.num_hot_plug_evts++;
1679 
1680   if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1681       (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1682     /* Received Hot Plug evt while waiting for other Host in the network to
1683      * bootup after DH host bootup is complete */
1684     if ((nfa_hci_cb.ee_disable_disc) &&
1685         (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1686         (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1687       /* Received expected number of Hot Plug event(s) before as many number of
1688        * EE DISC REQ Ntf(s) are received */
1689       nfa_sys_stop_timer(&nfa_hci_cb.timer);
1690       /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ
1691        * Ntf(s) */
1692       nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1693                           p_nfa_hci_cfg->hci_netwk_enable_timeout);
1694     }
1695   } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1696              (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
1697     /* Received Hot Plug evt during DH host bootup */
1698     if ((nfa_hci_cb.ee_disable_disc) &&
1699         (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1700         (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1701       /* Received expected number of Hot Plug event(s) before as many number of
1702        * EE DISC REQ Ntf(s) are received */
1703       nfa_hci_cb.w4_hci_netwk_init = false;
1704     }
1705   } else {
1706     /* Received Hot Plug evt on UICC self reset */
1707     evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
1708     /* Notify all registered application with the HOT_PLUG_EVT */
1709     nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data);
1710 
1711     /* Send Get Host List after receiving any pending response */
1712     p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
1713         sizeof(tNFA_HCI_API_GET_HOST_LIST));
1714     if (p_msg != nullptr) {
1715       p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
1716       /* Set Invalid handle to identify this Get Host List command is internal
1717        */
1718       p_msg->hci_handle = NFA_HANDLE_INVALID;
1719 
1720       nfa_sys_sendmsg(p_msg);
1721     }
1722   }
1723 }
1724 
1725 /*******************************************************************************
1726 **
1727 ** Function         nfa_hci_handle_dyn_pipe_pkt
1728 **
1729 ** Description      This function handles data received via dynamic pipe
1730 **
1731 ** Returns          none
1732 **
1733 *******************************************************************************/
nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id,uint8_t * p_data,uint16_t data_len)1734 void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data,
1735                                  uint16_t data_len) {
1736   tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1737   tNFA_HCI_DYN_GATE* p_gate;
1738 
1739   if (p_pipe == nullptr) {
1740     /* Invalid pipe ID */
1741     LOG(ERROR) << StringPrintf("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",
1742                                pipe_id);
1743     if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1744       nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1745                         nullptr);
1746     return;
1747   }
1748 
1749   if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
1750     nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe);
1751   } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1752     nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe);
1753   } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
1754     nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe);
1755   } else {
1756     p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
1757     if (p_gate == nullptr) {
1758       LOG(ERROR) << StringPrintf(
1759           "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",
1760           p_pipe->local_gate);
1761       if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1762         nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1763                           nullptr);
1764       return;
1765     }
1766 
1767     /* Check if data packet is a command, response or event */
1768     switch (nfa_hci_cb.type) {
1769       case NFA_HCI_COMMAND_TYPE:
1770         nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_pipe);
1771         break;
1772 
1773       case NFA_HCI_RESPONSE_TYPE:
1774         nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_pipe);
1775         break;
1776 
1777       case NFA_HCI_EVENT_TYPE:
1778         nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
1779         break;
1780     }
1781   }
1782 }
1783 
1784 /*******************************************************************************
1785 **
1786 ** Function         nfa_hci_handle_identity_mgmt_gate_pkt
1787 **
1788 ** Description      This function handles incoming Identity Management gate hci
1789 **                  commands
1790 **
1791 ** Returns          none
1792 **
1793 *******************************************************************************/
nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t * p_data,tNFA_HCI_DYN_PIPE * p_pipe)1794 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
1795                                                   tNFA_HCI_DYN_PIPE* p_pipe) {
1796   uint8_t data[20];
1797   uint8_t index;
1798   uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
1799   uint16_t rsp_len = 0;
1800   uint8_t* p_rsp = data;
1801   tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1802 
1803   /* We never send commands on a pipe where the local gate is the identity
1804    * management
1805    * gate, so only commands should be processed.
1806    */
1807   if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return;
1808 
1809   switch (nfa_hci_cb.inst) {
1810     case NFA_HCI_ANY_GET_PARAMETER:
1811       index = *(p_data++);
1812       if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
1813         switch (index) {
1814           case NFA_HCI_VERSION_SW_INDEX:
1815             data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF);
1816             data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF);
1817             data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF);
1818             rsp_len = 3;
1819             break;
1820 
1821           case NFA_HCI_HCI_VERSION_INDEX:
1822             data[0] = NFA_HCI_VERSION;
1823             rsp_len = 1;
1824             break;
1825 
1826           case NFA_HCI_VERSION_HW_INDEX:
1827             data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF);
1828             data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF);
1829             data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF);
1830             rsp_len = 3;
1831             break;
1832 
1833           case NFA_HCI_VENDOR_NAME_INDEX:
1834             memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME));
1835             rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME);
1836             break;
1837 
1838           case NFA_HCI_MODEL_ID_INDEX:
1839             data[0] = NFA_HCI_MODEL_ID;
1840             rsp_len = 1;
1841             break;
1842 
1843           case NFA_HCI_GATES_LIST_INDEX:
1844             gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
1845             gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
1846             gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
1847             num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]);
1848             rsp_len = num_gates + 3;
1849             p_rsp = gate_rsp;
1850             break;
1851 
1852           default:
1853             response = NFA_HCI_ANY_E_NOK;
1854             break;
1855         }
1856       } else {
1857         response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
1858       }
1859       break;
1860 
1861     case NFA_HCI_ANY_OPEN_PIPE:
1862       data[0] = 0;
1863       rsp_len = 1;
1864       p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1865       break;
1866 
1867     case NFA_HCI_ANY_CLOSE_PIPE:
1868       p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1869       break;
1870 
1871     default:
1872       response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1873       break;
1874   }
1875 
1876   nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
1877                     p_rsp);
1878 }
1879 
1880 /*******************************************************************************
1881 **
1882 ** Function         nfa_hci_handle_generic_gate_cmd
1883 **
1884 ** Description      This function handles all generic gates (excluding
1885 **                  connectivity gate) commands
1886 **
1887 ** Returns          none
1888 **
1889 *******************************************************************************/
nfa_hci_handle_generic_gate_cmd(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1890 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
1891                                             tNFA_HCI_DYN_PIPE* p_pipe) {
1892   tNFA_HCI_EVT_DATA evt_data;
1893   tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id);
1894 
1895   switch (nfa_hci_cb.inst) {
1896     case NFA_HCI_ANY_SET_PARAMETER:
1897       evt_data.registry.pipe = p_pipe->pipe_id;
1898       evt_data.registry.index = *p_data++;
1899       if (data_len > 0) data_len--;
1900       evt_data.registry.data_len = data_len;
1901 
1902       memcpy(evt_data.registry.reg_data, p_data, data_len);
1903 
1904       nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
1905       break;
1906 
1907     case NFA_HCI_ANY_GET_PARAMETER:
1908       evt_data.registry.pipe = p_pipe->pipe_id;
1909       evt_data.registry.index = *p_data;
1910       evt_data.registry.data_len = 0;
1911 
1912       nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
1913       break;
1914 
1915     case NFA_HCI_ANY_OPEN_PIPE:
1916       nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1917 
1918       evt_data.opened.pipe = p_pipe->pipe_id;
1919       evt_data.opened.status = NFA_STATUS_OK;
1920 
1921       nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
1922       break;
1923 
1924     case NFA_HCI_ANY_CLOSE_PIPE:
1925       nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1926 
1927       evt_data.closed.pipe = p_pipe->pipe_id;
1928       evt_data.opened.status = NFA_STATUS_OK;
1929 
1930       nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
1931       break;
1932 
1933     default:
1934       /* Could be application specific command, pass it on */
1935       evt_data.cmd_rcvd.status = NFA_STATUS_OK;
1936       evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;
1937       ;
1938       evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
1939       evt_data.cmd_rcvd.cmd_len = data_len;
1940 
1941       if (data_len <= NFA_MAX_HCI_CMD_LEN)
1942         memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len);
1943 
1944       nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
1945       break;
1946   }
1947 }
1948 
1949 /*******************************************************************************
1950 **
1951 ** Function         nfa_hci_handle_generic_gate_rsp
1952 **
1953 ** Description      This function handles all generic gates (excluding
1954 **                  connectivity) response
1955 **
1956 ** Returns          none
1957 **
1958 *******************************************************************************/
nfa_hci_handle_generic_gate_rsp(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1959 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
1960                                             tNFA_HCI_DYN_PIPE* p_pipe) {
1961   tNFA_HCI_EVT_DATA evt_data;
1962   tNFA_STATUS status = NFA_STATUS_OK;
1963 
1964   if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED;
1965 
1966   if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) {
1967     if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1968 
1969     nfa_hci_cb.nv_write_needed = true;
1970     /* Tell application */
1971     evt_data.opened.status = status;
1972     evt_data.opened.pipe = p_pipe->pipe_id;
1973 
1974     nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
1975                          nfa_hci_cb.app_in_use);
1976   } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) {
1977     p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1978 
1979     nfa_hci_cb.nv_write_needed = true;
1980     /* Tell application */
1981     evt_data.opened.status = status;
1982     ;
1983     evt_data.opened.pipe = p_pipe->pipe_id;
1984 
1985     nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
1986                          nfa_hci_cb.app_in_use);
1987   } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
1988     /* Tell application */
1989     evt_data.registry.status = status;
1990     evt_data.registry.pipe = p_pipe->pipe_id;
1991     evt_data.registry.data_len = data_len;
1992     evt_data.registry.index = nfa_hci_cb.param_in_use;
1993 
1994     memcpy(evt_data.registry.reg_data, p_data, data_len);
1995 
1996     nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data,
1997                          nfa_hci_cb.app_in_use);
1998   } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) {
1999     /* Tell application */
2000     evt_data.registry.status = status;
2001     ;
2002     evt_data.registry.pipe = p_pipe->pipe_id;
2003 
2004     nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data,
2005                          nfa_hci_cb.app_in_use);
2006   } else {
2007     /* Could be a response to application specific command sent, pass it on */
2008     evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2009     evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2010     ;
2011     evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2012     evt_data.rsp_rcvd.rsp_len = data_len;
2013 
2014     if (data_len <= NFA_MAX_HCI_RSP_LEN)
2015       memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2016 
2017     nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2018                          nfa_hci_cb.app_in_use);
2019   }
2020 }
2021 
2022 /*******************************************************************************
2023 **
2024 ** Function         nfa_hci_handle_connectivity_gate_pkt
2025 **
2026 ** Description      This function handles incoming connectivity gate packets
2027 **
2028 ** Returns          none
2029 **
2030 *******************************************************************************/
nfa_hci_handle_connectivity_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2031 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
2032                                                  uint16_t data_len,
2033                                                  tNFA_HCI_DYN_PIPE* p_pipe) {
2034   tNFA_HCI_EVT_DATA evt_data;
2035 
2036   if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2037     switch (nfa_hci_cb.inst) {
2038       case NFA_HCI_ANY_OPEN_PIPE:
2039       case NFA_HCI_ANY_CLOSE_PIPE:
2040         nfa_hci_handle_pipe_open_close_cmd(p_pipe);
2041         break;
2042 
2043       case NFA_HCI_CON_PRO_HOST_REQUEST:
2044         /* A request to the DH to activate another host. This is not supported
2045          * for */
2046         /* now, we will implement it when the spec is clearer and UICCs need it.
2047          */
2048         nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
2049                           NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
2050         break;
2051 
2052       default:
2053         nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
2054                           NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
2055         break;
2056     }
2057   } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2058     if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2059         (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2060       p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2061     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2062       p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2063 
2064     /* Could be a response to application specific command sent, pass it on */
2065     evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2066     evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2067     ;
2068     evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2069     evt_data.rsp_rcvd.rsp_len = data_len;
2070 
2071     if (data_len <= NFA_MAX_HCI_RSP_LEN)
2072       memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2073 
2074     nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2075                          nfa_hci_cb.app_in_use);
2076   } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2077     evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2078     evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2079     evt_data.rcvd_evt.evt_len = data_len;
2080     evt_data.rcvd_evt.p_evt_buf = p_data;
2081 
2082     /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2083     nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT,
2084                                                      &evt_data);
2085   }
2086 }
2087 
2088 /*******************************************************************************
2089 **
2090 ** Function         nfa_hci_handle_loopback_gate_pkt
2091 **
2092 ** Description      This function handles incoming loopback gate hci events
2093 **
2094 ** Returns          none
2095 **
2096 *******************************************************************************/
nfa_hci_handle_loopback_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2097 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
2098                                              tNFA_HCI_DYN_PIPE* p_pipe) {
2099   uint8_t data[1];
2100   uint8_t rsp_len = 0;
2101   tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
2102   tNFA_HCI_EVT_DATA evt_data;
2103 
2104   /* Check if data packet is a command, response or event */
2105   if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2106     if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
2107       data[0] = 0;
2108       rsp_len = 1;
2109       p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2110     } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
2111       p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2112     } else
2113       response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
2114 
2115     nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
2116                       data);
2117   } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2118     if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2119         (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2120       p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2121     else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2122       p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2123 
2124     /* Could be a response to application specific command sent, pass it on */
2125     evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2126     evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2127     ;
2128     evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2129     evt_data.rsp_rcvd.rsp_len = data_len;
2130 
2131     if (data_len <= NFA_MAX_HCI_RSP_LEN)
2132       memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2133 
2134     nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2135                          nfa_hci_cb.app_in_use);
2136   } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2137     if (nfa_hci_cb.w4_rsp_evt) {
2138       evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2139       evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2140       evt_data.rcvd_evt.evt_len = data_len;
2141       evt_data.rcvd_evt.p_evt_buf = p_data;
2142 
2143       nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data,
2144                            nfa_hci_cb.app_in_use);
2145     } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) {
2146       /* Send back the same data we got */
2147       nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE,
2148                         NFA_HCI_EVT_POST_DATA, data_len, p_data);
2149     }
2150   }
2151 }
2152 
2153 /*******************************************************************************
2154 **
2155 ** Function         nfa_hci_handle_generic_gate_evt
2156 **
2157 ** Description      This function handles incoming Generic gate hci events
2158 **
2159 ** Returns          none
2160 **
2161 *******************************************************************************/
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)2162 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
2163                                             tNFA_HCI_DYN_GATE* p_gate,
2164                                             tNFA_HCI_DYN_PIPE* p_pipe) {
2165   tNFA_HCI_EVT_DATA evt_data;
2166 
2167   evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2168   evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2169   evt_data.rcvd_evt.evt_len = data_len;
2170 
2171   if (nfa_hci_cb.assembly_failed)
2172     evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
2173   else
2174     evt_data.rcvd_evt.status = NFA_STATUS_OK;
2175 
2176   evt_data.rcvd_evt.p_evt_buf = p_data;
2177   nfa_hci_cb.rsp_buf_size = 0;
2178   nfa_hci_cb.p_rsp_buf = nullptr;
2179 
2180   /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2181   nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
2182 }
2183