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