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