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/logging.h>
25 #include <android-base/stringprintf.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 #include "nfc_config.h"
35
36 using android::base::StringPrintf;
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("%s: no free Gate ID=%u App Handle=0x%04x",
260 __func__, gate_id_index, app_handle);
261 return (nullptr);
262 }
263 }
264
265 /* Now look for a free control block */
266 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
267 xx++, pg++) {
268 if (pg->gate_id == 0) {
269 /* Found a free gate control block */
270 pg->gate_id = gate_id;
271 pg->gate_owner = app_handle;
272 pg->pipe_inx_mask = 0;
273
274 LOG(VERBOSE) << StringPrintf("%s: id=%d app_handle=0x%04x", __func__,
275 gate_id, app_handle);
276
277 nfa_hci_cb.nv_write_needed = true;
278 return (pg);
279 }
280 }
281
282 /* If here, no free gate control block */
283 LOG(ERROR) << StringPrintf("%s: no CB Gate ID=%u App Handle=0x%04x",
284 __func__, gate_id, app_handle);
285 return (nullptr);
286 }
287
288 /*******************************************************************************
289 **
290 ** Function nfa_hciu_send_msg
291 **
292 ** Description This function will fragment the given packet, if necessary
293 ** and send it on the given pipe.
294 **
295 ** Returns status
296 **
297 *******************************************************************************/
nfa_hciu_send_msg(uint8_t pipe_id,uint8_t type,uint8_t instruction,uint16_t msg_len,uint8_t * p_msg)298 tNFA_STATUS nfa_hciu_send_msg(uint8_t pipe_id, uint8_t type,
299 uint8_t instruction, uint16_t msg_len,
300 uint8_t* p_msg) {
301 NFC_HDR* p_buf;
302 uint8_t* p_data;
303 bool first_pkt = true;
304 uint16_t data_len;
305 tNFA_STATUS status = NFA_STATUS_OK;
306 if ((msg_len != 0) && (p_msg == nullptr)) {
307 LOG(ERROR) << StringPrintf("%s: msg_len is 0 and p_msg is null", __func__);
308 return NFA_STATUS_FAILED;
309 }
310 uint16_t max_seg_hcp_pkt_size;
311 if (nfa_hci_cb.buff_size > (NCI_DATA_HDR_SIZE + 2)) {
312 max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
313 } else {
314 android_errorWriteLog(0x534e4554, "124521372");
315 return NFA_STATUS_NO_BUFFERS;
316 }
317 const uint8_t MAX_BUFF_SIZE = 100;
318 char buff[MAX_BUFF_SIZE];
319
320 LOG(VERBOSE) << StringPrintf(
321 "%s: pipe_id=%d %s len=%d", __func__, pipe_id,
322 nfa_hciu_get_type_inst_names(pipe_id, type, instruction, buff,
323 MAX_BUFF_SIZE),
324 msg_len);
325
326 if (instruction == NFA_HCI_ANY_GET_PARAMETER)
327 nfa_hci_cb.param_in_use = *p_msg;
328
329 while ((first_pkt == true) || (msg_len != 0)) {
330 p_buf = (NFC_HDR*)GKI_getpoolbuf(NFC_RW_POOL_ID);
331 if (p_buf != nullptr) {
332 p_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
333
334 /* First packet has a 2-byte header, subsequent fragments have a 1-byte
335 * header */
336 data_len =
337 first_pkt ? (max_seg_hcp_pkt_size - 2) : (max_seg_hcp_pkt_size - 1);
338
339 p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
340
341 /* Last or only segment has "no fragmentation" bit set */
342 if (msg_len > data_len) {
343 *p_data++ = (NFA_HCI_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
344 } else {
345 data_len = msg_len;
346 *p_data++ = (NFA_HCI_NO_MESSAGE_FRAGMENTATION << 7) | (pipe_id & 0x7F);
347 }
348
349 p_buf->len = 1;
350
351 /* Message header only goes in the first segment */
352 if (first_pkt) {
353 first_pkt = false;
354 *p_data++ = (type << 6) | instruction;
355 p_buf->len++;
356 }
357
358 if (data_len != 0) {
359 memcpy(p_data, p_msg, data_len);
360
361 p_buf->len += data_len;
362 if (msg_len >= data_len) {
363 msg_len -= data_len;
364 p_msg += data_len;
365 } else {
366 msg_len = 0;
367 }
368 }
369
370 if (HCI_LOOPBACK_DEBUG == NFA_HCI_DEBUG_ON)
371 handle_debug_loopback(p_buf, type, instruction);
372 else
373 status = NFC_SendData(nfa_hci_cb.conn_id, p_buf);
374 } else {
375 LOG(ERROR) << StringPrintf("%s: no buffers", __func__);
376 status = NFA_STATUS_NO_BUFFERS;
377 break;
378 }
379 }
380
381 /* Start timer if response to wait for a particular time for the response */
382 if (type == NFA_HCI_COMMAND_TYPE) {
383 nfa_hci_cb.cmd_sent = instruction;
384
385 if (nfa_hci_cb.hci_state == NFA_HCI_STATE_IDLE)
386 nfa_hci_cb.hci_state = NFA_HCI_STATE_WAIT_RSP;
387
388 nfa_sys_start_timer(&nfa_hci_cb.timer, NFA_HCI_RSP_TIMEOUT_EVT,
389 p_nfa_hci_cfg->hcp_response_timeout);
390 }
391
392 return status;
393 }
394
395 /*******************************************************************************
396 **
397 ** Function nfa_hciu_get_allocated_gate_list
398 **
399 ** Description fills in a list of allocated gates
400 **
401 ** Returns the number of gates
402 **
403 *******************************************************************************/
nfa_hciu_get_allocated_gate_list(uint8_t * p_gate_list)404 uint8_t nfa_hciu_get_allocated_gate_list(uint8_t* p_gate_list) {
405 tNFA_HCI_DYN_GATE* p_cb;
406 int xx;
407 uint8_t count = 0;
408
409 for (xx = 0, p_cb = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB;
410 xx++, p_cb++) {
411 if (p_cb->gate_id != 0) {
412 *p_gate_list++ = p_cb->gate_id;
413 count++;
414 }
415 }
416
417 LOG(VERBOSE) << StringPrintf("%s: returns=%u", __func__, count);
418
419 return (count);
420 }
421
422 /*******************************************************************************
423 **
424 ** Function nfa_hciu_alloc_pipe
425 **
426 ** Description Allocate a pipe control block
427 **
428 ** Returns pointer to the pipe control block, or NULL if
429 ** cannot allocate
430 **
431 *******************************************************************************/
nfa_hciu_alloc_pipe(uint8_t pipe_id)432 tNFA_HCI_DYN_PIPE* nfa_hciu_alloc_pipe(uint8_t pipe_id) {
433 uint8_t xx;
434 tNFA_HCI_DYN_PIPE* pp;
435
436 /* If we already have a pipe of the same ID, release it first it */
437 pp = nfa_hciu_find_pipe_by_pid(pipe_id);
438 if (pp != nullptr) {
439 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) return pp;
440 nfa_hciu_release_pipe(pipe_id);
441 }
442
443 /* Look for a free pipe control block */
444 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
445 xx++, pp++) {
446 if (pp->pipe_id == 0) {
447 LOG(VERBOSE) << StringPrintf("%s: pipe_id=%d, index=%d", __func__,
448 pipe_id, xx);
449 pp->pipe_id = pipe_id;
450
451 nfa_hci_cb.nv_write_needed = true;
452 return (pp);
453 }
454 }
455
456 LOG(VERBOSE) << StringPrintf("%s: pipe_id=%d, NO free entries !!", __func__,
457 pipe_id);
458 return (nullptr);
459 }
460
461 /*******************************************************************************
462 **
463 ** Function nfa_hciu_release_gate
464 **
465 ** Description Remove a generic gate from gate list
466 **
467 ** Returns none
468 **
469 *******************************************************************************/
nfa_hciu_release_gate(uint8_t gate_id)470 void nfa_hciu_release_gate(uint8_t gate_id) {
471 tNFA_HCI_DYN_GATE* p_gate = nfa_hciu_find_gate_by_gid(gate_id);
472
473 if (p_gate != nullptr) {
474 LOG(VERBOSE) << StringPrintf(
475 "%s: gate_id=%d owner=0x%04x pipe_inx_mask=0x%04x", __func__, gate_id,
476 p_gate->gate_owner, p_gate->pipe_inx_mask);
477
478 p_gate->gate_id = 0;
479 p_gate->gate_owner = 0;
480 p_gate->pipe_inx_mask = 0;
481
482 nfa_hci_cb.nv_write_needed = true;
483 } else {
484 LOG(WARNING) << StringPrintf("%s: gate_id=%d NOT FOUND", __func__,
485 gate_id);
486 }
487 }
488
489 /*******************************************************************************
490 **
491 ** Function nfa_hciu_add_pipe_to_gate
492 **
493 ** Description Add pipe to generic gate
494 **
495 ** Returns NFA_STATUS_OK, if successfully add the pipe on to the gate
496 ** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
497 **
498 *******************************************************************************/
nfa_hciu_add_pipe_to_gate(uint8_t pipe_id,uint8_t local_gate,uint8_t dest_host,uint8_t dest_gate)499 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_gate(uint8_t pipe_id, uint8_t local_gate,
500 uint8_t dest_host,
501 uint8_t dest_gate) {
502 tNFA_HCI_DYN_GATE* p_gate;
503 tNFA_HCI_DYN_PIPE* p_pipe;
504 uint8_t pipe_index;
505
506 p_gate = nfa_hciu_find_gate_by_gid(local_gate);
507
508 if (p_gate != nullptr) {
509 /* Allocate a pipe control block */
510 p_pipe = nfa_hciu_alloc_pipe(pipe_id);
511 if (p_pipe != nullptr) {
512 p_pipe->pipe_id = pipe_id;
513 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
514 p_pipe->dest_host = dest_host;
515 p_pipe->dest_gate = dest_gate;
516 p_pipe->local_gate = local_gate;
517
518 /* Save the pipe in the gate that it belongs to */
519 pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
520 p_gate->pipe_inx_mask |= (uint32_t)(1 << pipe_index);
521
522 LOG(VERBOSE) << StringPrintf(
523 "%s: Gate ID=0x%02x Pipe ID=0x%02x "
524 "pipe_index=%u App Handle=0x%08x",
525 __func__, local_gate, pipe_id, pipe_index, p_gate->gate_owner);
526 return (NFA_HCI_ANY_OK);
527 }
528 }
529
530 LOG(VERBOSE) << StringPrintf("%s:: local_gate=0x%02x NOT FOUND", __func__,
531 local_gate);
532
533 return (NFA_HCI_ADM_E_NO_PIPES_AVAILABLE);
534 }
535
536 /*******************************************************************************
537 **
538 ** Function nfa_hciu_add_pipe_to_static_gate
539 **
540 ** Description Add pipe to identity management gate
541 **
542 ** Returns NFA_HCI_ANY_OK, if successfully add the pipe on to the gate
543 ** NFA_HCI_ADM_E_NO_PIPES_AVAILABLE, otherwise
544 **
545 *******************************************************************************/
nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,uint8_t pipe_id,uint8_t dest_host,uint8_t dest_gate)546 tNFA_HCI_RESPONSE nfa_hciu_add_pipe_to_static_gate(uint8_t local_gate,
547 uint8_t pipe_id,
548 uint8_t dest_host,
549 uint8_t dest_gate) {
550 tNFA_HCI_DYN_PIPE* p_pipe;
551 uint8_t pipe_index;
552
553 LOG(VERBOSE) << StringPrintf(
554 "%s: (%u) Pipe=0x%02x Dest Host=0x%02x "
555 "Dest Gate=0x%02x)",
556 __func__, local_gate, pipe_id, dest_host, dest_gate);
557
558 /* Allocate a pipe control block */
559 p_pipe = nfa_hciu_alloc_pipe(pipe_id);
560 if (p_pipe != nullptr) {
561 p_pipe->pipe_id = pipe_id;
562 p_pipe->pipe_state = NFA_HCI_PIPE_CLOSED;
563 p_pipe->dest_host = dest_host;
564 p_pipe->dest_gate = dest_gate;
565 p_pipe->local_gate = local_gate;
566
567 /* If this is the ID gate, save the pipe index in the ID gate info */
568 /* block. Note that for loopback, it is enough to just create the pipe */
569 if (local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
570 pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
571 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask |= (uint32_t)(1 << pipe_index);
572 }
573 return NFA_HCI_ANY_OK;
574 }
575
576 return NFA_HCI_ADM_E_NO_PIPES_AVAILABLE;
577 }
578
579 /*******************************************************************************
580 **
581 ** Function nfa_hciu_find_active_pipe_by_owner
582 **
583 ** Description Find the first pipe associated with the given app
584 **
585 ** Returns pointer to pipe, or NULL if none found
586 **
587 *******************************************************************************/
nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle)588 tNFA_HCI_DYN_PIPE* nfa_hciu_find_active_pipe_by_owner(tNFA_HANDLE app_handle) {
589 tNFA_HCI_DYN_GATE* pg;
590 tNFA_HCI_DYN_PIPE* pp;
591 int xx;
592
593 LOG(VERBOSE) << StringPrintf("%s: app_handle=0x%x", __func__, app_handle);
594
595 /* Loop through all pipes looking for the owner */
596 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
597 xx++, pp++) {
598 if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
599 (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
600 (nfa_hciu_is_active_host(pp->dest_host))) {
601 if (((pg = nfa_hciu_find_gate_by_gid(pp->local_gate)) != nullptr) &&
602 (pg->gate_owner == app_handle))
603 return (pp);
604 }
605 }
606
607 /* If here, not found */
608 return (nullptr);
609 }
610
611 /*******************************************************************************
612 **
613 ** Function nfa_hciu_check_pipe_between_gates
614 **
615 ** Description Check if there is a pipe between specified Terminal host
616 ** gate and and the specified UICC gate
617 **
618 ** Returns TRUE, if there exists a pipe between the two specified gated
619 ** FALSE, otherwise
620 **
621 *******************************************************************************/
nfa_hciu_check_pipe_between_gates(uint8_t local_gate,uint8_t dest_host,uint8_t dest_gate)622 bool nfa_hciu_check_pipe_between_gates(uint8_t local_gate, uint8_t dest_host,
623 uint8_t dest_gate) {
624 tNFA_HCI_DYN_PIPE* pp;
625 int xx;
626
627 LOG(VERBOSE) << StringPrintf(
628 "%s: Local gate=0x%02X, Host[0x%02X] "
629 "gate=0x%02X",
630 __func__, local_gate, dest_host, dest_gate);
631
632 /* Loop through all pipes looking for the owner */
633 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
634 xx++, pp++) {
635 if ((pp->pipe_id != 0) && (pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE) &&
636 (pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE) &&
637 (pp->local_gate == local_gate) && (pp->dest_host == dest_host) &&
638 (pp->dest_gate == dest_gate)) {
639 return true;
640 }
641 }
642
643 /* If here, not found */
644 return false;
645 }
646
647 /*******************************************************************************
648 **
649 ** Function nfa_hciu_find_pipe_by_owner
650 **
651 ** Description Find the first pipe associated with the given app
652 **
653 ** Returns pointer to pipe, or NULL if none found
654 **
655 *******************************************************************************/
nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle)656 tNFA_HCI_DYN_PIPE* nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle) {
657 tNFA_HCI_DYN_GATE* pg;
658 tNFA_HCI_DYN_PIPE* pp;
659 int xx;
660
661 LOG(VERBOSE) << StringPrintf("%s: app_handle=0x%x", __func__, 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 LOG(VERBOSE) << StringPrintf("%s: Gate=0x%x", __func__, 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 LOG(VERBOSE) << StringPrintf("%s: Gate=0x%x", __func__, 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 LOG(VERBOSE) << StringPrintf("%s: pipe_id=%u", __func__, pipe_id);
821
822 p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
823 if (p_pipe == nullptr) return (NFA_HCI_ANY_E_NOK);
824
825 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE) {
826 LOG(VERBOSE) << StringPrintf("%s: ignore pipe=%d", __func__, pipe_id);
827 return (NFA_HCI_ANY_E_NOK);
828 }
829
830 pipe_index = (uint8_t)(p_pipe - nfa_hci_cb.cfg.dyn_pipes);
831
832 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE) {
833 /* Remove pipe from ID management gate */
834 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
835 } else {
836 p_gate = nfa_hciu_find_gate_by_gid(p_pipe->local_gate);
837 if (p_gate == nullptr) {
838 /* Mark the pipe control block as free */
839 p_pipe->pipe_id = 0;
840 return (NFA_HCI_ANY_E_NOK);
841 }
842
843 /* Remove pipe from gate */
844 p_gate->pipe_inx_mask &= ~(uint32_t)(1 << pipe_index);
845 }
846
847 /* Reset pipe control block */
848 memset(p_pipe, 0, sizeof(tNFA_HCI_DYN_PIPE));
849 nfa_hci_cb.nv_write_needed = true;
850 return NFA_HCI_ANY_OK;
851 }
852
853 /*******************************************************************************
854 **
855 ** Function nfa_hciu_remove_all_pipes_from_host
856 **
857 ** Description remove all the pipes that are connected to a specific host
858 **
859 ** Returns None
860 **
861 *******************************************************************************/
nfa_hciu_remove_all_pipes_from_host(uint8_t host)862 void nfa_hciu_remove_all_pipes_from_host(uint8_t host) {
863 tNFA_HCI_DYN_GATE* pg;
864 tNFA_HCI_DYN_PIPE* pp;
865 int xx;
866 tNFA_HCI_EVT_DATA evt_data;
867
868 LOG(VERBOSE) << StringPrintf("%s: (0x%02x)", __func__, host);
869
870 /* Remove all pipes from the specified host connected to all generic gates */
871 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB;
872 xx++, pp++) {
873 if ((pp->pipe_id == 0) ||
874 ((host != 0) && ((pp->dest_host != host) ||
875 (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))))
876 continue;
877
878 pg = nfa_hciu_find_gate_by_gid(pp->local_gate);
879 if (pg != nullptr) {
880 evt_data.deleted.status = NFA_STATUS_OK;
881 evt_data.deleted.pipe = pp->pipe_id;
882
883 nfa_hciu_send_to_app(NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
884 }
885 nfa_hciu_release_pipe(pp->pipe_id);
886 }
887 }
888
889 /*******************************************************************************
890 **
891 ** Function nfa_hciu_send_create_pipe_cmd
892 **
893 ** Description Create dynamic pipe between the specified gates
894 **
895 ** Returns status
896 **
897 *******************************************************************************/
nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,uint8_t dest_host,uint8_t dest_gate)898 tNFA_STATUS nfa_hciu_send_create_pipe_cmd(uint8_t source_gate,
899 uint8_t dest_host,
900 uint8_t dest_gate) {
901 tNFA_STATUS status;
902 uint8_t data[3];
903
904 data[0] = source_gate;
905 data[1] = dest_host;
906 data[2] = dest_gate;
907
908 LOG(VERBOSE) << StringPrintf(
909 "%s: source_gate=%d, dest_host=%d, "
910 "dest_gate=%d",
911 __func__, source_gate, dest_host, dest_gate);
912
913 status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
914 NFA_HCI_ADM_CREATE_PIPE, 3, data);
915
916 return status;
917 }
918
919 /*******************************************************************************
920 **
921 ** Function nfa_hciu_send_delete_pipe_cmd
922 **
923 ** Description Delete the dynamic pipe
924 **
925 ** Returns None
926 **
927 *******************************************************************************/
nfa_hciu_send_delete_pipe_cmd(uint8_t pipe)928 tNFA_STATUS nfa_hciu_send_delete_pipe_cmd(uint8_t pipe) {
929 tNFA_STATUS status;
930
931 LOG(VERBOSE) << StringPrintf("%s: pipe=%d", __func__, pipe);
932
933 if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE) {
934 LOG(VERBOSE) << StringPrintf("%s: ignore pipe=%d", __func__, pipe);
935 return (NFA_HCI_ANY_E_NOK);
936 }
937 nfa_hci_cb.pipe_in_use = pipe;
938
939 status = nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
940 NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
941
942 return status;
943 }
944
945 /*******************************************************************************
946 **
947 ** Function nfa_hciu_send_clear_all_pipe_cmd
948 **
949 ** Description delete all the dynamic pipe connected to device host,
950 ** to close all static pipes connected to device host,
951 ** and to set registry values related to static pipes to
952 ** theri default values.
953 **
954 ** Returns None
955 **
956 *******************************************************************************/
nfa_hciu_send_clear_all_pipe_cmd(void)957 tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd(void) {
958 tNFA_STATUS status;
959 uint16_t id_ref_data = 0x0102;
960
961 LOG(VERBOSE) << __func__;
962
963 status =
964 nfa_hciu_send_msg(NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE,
965 NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (uint8_t*)&id_ref_data);
966
967 return status;
968 }
969
970 /*******************************************************************************
971 **
972 ** Function nfa_hciu_send_open_pipe_cmd
973 **
974 ** Description Open a closed pipe
975 **
976 ** Returns status
977 **
978 *******************************************************************************/
nfa_hciu_send_open_pipe_cmd(uint8_t pipe)979 tNFA_STATUS nfa_hciu_send_open_pipe_cmd(uint8_t pipe) {
980 tNFA_STATUS status;
981
982 nfa_hci_cb.pipe_in_use = pipe;
983
984 status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE,
985 0, nullptr);
986
987 return status;
988 }
989
990 /*******************************************************************************
991 **
992 ** Function nfa_hciu_send_close_pipe_cmd
993 **
994 ** Description Close an opened pipe
995 **
996 ** Returns status
997 **
998 *******************************************************************************/
nfa_hciu_send_close_pipe_cmd(uint8_t pipe)999 tNFA_STATUS nfa_hciu_send_close_pipe_cmd(uint8_t pipe) {
1000 tNFA_STATUS status;
1001
1002 nfa_hci_cb.pipe_in_use = pipe;
1003
1004 status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE,
1005 0, nullptr);
1006
1007 return status;
1008 }
1009
1010 /*******************************************************************************
1011 **
1012 ** Function nfa_hciu_send_get_param_cmd
1013 **
1014 ** Description Read a parameter value from gate registry
1015 **
1016 ** Returns None
1017 **
1018 *******************************************************************************/
nfa_hciu_send_get_param_cmd(uint8_t pipe,uint8_t index)1019 tNFA_STATUS nfa_hciu_send_get_param_cmd(uint8_t pipe, uint8_t index) {
1020 tNFA_STATUS status;
1021
1022 status = nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE,
1023 NFA_HCI_ANY_GET_PARAMETER, 1, &index);
1024 if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
1025
1026 return status;
1027 }
1028
1029 /*******************************************************************************
1030 **
1031 ** Function nfa_hciu_send_set_param_cmd
1032 **
1033 ** Description Set a parameter value in a gate registry
1034 **
1035 ** Returns None
1036 **
1037 *******************************************************************************/
nfa_hciu_send_set_param_cmd(uint8_t pipe,uint8_t index,uint8_t length,uint8_t * p_data)1038 tNFA_STATUS nfa_hciu_send_set_param_cmd(uint8_t pipe, uint8_t index,
1039 uint8_t length, uint8_t* p_data) {
1040 tNFA_STATUS status;
1041 uint8_t data[255];
1042
1043 data[0] = index;
1044
1045 memcpy(&data[1], p_data, length);
1046
1047 status =
1048 nfa_hciu_send_msg(pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER,
1049 (uint16_t)(length + 1), data);
1050 if (status == NFC_STATUS_OK) nfa_hci_cb.param_in_use = index;
1051
1052 return status;
1053 }
1054
1055 /*******************************************************************************
1056 **
1057 ** Function nfa_hciu_send_to_app
1058 **
1059 ** Description Send an event back to an application
1060 **
1061 ** Returns none
1062 **
1063 *******************************************************************************/
nfa_hciu_send_to_app(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt,tNFA_HANDLE app_handle)1064 void nfa_hciu_send_to_app(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt,
1065 tNFA_HANDLE app_handle) {
1066 uint8_t app_inx = app_handle & NFA_HANDLE_MASK;
1067
1068 /* First, check if the application handle is valid */
1069 if (((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI) &&
1070 (app_inx < NFA_HCI_MAX_APP_CB)) {
1071 if (nfa_hci_cb.p_app_cback[app_inx] != nullptr) {
1072 nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1073 return;
1074 }
1075 }
1076
1077 if (app_handle != NFA_HANDLE_INVALID) {
1078 LOG(WARNING) << StringPrintf(
1079 "%s: no callback, event=0x%04x app_handle=0x%04x", __func__, event,
1080 app_handle);
1081 }
1082 }
1083
1084 /*******************************************************************************
1085 **
1086 ** Function nfa_hciu_send_to_all_apps
1087 **
1088 ** Description Send an event back to all applications
1089 **
1090 ** Returns none
1091 **
1092 *******************************************************************************/
nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1093 void nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
1094 uint8_t app_inx;
1095
1096 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
1097 if (nfa_hci_cb.p_app_cback[app_inx] != nullptr)
1098 nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1099 }
1100 }
1101
1102 /*******************************************************************************
1103 **
1104 ** Function nfa_hciu_send_to_apps_handling_connectivity_evts
1105 **
1106 ** Description Send a connectivity event to all the application interested
1107 ** in connectivity events
1108 **
1109 ** Returns none
1110 **
1111 *******************************************************************************/
nfa_hciu_send_to_apps_handling_connectivity_evts(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1112 void nfa_hciu_send_to_apps_handling_connectivity_evts(
1113 tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* p_evt) {
1114 uint8_t app_inx;
1115
1116 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++) {
1117 if ((nfa_hci_cb.p_app_cback[app_inx] != nullptr) &&
1118 (nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
1119
1120 nfa_hci_cb.p_app_cback[app_inx](event, p_evt);
1121 }
1122 }
1123
1124 /*******************************************************************************
1125 **
1126 ** Function nfa_hciu_get_response_name
1127 **
1128 ** Description This function returns the error code name.
1129 **
1130 ** NOTE conditionally compiled to save memory.
1131 **
1132 ** Returns pointer to the name
1133 **
1134 *******************************************************************************/
nfa_hciu_get_response_name(uint8_t rsp_code)1135 static std::string nfa_hciu_get_response_name(uint8_t rsp_code) {
1136 switch (rsp_code) {
1137 case NFA_HCI_ANY_OK:
1138 return "ANY_OK";
1139 case NFA_HCI_ANY_E_NOT_CONNECTED:
1140 return "ANY_E_NOT_CONNECTED";
1141 case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
1142 return "ANY_E_CMD_PAR_UNKNOWN";
1143 case NFA_HCI_ANY_E_NOK:
1144 return "ANY_E_NOK";
1145 case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
1146 return "ADM_E_NO_PIPES_AVAILABLE";
1147 case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
1148 return "ANY_E_REG_PAR_UNKNOWN";
1149 case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
1150 return "ANY_E_PIPE_NOT_OPENED";
1151 case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
1152 return "ANY_E_CMD_NOT_SUPPORTED";
1153 case NFA_HCI_ANY_E_INHIBITED:
1154 return "ANY_E_INHIBITED";
1155 case NFA_HCI_ANY_E_TIMEOUT:
1156 return "ANY_E_TIMEOUT";
1157 case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
1158 return "ANY_E_REG_ACCESS_DENIED";
1159 case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
1160 return "ANY_E_PIPE_ACCESS_DENIED";
1161 default:
1162 return "UNKNOWN";
1163 }
1164 }
1165
1166 /*******************************************************************************
1167 **
1168 ** Function nfa_hciu_type_2_str
1169 **
1170 ** Description This function returns the type name.
1171 **
1172 ** Returns pointer to the name
1173 **
1174 *******************************************************************************/
nfa_hciu_type_2_str(uint8_t type)1175 static std::string nfa_hciu_type_2_str(uint8_t type) {
1176 switch (type) {
1177 case NFA_HCI_COMMAND_TYPE:
1178 return "COMMAND";
1179 case NFA_HCI_EVENT_TYPE:
1180 return "EVENT";
1181 case NFA_HCI_RESPONSE_TYPE:
1182 return "RESPONSE";
1183 default:
1184 return "UNKNOWN";
1185 }
1186 }
1187
1188 /*******************************************************************************
1189 **
1190 ** Function nfa_hciu_instr_2_str
1191 **
1192 ** Description This function returns the instruction name.
1193 **
1194 ** Returns pointer to the name
1195 **
1196 *******************************************************************************/
nfa_hciu_instr_2_str(uint8_t instruction)1197 std::string nfa_hciu_instr_2_str(uint8_t instruction) {
1198 switch (instruction) {
1199 case NFA_HCI_ANY_SET_PARAMETER:
1200 return "ANY_SET_PARAMETER";
1201 case NFA_HCI_ANY_GET_PARAMETER:
1202 return "ANY_GET_PARAMETER";
1203 case NFA_HCI_ANY_OPEN_PIPE:
1204 return "ANY_OPEN_PIPE";
1205 case NFA_HCI_ANY_CLOSE_PIPE:
1206 return "ANY_CLOSE_PIPE";
1207 case NFA_HCI_ADM_CREATE_PIPE:
1208 return "ADM_CREATE_PIPE";
1209 case NFA_HCI_ADM_DELETE_PIPE:
1210 return "ADM_DELETE_PIPE";
1211 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1212 return "ADM_NOTIFY_PIPE_CREATED";
1213 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1214 return "ADM_NOTIFY_PIPE_DELETED";
1215 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1216 return "ADM_CLEAR_ALL_PIPE";
1217 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1218 return "ADM_NOTIFY_ALL_PIPE_CLEARED";
1219 default:
1220 return "UNKNOWN";
1221 }
1222 }
1223
1224 /*******************************************************************************
1225 **
1226 ** Function nfa_hciu_get_event_name
1227 **
1228 ** Description This function returns the event code name.
1229 **
1230 ** Returns pointer to the name
1231 **
1232 *******************************************************************************/
nfa_hciu_get_event_name(uint16_t event)1233 std::string nfa_hciu_get_event_name(uint16_t event) {
1234 switch (event) {
1235 case NFA_HCI_API_REGISTER_APP_EVT:
1236 return "API_REGISTER";
1237 case NFA_HCI_API_DEREGISTER_APP_EVT:
1238 return "API_DEREGISTER";
1239 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:
1240 return "API_GET_GATE_LIST";
1241 case NFA_HCI_API_ALLOC_GATE_EVT:
1242 return "API_ALLOC_GATE";
1243 case NFA_HCI_API_DEALLOC_GATE_EVT:
1244 return "API_DEALLOC_GATE";
1245 case NFA_HCI_API_GET_HOST_LIST_EVT:
1246 return "API_GET_HOST_LIST";
1247 case NFA_HCI_API_GET_REGISTRY_EVT:
1248 return "API_GET_REG_VALUE";
1249 case NFA_HCI_API_SET_REGISTRY_EVT:
1250 return "API_SET_REG_VALUE";
1251 case NFA_HCI_API_CREATE_PIPE_EVT:
1252 return "API_CREATE_PIPE";
1253 case NFA_HCI_API_OPEN_PIPE_EVT:
1254 return "API_OPEN_PIPE";
1255 case NFA_HCI_API_CLOSE_PIPE_EVT:
1256 return "API_CLOSE_PIPE";
1257 case NFA_HCI_API_DELETE_PIPE_EVT:
1258 return "API_DELETE_PIPE";
1259 case NFA_HCI_API_SEND_CMD_EVT:
1260 return "API_SEND_COMMAND_EVT";
1261 case NFA_HCI_API_SEND_RSP_EVT:
1262 return "API_SEND_RESPONSE_EVT";
1263 case NFA_HCI_API_SEND_EVENT_EVT:
1264 return "API_SEND_EVENT_EVT";
1265 case NFA_HCI_RSP_NV_READ_EVT:
1266 return "NV_READ_EVT";
1267 case NFA_HCI_RSP_NV_WRITE_EVT:
1268 return "NV_WRITE_EVT";
1269 case NFA_HCI_RSP_TIMEOUT_EVT:
1270 return "RESPONSE_TIMEOUT_EVT";
1271 case NFA_HCI_CHECK_QUEUE_EVT:
1272 return "CHECK_QUEUE";
1273 default:
1274 return "UNKNOWN";
1275 }
1276 }
1277
1278 /*******************************************************************************
1279 **
1280 ** Function nfa_hciu_get_state_name
1281 **
1282 ** Description This function returns the state name.
1283 **
1284 ** Returns pointer to the name
1285 **
1286 *******************************************************************************/
nfa_hciu_get_state_name(uint8_t state)1287 std::string nfa_hciu_get_state_name(uint8_t state) {
1288 switch (state) {
1289 case NFA_HCI_STATE_DISABLED:
1290 return "DISABLED";
1291 case NFA_HCI_STATE_STARTUP:
1292 return "STARTUP";
1293 case NFA_HCI_STATE_WAIT_NETWK_ENABLE:
1294 return "WAIT_NETWK_ENABLE";
1295 case NFA_HCI_STATE_IDLE:
1296 return "IDLE";
1297 case NFA_HCI_STATE_WAIT_RSP:
1298 return "WAIT_RSP";
1299 case NFA_HCI_STATE_REMOVE_GATE:
1300 return "REMOVE_GATE";
1301 case NFA_HCI_STATE_APP_DEREGISTER:
1302 return "APP_DEREGISTER";
1303 case NFA_HCI_STATE_RESTORE:
1304 return "RESTORE";
1305 case NFA_HCI_STATE_RESTORE_NETWK_ENABLE:
1306 return "WAIT_NETWK_ENABLE_AFTER_RESTORE";
1307 default:
1308 return "UNKNOWN";
1309 }
1310 }
1311
1312 /*******************************************************************************
1313 **
1314 ** Function nfa_hciu_get_type_inst_names
1315 **
1316 ** Description This function returns command/response/event name.
1317 **
1318 ** Returns none
1319 **
1320 *******************************************************************************/
nfa_hciu_get_type_inst_names(uint8_t pipe,uint8_t type,uint8_t inst,char * p_buff,const uint8_t max_buff_size)1321 char* nfa_hciu_get_type_inst_names(uint8_t pipe, uint8_t type, uint8_t inst,
1322 char* p_buff, const uint8_t max_buff_size) {
1323 int xx;
1324
1325 xx = snprintf(p_buff, max_buff_size, "Type=%s [0x%02x] ",
1326 nfa_hciu_type_2_str(type).c_str(), type);
1327
1328 switch (type) {
1329 case NFA_HCI_COMMAND_TYPE:
1330 snprintf(&p_buff[xx], max_buff_size - xx, "Inst=%s [0x%02x] ",
1331 nfa_hciu_instr_2_str(inst).c_str(), inst);
1332
1333 break;
1334 case NFA_HCI_EVENT_TYPE:
1335 snprintf(&p_buff[xx], max_buff_size - xx, "Evt=%s [0x%02x] ",
1336 nfa_hciu_evt_2_str(pipe, inst).c_str(), inst);
1337
1338 break;
1339 case NFA_HCI_RESPONSE_TYPE:
1340 snprintf(&p_buff[xx], max_buff_size - xx, "Resp=%s [0x%02x] ",
1341 nfa_hciu_get_response_name(inst).c_str(), inst);
1342
1343 break;
1344 default:
1345 snprintf(&p_buff[xx], max_buff_size - xx, "Inst=%u ", inst);
1346 break;
1347 }
1348 return p_buff;
1349 }
1350
1351 /*******************************************************************************
1352 **
1353 ** Function nfa_hciu_evt_2_str
1354 **
1355 ** Description This function returns the event name.
1356 **
1357 ** Returns pointer to the name
1358 **
1359 *******************************************************************************/
nfa_hciu_evt_2_str(uint8_t pipe_id,uint8_t evt)1360 std::string nfa_hciu_evt_2_str(uint8_t pipe_id, uint8_t evt) {
1361 tNFA_HCI_DYN_PIPE* p_pipe = nfa_hciu_find_pipe_by_pid(pipe_id);
1362 std::vector<uint8_t> conn_pipe_ids;
1363 bool is_conn_pipe = nfa_hciu_check_sim_pipe_ids(pipe_id);
1364
1365 if (pipe_id != NFA_HCI_ADMIN_PIPE &&
1366 pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE && p_pipe != nullptr &&
1367 ((p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE) || is_conn_pipe)) {
1368 switch (evt) {
1369 case NFA_HCI_EVT_CONNECTIVITY:
1370 return "EVT_CONNECTIVITY";
1371 case NFA_HCI_EVT_TRANSACTION:
1372 return "EVT_TRANSACTION";
1373 case NFA_HCI_EVT_OPERATION_ENDED:
1374 return "EVT_OPERATION_ENDED";
1375 default:
1376 return "UNKNOWN";
1377 }
1378 }
1379
1380 switch (evt) {
1381 case NFA_HCI_EVT_HCI_END_OF_OPERATION:
1382 return "EVT_END_OF_OPERATION";
1383 case NFA_HCI_EVT_POST_DATA:
1384 return "EVT_POST_DATA";
1385 case NFA_HCI_EVT_HOT_PLUG:
1386 return "EVT_HOT_PLUG";
1387 default:
1388 return "UNKNOWN";
1389 }
1390 }
1391
handle_debug_loopback(NFC_HDR * p_buf,uint8_t type,uint8_t instruction)1392 static void handle_debug_loopback(NFC_HDR* p_buf, uint8_t type,
1393 uint8_t instruction) {
1394 uint8_t* p = (uint8_t*)(p_buf + 1) + p_buf->offset;
1395 static uint8_t next_pipe = 0x10;
1396
1397 if (type == NFA_HCI_COMMAND_TYPE) {
1398 switch (instruction) {
1399 case NFA_HCI_ADM_CREATE_PIPE:
1400 p[6] = next_pipe++;
1401 p[5] = p[4];
1402 p[4] = p[3];
1403 p[3] = p[2];
1404 p[2] = 3;
1405 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1406 p_buf->len = p_buf->offset + 7;
1407 break;
1408
1409 case NFA_HCI_ANY_GET_PARAMETER:
1410 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1411 memcpy(&p[2], (uint8_t*)nfa_hci_cb.cfg.admin_gate.session_id,
1412 NFA_HCI_SESSION_ID_LEN);
1413 p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
1414 break;
1415
1416 default:
1417 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1418 p_buf->len = p_buf->offset + 2;
1419 break;
1420 }
1421 } else if (type == NFA_HCI_RESPONSE_TYPE) {
1422 GKI_freebuf(p_buf);
1423 return;
1424 }
1425
1426 p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
1427 nfa_sys_sendmsg(p_buf);
1428 }
1429
1430 /*******************************************************************************
1431 **
1432 ** Function nfa_hciu_check_sim_pipe_ids
1433 **
1434 ** Description This function checks if the pipe Id is in the list
1435 ** NAME_OFF_HOST_SIM_PIPE_IDS, if used.
1436 **
1437 ** Returns true if match
1438 **
1439 *******************************************************************************/
nfa_hciu_check_sim_pipe_ids(uint8_t pipe_id)1440 bool nfa_hciu_check_sim_pipe_ids(uint8_t pipe_id) {
1441 std::vector<uint8_t> conn_pipe_ids;
1442 bool is_conn_pipe = false;
1443
1444 if (NfcConfig::hasKey(NAME_OFF_HOST_SIM_PIPE_IDS)) {
1445 conn_pipe_ids = NfcConfig::getBytes(NAME_OFF_HOST_SIM_PIPE_IDS);
1446 for (int i = 0; i < conn_pipe_ids.size(); i++) {
1447 if (pipe_id == conn_pipe_ids[i]) {
1448 LOG(VERBOSE) << StringPrintf(
1449 "%s: pipe 0x%x is in OFF_HOST_SIM_PIPE_IDS", __func__, pipe_id);
1450 return true;
1451 }
1452 }
1453 }
1454 return false;
1455 }
1456