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
34 using android::base::StringPrintf;
35
36 /* Static local functions */
37 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data);
38 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data);
39 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data);
40 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data);
41 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
42 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data);
43 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
44 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
45 static void nfa_hci_api_close_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
46 static void nfa_hci_api_delete_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
47 static bool nfa_hci_api_send_event(tNFA_HCI_EVENT_DATA* p_evt_data);
48 static bool nfa_hci_api_send_cmd(tNFA_HCI_EVENT_DATA* p_evt_data);
49 static void nfa_hci_api_send_rsp(tNFA_HCI_EVENT_DATA* p_evt_data);
50 static void nfa_hci_api_add_static_pipe(tNFA_HCI_EVENT_DATA* p_evt_data);
51
52 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
53 tNFA_HCI_DYN_PIPE* p_pipe);
54 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
55 tNFA_HCI_DYN_PIPE* p_pipe);
56 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
57 uint16_t data_len,
58 tNFA_HCI_DYN_PIPE* p_pipe);
59 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
60 tNFA_HCI_DYN_PIPE* p_pipe);
61 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
62 tNFA_HCI_DYN_PIPE* p_pipe);
63 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
64 tNFA_HCI_DYN_GATE* p_gate,
65 tNFA_HCI_DYN_PIPE* p_pipe);
66
67 /*******************************************************************************
68 **
69 ** Function nfa_hci_check_pending_api_requests
70 **
71 ** Description This function handles pending API requests
72 **
73 ** Returns none
74 **
75 *******************************************************************************/
nfa_hci_check_pending_api_requests(void)76 void nfa_hci_check_pending_api_requests(void) {
77 NFC_HDR* p_msg;
78 tNFA_HCI_EVENT_DATA* p_evt_data;
79 bool b_free;
80
81 /* If busy, or API queue is empty, then exit */
82 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
83 ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_host_reset_api_q)) ==
84 nullptr))
85 return;
86
87 /* Process API request */
88 p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
89
90 /* Save the application handle */
91 nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
92
93 b_free = true;
94 switch (p_msg->event) {
95 case NFA_HCI_API_CREATE_PIPE_EVT:
96 if (nfa_hci_api_create_pipe(p_evt_data) == false) b_free = false;
97 break;
98
99 case NFA_HCI_API_GET_REGISTRY_EVT:
100 if (nfa_hci_api_get_reg_value(p_evt_data) == false) b_free = false;
101 break;
102
103 case NFA_HCI_API_SET_REGISTRY_EVT:
104 if (nfa_hci_api_set_reg_value(p_evt_data) == false) b_free = false;
105 break;
106
107 case NFA_HCI_API_SEND_CMD_EVT:
108 if (nfa_hci_api_send_cmd(p_evt_data) == false) b_free = false;
109 break;
110 case NFA_HCI_API_SEND_EVENT_EVT:
111 if (nfa_hci_api_send_event(p_evt_data) == false) b_free = false;
112 break;
113 }
114
115 if (b_free) GKI_freebuf(p_msg);
116 }
117
118 /*******************************************************************************
119 **
120 ** Function nfa_hci_check_api_requests
121 **
122 ** Description This function handles API requests
123 **
124 ** Returns none
125 **
126 *******************************************************************************/
nfa_hci_check_api_requests(void)127 void nfa_hci_check_api_requests(void) {
128 NFC_HDR* p_msg;
129 tNFA_HCI_EVENT_DATA* p_evt_data;
130
131 for (;;) {
132 /* If busy, or API queue is empty, then exit */
133 if ((nfa_hci_cb.hci_state != NFA_HCI_STATE_IDLE) ||
134 ((p_msg = (NFC_HDR*)GKI_dequeue(&nfa_hci_cb.hci_api_q)) == nullptr))
135 break;
136
137 /* Process API request */
138 p_evt_data = (tNFA_HCI_EVENT_DATA*)p_msg;
139
140 /* Save the application handle */
141 nfa_hci_cb.app_in_use = p_evt_data->comm.hci_handle;
142
143 switch (p_msg->event) {
144 case NFA_HCI_API_REGISTER_APP_EVT:
145 nfa_hci_api_register(p_evt_data);
146 break;
147
148 case NFA_HCI_API_DEREGISTER_APP_EVT:
149 nfa_hci_api_deregister(p_evt_data);
150 break;
151
152 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
153 nfa_hci_api_get_gate_pipe_list(p_evt_data);
154 break;
155
156 case NFA_HCI_API_ALLOC_GATE_EVT:
157 nfa_hci_api_alloc_gate(p_evt_data);
158 break;
159
160 case NFA_HCI_API_DEALLOC_GATE_EVT:
161 nfa_hci_api_dealloc_gate(p_evt_data);
162 break;
163
164 case NFA_HCI_API_GET_HOST_LIST_EVT:
165 nfa_hci_api_get_host_list(p_evt_data);
166 break;
167
168 case NFA_HCI_API_GET_REGISTRY_EVT:
169 if (nfa_hci_api_get_reg_value(p_evt_data) == false) continue;
170 break;
171
172 case NFA_HCI_API_SET_REGISTRY_EVT:
173 if (nfa_hci_api_set_reg_value(p_evt_data) == false) continue;
174 break;
175
176 case NFA_HCI_API_CREATE_PIPE_EVT:
177 if (nfa_hci_api_create_pipe(p_evt_data) == false) continue;
178 break;
179
180 case NFA_HCI_API_OPEN_PIPE_EVT:
181 nfa_hci_api_open_pipe(p_evt_data);
182 break;
183
184 case NFA_HCI_API_CLOSE_PIPE_EVT:
185 nfa_hci_api_close_pipe(p_evt_data);
186 break;
187
188 case NFA_HCI_API_DELETE_PIPE_EVT:
189 nfa_hci_api_delete_pipe(p_evt_data);
190 break;
191
192 case NFA_HCI_API_SEND_CMD_EVT:
193 if (nfa_hci_api_send_cmd(p_evt_data) == false) continue;
194 break;
195
196 case NFA_HCI_API_SEND_RSP_EVT:
197 nfa_hci_api_send_rsp(p_evt_data);
198 break;
199
200 case NFA_HCI_API_SEND_EVENT_EVT:
201 if (nfa_hci_api_send_event(p_evt_data) == false) continue;
202 break;
203
204 case NFA_HCI_API_ADD_STATIC_PIPE_EVT:
205 nfa_hci_api_add_static_pipe(p_evt_data);
206 break;
207
208 default:
209 LOG(ERROR) << StringPrintf("Unknown event: 0x%04x", p_msg->event);
210 break;
211 }
212
213 GKI_freebuf(p_msg);
214 }
215 }
216
217 /*******************************************************************************
218 **
219 ** Function nfa_hci_api_register
220 **
221 ** Description action function to register the events for the given AID
222 **
223 ** Returns None
224 **
225 *******************************************************************************/
nfa_hci_api_register(tNFA_HCI_EVENT_DATA * p_evt_data)226 static void nfa_hci_api_register(tNFA_HCI_EVENT_DATA* p_evt_data) {
227 tNFA_HCI_EVT_DATA evt_data;
228 char* p_app_name = p_evt_data->app_info.app_name;
229 tNFA_HCI_CBACK* p_cback = p_evt_data->app_info.p_cback;
230 int xx, yy;
231 uint8_t num_gates = 0, num_pipes = 0;
232 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
233
234 /* First, see if the application was already registered */
235 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
236 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
237 !strncmp(p_app_name, &nfa_hci_cb.cfg.reg_app_names[xx][0],
238 strlen(p_app_name))) {
239 LOG(VERBOSE) << StringPrintf("nfa_hci_api_register (%s) Reusing: %u",
240 p_app_name, xx);
241 break;
242 }
243 }
244
245 if (xx != NFA_HCI_MAX_APP_CB) {
246 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
247 /* The app was registered, find the number of gates and pipes associated to
248 * the app */
249
250 for (yy = 0; yy < NFA_HCI_MAX_GATE_CB; yy++, pg++) {
251 if (pg->gate_owner == nfa_hci_cb.app_in_use) {
252 num_gates++;
253 num_pipes += nfa_hciu_count_pipes_on_gate(pg);
254 }
255 }
256 } else {
257 /* Not registered, look for a free entry */
258 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
259 if (nfa_hci_cb.cfg.reg_app_names[xx][0] == 0) {
260 memset(&nfa_hci_cb.cfg.reg_app_names[xx][0], 0,
261 sizeof(nfa_hci_cb.cfg.reg_app_names[xx]));
262 strlcpy(&nfa_hci_cb.cfg.reg_app_names[xx][0], p_app_name,
263 NFA_MAX_HCI_APP_NAME_LEN);
264 nfa_hci_cb.nv_write_needed = true;
265 LOG(VERBOSE) << StringPrintf("nfa_hci_api_register (%s) Allocated: %u",
266 p_app_name, xx);
267 break;
268 }
269 }
270
271 if (xx == NFA_HCI_MAX_APP_CB) {
272 LOG(ERROR) << StringPrintf("nfa_hci_api_register (%s) NO ENTRIES",
273 p_app_name);
274
275 evt_data.hci_register.status = NFA_STATUS_FAILED;
276 p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
277 return;
278 }
279 }
280
281 evt_data.hci_register.num_pipes = num_pipes;
282 evt_data.hci_register.num_gates = num_gates;
283 nfa_hci_cb.p_app_cback[xx] = p_cback;
284
285 nfa_hci_cb.cfg.b_send_conn_evts[xx] = p_evt_data->app_info.b_send_conn_evts;
286
287 evt_data.hci_register.hci_handle = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
288
289 evt_data.hci_register.status = NFA_STATUS_OK;
290
291 /* notify NFA_HCI_REGISTER_EVT to the application */
292 p_evt_data->app_info.p_cback(NFA_HCI_REGISTER_EVT, &evt_data);
293 }
294
295 /*******************************************************************************
296 **
297 ** Function nfa_hci_api_deregister
298 **
299 ** Description action function to deregister the given application
300 **
301 ** Returns None
302 **
303 *******************************************************************************/
nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA * p_evt_data)304 void nfa_hci_api_deregister(tNFA_HCI_EVENT_DATA* p_evt_data) {
305 tNFA_HCI_EVT_DATA evt_data;
306 tNFA_HCI_CBACK* p_cback = nullptr;
307 int xx;
308 tNFA_HCI_DYN_PIPE* p_pipe;
309 tNFA_HCI_DYN_GATE* p_gate;
310
311 /* If needed, find the application registration handle */
312 if (p_evt_data != nullptr) {
313 for (xx = 0; xx < NFA_HCI_MAX_APP_CB; xx++) {
314 if ((nfa_hci_cb.cfg.reg_app_names[xx][0] != 0) &&
315 !strncmp(p_evt_data->app_info.app_name,
316 &nfa_hci_cb.cfg.reg_app_names[xx][0],
317 strlen(p_evt_data->app_info.app_name))) {
318 LOG(VERBOSE) << StringPrintf("nfa_hci_api_deregister (%s) inx: %u",
319 p_evt_data->app_info.app_name, xx);
320 break;
321 }
322 }
323
324 if (xx == NFA_HCI_MAX_APP_CB) {
325 LOG(WARNING) << StringPrintf("Unknown app: %s",
326 p_evt_data->app_info.app_name);
327 return;
328 }
329 nfa_hci_cb.app_in_use = (tNFA_HANDLE)(xx | NFA_HANDLE_GROUP_HCI);
330 p_cback = nfa_hci_cb.p_app_cback[xx];
331 } else {
332 nfa_sys_stop_timer(&nfa_hci_cb.timer);
333 /* We are recursing through deleting all the app's pipes and gates */
334 p_cback = nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK];
335 }
336
337 /* See if any pipe is owned by this app */
338 if (nfa_hciu_find_pipe_by_owner(nfa_hci_cb.app_in_use) == nullptr) {
339 /* No pipes, release all gates owned by this app */
340 while ((p_gate = nfa_hciu_find_gate_by_owner(nfa_hci_cb.app_in_use)) !=
341 nullptr)
342 nfa_hciu_release_gate(p_gate->gate_id);
343
344 memset(&nfa_hci_cb.cfg
345 .reg_app_names[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK][0],
346 0, NFA_MAX_HCI_APP_NAME_LEN + 1);
347 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = nullptr;
348
349 nfa_hci_cb.nv_write_needed = true;
350
351 evt_data.hci_deregister.status = NFC_STATUS_OK;
352
353 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
354 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
355
356 /* notify NFA_HCI_DEREGISTER_EVT to the application */
357 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
358 } else if ((p_pipe = nfa_hciu_find_active_pipe_by_owner(
359 nfa_hci_cb.app_in_use)) == nullptr) {
360 /* No pipes, release all gates owned by this app */
361 while ((p_gate = nfa_hciu_find_gate_with_nopipes_by_owner(
362 nfa_hci_cb.app_in_use)) != nullptr)
363 nfa_hciu_release_gate(p_gate->gate_id);
364
365 nfa_hci_cb.p_app_cback[nfa_hci_cb.app_in_use & NFA_HANDLE_MASK] = nullptr;
366
367 nfa_hci_cb.nv_write_needed = true;
368
369 evt_data.hci_deregister.status = NFC_STATUS_FAILED;
370
371 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
372 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
373
374 /* notify NFA_HCI_DEREGISTER_EVT to the application */
375 if (p_cback) p_cback(NFA_HCI_DEREGISTER_EVT, &evt_data);
376 } else {
377 /* Delete all active pipes created for the application before de registering
378 **/
379 nfa_hci_cb.hci_state = NFA_HCI_STATE_APP_DEREGISTER;
380
381 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
382 }
383 }
384
385 /*******************************************************************************
386 **
387 ** Function nfa_hci_api_get_gate_pipe_list
388 **
389 ** Description action function to get application allocated gates and
390 ** application created pipes
391 **
392 ** Returns None
393 **
394 *******************************************************************************/
nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA * p_evt_data)395 static void nfa_hci_api_get_gate_pipe_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
396 tNFA_HCI_EVT_DATA evt_data;
397 int xx, yy;
398 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
399 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
400
401 evt_data.gates_pipes.num_gates = 0;
402 evt_data.gates_pipes.num_pipes = 0;
403
404 for (xx = 0; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
405 if (pg->gate_owner == p_evt_data->get_gate_pipe_list.hci_handle) {
406 evt_data.gates_pipes.gate[evt_data.gates_pipes.num_gates++] = pg->gate_id;
407
408 pp = nfa_hci_cb.cfg.dyn_pipes;
409
410 /* Loop through looking for a match */
411 for (yy = 0; yy < NFA_HCI_MAX_PIPE_CB; yy++, pp++) {
412 if (pp->local_gate == pg->gate_id)
413 evt_data.gates_pipes.pipe[evt_data.gates_pipes.num_pipes++] =
414 *(tNFA_HCI_PIPE_INFO*)pp;
415 }
416 }
417 }
418
419 evt_data.gates_pipes.num_uicc_created_pipes = 0;
420 /* Loop through all pipes that are connected to connectivity gate */
421 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
422 xx++, pp++) {
423 if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
424 memcpy(&evt_data.gates_pipes.uicc_created_pipe
425 [evt_data.gates_pipes.num_uicc_created_pipes++],
426 pp, sizeof(tNFA_HCI_PIPE_INFO));
427 } else if (pp->pipe_id != 0 && pp->local_gate == NFA_HCI_LOOP_BACK_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 >= NFA_HCI_FIRST_DYNAMIC_PIPE &&
432 pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE && pp->pipe_id &&
433 pp->local_gate >= NFA_HCI_FIRST_PROP_GATE &&
434 pp->local_gate <= NFA_HCI_LAST_PROP_GATE) {
435 for (yy = 0, pg = nfa_hci_cb.cfg.dyn_gates; yy < NFA_HCI_MAX_GATE_CB;
436 yy++, pg++) {
437 if (pp->local_gate == pg->gate_id) {
438 if (!pg->gate_owner)
439 memcpy(&evt_data.gates_pipes.uicc_created_pipe
440 [evt_data.gates_pipes.num_uicc_created_pipes++],
441 pp, sizeof(tNFA_HCI_PIPE_INFO));
442 break;
443 }
444 }
445 }
446 }
447
448 evt_data.gates_pipes.status = NFA_STATUS_OK;
449
450 /* notify NFA_HCI_GET_GATE_PIPE_LIST_EVT to the application */
451 nfa_hciu_send_to_app(NFA_HCI_GET_GATE_PIPE_LIST_EVT, &evt_data,
452 p_evt_data->get_gate_pipe_list.hci_handle);
453 }
454
455 /*******************************************************************************
456 **
457 ** Function nfa_hci_api_alloc_gate
458 **
459 ** Description action function to allocate gate
460 **
461 ** Returns None
462 **
463 *******************************************************************************/
nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)464 static void nfa_hci_api_alloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
465 tNFA_HANDLE app_handle = p_evt_data->comm.hci_handle;
466 tNFA_HCI_EVT_DATA evt_data;
467 tNFA_HCI_DYN_GATE* p_gate;
468
469 p_gate = nfa_hciu_alloc_gate(p_evt_data->gate_info.gate, app_handle);
470
471 if (p_gate) {
472 if (!p_gate->gate_owner) {
473 /* No app owns the gate yet */
474 p_gate->gate_owner = app_handle;
475 } else if (p_gate->gate_owner != app_handle) {
476 /* Some other app owns the gate */
477 p_gate = nullptr;
478 LOG(ERROR) << StringPrintf("The Gate (0X%02x) already taken!",
479 p_evt_data->gate_info.gate);
480 }
481 }
482
483 evt_data.allocated.gate = p_gate ? p_gate->gate_id : 0;
484 evt_data.allocated.status = p_gate ? NFA_STATUS_OK : NFA_STATUS_FAILED;
485
486 /* notify NFA_HCI_ALLOCATE_GATE_EVT to the application */
487 nfa_hciu_send_to_app(NFA_HCI_ALLOCATE_GATE_EVT, &evt_data, app_handle);
488 }
489
490 /*******************************************************************************
491 **
492 ** Function nfa_hci_api_dealloc_gate
493 **
494 ** Description action function to deallocate the given generic gate
495 **
496 ** Returns None
497 **
498 *******************************************************************************/
nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA * p_evt_data)499 void nfa_hci_api_dealloc_gate(tNFA_HCI_EVENT_DATA* p_evt_data) {
500 tNFA_HCI_EVT_DATA evt_data;
501 uint8_t gate_id;
502 tNFA_HCI_DYN_GATE* p_gate;
503 tNFA_HCI_DYN_PIPE* p_pipe;
504 tNFA_HANDLE app_handle;
505
506 /* p_evt_data may be NULL if we are recursively deleting pipes */
507 if (p_evt_data) {
508 gate_id = p_evt_data->gate_dealloc.gate;
509 app_handle = p_evt_data->gate_dealloc.hci_handle;
510
511 } else {
512 nfa_sys_stop_timer(&nfa_hci_cb.timer);
513 gate_id = nfa_hci_cb.local_gate_in_use;
514 app_handle = nfa_hci_cb.app_in_use;
515 }
516
517 evt_data.deallocated.gate = gate_id;
518 ;
519
520 p_gate = nfa_hciu_find_gate_by_gid(gate_id);
521
522 if (p_gate == nullptr) {
523 evt_data.deallocated.status = NFA_STATUS_UNKNOWN_GID;
524 } else if (p_gate->gate_owner != app_handle) {
525 evt_data.deallocated.status = NFA_STATUS_FAILED;
526 } else {
527 /* See if any pipe is owned by this app */
528 if (nfa_hciu_find_pipe_on_gate(p_gate->gate_id) == nullptr) {
529 nfa_hciu_release_gate(p_gate->gate_id);
530
531 nfa_hci_cb.nv_write_needed = true;
532 evt_data.deallocated.status = NFA_STATUS_OK;
533
534 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
535 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
536 } else if ((p_pipe = nfa_hciu_find_active_pipe_on_gate(p_gate->gate_id)) ==
537 nullptr) {
538 /* UICC is not active at the moment and cannot delete the pipe */
539 nfa_hci_cb.nv_write_needed = true;
540 evt_data.deallocated.status = NFA_STATUS_FAILED;
541
542 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
543 nfa_hci_cb.hci_state = NFA_HCI_STATE_IDLE;
544 } else {
545 /* Delete pipes on the gate */
546 nfa_hci_cb.local_gate_in_use = gate_id;
547 nfa_hci_cb.app_in_use = app_handle;
548 nfa_hci_cb.hci_state = NFA_HCI_STATE_REMOVE_GATE;
549
550 nfa_hciu_send_delete_pipe_cmd(p_pipe->pipe_id);
551 return;
552 }
553 }
554
555 nfa_hciu_send_to_app(NFA_HCI_DEALLOCATE_GATE_EVT, &evt_data, app_handle);
556 }
557
558 /*******************************************************************************
559 **
560 ** Function nfa_hci_api_get_host_list
561 **
562 ** Description action function to get the host list from HCI network
563 **
564 ** Returns None
565 **
566 *******************************************************************************/
nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA * p_evt_data)567 static void nfa_hci_api_get_host_list(tNFA_HCI_EVENT_DATA* p_evt_data) {
568 uint8_t app_inx = p_evt_data->get_host_list.hci_handle & NFA_HANDLE_MASK;
569
570 nfa_hci_cb.app_in_use = p_evt_data->get_host_list.hci_handle;
571
572 /* Send Get Host List command on "Internal request" or requested by registered
573 * application with valid handle and callback function */
574 if ((nfa_hci_cb.app_in_use == NFA_HANDLE_INVALID) ||
575 ((app_inx < NFA_HCI_MAX_APP_CB) &&
576 (nfa_hci_cb.p_app_cback[app_inx] != nullptr))) {
577 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE, NFA_HCI_HOST_LIST_INDEX);
578 }
579 }
580
581 /*******************************************************************************
582 **
583 ** Function nfa_hci_api_create_pipe
584 **
585 ** Description action function to create a pipe
586 **
587 ** Returns TRUE, if the command is processed
588 ** FALSE, if command is queued for processing later
589 **
590 *******************************************************************************/
nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)591 static bool nfa_hci_api_create_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
592 tNFA_HCI_DYN_GATE* p_gate =
593 nfa_hciu_find_gate_by_gid(p_evt_data->create_pipe.source_gate);
594 tNFA_HCI_EVT_DATA evt_data;
595 bool report_failed = false;
596
597 /* Verify that the app owns the gate that the pipe is being created on */
598 if ((p_gate == nullptr) ||
599 (p_gate->gate_owner != p_evt_data->create_pipe.hci_handle)) {
600 report_failed = true;
601 LOG(ERROR) << StringPrintf(
602 "nfa_hci_api_create_pipe Cannot create pipe! APP: 0x%02x does not own "
603 "the gate:0x%x",
604 p_evt_data->create_pipe.hci_handle,
605 p_evt_data->create_pipe.source_gate);
606 } else if (nfa_hciu_check_pipe_between_gates(
607 p_evt_data->create_pipe.source_gate,
608 p_evt_data->create_pipe.dest_host,
609 p_evt_data->create_pipe.dest_gate)) {
610 report_failed = true;
611 LOG(ERROR) << StringPrintf(
612 "nfa_hci_api_create_pipe : Cannot create multiple pipe between the "
613 "same two gates!");
614 }
615
616 if (report_failed) {
617 evt_data.created.source_gate = p_evt_data->create_pipe.source_gate;
618 evt_data.created.status = NFA_STATUS_FAILED;
619
620 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
621 p_evt_data->open_pipe.hci_handle);
622 } else {
623 if (nfa_hciu_is_host_reseting(p_evt_data->create_pipe.dest_gate)) {
624 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
625 return false;
626 }
627
628 nfa_hci_cb.local_gate_in_use = p_evt_data->create_pipe.source_gate;
629 nfa_hci_cb.remote_gate_in_use = p_evt_data->create_pipe.dest_gate;
630 nfa_hci_cb.remote_host_in_use = p_evt_data->create_pipe.dest_host;
631 nfa_hci_cb.app_in_use = p_evt_data->create_pipe.hci_handle;
632
633 nfa_hciu_send_create_pipe_cmd(p_evt_data->create_pipe.source_gate,
634 p_evt_data->create_pipe.dest_host,
635 p_evt_data->create_pipe.dest_gate);
636 }
637 return true;
638 }
639
640 /*******************************************************************************
641 **
642 ** Function nfa_hci_api_open_pipe
643 **
644 ** Description action function to open a pipe
645 **
646 ** Returns None
647 **
648 *******************************************************************************/
nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA * p_evt_data)649 static void nfa_hci_api_open_pipe(tNFA_HCI_EVENT_DATA* p_evt_data) {
650 tNFA_HCI_EVT_DATA evt_data;
651 tNFA_HCI_DYN_PIPE* p_pipe =
652 nfa_hciu_find_pipe_by_pid(p_evt_data->open_pipe.pipe);
653 tNFA_HCI_DYN_GATE* p_gate = nullptr;
654
655 if (p_pipe != nullptr) p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
656
657 if ((p_pipe != nullptr) && (p_gate != nullptr) &&
658 (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
659 (p_gate->gate_owner == p_evt_data->open_pipe.hci_handle)) {
660 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
661 nfa_hciu_send_open_pipe_cmd(p_evt_data->open_pipe.pipe);
662 } else {
663 evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
664 evt_data.opened.status = NFA_STATUS_OK;
665
666 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
667 p_evt_data->open_pipe.hci_handle);
668 }
669 } else {
670 evt_data.opened.pipe = p_evt_data->open_pipe.pipe;
671 evt_data.opened.status = NFA_STATUS_FAILED;
672
673 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
674 p_evt_data->open_pipe.hci_handle);
675 }
676 }
677
678 /*******************************************************************************
679 **
680 ** Function nfa_hci_api_get_reg_value
681 **
682 ** Description action function to get the reg value of the specified index
683 **
684 ** Returns TRUE, if the command is processed
685 ** FALSE, if command is queued for processing later
686 **
687 *******************************************************************************/
nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)688 static bool nfa_hci_api_get_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
689 tNFA_HCI_DYN_PIPE* p_pipe =
690 nfa_hciu_find_pipe_by_pid(p_evt_data->get_registry.pipe);
691 tNFA_HCI_DYN_GATE* p_gate;
692 tNFA_STATUS status = NFA_STATUS_FAILED;
693 tNFA_HCI_EVT_DATA evt_data;
694
695 if (p_pipe != nullptr) {
696 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
697
698 if ((p_gate != nullptr) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
699 (p_gate->gate_owner == p_evt_data->get_registry.hci_handle)) {
700 nfa_hci_cb.app_in_use = p_evt_data->get_registry.hci_handle;
701
702 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
703 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
704 return false;
705 }
706
707 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
708 LOG(WARNING) << StringPrintf(
709 "nfa_hci_api_get_reg_value pipe:%d not open",
710 p_evt_data->get_registry.pipe);
711 } else {
712 status = nfa_hciu_send_get_param_cmd(p_evt_data->get_registry.pipe,
713 p_evt_data->get_registry.reg_inx);
714 if (status == NFA_STATUS_OK) return true;
715 }
716 }
717 }
718
719 evt_data.cmd_sent.status = status;
720
721 /* Send NFA_HCI_CMD_SENT_EVT to notify failure */
722 nfa_hciu_send_to_app(NFA_HCI_CMD_SENT_EVT, &evt_data,
723 p_evt_data->get_registry.hci_handle);
724 return true;
725 }
726
727 /*******************************************************************************
728 **
729 ** Function nfa_hci_api_set_reg_value
730 **
731 ** Description action function to set the reg value at specified index
732 **
733 ** Returns TRUE, if the command is processed
734 ** FALSE, if command is queued for processing later
735 **
736 *******************************************************************************/
nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA * p_evt_data)737 static bool nfa_hci_api_set_reg_value(tNFA_HCI_EVENT_DATA* p_evt_data) {
738 tNFA_HCI_DYN_PIPE* p_pipe =
739 nfa_hciu_find_pipe_by_pid(p_evt_data->set_registry.pipe);
740 tNFA_HCI_DYN_GATE* p_gate;
741 tNFA_STATUS status = NFA_STATUS_FAILED;
742 tNFA_HCI_EVT_DATA evt_data;
743
744 if (p_pipe != nullptr) {
745 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
746
747 if ((p_gate != nullptr) && (nfa_hciu_is_active_host(p_pipe->dest_host)) &&
748 (p_gate->gate_owner == p_evt_data->set_registry.hci_handle)) {
749 nfa_hci_cb.app_in_use = p_evt_data->set_registry.hci_handle;
750
751 if (nfa_hciu_is_host_reseting(p_pipe->dest_host)) {
752 GKI_enqueue(&nfa_hci_cb.hci_host_reset_api_q, (NFC_HDR*)p_evt_data);
753 return false;
754 }
755
756 if (p_pipe->pipe_state == NFA_HCI_PIPE_CLOSED) {
757 LOG(WARNING) << StringPrintf(
758 "nfa_hci_api_set_reg_value pipe:%d not open",
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("nfa_hci_api_send_cmd pipe:%d not open",
882 p_pipe->pipe_id);
883 }
884 } else {
885 LOG(WARNING) << StringPrintf(
886 "nfa_hci_api_send_cmd pipe:%d Owned by different application or "
887 "Destination host is not active",
888 p_pipe->pipe_id);
889 }
890 } else {
891 LOG(WARNING) << StringPrintf("nfa_hci_api_send_cmd pipe:%d not found",
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("nfa_hci_api_send_rsp pipe:%d not open",
933 p_pipe->pipe_id);
934 }
935 } else {
936 LOG(WARNING) << StringPrintf(
937 "nfa_hci_api_send_rsp pipe:%d Owned by different application or "
938 "Destination host is not active",
939 p_pipe->pipe_id);
940 }
941 } else {
942 LOG(WARNING) << StringPrintf("nfa_hci_api_send_rsp pipe:%d not found",
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("nfa_hci_api_send_event pipe:%d not open",
1017 p_pipe->pipe_id);
1018 }
1019 } else {
1020 LOG(WARNING) << StringPrintf(
1021 "nfa_hci_api_send_event pipe:%d Owned by different application or "
1022 "Destination host is not active",
1023 p_pipe->pipe_id);
1024 }
1025 } else {
1026 LOG(WARNING) << StringPrintf("nfa_hci_api_send_event pipe:%d not found",
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 "nfa_hci_handle_admin_gate_rsp - LastCmdSent: %s App: 0x%04x Gate: "
1351 "0x%02x Pipe: 0x%02x",
1352 nfa_hciu_instr_2_str(nfa_hci_cb.cmd_sent).c_str(), nfa_hci_cb.app_in_use,
1353 nfa_hci_cb.local_gate_in_use, nfa_hci_cb.pipe_in_use);
1354
1355 /* If starting up, handle events here */
1356 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1357 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE) ||
1358 (nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1359 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1360 if (nfa_hci_cb.inst == NFA_HCI_ANY_E_PIPE_NOT_OPENED) {
1361 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1362 return;
1363 }
1364
1365 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) {
1366 LOG(ERROR) << StringPrintf(
1367 "nfa_hci_handle_admin_gate_rsp - Initialization failed");
1368 nfa_hci_startup_complete(NFA_STATUS_FAILED);
1369 return;
1370 }
1371
1372 switch (nfa_hci_cb.cmd_sent) {
1373 case NFA_HCI_ANY_SET_PARAMETER:
1374 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1375 /* Set WHITELIST */
1376 nfa_hciu_send_set_param_cmd(
1377 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
1378 p_nfa_hci_cfg->num_allowlist_host, p_nfa_hci_cfg->p_allowlist);
1379 } else if (nfa_hci_cb.param_in_use == NFA_HCI_WHITELIST_INDEX) {
1380 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1381 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE))
1382 nfa_hci_dh_startup_complete();
1383 if (NFA_GetNCIVersion() >= NCI_VERSION_2_0) {
1384 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_NETWK_ENABLE;
1385 NFA_EeGetInfo(&nfa_hci_cb.num_nfcee, nfa_hci_cb.ee_info);
1386 nfa_hci_enable_one_nfcee();
1387 }
1388 }
1389 break;
1390
1391 case NFA_HCI_ANY_GET_PARAMETER:
1392 if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1393 uint8_t host_index = 0;
1394
1395 memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);
1396
1397 host_count = 0;
1398
1399 /* Collect active host in the Host Network */
1400 while ((host_count < data_len) &&
1401 (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
1402 host_id = (uint8_t)*p_data++;
1403
1404 if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
1405 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
1406 nfa_hci_cb.active_host[host_index] = host_id;
1407 uint8_t index = 0;
1408 while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
1409 if (nfa_hci_cb.reset_host[index] == host_id) {
1410 nfa_hci_cb.reset_host[index] = 0x0;
1411 break;
1412 }
1413 index++;
1414 }
1415 host_index++;
1416 }
1417 host_count++;
1418 }
1419
1420 nfa_hci_startup_complete(NFA_STATUS_OK);
1421 } else if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1422 /* The only parameter we get when initializing is the session ID.
1423 * Check for match. */
1424 if (data_len >= NFA_HCI_SESSION_ID_LEN &&
1425 !memcmp((uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id, p_data,
1426 NFA_HCI_SESSION_ID_LEN)) {
1427 /* Session has not changed, Set WHITELIST */
1428 nfa_hciu_send_set_param_cmd(
1429 NFA_HCI_ADMIN_PIPE, NFA_HCI_WHITELIST_INDEX,
1430 p_nfa_hci_cfg->num_allowlist_host, p_nfa_hci_cfg->p_allowlist);
1431 } else {
1432 /* Something wrong, NVRAM data could be corrupt or first start with
1433 * default session id */
1434 nfa_hciu_send_clear_all_pipe_cmd();
1435 nfa_hci_cb.b_hci_new_sessionId = true;
1436 if (data_len < NFA_HCI_SESSION_ID_LEN) {
1437 android_errorWriteLog(0x534e4554, "124524315");
1438 }
1439 }
1440 }
1441 break;
1442
1443 case NFA_HCI_ANY_OPEN_PIPE:
1444 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_OPENED;
1445 if (nfa_hci_cb.b_hci_netwk_reset) {
1446 /* Something wrong, NVRAM data could be corrupt or first start with
1447 * default session id */
1448 nfa_hciu_send_clear_all_pipe_cmd();
1449 nfa_hci_cb.b_hci_netwk_reset = false;
1450 nfa_hci_cb.b_hci_new_sessionId = true;
1451 } else if (nfa_hci_cb.b_hci_new_sessionId) {
1452 nfa_hci_cb.b_hci_new_sessionId = false;
1453
1454 /* Session ID is reset, Set New session id */
1455 memcpy(
1456 &nfa_hci_cb.cfg.admin_gate.session_id[NFA_HCI_SESSION_ID_LEN / 2],
1457 nfa_hci_cb.cfg.admin_gate.session_id,
1458 (NFA_HCI_SESSION_ID_LEN / 2));
1459 os_tick = GKI_get_os_tick_count();
1460 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1461 (NFA_HCI_SESSION_ID_LEN / 2));
1462 nfa_hciu_send_set_param_cmd(
1463 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1464 NFA_HCI_SESSION_ID_LEN,
1465 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1466 } else {
1467 /* First thing is to get the session ID */
1468 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1469 NFA_HCI_SESSION_IDENTITY_INDEX);
1470 }
1471 break;
1472
1473 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1474 nfa_hciu_remove_all_pipes_from_host(0);
1475 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1476 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1477 nfa_hci_cb.nv_write_needed = true;
1478
1479 /* Open admin */
1480 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1481 break;
1482 }
1483 } else {
1484 status =
1485 (nfa_hci_cb.inst == NFA_HCI_ANY_OK) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
1486
1487 switch (nfa_hci_cb.cmd_sent) {
1488 case NFA_HCI_ANY_SET_PARAMETER:
1489 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1490 nfa_hci_api_deregister(nullptr);
1491 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1492 nfa_hci_api_dealloc_gate(nullptr);
1493 break;
1494
1495 case NFA_HCI_ANY_GET_PARAMETER:
1496 if (nfa_hci_cb.param_in_use == NFA_HCI_SESSION_IDENTITY_INDEX) {
1497 if (data_len >= NFA_HCI_SESSION_ID_LEN &&
1498 !memcmp((uint8_t*)default_session, p_data,
1499 NFA_HCI_SESSION_ID_LEN)) {
1500 memcpy(&nfa_hci_cb.cfg.admin_gate
1501 .session_id[(NFA_HCI_SESSION_ID_LEN / 2)],
1502 nfa_hci_cb.cfg.admin_gate.session_id,
1503 (NFA_HCI_SESSION_ID_LEN / 2));
1504 os_tick = GKI_get_os_tick_count();
1505 memcpy(nfa_hci_cb.cfg.admin_gate.session_id, (uint8_t*)&os_tick,
1506 (NFA_HCI_SESSION_ID_LEN / 2));
1507 nfa_hci_cb.nv_write_needed = true;
1508 nfa_hciu_send_set_param_cmd(
1509 NFA_HCI_ADMIN_PIPE, NFA_HCI_SESSION_IDENTITY_INDEX,
1510 NFA_HCI_SESSION_ID_LEN,
1511 (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id);
1512 } else {
1513 if (data_len < NFA_HCI_SESSION_ID_LEN) {
1514 android_errorWriteLog(0x534e4554, "124524315");
1515 }
1516 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1517 nfa_hci_api_deregister(nullptr);
1518 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1519 nfa_hci_api_dealloc_gate(nullptr);
1520 }
1521 } else if (nfa_hci_cb.param_in_use == NFA_HCI_HOST_LIST_INDEX) {
1522 evt_data.hosts.status = status;
1523 if (data_len > NFA_HCI_MAX_HOST_IN_NETWORK) {
1524 data_len = NFA_HCI_MAX_HOST_IN_NETWORK;
1525 android_errorWriteLog(0x534e4554, "124524315");
1526 }
1527 evt_data.hosts.num_hosts = data_len;
1528 memcpy(evt_data.hosts.host, p_data, data_len);
1529
1530 uint8_t host_index = 0;
1531
1532 memset(nfa_hci_cb.active_host, 0x0, NFA_HCI_MAX_HOST_IN_NETWORK);
1533
1534 host_count = 0;
1535 /* Collect active host in the Host Network */
1536 while ((host_count < data_len) &&
1537 (host_count < NFA_HCI_MAX_HOST_IN_NETWORK)) {
1538 host_id = (uint8_t)*p_data++;
1539
1540 if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
1541 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
1542 nfa_hci_cb.active_host[host_index] = host_id;
1543 uint8_t index = 0;
1544 while (index < NFA_HCI_MAX_HOST_IN_NETWORK) {
1545 if (nfa_hci_cb.reset_host[index] == host_id) {
1546 nfa_hci_cb.reset_host[index] = 0x0;
1547 break;
1548 }
1549 index++;
1550 }
1551 host_index++;
1552 }
1553 host_count++;
1554 }
1555
1556 if (nfa_hciu_is_no_host_resetting())
1557 nfa_hci_check_pending_api_requests();
1558 nfa_hciu_send_to_app(NFA_HCI_HOST_LIST_EVT, &evt_data,
1559 nfa_hci_cb.app_in_use);
1560 }
1561 break;
1562
1563 case NFA_HCI_ADM_CREATE_PIPE:
1564 // p_data should have at least 5 bytes length for pipe info
1565 if (data_len >= 5 && status == NFA_STATUS_OK) {
1566 STREAM_TO_UINT8(source_host, p_data);
1567 STREAM_TO_UINT8(source_gate, p_data);
1568 STREAM_TO_UINT8(dest_host, p_data);
1569 STREAM_TO_UINT8(dest_gate, p_data);
1570 STREAM_TO_UINT8(pipe, p_data);
1571
1572 /* Sanity check */
1573 if (source_gate != nfa_hci_cb.local_gate_in_use) {
1574 LOG(WARNING) << StringPrintf(
1575 "nfa_hci_handle_admin_gate_rsp sent create pipe with gate: %u "
1576 "got back: %u",
1577 nfa_hci_cb.local_gate_in_use, source_gate);
1578 break;
1579 }
1580
1581 nfa_hciu_add_pipe_to_gate(pipe, source_gate, dest_host, dest_gate);
1582 } else if (data_len < 5 && status == NFA_STATUS_OK) {
1583 android_errorWriteLog(0x534e4554, "124524315");
1584 status = NFA_STATUS_FAILED;
1585 }
1586
1587 /* Tell the application his pipe was created or not */
1588 evt_data.created.status = status;
1589 evt_data.created.pipe = pipe;
1590 evt_data.created.source_gate = source_gate;
1591 evt_data.created.dest_host = dest_host;
1592 evt_data.created.dest_gate = dest_gate;
1593
1594 nfa_hciu_send_to_app(NFA_HCI_CREATE_PIPE_EVT, &evt_data,
1595 nfa_hci_cb.app_in_use);
1596 break;
1597
1598 case NFA_HCI_ADM_DELETE_PIPE:
1599 if (status == NFA_STATUS_OK) {
1600 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1601
1602 /* If only deleting one pipe, tell the app we are done */
1603 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1604 evt_data.deleted.status = status;
1605 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1606
1607 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1608 nfa_hci_cb.app_in_use);
1609 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER)
1610 nfa_hci_api_deregister(nullptr);
1611 else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE)
1612 nfa_hci_api_dealloc_gate(nullptr);
1613 } else {
1614 /* If only deleting one pipe, tell the app we are done */
1615 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE) {
1616 evt_data.deleted.status = status;
1617 evt_data.deleted.pipe = nfa_hci_cb.pipe_in_use;
1618
1619 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data,
1620 nfa_hci_cb.app_in_use);
1621 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_APP_DEREGISTER) {
1622 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1623 nfa_hci_api_deregister(nullptr);
1624 } else if (nfa_hci_cb.hci_state == NFA_HCI_STATE_REMOVE_GATE) {
1625 nfa_hciu_release_pipe(nfa_hci_cb.pipe_in_use);
1626 nfa_hci_api_dealloc_gate(nullptr);
1627 }
1628 }
1629 break;
1630
1631 case NFA_HCI_ANY_OPEN_PIPE:
1632 nfa_hci_cb.cfg.admin_gate.pipe01_state =
1633 status ? NFA_HCI_PIPE_CLOSED : NFA_HCI_PIPE_OPENED;
1634 nfa_hci_cb.nv_write_needed = true;
1635 if (nfa_hci_cb.cfg.admin_gate.pipe01_state == NFA_HCI_PIPE_OPENED) {
1636 /* First thing is to get the session ID */
1637 nfa_hciu_send_get_param_cmd(NFA_HCI_ADMIN_PIPE,
1638 NFA_HCI_SESSION_IDENTITY_INDEX);
1639 }
1640 break;
1641
1642 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1643 nfa_hciu_remove_all_pipes_from_host(0);
1644 nfa_hci_cb.cfg.admin_gate.pipe01_state = NFA_HCI_PIPE_CLOSED;
1645 nfa_hci_cb.cfg.link_mgmt_gate.pipe00_state = NFA_HCI_PIPE_CLOSED;
1646 nfa_hci_cb.nv_write_needed = true;
1647 /* Open admin */
1648 nfa_hciu_send_open_pipe_cmd(NFA_HCI_ADMIN_PIPE);
1649 break;
1650 }
1651 }
1652 }
1653
1654 /*******************************************************************************
1655 **
1656 ** Function nfa_hci_handle_admin_gate_evt
1657 **
1658 ** Description This function handles events received on admin gate
1659 **
1660 ** Returns none
1661 **
1662 *******************************************************************************/
nfa_hci_handle_admin_gate_evt()1663 void nfa_hci_handle_admin_gate_evt() {
1664 tNFA_HCI_EVT_DATA evt_data;
1665 tNFA_HCI_API_GET_HOST_LIST* p_msg;
1666
1667 if (nfa_hci_cb.inst != NFA_HCI_EVT_HOT_PLUG) {
1668 LOG(ERROR) << StringPrintf(
1669 "nfa_hci_handle_admin_gate_evt - Unknown event on ADMIN Pipe");
1670 return;
1671 }
1672
1673 LOG(VERBOSE) << StringPrintf(
1674 "nfa_hci_handle_admin_gate_evt - HOT PLUG EVT event on ADMIN Pipe");
1675 nfa_hci_cb.num_hot_plug_evts++;
1676
1677 if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_WAIT_NETWK_ENABLE) ||
1678 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE_NETWK_ENABLE)) {
1679 /* Received Hot Plug evt while waiting for other Host in the network to
1680 * bootup after DH host bootup is complete */
1681 if ((nfa_hci_cb.ee_disable_disc) &&
1682 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1683 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1684 /* Received expected number of Hot Plug event(s) before as many number of
1685 * EE DISC REQ Ntf(s) are received */
1686 nfa_sys_stop_timer(&nfa_hci_cb.timer);
1687 /* Received HOT PLUG EVT(s), now wait some more time for EE DISC REQ
1688 * Ntf(s) */
1689 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
1690 p_nfa_hci_cfg->hci_netwk_enable_timeout);
1691 }
1692 } else if ((nfa_hci_cb.hci_state == NFA_HCI_STATE_STARTUP) ||
1693 (nfa_hci_cb.hci_state == NFA_HCI_STATE_RESTORE)) {
1694 /* Received Hot Plug evt during DH host bootup */
1695 if ((nfa_hci_cb.ee_disable_disc) &&
1696 (nfa_hci_cb.num_hot_plug_evts == (nfa_hci_cb.num_nfcee - 1)) &&
1697 (nfa_hci_cb.num_ee_dis_req_ntf < (nfa_hci_cb.num_nfcee - 1))) {
1698 /* Received expected number of Hot Plug event(s) before as many number of
1699 * EE DISC REQ Ntf(s) are received */
1700 nfa_hci_cb.w4_hci_netwk_init = false;
1701 }
1702 } else {
1703 /* Received Hot Plug evt on UICC self reset */
1704 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
1705 /* Notify all registered application with the HOT_PLUG_EVT */
1706 nfa_hciu_send_to_all_apps(NFA_HCI_EVENT_RCVD_EVT, &evt_data);
1707
1708 /* Send Get Host List after receiving any pending response */
1709 p_msg = (tNFA_HCI_API_GET_HOST_LIST*)GKI_getbuf(
1710 sizeof(tNFA_HCI_API_GET_HOST_LIST));
1711 if (p_msg != nullptr) {
1712 p_msg->hdr.event = NFA_HCI_API_GET_HOST_LIST_EVT;
1713 /* Set Invalid handle to identify this Get Host List command is internal
1714 */
1715 p_msg->hci_handle = NFA_HANDLE_INVALID;
1716
1717 nfa_sys_sendmsg(p_msg);
1718 }
1719 }
1720 }
1721
1722 /*******************************************************************************
1723 **
1724 ** Function nfa_hci_handle_dyn_pipe_pkt
1725 **
1726 ** Description This function handles data received via dynamic pipe
1727 **
1728 ** Returns none
1729 **
1730 *******************************************************************************/
nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id,uint8_t * p_data,uint16_t data_len)1731 void nfa_hci_handle_dyn_pipe_pkt(uint8_t pipe_id, uint8_t* p_data,
1732 uint16_t data_len) {
1733 tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1734 tNFA_HCI_DYN_GATE* p_gate;
1735
1736 if (p_pipe == nullptr) {
1737 /* Invalid pipe ID */
1738 LOG(ERROR) << StringPrintf("nfa_hci_handle_dyn_pipe_pkt - Unknown pipe %d",
1739 pipe_id);
1740 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1741 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1742 nullptr);
1743 return;
1744 }
1745
1746 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
1747 nfa_hci_handle_identity_mgmt_gate_pkt(p_data, p_pipe);
1748 } else if (p_pipe->local_gate == NFA_HCI_LOOP_BACK_GATE) {
1749 nfa_hci_handle_loopback_gate_pkt(p_data, data_len, p_pipe);
1750 } else if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
1751 nfa_hci_handle_connectivity_gate_pkt(p_data, data_len, p_pipe);
1752 } else {
1753 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
1754 if (p_gate == nullptr) {
1755 LOG(ERROR) << StringPrintf(
1756 "nfa_hci_handle_dyn_pipe_pkt - Pipe's gate %d is corrupt",
1757 p_pipe->local_gate);
1758 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE)
1759 nfa_hciu_send_msg(pipe_id, NFA_HCI_RESPONSE_TYPE, NFA_HCI_ANY_E_NOK, 0,
1760 nullptr);
1761 return;
1762 }
1763
1764 /* Check if data packet is a command, response or event */
1765 switch (nfa_hci_cb.type) {
1766 case NFA_HCI_COMMAND_TYPE:
1767 nfa_hci_handle_generic_gate_cmd(p_data, (uint8_t)data_len, p_pipe);
1768 break;
1769
1770 case NFA_HCI_RESPONSE_TYPE:
1771 nfa_hci_handle_generic_gate_rsp(p_data, (uint8_t)data_len, p_pipe);
1772 break;
1773
1774 case NFA_HCI_EVENT_TYPE:
1775 nfa_hci_handle_generic_gate_evt(p_data, data_len, p_gate, p_pipe);
1776 break;
1777 }
1778 }
1779 }
1780
1781 /*******************************************************************************
1782 **
1783 ** Function nfa_hci_handle_identity_mgmt_gate_pkt
1784 **
1785 ** Description This function handles incoming Identity Management gate hci
1786 ** commands
1787 **
1788 ** Returns none
1789 **
1790 *******************************************************************************/
nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t * p_data,tNFA_HCI_DYN_PIPE * p_pipe)1791 static void nfa_hci_handle_identity_mgmt_gate_pkt(uint8_t* p_data,
1792 tNFA_HCI_DYN_PIPE* p_pipe) {
1793 uint8_t data[20];
1794 uint8_t index;
1795 uint8_t gate_rsp[3 + NFA_HCI_MAX_GATE_CB], num_gates;
1796 uint16_t rsp_len = 0;
1797 uint8_t* p_rsp = data;
1798 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
1799
1800 /* We never send commands on a pipe where the local gate is the identity
1801 * management
1802 * gate, so only commands should be processed.
1803 */
1804 if (nfa_hci_cb.type != NFA_HCI_COMMAND_TYPE) return;
1805
1806 switch (nfa_hci_cb.inst) {
1807 case NFA_HCI_ANY_GET_PARAMETER:
1808 index = *(p_data++);
1809 if (p_pipe->pipe_state == NFA_HCI_PIPE_OPENED) {
1810 switch (index) {
1811 case NFA_HCI_VERSION_SW_INDEX:
1812 data[0] = (uint8_t)((NFA_HCI_VERSION_SW >> 16) & 0xFF);
1813 data[1] = (uint8_t)((NFA_HCI_VERSION_SW >> 8) & 0xFF);
1814 data[2] = (uint8_t)((NFA_HCI_VERSION_SW)&0xFF);
1815 rsp_len = 3;
1816 break;
1817
1818 case NFA_HCI_HCI_VERSION_INDEX:
1819 data[0] = NFA_HCI_VERSION;
1820 rsp_len = 1;
1821 break;
1822
1823 case NFA_HCI_VERSION_HW_INDEX:
1824 data[0] = (uint8_t)((NFA_HCI_VERSION_HW >> 16) & 0xFF);
1825 data[1] = (uint8_t)((NFA_HCI_VERSION_HW >> 8) & 0xFF);
1826 data[2] = (uint8_t)((NFA_HCI_VERSION_HW)&0xFF);
1827 rsp_len = 3;
1828 break;
1829
1830 case NFA_HCI_VENDOR_NAME_INDEX:
1831 memcpy(data, NFA_HCI_VENDOR_NAME, strlen(NFA_HCI_VENDOR_NAME));
1832 rsp_len = (uint8_t)strlen(NFA_HCI_VENDOR_NAME);
1833 break;
1834
1835 case NFA_HCI_MODEL_ID_INDEX:
1836 data[0] = NFA_HCI_MODEL_ID;
1837 rsp_len = 1;
1838 break;
1839
1840 case NFA_HCI_GATES_LIST_INDEX:
1841 gate_rsp[0] = NFA_HCI_LOOP_BACK_GATE;
1842 gate_rsp[1] = NFA_HCI_IDENTITY_MANAGEMENT_GATE;
1843 gate_rsp[2] = NFA_HCI_CONNECTIVITY_GATE;
1844 num_gates = nfa_hciu_get_allocated_gate_list(&gate_rsp[3]);
1845 rsp_len = num_gates + 3;
1846 p_rsp = gate_rsp;
1847 break;
1848
1849 default:
1850 response = NFA_HCI_ANY_E_NOK;
1851 break;
1852 }
1853 } else {
1854 response = NFA_HCI_ANY_E_PIPE_NOT_OPENED;
1855 }
1856 break;
1857
1858 case NFA_HCI_ANY_OPEN_PIPE:
1859 data[0] = 0;
1860 rsp_len = 1;
1861 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1862 break;
1863
1864 case NFA_HCI_ANY_CLOSE_PIPE:
1865 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1866 break;
1867
1868 default:
1869 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
1870 break;
1871 }
1872
1873 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
1874 p_rsp);
1875 }
1876
1877 /*******************************************************************************
1878 **
1879 ** Function nfa_hci_handle_generic_gate_cmd
1880 **
1881 ** Description This function handles all generic gates (excluding
1882 ** connectivity gate) commands
1883 **
1884 ** Returns none
1885 **
1886 *******************************************************************************/
nfa_hci_handle_generic_gate_cmd(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1887 static void nfa_hci_handle_generic_gate_cmd(uint8_t* p_data, uint8_t data_len,
1888 tNFA_HCI_DYN_PIPE* p_pipe) {
1889 tNFA_HCI_EVT_DATA evt_data;
1890 tNFA_HANDLE app_handle = nfa_hciu_get_pipe_owner(p_pipe->pipe_id);
1891
1892 switch (nfa_hci_cb.inst) {
1893 case NFA_HCI_ANY_SET_PARAMETER:
1894 evt_data.registry.pipe = p_pipe->pipe_id;
1895 evt_data.registry.index = *p_data++;
1896 if (data_len > 0) data_len--;
1897 evt_data.registry.data_len = data_len;
1898
1899 memcpy(evt_data.registry.reg_data, p_data, data_len);
1900
1901 nfa_hciu_send_to_app(NFA_HCI_SET_REG_CMD_EVT, &evt_data, app_handle);
1902 break;
1903
1904 case NFA_HCI_ANY_GET_PARAMETER:
1905 evt_data.registry.pipe = p_pipe->pipe_id;
1906 evt_data.registry.index = *p_data;
1907 evt_data.registry.data_len = 0;
1908
1909 nfa_hciu_send_to_app(NFA_HCI_GET_REG_CMD_EVT, &evt_data, app_handle);
1910 break;
1911
1912 case NFA_HCI_ANY_OPEN_PIPE:
1913 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1914
1915 evt_data.opened.pipe = p_pipe->pipe_id;
1916 evt_data.opened.status = NFA_STATUS_OK;
1917
1918 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data, app_handle);
1919 break;
1920
1921 case NFA_HCI_ANY_CLOSE_PIPE:
1922 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
1923
1924 evt_data.closed.pipe = p_pipe->pipe_id;
1925 evt_data.opened.status = NFA_STATUS_OK;
1926
1927 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data, app_handle);
1928 break;
1929
1930 default:
1931 /* Could be application specific command, pass it on */
1932 evt_data.cmd_rcvd.status = NFA_STATUS_OK;
1933 evt_data.cmd_rcvd.pipe = p_pipe->pipe_id;
1934 ;
1935 evt_data.cmd_rcvd.cmd_code = nfa_hci_cb.inst;
1936 evt_data.cmd_rcvd.cmd_len = data_len;
1937
1938 if (data_len <= NFA_MAX_HCI_CMD_LEN)
1939 memcpy(evt_data.cmd_rcvd.cmd_data, p_data, data_len);
1940
1941 nfa_hciu_send_to_app(NFA_HCI_CMD_RCVD_EVT, &evt_data, app_handle);
1942 break;
1943 }
1944 }
1945
1946 /*******************************************************************************
1947 **
1948 ** Function nfa_hci_handle_generic_gate_rsp
1949 **
1950 ** Description This function handles all generic gates (excluding
1951 ** connectivity) response
1952 **
1953 ** Returns none
1954 **
1955 *******************************************************************************/
nfa_hci_handle_generic_gate_rsp(uint8_t * p_data,uint8_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)1956 static void nfa_hci_handle_generic_gate_rsp(uint8_t* p_data, uint8_t data_len,
1957 tNFA_HCI_DYN_PIPE* p_pipe) {
1958 tNFA_HCI_EVT_DATA evt_data;
1959 tNFA_STATUS status = NFA_STATUS_OK;
1960
1961 if (nfa_hci_cb.inst != NFA_HCI_ANY_OK) status = NFA_STATUS_FAILED;
1962
1963 if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) {
1964 if (status == NFA_STATUS_OK) p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
1965
1966 nfa_hci_cb.nv_write_needed = true;
1967 /* Tell application */
1968 evt_data.opened.status = status;
1969 evt_data.opened.pipe = p_pipe->pipe_id;
1970
1971 nfa_hciu_send_to_app(NFA_HCI_OPEN_PIPE_EVT, &evt_data,
1972 nfa_hci_cb.app_in_use);
1973 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE) {
1974 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
1975
1976 nfa_hci_cb.nv_write_needed = true;
1977 /* Tell application */
1978 evt_data.opened.status = status;
1979 ;
1980 evt_data.opened.pipe = p_pipe->pipe_id;
1981
1982 nfa_hciu_send_to_app(NFA_HCI_CLOSE_PIPE_EVT, &evt_data,
1983 nfa_hci_cb.app_in_use);
1984 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_GET_PARAMETER) {
1985 /* Tell application */
1986 evt_data.registry.status = status;
1987 evt_data.registry.pipe = p_pipe->pipe_id;
1988 evt_data.registry.data_len = data_len;
1989 evt_data.registry.index = nfa_hci_cb.param_in_use;
1990
1991 memcpy(evt_data.registry.reg_data, p_data, data_len);
1992
1993 nfa_hciu_send_to_app(NFA_HCI_GET_REG_RSP_EVT, &evt_data,
1994 nfa_hci_cb.app_in_use);
1995 } else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_SET_PARAMETER) {
1996 /* Tell application */
1997 evt_data.registry.status = status;
1998 ;
1999 evt_data.registry.pipe = p_pipe->pipe_id;
2000
2001 nfa_hciu_send_to_app(NFA_HCI_SET_REG_RSP_EVT, &evt_data,
2002 nfa_hci_cb.app_in_use);
2003 } else {
2004 /* Could be a response to application specific command sent, pass it on */
2005 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2006 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2007 ;
2008 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2009 evt_data.rsp_rcvd.rsp_len = data_len;
2010
2011 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2012 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2013
2014 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2015 nfa_hci_cb.app_in_use);
2016 }
2017 }
2018
2019 /*******************************************************************************
2020 **
2021 ** Function nfa_hci_handle_connectivity_gate_pkt
2022 **
2023 ** Description This function handles incoming connectivity gate packets
2024 **
2025 ** Returns none
2026 **
2027 *******************************************************************************/
nfa_hci_handle_connectivity_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2028 static void nfa_hci_handle_connectivity_gate_pkt(uint8_t* p_data,
2029 uint16_t data_len,
2030 tNFA_HCI_DYN_PIPE* p_pipe) {
2031 tNFA_HCI_EVT_DATA evt_data;
2032
2033 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2034 switch (nfa_hci_cb.inst) {
2035 case NFA_HCI_ANY_OPEN_PIPE:
2036 case NFA_HCI_ANY_CLOSE_PIPE:
2037 nfa_hci_handle_pipe_open_close_cmd(p_pipe);
2038 break;
2039
2040 case NFA_HCI_CON_PRO_HOST_REQUEST:
2041 /* A request to the DH to activate another host. This is not supported
2042 * for */
2043 /* now, we will implement it when the spec is clearer and UICCs need it.
2044 */
2045 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
2046 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
2047 break;
2048
2049 default:
2050 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE,
2051 NFA_HCI_ANY_E_CMD_NOT_SUPPORTED, 0, nullptr);
2052 break;
2053 }
2054 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2055 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2056 (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2057 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2058 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2059 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2060
2061 /* Could be a response to application specific command sent, pass it on */
2062 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2063 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2064 ;
2065 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2066 evt_data.rsp_rcvd.rsp_len = data_len;
2067
2068 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2069 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2070
2071 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2072 nfa_hci_cb.app_in_use);
2073 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2074 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2075 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2076 evt_data.rcvd_evt.evt_len = data_len;
2077 evt_data.rcvd_evt.p_evt_buf = p_data;
2078
2079 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2080 nfa_hciu_send_to_apps_handling_connectivity_evts(NFA_HCI_EVENT_RCVD_EVT,
2081 &evt_data);
2082 }
2083 }
2084
2085 /*******************************************************************************
2086 **
2087 ** Function nfa_hci_handle_loopback_gate_pkt
2088 **
2089 ** Description This function handles incoming loopback gate hci events
2090 **
2091 ** Returns none
2092 **
2093 *******************************************************************************/
nfa_hci_handle_loopback_gate_pkt(uint8_t * p_data,uint16_t data_len,tNFA_HCI_DYN_PIPE * p_pipe)2094 static void nfa_hci_handle_loopback_gate_pkt(uint8_t* p_data, uint16_t data_len,
2095 tNFA_HCI_DYN_PIPE* p_pipe) {
2096 uint8_t data[1];
2097 uint8_t rsp_len = 0;
2098 tNFA_HCI_RESPONSE response = NFA_HCI_ANY_OK;
2099 tNFA_HCI_EVT_DATA evt_data;
2100
2101 /* Check if data packet is a command, response or event */
2102 if (nfa_hci_cb.type == NFA_HCI_COMMAND_TYPE) {
2103 if (nfa_hci_cb.inst == NFA_HCI_ANY_OPEN_PIPE) {
2104 data[0] = 0;
2105 rsp_len = 1;
2106 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2107 } else if (nfa_hci_cb.inst == NFA_HCI_ANY_CLOSE_PIPE) {
2108 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2109 } else
2110 response = NFA_HCI_ANY_E_CMD_NOT_SUPPORTED;
2111
2112 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_RESPONSE_TYPE, response, rsp_len,
2113 data);
2114 } else if (nfa_hci_cb.type == NFA_HCI_RESPONSE_TYPE) {
2115 if ((nfa_hci_cb.cmd_sent == NFA_HCI_ANY_OPEN_PIPE) &&
2116 (nfa_hci_cb.inst == NFA_HCI_ANY_OK))
2117 p_pipe->pipe_state = NFA_HCI_PIPE_OPENED;
2118 else if (nfa_hci_cb.cmd_sent == NFA_HCI_ANY_CLOSE_PIPE)
2119 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
2120
2121 /* Could be a response to application specific command sent, pass it on */
2122 evt_data.rsp_rcvd.status = NFA_STATUS_OK;
2123 evt_data.rsp_rcvd.pipe = p_pipe->pipe_id;
2124 ;
2125 evt_data.rsp_rcvd.rsp_code = nfa_hci_cb.inst;
2126 evt_data.rsp_rcvd.rsp_len = data_len;
2127
2128 if (data_len <= NFA_MAX_HCI_RSP_LEN)
2129 memcpy(evt_data.rsp_rcvd.rsp_data, p_data, data_len);
2130
2131 nfa_hciu_send_to_app(NFA_HCI_RSP_RCVD_EVT, &evt_data,
2132 nfa_hci_cb.app_in_use);
2133 } else if (nfa_hci_cb.type == NFA_HCI_EVENT_TYPE) {
2134 if (nfa_hci_cb.w4_rsp_evt) {
2135 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2136 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2137 evt_data.rcvd_evt.evt_len = data_len;
2138 evt_data.rcvd_evt.p_evt_buf = p_data;
2139
2140 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data,
2141 nfa_hci_cb.app_in_use);
2142 } else if (nfa_hci_cb.inst == NFA_HCI_EVT_POST_DATA) {
2143 /* Send back the same data we got */
2144 nfa_hciu_send_msg(p_pipe->pipe_id, NFA_HCI_EVENT_TYPE,
2145 NFA_HCI_EVT_POST_DATA, data_len, p_data);
2146 }
2147 }
2148 }
2149
2150 /*******************************************************************************
2151 **
2152 ** Function nfa_hci_handle_generic_gate_evt
2153 **
2154 ** Description This function handles incoming Generic gate hci events
2155 **
2156 ** Returns none
2157 **
2158 *******************************************************************************/
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)2159 static void nfa_hci_handle_generic_gate_evt(uint8_t* p_data, uint16_t data_len,
2160 tNFA_HCI_DYN_GATE* p_gate,
2161 tNFA_HCI_DYN_PIPE* p_pipe) {
2162 tNFA_HCI_EVT_DATA evt_data;
2163
2164 evt_data.rcvd_evt.pipe = p_pipe->pipe_id;
2165 evt_data.rcvd_evt.evt_code = nfa_hci_cb.inst;
2166 evt_data.rcvd_evt.evt_len = data_len;
2167
2168 if (nfa_hci_cb.assembly_failed)
2169 evt_data.rcvd_evt.status = NFA_STATUS_BUFFER_FULL;
2170 else
2171 evt_data.rcvd_evt.status = NFA_STATUS_OK;
2172
2173 evt_data.rcvd_evt.p_evt_buf = p_data;
2174 nfa_hci_cb.rsp_buf_size = 0;
2175 nfa_hci_cb.p_rsp_buf = nullptr;
2176
2177 /* notify NFA_HCI_EVENT_RCVD_EVT to the application */
2178 nfa_hciu_send_to_app(NFA_HCI_EVENT_RCVD_EVT, &evt_data, p_gate->gate_owner);
2179 }
2180