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