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