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 utility functions for the NFA HCI.
22 *
23 ******************************************************************************/
24 #include <android-base/stringprintf.h>
25 #include <base/logging.h>
26 #include <log/log.h>
27
28 #include <string>
29
30 #include "nfa_dm_int.h"
31 #include "nfa_hci_api.h"
32 #include "nfa_hci_defs.h"
33 #include "nfa_hci_int.h"
34
35 using android::base::StringPrintf;
36
37 extern bool nfc_debug_enabled;
38
39 static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t type,
40 uint8_t instruction);
41 uint8_t HCI_LOOPBACK_DEBUG = NFA_HCI_DEBUG_OFF;
42
43 /*******************************************************************************
44 **
45 ** Function nfa_hciu_find_pipe_by_pid
46 **
47 ** Description look for the pipe control block based on pipe id
48 **
49 ** Returns pointer to the pipe control block, or NULL if not found
50 **
51 *******************************************************************************/
nfa_hciu_find_pipe_by_pid(uint8_t pipe_id)52 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_pid(uint8_t pipe_id) {
53 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
54 int xx = 0;
55
56 /* Loop through looking for a match */
57 for (; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
58 if (pp->pipe_id == pipe_id) return (pp);
59 }
60
61 /* If here, not found */
62 return (nullptr);
63 }
64
65 /*******************************************************************************
66 **
67 ** Function nfa_hciu_find_gate_by_gid
68 **
69 ** Description Find the gate control block for the given gate id
70 **
71 ** Returns pointer to the gate control block, or NULL if not found
72 **
73 *******************************************************************************/
nfa_hciu_find_gate_by_gid(uint8_t gate_id)74 tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_gid(uint8_t gate_id) {
75 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
76 int xx = 0;
77
78 for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
79 if (pg->gate_id == gate_id) return (pg);
80 }
81
82 return (nullptr);
83 }
84
85 /*******************************************************************************
86 **
87 ** Function nfa_hciu_find_gate_by_owner
88 **
89 ** Description Find the the first gate control block for the given owner
90 **
91 ** Returns pointer to the gate control block, or NULL if not found
92 **
93 *******************************************************************************/
nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle)94 tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle) {
95 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
96 int xx = 0;
97
98 for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
99 if (pg->gate_owner == app_handle) return (pg);
100 }
101
102 return (nullptr);
103 }
104
105 /*******************************************************************************
106 **
107 ** Function nfa_hciu_find_gate_with_nopipes_by_owner
108 **
109 ** Description Find the the first gate control block with no pipes
110 ** for the given owner
111 **
112 ** Returns pointer to the gate control block, or NULL if not found
113 **
114 *******************************************************************************/
nfa_hciu_find_gate_with_nopipes_by_owner(tNFA_HANDLE app_handle)115 tNFA_HCI_DYN_GATE* nfa_hciu_find_gate_with_nopipes_by_owner(
116 tNFA_HANDLE app_handle) {
117 tNFA_HCI_DYN_GATE* pg = nfa_hci_cb.cfg.dyn_gates;
118 int xx = 0;
119
120 for (; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++) {
121 if ((pg->gate_owner == app_handle) && (pg->pipe_inx_mask == 0)) return (pg);
122 }
123
124 return (nullptr);
125 }
126
127 /*******************************************************************************
128 **
129 ** Function nfa_hciu_count_pipes_on_gate
130 **
131 ** Description Count the number of pipes on the given gate
132 **
133 ** Returns the number of pipes on the gate
134 **
135 *******************************************************************************/
nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE * p_gate)136 uint8_t nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate) {
137 int xx = 0;
138 uint32_t mask = 1;
139 uint8_t count = 0;
140
141 for (; xx < NFA_HCI_MAX_PIPE_CB; xx++) {
142 if (p_gate->pipe_inx_mask & mask) count++;
143
144 mask = mask << 1;
145 }
146
147 return (count);
148 }
149
150 /*******************************************************************************
151 **
152 ** Function nfa_hciu_count_open_pipes_on_gate
153 **
154 ** Description Count the number of opened pipes on the given gate
155 **
156 ** Returns the number of pipes in OPENED state on the gate
157 **
158 *******************************************************************************/
nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE * p_gate)159 uint8_t nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE* p_gate) {
160 tNFA_HCI_DYN_PIPE* pp = nfa_hci_cb.cfg.dyn_pipes;
161 int xx = 0;
162 uint32_t mask = 1;
163 uint8_t count = 0;
164
165 for (; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++) {
166 /* For each pipe on this gate, check if it is open */
167 if ((p_gate->pipe_inx_mask & mask) &&
168 (pp->pipe_state == NFA_HCI_PIPE_OPENED))
169 count++;
170
171 mask = mask << 1;
172 }
173
174 return (count);
175 }
176
177 /*******************************************************************************
178 **
179 ** Function nfa_hciu_get_gate_owner
180 **
181 ** Description Find the application that owns a gate
182 **
183 ** Returns application handle
184 **
185 *******************************************************************************/
nfa_hciu_get_gate_owner(uint8_t gate_id)186 tNFA_HANDLE nfa_hciu_get_gate_owner(uint8_t gate_id) {
187 tNFA_HCI_DYN_GATE* pg;
188
189 pg = nfa_hciu_find_gate_by_gid(gate_id);
190 if (pg == nullptr) return (NFA_HANDLE_INVALID);
191
192 return (pg->gate_owner);
193 }
194
195 /*******************************************************************************
196 **
197 ** Function nfa_hciu_get_pipe_owner
198 **
199 ** Description Find the application that owns a pipe
200 **
201 ** Returns application handle
202 **
203 *******************************************************************************/
nfa_hciu_get_pipe_owner(uint8_t pipe_id)204 tNFA_HANDLE nfa_hciu_get_pipe_owner(uint8_t pipe_id) {
205 tNFA_HCI_DYN_PIPE* pp;
206 tNFA_HCI_DYN_GATE* pg;
207
208 pp = nfa_hciu_find_pipe_by_pid(pipe_id);
209 if (pp == nullptr) return (NFA_HANDLE_INVALID);
210
211 pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
212 if (pg == nullptr) return (NFA_HANDLE_INVALID);
213
214 return (pg->gate_owner);
215 }
216
217 /*******************************************************************************
218 **
219 ** Function nfa_hciu_alloc_gate
220 **
221 ** Description Allocate an gate control block
222 **
223 ** Returns pointer to the allocated gate, or NULL if cannot allocate
224 **
225 *******************************************************************************/
nfa_hciu_alloc_gate(uint8_t gate_id,tNFA_HANDLE app_handle)226 tNFA_HCI_DYN_GATE* nfa_hciu_alloc_gate(uint8_t gate_id,
227 tNFA_HANDLE app_handle) {
228 tNFA_HCI_DYN_GATE* pg;
229 int xx;
230 uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
231
232 /* First, check if the application handle is valid */
233 if ((gate_id != NFA_HCI_CONNECTIVITY_GATE) &&
234 (gate_id < NFA_HCI_FIRST_PROP_GATE) &&
235 (((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI) ||
236 (app_inx >= NFA_HCI_MAX_APP_CB) ||
237 (nfa_hci_cb.p_app_cback[app_inx] == nullptr))) {
238 return (nullptr);
239 }
240
241 if (gate_id != 0) {
242 pg = nfa_hciu_find_gate_by_gid(gate_id);
243 if (pg != nullptr) return (pg);
244 } else {
245 /* If gate_id is 0, we need to assign a free one */
246 /* Loop through all possible gate IDs checking if they are already used */
247 uint32_t gate_id_index;
248 for (gate_id_index = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE;
249 gate_id_index <= NFA_HCI_LAST_PROP_GATE; gate_id_index++) {
250 /* Skip connectivity gate */
251 if (gate_id_index == NFA_HCI_CONNECTIVITY_GATE) continue;
252
253 /* Check if the gate is already allocated */
254 if (nfa_hciu_find_gate_by_gid(gate_id_index) == nullptr) {
255 gate_id = gate_id_index & 0xFF;
256 break;
257 }
258 }
259 if (gate_id_index > NFA_HCI_LAST_PROP_GATE) {
260 LOG(ERROR) << StringPrintf(
261 "nfa_hci_alloc_gate - no free Gate ID: %u App Handle: 0x%04x",
262 gate_id_index, app_handle);
263 return (nullptr);
264 }
265 }
266
267 /* Now look for a free control block */
268 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
269 xx++, pg++) {
270 if (pg->gate_id == 0) {
271 /* Found a free gate control block */
272 pg->gate_id = gate_id;
273 pg->gate_owner = app_handle;
274 pg->pipe_inx_mask = 0;
275
276 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
277 "nfa_hciu_alloc_gate id:%d app_handle: 0x%04x", gate_id, app_handle);
278
279 nfa_hci_cb.nv_write_needed = true;
280 return (pg);
281 }
282 }
283
284 /* If here, no free gate control block */
285 LOG(ERROR) << StringPrintf(
286 "nfa_hci_alloc_gate - no CB Gate ID: %u App Handle: 0x%04x", gate_id,
287 app_handle);
288 return (nullptr);
289 }
290
291 /*******************************************************************************
292 **
293 ** Function nfa_hciu_send_msg
294 **
295 ** Description This function will fragment the given packet, if necessary
296 ** and send it on the given pipe.
297 **
298 ** Returns status
299 **
300 *******************************************************************************/
nfa_hciu_send_msg(uint8_t pipe_id,uint8_t type,uint8_t instruction,uint16_t msg_len,uint8_t * p_msg)301 tNFA_STATUS nfa_hciu_send_msg(uint8_t pipe_id, uint8_t type,
302 uint8_t instruction, uint16_t msg_len,
303 uint8_t* p_msg) {
304 NFC_HDR* p_buf;
305 uint8_t* p_data;
306 bool first_pkt = true;
307 uint16_t data_len;
308 tNFA_STATUS status = NFA_STATUS_OK;
309 uint16_t max_seg_hcp_pkt_size;
310 if (nfa_hci_cb.buff_size > (NCI_DATA_HDR_SIZE + 2)) {
311 max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
312 } else {
313 android_errorWriteLog(0x534e4554, "124521372");
314 return NFA_STATUS_NO_BUFFERS;
315 }
316 const uint8_t MAX_BUFF_SIZE = 100;
317 char buff[MAX_BUFF_SIZE];
318
319 DLOG_IF(INFO, nfc_debug_enabled)
320 << StringPrintf("nfa_hciu_send_msg pipe_id:%d %s len:%d", pipe_id,
321 nfa_hciu_get_type_inst_names(pipe_id, type, instruction,
322 buff, MAX_BUFF_SIZE),
323 msg_len);
324
325 if (instruction == NFA_HCI_ANY_GET_PARAMETER)
326 nfa_hci_cb.param_in_use = *p_msg;
327
328 while ((first_pkt == true) || (msg_len != 0)) {
329 p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
330 if (p_buf != nullptr) {
331 p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
332
333 /* First packet has a 2-byte header, subsequent fragments have a 1-byte
334 * header */
335 data_len =
336 first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1);
337
338 p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
339
340 /* Last or only segment has "no fragmentation" bit set */
341 if (msg_len > data_len) {
342 *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
343 } else {
344 data_len = msg_len;
345 *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
346 }
347
348 p_buf->len = 1;
349
350 /* Message header only goes in the first segment */
351 if (first_pkt) {
352 first_pkt = false;
353 *p_data++ = (type << 6) | instruction;
354 p_buf->len++;
355 }
356
357 if (data_len != 0) {
358 memcpy(p_data, p_msg, data_len);
359
360 p_buf->len += data_len;
361 if (msg_len >= data_len) {
362 msg_len -= data_len;
363 p_msg += data_len;
364 } else {
365 msg_len = 0;
366 }
367 }
368
369 if (HCI_LOOPBACK_DEBUG == NFA_HCI_DEBUG_ON)
370 handle_debug_loopback(p_buf, type, instruction);
371 else
372 status = NFC_SendData(nfa_hci_cb.conn_id, p_buf);
373 } else {
374 LOG(ERROR) << StringPrintf("nfa_hciu_send_data_packet no buffers");
375 status = NFA_STATUS_NO_BUFFERS;
376 break;
377 }
378 }
379
380 /* Start timer if response to wait for a particular time for the response */
381 if (type == NFA_HCI_COMMAND_TYPE) {
382 nfa_hci_cb.cmd_sent = instruction;
383
384 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
385 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
386
387 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
388 p_nfa_hci_cfg->hcp_response_timeout);
389 }
390
391 return status;
392 }
393
394 /*******************************************************************************
395 **
396 ** Function nfa_hciu_get_allocated_gate_list
397 **
398 ** Description fills in a list of allocated gates
399 **
400 ** Returns the number of gates
401 **
402 *******************************************************************************/
nfa_hciu_get_allocated_gate_list(uint8_t * p_gate_list)403 uint8_t nfa_hciu_get_allocated_gate_list(uint8_t* p_gate_list) {
404 tNFA_HCI_DYN_GATE* p_cb;
405 int xx;
406 uint8_t count = 0;
407
408 for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
409 xx++, p_cb++) {
410 if (p_cb->gate_id != 0) {
411 *p_gate_list++ = p_cb->gate_id;
412 count++;
413 }
414 }
415
416 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("returns: %u", count);
417
418 return (count);
419 }
420
421 /*******************************************************************************
422 **
423 ** Function nfa_hciu_alloc_pipe
424 **
425 ** Description Allocate a pipe control block
426 **
427 ** Returns pointer to the pipe control block, or NULL if
428 ** cannot allocate
429 **
430 *******************************************************************************/
nfa_hciu_alloc_pipe(uint8_t pipe_id)431 tNFA_HCI_DYN_PIPE* nfa_hciu_alloc_pipe(uint8_t pipe_id) {
432 uint8_t xx;
433 tNFA_HCI_DYN_PIPE* pp;
434
435 /* If we already have a pipe of the same ID, release it first it */
436 pp = nfa_hciu_find_pipe_by_pid(pipe_id);
437 if (pp != nullptr) {
438 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) return pp;
439 nfa_hciu_release_pipe(pipe_id);
440 }
441
442 /* Look for a free pipe control block */
443 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
444 xx++, pp++) {
445 if (pp->pipe_id == 0) {
446 DLOG_IF(INFO, nfc_debug_enabled)
447 << StringPrintf("nfa_hciu_alloc_pipe:%d, index:%d", pipe_id, xx);
448 pp->pipe_id = pipe_id;
449
450 nfa_hci_cb.nv_write_needed = true;
451 return (pp);
452 }
453 }
454
455 DLOG_IF(INFO, nfc_debug_enabled)
456 << StringPrintf("nfa_hciu_alloc_pipe:%d, NO free entries !!", pipe_id);
457 return (nullptr);
458 }
459
460 /*******************************************************************************
461 **
462 ** Function nfa_hciu_release_gate
463 **
464 ** Description Remove a generic gate from gate list
465 **
466 ** Returns none
467 **
468 *******************************************************************************/
nfa_hciu_release_gate(uint8_t gate_id)469 void nfa_hciu_release_gate(uint8_t gate_id) {
470 tNFA_HCI_DYN_GATE* p_gate = nfa_hciu_find_gate_by_gid(gate_id);
471
472 if (p_gate != nullptr) {
473 DLOG_IF(INFO, nfc_debug_enabled)
474 << StringPrintf("ID: %d owner: 0x%04x pipe_inx_mask: 0x%04x", gate_id,
475 p_gate->gate_owner, p_gate->pipe_inx_mask);
476
477 p_gate->gate_id = 0;
478 p_gate->gate_owner = 0;
479 p_gate->pipe_inx_mask = 0;
480
481 nfa_hci_cb.nv_write_needed = true;
482 } else {
483 LOG(WARNING) << StringPrintf("ID: %d NOT FOUND", gate_id);
484 }
485 }
486
487 /*******************************************************************************
488 **
489 ** Function nfa_hciu_add_pipe_to_gate
490 **
491 ** Description Add pipe to generic gate
492 **
493 ** Returns NFA_STATUS_OK, if successfully add the pipe on to the gate
494 ** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
495 **
496 *******************************************************************************/
nfa_hciu_add_pipe_to_gate(uint8_t pipe_id,uint8_t local_gate,uint8_t dest_host,uint8_t dest_gate)497 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate(uint8_t pipe_id, uint8_t local_gate,
498 uint8_t dest_host,
499 uint8_t dest_gate) {
500 tNFA_HCI_DYN_GATE* p_gate;
501 tNFA_HCI_DYN_PIPE* p_pipe;
502 uint8_t pipe_index;
503
504 p_gate = nfa_hciu_find_gate_by_gid(local_gate);
505
506 if (p_gate != nullptr) {
507 /* Allocate a pipe control block */
508 p_pipe = nfa_hciu_alloc_pipe(pipe_id);
509 if (p_pipe != nullptr) {
510 p_pipe->pipe_id = pipe_id;
511 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
512 p_pipe->dest_host = dest_host;
513 p_pipe->dest_gate = dest_gate;
514 p_pipe->local_gate = local_gate;
515
516 /* Save the pipe in the gate that it belongs to */
517 pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
518 p_gate->pipe_inx_mask |= (uint32_t)(1 << pipe_index);
519
520 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
521 "nfa_hciu_add_pipe_to_gate Gate ID: 0x%02x Pipe ID: 0x%02x "
522 "pipe_index: %u App Handle: 0x%08x",
523 local_gate, pipe_id, pipe_index, p_gate->gate_owner);
524 return (NFA_HCI_ANY_OK);
525 }
526 }
527
528 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
529 "nfa_hciu_add_pipe_to_gate: 0x%02x NOT FOUND", local_gate);
530
531 return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE);
532 }
533
534 /*******************************************************************************
535 **
536 ** Function nfa_hciu_add_pipe_to_static_gate
537 **
538 ** Description Add pipe to identity management gate
539 **
540 ** Returns NFA_HCI_ANY_OK, if successfully add the pipe on to the gate
541 ** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
542 **
543 *******************************************************************************/
nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,uint8_t pipe_id,uint8_t dest_host,uint8_t dest_gate)544 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,
545 uint8_t pipe_id,
546 uint8_t dest_host,
547 uint8_t dest_gate) {
548 tNFA_HCI_DYN_PIPE* p_pipe;
549 uint8_t pipe_index;
550
551 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
552 "nfa_hciu_add_pipe_to_static_gate (%u) Pipe: 0x%02x Dest Host: 0x%02x "
553 "Dest Gate: 0x%02x)",
554 local_gate, pipe_id, dest_host, dest_gate);
555
556 /* Allocate a pipe control block */
557 p_pipe = nfa_hciu_alloc_pipe(pipe_id);
558 if (p_pipe != nullptr) {
559 p_pipe->pipe_id = pipe_id;
560 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
561 p_pipe->dest_host = dest_host;
562 p_pipe->dest_gate = dest_gate;
563 p_pipe->local_gate = local_gate;
564
565 /* If this is the ID gate, save the pipe index in the ID gate info */
566 /* block. Note that for loopback, it is enough to just create the pipe */
567 if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
568 pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
569 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask |= (uint32_t)(1 << pipe_index);
570 }
571 return NFA_HCI_ANY_OK;
572 }
573
574 return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE;
575 }
576
577 /*******************************************************************************
578 **
579 ** Function nfa_hciu_find_active_pipe_by_owner
580 **
581 ** Description Find the first pipe associated with the given app
582 **
583 ** Returns pointer to pipe, or NULL if none found
584 **
585 *******************************************************************************/
nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle)586 tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle) {
587 tNFA_HCI_DYN_GATE* pg;
588 tNFA_HCI_DYN_PIPE* pp;
589 int xx;
590
591 DLOG_IF(INFO, nfc_debug_enabled)
592 << StringPrintf("app_handle:0x%x", app_handle);
593
594 /* Loop through all pipes looking for the owner */
595 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
596 xx++, pp++) {
597 if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
598 (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
599 (nfa_hciu_is_active_host(pp->dest_host))) {
600 if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
601 (pg->gate_owner == app_handle))
602 return (pp);
603 }
604 }
605
606 /* If here, not found */
607 return (nullptr);
608 }
609
610 /*******************************************************************************
611 **
612 ** Function nfa_hciu_check_pipe_between_gates
613 **
614 ** Description Check if there is a pipe between specified Terminal host
615 ** gate and and the specified UICC gate
616 **
617 ** Returns TRUE, if there exists a pipe between the two specified gated
618 ** FALSE, otherwise
619 **
620 *******************************************************************************/
nfa_hciu_check_pipe_between_gates(uint8_t local_gate,uint8_t dest_host,uint8_t dest_gate)621 bool nfa_hciu_check_pipe_between_gates(uint8_t local_gate, uint8_t dest_host,
622 uint8_t dest_gate) {
623 tNFA_HCI_DYN_PIPE* pp;
624 int xx;
625
626 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
627 "Local gate: 0x%02X, Host[0x%02X] "
628 "gate: 0x%02X",
629 local_gate, dest_host, dest_gate);
630
631 /* Loop through all pipes looking for the owner */
632 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
633 xx++, pp++) {
634 if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
635 (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
636 (pp->local_gate == local_gate) && (pp->dest_host == dest_host) &&
637 (pp->dest_gate == dest_gate)) {
638 return true;
639 }
640 }
641
642 /* If here, not found */
643 return false;
644 }
645
646 /*******************************************************************************
647 **
648 ** Function nfa_hciu_find_pipe_by_owner
649 **
650 ** Description Find the first pipe associated with the given app
651 **
652 ** Returns pointer to pipe, or NULL if none found
653 **
654 *******************************************************************************/
nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle)655 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle) {
656 tNFA_HCI_DYN_GATE* pg;
657 tNFA_HCI_DYN_PIPE* pp;
658 int xx;
659
660 DLOG_IF(INFO, nfc_debug_enabled)
661 << StringPrintf("app_handle:0x%x", app_handle);
662
663 /* Loop through all pipes looking for the owner */
664 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
665 xx++, pp++) {
666 if (pp->pipe_id != 0) {
667 if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
668 (pg->gate_owner == app_handle))
669 return (pp);
670 }
671 }
672
673 /* If here, not found */
674 return (nullptr);
675 }
676
677 /*******************************************************************************
678 **
679 ** Function nfa_hciu_find_pipe_on_gate
680 **
681 ** Description Find the first pipe associated with the given gate
682 **
683 ** Returns pointer to pipe, or NULL if none found
684 **
685 *******************************************************************************/
nfa_hciu_find_pipe_on_gate(uint8_t gate_id)686 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_on_gate(uint8_t gate_id) {
687 tNFA_HCI_DYN_GATE* pg;
688 tNFA_HCI_DYN_PIPE* pp;
689 int xx;
690
691 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Gate:0x%x", gate_id);
692
693 /* Loop through all pipes looking for the owner */
694 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
695 xx++, pp++) {
696 if (pp->pipe_id != 0) {
697 if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
698 (pg->gate_id == gate_id))
699 return (pp);
700 }
701 }
702
703 /* If here, not found */
704 return (nullptr);
705 }
706
707 /*******************************************************************************
708 **
709 ** Function nfa_hciu_is_active_host
710 **
711 ** Description Check if the host is currently active
712 **
713 ** Returns TRUE, if the host is active in the host network
714 ** FALSE, if the host is not active in the host network
715 **
716 *******************************************************************************/
nfa_hciu_is_active_host(uint8_t host_id)717 bool nfa_hciu_is_active_host(uint8_t host_id) {
718 uint8_t xx;
719
720 if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
721 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
722 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
723 if (nfa_hci_cb.active_host[xx] == host_id) return true;
724 }
725 }
726
727 return false;
728 }
729
730 /*******************************************************************************
731 **
732 ** Function nfa_hciu_is_host_reseting
733 **
734 ** Description Check if the host is currently reseting
735 **
736 ** Returns TRUE, if the host is reseting
737 ** FALSE, if the host is not reseting
738 **
739 *******************************************************************************/
nfa_hciu_is_host_reseting(uint8_t host_id)740 bool nfa_hciu_is_host_reseting(uint8_t host_id) {
741 uint8_t xx;
742
743 if ((host_id == NFA_HCI_HOST_ID_UICC0) ||
744 (host_id >= NFA_HCI_HOST_ID_FIRST_DYNAMICALLY_ALLOCATED)) {
745 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
746 if (nfa_hci_cb.reset_host[xx] == host_id) return true;
747 }
748 }
749
750 return false;
751 }
752
753 /*******************************************************************************
754 **
755 ** Function nfa_hciu_is_no_host_resetting
756 **
757 ** Description Check if no host is reseting
758 **
759 ** Returns TRUE, if no host is resetting at this time
760 ** FALSE, if one or more host is resetting
761 **
762 *******************************************************************************/
nfa_hciu_is_no_host_resetting(void)763 bool nfa_hciu_is_no_host_resetting(void) {
764 uint8_t xx;
765
766 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++) {
767 if (nfa_hci_cb.reset_host[xx] != 0) return false;
768 }
769
770 return true;
771 }
772
773 /*******************************************************************************
774 **
775 ** Function nfa_hciu_find_active_pipe_on_gate
776 **
777 ** Description Find the first active pipe associated with the given gate
778 **
779 ** Returns pointer to pipe, or NULL if none found
780 **
781 *******************************************************************************/
nfa_hciu_find_active_pipe_on_gate(uint8_t gate_id)782 tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_on_gate(uint8_t gate_id) {
783 tNFA_HCI_DYN_GATE* pg;
784 tNFA_HCI_DYN_PIPE* pp;
785 int xx;
786
787 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Gate:0x%x", gate_id);
788
789 /* Loop through all pipes looking for the owner */
790 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
791 xx++, pp++) {
792 if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
793 (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
794 (nfa_hciu_is_active_host(pp->dest_host))) {
795 if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
796 (pg->gate_id == gate_id))
797 return (pp);
798 }
799 }
800
801 /* If here, not found */
802 return (nullptr);
803 }
804
805 /*******************************************************************************
806 **
807 ** Function nfa_hciu_release_pipe
808 **
809 ** Description remove the specified pipe
810 **
811 ** Returns NFA_HCI_ANY_OK, if removed
812 ** NFA_HCI_ANY_E_NOK, if otherwise
813 **
814 *******************************************************************************/
nfa_hciu_release_pipe(uint8_t pipe_id)815 tNFA_HCI_RESPONSE nfa_hciu_release_pipe(uint8_t pipe_id) {
816 tNFA_HCI_DYN_GATE* p_gate;
817 tNFA_HCI_DYN_PIPE* p_pipe;
818 uint8_t pipe_index;
819
820 DLOG_IF(INFO, nfc_debug_enabled)
821 << StringPrintf("nfa_hciu_release_pipe: %u", pipe_id);
822
823 p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
824 if (p_pipe == nullptr) return (NFA_HCI_ANY_E_NOK);
825
826 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) {
827 DLOG_IF(INFO, nfc_debug_enabled)
828 << StringPrintf("ignore pipe: %d", pipe_id);
829 return (NFA_HCI_ANY_E_NOK);
830 }
831
832 pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
833
834 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
835 /* Remove pipe from ID management gate */
836 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
837 } else {
838 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
839 if (p_gate == nullptr) {
840 /* Mark the pipe control block as free */
841 p_pipe->pipe_id = 0;
842 return (NFA_HCI_ANY_E_NOK);
843 }
844
845 /* Remove pipe from gate */
846 p_gate->pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
847 }
848
849 /* Reset pipe control block */
850 memset(p_pipe, 0, sizeof(tNFA_HCI_DYN_PIPE));
851 nfa_hci_cb.nv_write_needed = true;
852 return NFA_HCI_ANY_OK;
853 }
854
855 /*******************************************************************************
856 **
857 ** Function nfa_hciu_remove_all_pipes_from_host
858 **
859 ** Description remove all the pipes that are connected to a specific host
860 **
861 ** Returns None
862 **
863 *******************************************************************************/
nfa_hciu_remove_all_pipes_from_host(uint8_t host)864 void nfa_hciu_remove_all_pipes_from_host(uint8_t host) {
865 tNFA_HCI_DYN_GATE* pg;
866 tNFA_HCI_DYN_PIPE* pp;
867 int xx;
868 tNFA_HCI_EVT_DATA evt_data;
869
870 DLOG_IF(INFO, nfc_debug_enabled)
871 << StringPrintf("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
872
873 /* Remove all pipes from the specified host connected to all generic gates */
874 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
875 xx++, pp++) {
876 if ((pp->pipe_id == 0) ||
877 ((host != 0) && ((pp->dest_host != host) ||
878 (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))))
879 continue;
880
881 pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
882 if (pg != nullptr) {
883 evt_data.deleted.status = NFA_STATUS_OK;
884 evt_data.deleted.pipe = pp->pipe_id;
885
886 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
887 }
888 nfa_hciu_release_pipe(pp->pipe_id);
889 }
890 }
891
892 /*******************************************************************************
893 **
894 ** Function nfa_hciu_send_create_pipe_cmd
895 **
896 ** Description Create dynamic pipe between the specified gates
897 **
898 ** Returns status
899 **
900 *******************************************************************************/
nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,uint8_t dest_host,uint8_t dest_gate)901 tNFA_STATUS nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,
902 uint8_t dest_host,
903 uint8_t dest_gate) {
904 tNFA_STATUS status;
905 uint8_t data[3];
906
907 data[0] = source_gate;
908 data[1] = dest_host;
909 data[2] = dest_gate;
910
911 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
912 "nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, "
913 "dest_gate:%d",
914 source_gate, dest_host, dest_gate);
915
916 status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
917 NFA_HCI_ADM_CREATE_PIPE, 3, data);
918
919 return status;
920 }
921
922 /*******************************************************************************
923 **
924 ** Function nfa_hciu_send_delete_pipe_cmd
925 **
926 ** Description Delete the dynamic pipe
927 **
928 ** Returns None
929 **
930 *******************************************************************************/
nfa_hciu_send_delete_pipe_cmd(uint8_t pipe)931 tNFA_STATUS nfa_hciu_send_delete_pipe_cmd(uint8_t pipe) {
932 tNFA_STATUS status;
933
934 DLOG_IF(INFO, nfc_debug_enabled)
935 << StringPrintf("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
936
937 if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE) {
938 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("ignore pipe: %d", pipe);
939 return (NFA_HCI_ANY_E_NOK);
940 }
941 nfa_hci_cb.pipe_in_use = pipe;
942
943 status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
944 NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
945
946 return status;
947 }
948
949 /*******************************************************************************
950 **
951 ** Function nfa_hciu_send_clear_all_pipe_cmd
952 **
953 ** Description delete all the dynamic pipe connected to device host,
954 ** to close all static pipes connected to device host,
955 ** and to set registry values related to static pipes to
956 ** theri default values.
957 **
958 ** Returns None
959 **
960 *******************************************************************************/
nfa_hciu_send_clear_all_pipe_cmd(void)961 tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd(void) {
962 tNFA_STATUS status;
963 uint16_t id_ref_data = 0x0102;
964
965 DLOG_IF(INFO, nfc_debug_enabled)
966 << StringPrintf("nfa_hciu_send_clear_all_pipe_cmd");
967
968 status =
969 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
970 NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (uint8_t*)&id_ref_data);
971
972 return status;
973 }
974
975 /*******************************************************************************
976 **
977 ** Function nfa_hciu_send_open_pipe_cmd
978 **
979 ** Description Open a closed pipe
980 **
981 ** Returns status
982 **
983 *******************************************************************************/
nfa_hciu_send_open_pipe_cmd(uint8_t pipe)984 tNFA_STATUS nfa_hciu_send_open_pipe_cmd(uint8_t pipe) {
985 tNFA_STATUS status;
986
987 nfa_hci_cb.pipe_in_use = pipe;
988
989 status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE,
990 0, nullptr);
991
992 return status;
993 }
994
995 /*******************************************************************************
996 **
997 ** Function nfa_hciu_send_close_pipe_cmd
998 **
999 ** Description Close an opened pipe
1000 **
1001 ** Returns status
1002 **
1003 *******************************************************************************/
nfa_hciu_send_close_pipe_cmd(uint8_t pipe)1004 tNFA_STATUS nfa_hciu_send_close_pipe_cmd(uint8_t pipe) {
1005 tNFA_STATUS status;
1006
1007 nfa_hci_cb.pipe_in_use = pipe;
1008
1009 status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE,
1010 0, nullptr);
1011
1012 return status;
1013 }
1014
1015 /*******************************************************************************
1016 **
1017 ** Function nfa_hciu_send_get_param_cmd
1018 **
1019 ** Description Read a parameter value from gate registry
1020 **
1021 ** Returns None
1022 **
1023 *******************************************************************************/
nfa_hciu_send_get_param_cmd(uint8_t pipe,uint8_t index)1024 tNFA_STATUS nfa_hciu_send_get_param_cmd(uint8_t pipe, uint8_t index) {
1025 tNFA_STATUS status;
1026
1027 status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE,
1028 NFA_HCI_ANY_GET_PARAMETER, 1, &index);
1029 if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
1030
1031 return status;
1032 }
1033
1034 /*******************************************************************************
1035 **
1036 ** Function nfa_hciu_send_set_param_cmd
1037 **
1038 ** Description Set a parameter value in a gate registry
1039 **
1040 ** Returns None
1041 **
1042 *******************************************************************************/
nfa_hciu_send_set_param_cmd(uint8_t pipe,uint8_t index,uint8_t length,uint8_t * p_data)1043 tNFA_STATUS nfa_hciu_send_set_param_cmd(uint8_t pipe, uint8_t index,
1044 uint8_t length, uint8_t* p_data) {
1045 tNFA_STATUS status;
1046 uint8_t data[255];
1047
1048 data[0] = index;
1049
1050 memcpy(&data[1], p_data, length);
1051
1052 status =
1053 nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER,
1054 (uint16_t)(length + 1), data);
1055 if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
1056
1057 return status;
1058 }
1059
1060 /*******************************************************************************
1061 **
1062 ** Function nfa_hciu_send_to_app
1063 **
1064 ** Description Send an event back to an application
1065 **
1066 ** Returns none
1067 **
1068 *******************************************************************************/
nfa_hciu_send_to_app(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt,tNFA_HANDLE app_handle)1069 void nfa_hciu_send_to_app(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt,
1070 tNFA_HANDLE app_handle) {
1071 uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
1072
1073 /* First, check if the application handle is valid */
1074 if (((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI) &&
1075 (app_inx < NFA_HCI_MAX_APP_CB)) {
1076 if (nfa_hci_cb.p_app_cback[app_inx] != nullptr) {
1077 nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1078 return;
1079 }
1080 }
1081
1082 if (app_handle != NFA_HANDLE_INVALID) {
1083 LOG(WARNING) << StringPrintf(
1084 "nfa_hciu_send_to_app no callback, event: 0x%04x app_handle: 0x%04x",
1085 event, app_handle);
1086 }
1087 }
1088
1089 /*******************************************************************************
1090 **
1091 ** Function nfa_hciu_send_to_all_apps
1092 **
1093 ** Description Send an event back to all applications
1094 **
1095 ** Returns none
1096 **
1097 *******************************************************************************/
nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1098 void nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
1099 uint8_t app_inx;
1100
1101 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
1102 if (nfa_hci_cb.p_app_cback[app_inx] != nullptr)
1103 nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1104 }
1105 }
1106
1107 /*******************************************************************************
1108 **
1109 ** Function nfa_hciu_send_to_apps_handling_connectivity_evts
1110 **
1111 ** Description Send a connectivity event to all the application interested
1112 ** in connectivity events
1113 **
1114 ** Returns none
1115 **
1116 *******************************************************************************/
nfa_hciu_send_to_apps_handling_connectivity_evts(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1117 void nfa_hciu_send_to_apps_handling_connectivity_evts(
1118 tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
1119 uint8_t app_inx;
1120
1121 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
1122 if ((nfa_hci_cb.p_app_cback[app_inx] != nullptr) &&
1123 (nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
1124
1125 nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1126 }
1127 }
1128
1129 /*******************************************************************************
1130 **
1131 ** Function nfa_hciu_get_response_name
1132 **
1133 ** Description This function returns the error code name.
1134 **
1135 ** NOTE conditionally compiled to save memory.
1136 **
1137 ** Returns pointer to the name
1138 **
1139 *******************************************************************************/
nfa_hciu_get_response_name(uint8_t rsp_code)1140 static std::string nfa_hciu_get_response_name(uint8_t rsp_code) {
1141 switch (rsp_code) {
1142 case NFA_HCI_ANY_OK:
1143 return "ANY_OK";
1144 case NFA_HCI_ANY_E_NOT_CONNECTED:
1145 return "ANY_E_NOT_CONNECTED";
1146 case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
1147 return "ANY_E_CMD_PAR_UNKNOWN";
1148 case NFA_HCI_ANY_E_NOK:
1149 return "ANY_E_NOK";
1150 case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
1151 return "ADM_E_NO_PIPES_AVAILABLE";
1152 case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
1153 return "ANY_E_REG_PAR_UNKNOWN";
1154 case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
1155 return "ANY_E_PIPE_NOT_OPENED";
1156 case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
1157 return "ANY_E_CMD_NOT_SUPPORTED";
1158 case NFA_HCI_ANY_E_INHIBITED:
1159 return "ANY_E_INHIBITED";
1160 case NFA_HCI_ANY_E_TIMEOUT:
1161 return "ANY_E_TIMEOUT";
1162 case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
1163 return "ANY_E_REG_ACCESS_DENIED";
1164 case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
1165 return "ANY_E_PIPE_ACCESS_DENIED";
1166 default:
1167 return "UNKNOWN";
1168 }
1169 }
1170
1171 /*******************************************************************************
1172 **
1173 ** Function nfa_hciu_type_2_str
1174 **
1175 ** Description This function returns the type name.
1176 **
1177 ** Returns pointer to the name
1178 **
1179 *******************************************************************************/
nfa_hciu_type_2_str(uint8_t type)1180 static std::string nfa_hciu_type_2_str(uint8_t type) {
1181 switch (type) {
1182 case NFA_HCI_COMMAND_TYPE:
1183 return "COMMAND";
1184 case NFA_HCI_EVENT_TYPE:
1185 return "EVENT";
1186 case NFA_HCI_RESPONSE_TYPE:
1187 return "RESPONSE";
1188 default:
1189 return "UNKNOWN";
1190 }
1191 }
1192
1193 /*******************************************************************************
1194 **
1195 ** Function nfa_hciu_instr_2_str
1196 **
1197 ** Description This function returns the instruction name.
1198 **
1199 ** Returns pointer to the name
1200 **
1201 *******************************************************************************/
nfa_hciu_instr_2_str(uint8_t instruction)1202 std::string nfa_hciu_instr_2_str(uint8_t instruction) {
1203 switch (instruction) {
1204 case NFA_HCI_ANY_SET_PARAMETER:
1205 return "ANY_SET_PARAMETER";
1206 case NFA_HCI_ANY_GET_PARAMETER:
1207 return "ANY_GET_PARAMETER";
1208 case NFA_HCI_ANY_OPEN_PIPE:
1209 return "ANY_OPEN_PIPE";
1210 case NFA_HCI_ANY_CLOSE_PIPE:
1211 return "ANY_CLOSE_PIPE";
1212 case NFA_HCI_ADM_CREATE_PIPE:
1213 return "ADM_CREATE_PIPE";
1214 case NFA_HCI_ADM_DELETE_PIPE:
1215 return "ADM_DELETE_PIPE";
1216 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1217 return "ADM_NOTIFY_PIPE_CREATED";
1218 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1219 return "ADM_NOTIFY_PIPE_DELETED";
1220 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1221 return "ADM_CLEAR_ALL_PIPE";
1222 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1223 return "ADM_NOTIFY_ALL_PIPE_CLEARED";
1224 default:
1225 return "UNKNOWN";
1226 }
1227 }
1228
1229 /*******************************************************************************
1230 **
1231 ** Function nfa_hciu_get_event_name
1232 **
1233 ** Description This function returns the event code name.
1234 **
1235 ** Returns pointer to the name
1236 **
1237 *******************************************************************************/
nfa_hciu_get_event_name(uint16_t event)1238 std::string nfa_hciu_get_event_name(uint16_t event) {
1239 switch (event) {
1240 case NFA_HCI_API_REGISTER_APP_EVT:
1241 return "API_REGISTER";
1242 case NFA_HCI_API_DEREGISTER_APP_EVT:
1243 return "API_DEREGISTER";
1244 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
1245 return "API_GET_GATE_LIST";
1246 case NFA_HCI_API_ALLOC_GATE_EVT:
1247 return "API_ALLOC_GATE";
1248 case NFA_HCI_API_DEALLOC_GATE_EVT:
1249 return "API_DEALLOC_GATE";
1250 case NFA_HCI_API_GET_HOST_LIST_EVT:
1251 return "API_GET_HOST_LIST";
1252 case NFA_HCI_API_GET_REGISTRY_EVT:
1253 return "API_GET_REG_VALUE";
1254 case NFA_HCI_API_SET_REGISTRY_EVT:
1255 return "API_SET_REG_VALUE";
1256 case NFA_HCI_API_CREATE_PIPE_EVT:
1257 return "API_CREATE_PIPE";
1258 case NFA_HCI_API_OPEN_PIPE_EVT:
1259 return "API_OPEN_PIPE";
1260 case NFA_HCI_API_CLOSE_PIPE_EVT:
1261 return "API_CLOSE_PIPE";
1262 case NFA_HCI_API_DELETE_PIPE_EVT:
1263 return "API_DELETE_PIPE";
1264 case NFA_HCI_API_SEND_CMD_EVT:
1265 return "API_SEND_COMMAND_EVT";
1266 case NFA_HCI_API_SEND_RSP_EVT:
1267 return "API_SEND_RESPONSE_EVT";
1268 case NFA_HCI_API_SEND_EVENT_EVT:
1269 return "API_SEND_EVENT_EVT";
1270 case NFA_HCI_RSP_NV_READ_EVT:
1271 return "NV_READ_EVT";
1272 case NFA_HCI_RSP_NV_WRITE_EVT:
1273 return "NV_WRITE_EVT";
1274 case NFA_HCI_RSP_TIMEOUT_EVT:
1275 return "RESPONSE_TIMEOUT_EVT";
1276 case NFA_HCI_CHECK_QUEUE_EVT:
1277 return "CHECK_QUEUE";
1278 default:
1279 return "UNKNOWN";
1280 }
1281 }
1282
1283 /*******************************************************************************
1284 **
1285 ** Function nfa_hciu_get_state_name
1286 **
1287 ** Description This function returns the state name.
1288 **
1289 ** Returns pointer to the name
1290 **
1291 *******************************************************************************/
nfa_hciu_get_state_name(uint8_t state)1292 std::string nfa_hciu_get_state_name(uint8_t state) {
1293 switch (state) {
1294 case NFA_HCI_STATE_DISABLED:
1295 return "DISABLED";
1296 case NFA_HCI_STATE_STARTUP:
1297 return "STARTUP";
1298 case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
1299 return "WAIT_NETWK_ENABLE";
1300 case NFA_HCI_STATE_IDLE:
1301 return "IDLE";
1302 case NFA_HCI_STATE_WAIT_RSP:
1303 return "WAIT_RSP";
1304 case NFA_HCI_STATE_REMOVE_GATE:
1305 return "REMOVE_GATE";
1306 case NFA_HCI_STATE_APP_DEREGISTER:
1307 return "APP_DEREGISTER";
1308 case NFA_HCI_STATE_RESTORE:
1309 return "RESTORE";
1310 case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
1311 return "WAIT_NETWK_ENABLE_AFTER_RESTORE";
1312 default:
1313 return "UNKNOWN";
1314 }
1315 }
1316
1317 /*******************************************************************************
1318 **
1319 ** Function nfa_hciu_get_type_inst_names
1320 **
1321 ** Description This function returns command/response/event name.
1322 **
1323 ** Returns none
1324 **
1325 *******************************************************************************/
nfa_hciu_get_type_inst_names(uint8_t pipe,uint8_t type,uint8_t inst,char * p_buff,const uint8_t max_buff_size)1326 char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type, uint8_t inst,
1327 char* p_buff, const uint8_t max_buff_size) {
1328 int xx;
1329
1330 xx = snprintf(p_buff, max_buff_size, "Type: %s [0x%02x] ",
1331 nfa_hciu_type_2_str(type).c_str(), type);
1332
1333 switch (type) {
1334 case NFA_HCI_COMMAND_TYPE:
1335 snprintf(&p_buff[xx], max_buff_size - xx, "Inst: %s [0x%02x] ",
1336 nfa_hciu_instr_2_str(inst).c_str(), inst);
1337
1338 break;
1339 case NFA_HCI_EVENT_TYPE:
1340 snprintf(&p_buff[xx], max_buff_size - xx, "Evt: %s [0x%02x] ",
1341 nfa_hciu_evt_2_str(pipe, inst).c_str(), inst);
1342
1343 break;
1344 case NFA_HCI_RESPONSE_TYPE:
1345 snprintf(&p_buff[xx], max_buff_size - xx, "Resp: %s [0x%02x] ",
1346 nfa_hciu_get_response_name(inst).c_str(), inst);
1347
1348 break;
1349 default:
1350 snprintf(&p_buff[xx], max_buff_size - xx, "Inst: %u ", inst);
1351 break;
1352 }
1353 return p_buff;
1354 }
1355
1356 /*******************************************************************************
1357 **
1358 ** Function nfa_hciu_evt_2_str
1359 **
1360 ** Description This function returns the event name.
1361 **
1362 ** Returns pointer to the name
1363 **
1364 *******************************************************************************/
nfa_hciu_evt_2_str(uint8_t pipe_id,uint8_t evt)1365 std::string nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt) {
1366 tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1367 if (pipe_id != NFA_HCI_ADMIN_PIPE &&
1368 pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE && p_pipe != nullptr &&
1369 p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) {
1370 switch (evt) {
1371 case NFA_HCI_EVT_CONNECTIVITY:
1372 return "EVT_CONNECTIVITY";
1373 case NFA_HCI_EVT_TRANSACTION:
1374 return "EVT_TRANSACTION";
1375 case NFA_HCI_EVT_OPERATION_ENDED:
1376 return "EVT_OPERATION_ENDED";
1377 default:
1378 return "UNKNOWN";
1379 }
1380 }
1381
1382 switch (evt) {
1383 case NFA_HCI_EVT_HCI_END_OF_OPERATION:
1384 return "EVT_END_OF_OPERATION";
1385 case NFA_HCI_EVT_POST_DATA:
1386 return "EVT_POST_DATA";
1387 case NFA_HCI_EVT_HOT_PLUG:
1388 return "EVT_HOT_PLUG";
1389 default:
1390 return "UNKNOWN";
1391 }
1392 }
1393
handle_debug_loopback(NFC_HDR * p_buf,uint8_t type,uint8_t instruction)1394 static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t type,
1395 uint8_t instruction) {
1396 uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1397 static uint8_t next_pipe = 0x10;
1398
1399 if (type == NFA_HCI_COMMAND_TYPE) {
1400 switch (instruction) {
1401 case NFA_HCI_ADM_CREATE_PIPE:
1402 p[6] = next_pipe++;
1403 p[5] = p[4];
1404 p[4] = p[3];
1405 p[3] = p[2];
1406 p[2] = 3;
1407 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1408 p_buf->len = p_buf->offset + 7;
1409 break;
1410
1411 case NFA_HCI_ANY_GET_PARAMETER:
1412 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1413 memcpy(&p[2], (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id,
1414 NFA_HCI_SESSION_ID_LEN);
1415 p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
1416 break;
1417
1418 default:
1419 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1420 p_buf->len = p_buf->offset + 2;
1421 break;
1422 }
1423 } else if (type == NFA_HCI_RESPONSE_TYPE) {
1424 GKI_freebuf(p_buf);
1425 return;
1426 }
1427
1428 p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
1429 nfa_sys_sendmsg(p_buf);
1430 }
1431