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