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 strlcpy(&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_new_sessionId = 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 if (nfa_hci_cb.b_hci_netwk_reset) {
1427 /* Something wrong, NVRAM data could be corrupt or first start with
1428 * default session id */
1429 nfa_hciu_send_clear_all_pipe_cmd();
1430 nfa_hci_cb.b_hci_netwk_reset = false;
1431 nfa_hci_cb.b_hci_new_sessionId = true;
1432 } else if (nfa_hci_cb.b_hci_new_sessionId) {
1433 nfa_hci_cb.b_hci_new_sessionId = false;
1434
1435 /* Session ID is reset, Set New session id */
1436 memcpy(
1437 &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2],
1438 nfa_hci_cb.cfg.admin_gate.session_id,
1439 (NFA_HCI_SESSION_ID_LEN / 2));
1440 os_tick = GKI_get_os_tick_count();
1441 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1442 (NFA_HCI_SESSION_ID_LEN / 2));
1443 nfa_hciu_send_set_param_cmd(
1444 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1445 NFA_HCI_SESSION_ID_LEN,
1446 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1447 } else {
1448 /* First thing is to get the session ID */
1449 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1450 NFA_HCI_SESSION_IDENTITY_INDEX);
1451 }
1452 break;
1453
1454 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1455 nfa_hciu_remove_all_pipes_from_host(0);
1456 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1457 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1458 nfa_hci_cb.nv_write_needed = true;
1459
1460 /* Open admin */
1461 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1462 break;
1463 }
1464 } else {
1465 status =
1466 (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
1467
1468 switch (nfa_hci_cb.cmd_sent) {
1469 case NFA_HCI_ANY_SET_PARAMETER:
1470 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1471 nfa_hci_api_deregister(nullptr);
1472 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1473 nfa_hci_api_dealloc_gate(nullptr);
1474 break;
1475
1476 case NFA_HCI_ANY_GET_PARAMETER:
1477 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1478 if (data_len >= NFA_HCI_SESSION_ID_LEN &&
1479 !memcmp((uint8_t*)default_session, p_data,
1480 NFA_HCI_SESSION_ID_LEN)) {
1481 memcpy(&nfa_hci_cb.cfg.admin_gate
1482 .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
1483 nfa_hci_cb.cfg.admin_gate.session_id,
1484 (NFA_HCI_SESSION_ID_LEN / 2));
1485 os_tick = GKI_get_os_tick_count();
1486 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1487 (NFA_HCI_SESSION_ID_LEN / 2));
1488 nfa_hci_cb.nv_write_needed = true;
1489 nfa_hciu_send_set_param_cmd(
1490 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1491 NFA_HCI_SESSION_ID_LEN,
1492 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1493 } else {
1494 if (data_len < NFA_HCI_SESSION_ID_LEN) {
1495 android_errorWriteLog(0x534e4554, "124524315");
1496 }
1497 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1498 nfa_hci_api_deregister(nullptr);
1499 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1500 nfa_hci_api_dealloc_gate(nullptr);
1501 }
1502 } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1503 evt_data.hosts.status = status;
1504 if (data_len > NFA_HCI_MAX_HOST_IN_NETWORK) {
1505 data_len = NFA_HCI_MAX_HOST_IN_NETWORK;
1506 android_errorWriteLog(0x534e4554, "124524315");
1507 }
1508 evt_data.hosts.num_hosts = data_len;
1509 memcpy(evt_data.hosts.host, p_data, data_len);
1510
1511 uint8_t host_index = 0;
1512
1513 memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);
1514
1515 host_count = 0;
1516 /* Collect active host in the Host Network */
1517 while ((host_count < data_len) &&
1518 (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
1519 host_id = (uint8_t)*p_data++;
1520
1521 if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
1522 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
1523 nfa_hci_cb.active_host[host_index] = host_id;
1524 uint8_t index = 0;
1525 while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
1526 if (nfa_hci_cb.reset_host[index] == host_id) {
1527 nfa_hci_cb.reset_host[index] = 0x0;
1528 break;
1529 }
1530 index++;
1531 }
1532 host_index++;
1533 }
1534 host_count++;
1535 }
1536
1537 if (nfa_hciu_is_no_host_resetting())
1538 nfa_hci_check_pending_api_requests();
1539 nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data,
1540 nfa_hci_cb.app_in_use);
1541 }
1542 break;
1543
1544 case NFA_HCI_ADM_CREATE_PIPE:
1545 // p_data should have at least 5 bytes length for pipe info
1546 if (data_len >= 5 && status == NFA_STATUS_OK) {
1547 STREAM_TO_UINT8(source_host, p_data);
1548 STREAM_TO_UINT8(source_gate, p_data);
1549 STREAM_TO_UINT8(dest_host, p_data);
1550 STREAM_TO_UINT8(dest_gate, p_data);
1551 STREAM_TO_UINT8(pipe, p_data);
1552
1553 /* Sanity check */
1554 if (source_gate != nfa_hci_cb.local_gate_in_use) {
1555 LOG(WARNING) << StringPrintf(
1556 "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u "
1557 "got back: %u",
1558 nfa_hci_cb.local_gate_in_use, source_gate);
1559 break;
1560 }
1561
1562 nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
1563 } else if (data_len < 5 && status == NFA_STATUS_OK) {
1564 android_errorWriteLog(0x534e4554, "124524315");
1565 status = NFA_STATUS_FAILED;
1566 }
1567
1568 /* Tell the application his pipe was created or not */
1569 evt_data.created.status = status;
1570 evt_data.created.pipe = pipe;
1571 evt_data.created.source_gate = source_gate;
1572 evt_data.created.dest_host = dest_host;
1573 evt_data.created.dest_gate = dest_gate;
1574
1575 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
1576 nfa_hci_cb.app_in_use);
1577 break;
1578
1579 case NFA_HCI_ADM_DELETE_PIPE:
1580 if (status == NFA_STATUS_OK) {
1581 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1582
1583 /* If only deleting one pipe, tell the app we are done */
1584 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1585 evt_data.deleted.status = status;
1586 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1587
1588 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1589 nfa_hci_cb.app_in_use);
1590 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1591 nfa_hci_api_deregister(nullptr);
1592 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1593 nfa_hci_api_dealloc_gate(nullptr);
1594 } else {
1595 /* If only deleting one pipe, tell the app we are done */
1596 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1597 evt_data.deleted.status = status;
1598 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1599
1600 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1601 nfa_hci_cb.app_in_use);
1602 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) {
1603 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1604 nfa_hci_api_deregister(nullptr);
1605 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) {
1606 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1607 nfa_hci_api_dealloc_gate(nullptr);
1608 }
1609 }
1610 break;
1611
1612 case NFA_HCI_ANY_OPEN_PIPE:
1613 nfa_hci_cb.cfg.admin_gate.pipe01_state =
1614 status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED;
1615 nfa_hci_cb.nv_write_needed = true;
1616 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
1617 /* First thing is to get the session ID */
1618 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1619 NFA_HCI_SESSION_IDENTITY_INDEX);
1620 }
1621 break;
1622
1623 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1624 nfa_hciu_remove_all_pipes_from_host(0);
1625 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1626 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1627 nfa_hci_cb.nv_write_needed = true;
1628 /* Open admin */
1629 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1630 break;
1631 }
1632 }
1633 }
1634
1635 /*******************************************************************************
1636 **
1637 ** Function nfa_hci_handle_admin_gate_evt
1638 **
1639 ** Description This function handles events received on admin gate
1640 **
1641 ** Returns none
1642 **
1643 *******************************************************************************/
nfa_hci_handle_admin_gate_evt()1644 void nfa_hci_handle_admin_gate_evt() {
1645 tNFA_HCI_EVT_DATA evt_data;
1646 tNFA_HCI_API_GET_HOST_LIST* p_msg;
1647
1648 if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) {
1649 LOG(ERROR) << StringPrintf(
1650 "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
1651 return;
1652 }
1653
1654 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1655 "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
1656 nfa_hci_cb.num_hot_plug_evts++;
1657
1658 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1659 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1660 /* Received Hot Plug evt while waiting for other Host in the network to
1661 * bootup after DH host bootup is complete */
1662 if ((nfa_hci_cb.ee_disable_disc) &&
1663 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1664 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1665 /* Received expected number of Hot Plug event(s) before as many number of
1666 * EE DISC REQ Ntf(s) are received */
1667 nfa_sys_stop_timer(&nfa_hci_cb.timer);
1668 /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ
1669 * Ntf(s) */
1670 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1671 p_nfa_hci_cfg->hci_netwk_enable_timeout);
1672 }
1673 } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1674 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
1675 /* Received Hot Plug evt during DH host bootup */
1676 if ((nfa_hci_cb.ee_disable_disc) &&
1677 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1678 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1679 /* Received expected number of Hot Plug event(s) before as many number of
1680 * EE DISC REQ Ntf(s) are received */
1681 nfa_hci_cb.w4_hci_netwk_init = false;
1682 }
1683 } else {
1684 /* Received Hot Plug evt on UICC self reset */
1685 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
1686 /* Notify all registered application with the HOT_PLUG_EVT */
1687 nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data);
1688
1689 /* Send Get Host List after receiving any pending response */
1690 p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
1691 sizeof(tNFA_HCI_API_GET_HOST_LIST));
1692 if (p_msg != nullptr) {
1693 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
1694 /* Set Invalid handle to identify this Get Host List command is internal
1695 */
1696 p_msg->hci_handle = NFA_HANDLE_INVALID;
1697
1698 nfa_sys_sendmsg(p_msg);
1699 }
1700 }
1701 }
1702
1703 /*******************************************************************************
1704 **
1705 ** Function nfa_hci_handle_dyn_pipe_pkt
1706 **
1707 ** Description This function handles data received via dynamic pipe
1708 **
1709 ** Returns none
1710 **
1711 *******************************************************************************/
nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id,uint8_t * p_data,uint16_t data_len)1712 void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data,
1713 uint16_t data_len) {
1714 tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1715 tNFA_HCI_DYN_GATE* p_gate;
1716
1717 if (p_pipe == nullptr) {
1718 /* Invalid pipe ID */
1719 LOG(ERROR) << StringPrintf("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",
1720 pipe_id);
1721 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1722 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1723 nullptr);
1724 return;
1725 }
1726
1727 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
1728 nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe);
1729 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1730 nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe);
1731 } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
1732 nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe);
1733 } else {
1734 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
1735 if (p_gate == nullptr) {
1736 LOG(ERROR) << StringPrintf(
1737 "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",
1738 p_pipe->local_gate);
1739 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1740 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1741 nullptr);
1742 return;
1743 }
1744
1745 /* Check if data packet is a command, response or event */
1746 switch (nfa_hci_cb.type) {
1747 case NFA_HCI_COMMAND_TYPE:
1748 nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_pipe);
1749 break;
1750
1751 case NFA_HCI_RESPONSE_TYPE:
1752 nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_pipe);
1753 break;
1754
1755 case NFA_HCI_EVENT_TYPE:
1756 nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
1757 break;
1758 }
1759 }
1760 }
1761
1762 /*******************************************************************************
1763 **
1764 ** Function nfa_hci_handle_identity_mgmt_gate_pkt
1765 **
1766 ** Description This function handles incoming Identity Management gate hci
1767 ** commands
1768 **
1769 ** Returns none
1770 **
1771 *******************************************************************************/
nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t * p_data,tNFA_HCI_DYN_PIPE * p_pipe)1772 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
1773 tNFA_HCI_DYN_PIPE* p_pipe) {
1774 uint8_t data[20];
1775 uint8_t index;
1776 uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
1777 uint16_t rsp_len = 0;
1778 uint8_t* p_rsp = data;
1779 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1780
1781 /* We never send commands on a pipe where the local gate is the identity
1782 * management
1783 * gate, so only commands should be processed.
1784 */
1785 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return;
1786
1787 switch (nfa_hci_cb.inst) {
1788 case NFA_HCI_ANY_GET_PARAMETER:
1789 index = *(p_data++);
1790 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
1791 switch (index) {
1792 case NFA_HCI_VERSION_SW_INDEX:
1793 data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF);
1794 data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF);
1795 data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF);
1796 rsp_len = 3;
1797 break;
1798
1799 case NFA_HCI_HCI_VERSION_INDEX:
1800 data[0] = NFA_HCI_VERSION;
1801 rsp_len = 1;
1802 break;
1803
1804 case NFA_HCI_VERSION_HW_INDEX:
1805 data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF);
1806 data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF);
1807 data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF);
1808 rsp_len = 3;
1809 break;
1810
1811 case NFA_HCI_VENDOR_NAME_INDEX:
1812 memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME));
1813 rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME);
1814 break;
1815
1816 case NFA_HCI_MODEL_ID_INDEX:
1817 data[0] = NFA_HCI_MODEL_ID;
1818 rsp_len = 1;
1819 break;
1820
1821 case NFA_HCI_GATES_LIST_INDEX:
1822 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
1823 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
1824 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
1825 num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]);
1826 rsp_len = num_gates + 3;
1827 p_rsp = gate_rsp;
1828 break;
1829
1830 default:
1831 response = NFA_HCI_ANY_E_NOK;
1832 break;
1833 }
1834 } else {
1835 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
1836 }
1837 break;
1838
1839 case NFA_HCI_ANY_OPEN_PIPE:
1840 data[0] = 0;
1841 rsp_len = 1;
1842 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1843 break;
1844
1845 case NFA_HCI_ANY_CLOSE_PIPE:
1846 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1847 break;
1848
1849 default:
1850 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1851 break;
1852 }
1853
1854 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
1855 p_rsp);
1856 }
1857
1858 /*******************************************************************************
1859 **
1860 ** Function nfa_hci_handle_generic_gate_cmd
1861 **
1862 ** Description This function handles all generic gates (excluding
1863 ** connectivity gate) commands
1864 **
1865 ** Returns none
1866 **
1867 *******************************************************************************/
nfa_hci_handle_generic_gate_cmd(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1868 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
1869 tNFA_HCI_DYN_PIPE* p_pipe) {
1870 tNFA_HCI_EVT_DATA evt_data;
1871 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id);
1872
1873 switch (nfa_hci_cb.inst) {
1874 case NFA_HCI_ANY_SET_PARAMETER:
1875 evt_data.registry.pipe = p_pipe->pipe_id;
1876 evt_data.registry.index = *p_data++;
1877 if (data_len > 0) data_len--;
1878 evt_data.registry.data_len = data_len;
1879
1880 memcpy(evt_data.registry.reg_data, p_data, data_len);
1881
1882 nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
1883 break;
1884
1885 case NFA_HCI_ANY_GET_PARAMETER:
1886 evt_data.registry.pipe = p_pipe->pipe_id;
1887 evt_data.registry.index = *p_data;
1888 evt_data.registry.data_len = 0;
1889
1890 nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
1891 break;
1892
1893 case NFA_HCI_ANY_OPEN_PIPE:
1894 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1895
1896 evt_data.opened.pipe = p_pipe->pipe_id;
1897 evt_data.opened.status = NFA_STATUS_OK;
1898
1899 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
1900 break;
1901
1902 case NFA_HCI_ANY_CLOSE_PIPE:
1903 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1904
1905 evt_data.closed.pipe = p_pipe->pipe_id;
1906 evt_data.opened.status = NFA_STATUS_OK;
1907
1908 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
1909 break;
1910
1911 default:
1912 /* Could be application specific command, pass it on */
1913 evt_data.cmd_rcvd.status = NFA_STATUS_OK;
1914 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;
1915 ;
1916 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
1917 evt_data.cmd_rcvd.cmd_len = data_len;
1918
1919 if (data_len <= NFA_MAX_HCI_CMD_LEN)
1920 memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len);
1921
1922 nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
1923 break;
1924 }
1925 }
1926
1927 /*******************************************************************************
1928 **
1929 ** Function nfa_hci_handle_generic_gate_rsp
1930 **
1931 ** Description This function handles all generic gates (excluding
1932 ** connectivity) response
1933 **
1934 ** Returns none
1935 **
1936 *******************************************************************************/
nfa_hci_handle_generic_gate_rsp(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1937 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
1938 tNFA_HCI_DYN_PIPE* p_pipe) {
1939 tNFA_HCI_EVT_DATA evt_data;
1940 tNFA_STATUS status = NFA_STATUS_OK;
1941
1942 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED;
1943
1944 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) {
1945 if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1946
1947 nfa_hci_cb.nv_write_needed = true;
1948 /* Tell application */
1949 evt_data.opened.status = status;
1950 evt_data.opened.pipe = p_pipe->pipe_id;
1951
1952 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
1953 nfa_hci_cb.app_in_use);
1954 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) {
1955 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1956
1957 nfa_hci_cb.nv_write_needed = true;
1958 /* Tell application */
1959 evt_data.opened.status = status;
1960 ;
1961 evt_data.opened.pipe = p_pipe->pipe_id;
1962
1963 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
1964 nfa_hci_cb.app_in_use);
1965 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
1966 /* Tell application */
1967 evt_data.registry.status = status;
1968 evt_data.registry.pipe = p_pipe->pipe_id;
1969 evt_data.registry.data_len = data_len;
1970 evt_data.registry.index = nfa_hci_cb.param_in_use;
1971
1972 memcpy(evt_data.registry.reg_data, p_data, data_len);
1973
1974 nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data,
1975 nfa_hci_cb.app_in_use);
1976 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) {
1977 /* Tell application */
1978 evt_data.registry.status = status;
1979 ;
1980 evt_data.registry.pipe = p_pipe->pipe_id;
1981
1982 nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data,
1983 nfa_hci_cb.app_in_use);
1984 } else {
1985 /* Could be a response to application specific command sent, pass it on */
1986 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
1987 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
1988 ;
1989 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
1990 evt_data.rsp_rcvd.rsp_len = data_len;
1991
1992 if (data_len <= NFA_MAX_HCI_RSP_LEN)
1993 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
1994
1995 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
1996 nfa_hci_cb.app_in_use);
1997 }
1998 }
1999
2000 /*******************************************************************************
2001 **
2002 ** Function nfa_hci_handle_connectivity_gate_pkt
2003 **
2004 ** Description This function handles incoming connectivity gate packets
2005 **
2006 ** Returns none
2007 **
2008 *******************************************************************************/
nfa_hci_handle_connectivity_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2009 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
2010 uint16_t data_len,
2011 tNFA_HCI_DYN_PIPE* p_pipe) {
2012 tNFA_HCI_EVT_DATA evt_data;
2013
2014 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2015 switch (nfa_hci_cb.inst) {
2016 case NFA_HCI_ANY_OPEN_PIPE:
2017 case NFA_HCI_ANY_CLOSE_PIPE:
2018 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
2019 break;
2020
2021 case NFA_HCI_CON_PRO_HOST_REQUEST:
2022 /* A request to the DH to activate another host. This is not supported
2023 * for */
2024 /* now, we will implement it when the spec is clearer and UICCs need it.
2025 */
2026 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
2027 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
2028 break;
2029
2030 default:
2031 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
2032 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
2033 break;
2034 }
2035 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2036 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2037 (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2038 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2039 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2040 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2041
2042 /* Could be a response to application specific command sent, pass it on */
2043 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2044 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2045 ;
2046 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2047 evt_data.rsp_rcvd.rsp_len = data_len;
2048
2049 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2050 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2051
2052 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2053 nfa_hci_cb.app_in_use);
2054 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2055 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2056 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2057 evt_data.rcvd_evt.evt_len = data_len;
2058 evt_data.rcvd_evt.p_evt_buf = p_data;
2059
2060 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2061 nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT,
2062 &evt_data);
2063 }
2064 }
2065
2066 /*******************************************************************************
2067 **
2068 ** Function nfa_hci_handle_loopback_gate_pkt
2069 **
2070 ** Description This function handles incoming loopback gate hci events
2071 **
2072 ** Returns none
2073 **
2074 *******************************************************************************/
nfa_hci_handle_loopback_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2075 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
2076 tNFA_HCI_DYN_PIPE* p_pipe) {
2077 uint8_t data[1];
2078 uint8_t rsp_len = 0;
2079 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
2080 tNFA_HCI_EVT_DATA evt_data;
2081
2082 /* Check if data packet is a command, response or event */
2083 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2084 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
2085 data[0] = 0;
2086 rsp_len = 1;
2087 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2088 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
2089 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2090 } else
2091 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
2092
2093 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
2094 data);
2095 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2096 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2097 (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2098 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2099 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2100 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2101
2102 /* Could be a response to application specific command sent, pass it on */
2103 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2104 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2105 ;
2106 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2107 evt_data.rsp_rcvd.rsp_len = data_len;
2108
2109 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2110 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2111
2112 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2113 nfa_hci_cb.app_in_use);
2114 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2115 if (nfa_hci_cb.w4_rsp_evt) {
2116 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2117 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2118 evt_data.rcvd_evt.evt_len = data_len;
2119 evt_data.rcvd_evt.p_evt_buf = p_data;
2120
2121 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data,
2122 nfa_hci_cb.app_in_use);
2123 } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) {
2124 /* Send back the same data we got */
2125 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE,
2126 NFA_HCI_EVT_POST_DATA, data_len, p_data);
2127 }
2128 }
2129 }
2130
2131 /*******************************************************************************
2132 **
2133 ** Function nfa_hci_handle_generic_gate_evt
2134 **
2135 ** Description This function handles incoming Generic gate hci events
2136 **
2137 ** Returns none
2138 **
2139 *******************************************************************************/
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)2140 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
2141 tNFA_HCI_DYN_GATE* p_gate,
2142 tNFA_HCI_DYN_PIPE* p_pipe) {
2143 tNFA_HCI_EVT_DATA evt_data;
2144
2145 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2146 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2147 evt_data.rcvd_evt.evt_len = data_len;
2148
2149 if (nfa_hci_cb.assembly_failed)
2150 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
2151 else
2152 evt_data.rcvd_evt.status = NFA_STATUS_OK;
2153
2154 evt_data.rcvd_evt.p_evt_buf = p_data;
2155 nfa_hci_cb.rsp_buf_size = 0;
2156 nfa_hci_cb.p_rsp_buf = nullptr;
2157
2158 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2159 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
2160 }
2161