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