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