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