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