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