1 /******************************************************************************
2 *
3 * Copyright (C) 2010-2012 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 "trace_api.h"
26 #include "nfc_api.h"
27 #include "nfa_sys.h"
28 #include "nfa_sys_int.h"
29 #include "nfa_hci_api.h"
30 #include "nfa_hci_int.h"
31 #include "nfa_nv_co.h"
32 #include "nfa_mem_co.h"
33 #include "nfa_hci_defs.h"
34
35 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction);
36 BOOLEAN HCI_LOOPBACK_DEBUG = FALSE;
37
38 /*******************************************************************************
39 **
40 ** Function nfa_hciu_find_pipe_by_pid
41 **
42 ** Description look for the pipe control block based on pipe id
43 **
44 ** Returns pointer to the pipe control block, or NULL if not found
45 **
46 *******************************************************************************/
nfa_hciu_find_pipe_by_pid(UINT8 pipe_id)47 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id)
48 {
49 tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes;
50 int xx = 0;
51
52 /* Loop through looking for a match */
53 for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
54 {
55 if (pp->pipe_id == pipe_id)
56 return (pp);
57 }
58
59 /* If here, not found */
60 return (NULL);
61 }
62
63 /*******************************************************************************
64 **
65 ** Function nfa_hciu_find_gate_by_gid
66 **
67 ** Description Find the gate control block for the given gate id
68 **
69 ** Returns pointer to the gate control block, or NULL if not found
70 **
71 *******************************************************************************/
nfa_hciu_find_gate_by_gid(UINT8 gate_id)72 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id)
73 {
74 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
75 int xx = 0;
76
77 for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
78 {
79 if (pg->gate_id == gate_id)
80 return (pg);
81 }
82
83 return (NULL);
84 }
85
86 /*******************************************************************************
87 **
88 ** Function nfa_hciu_find_gate_by_owner
89 **
90 ** Description Find the the first gate control block for the given owner
91 **
92 ** Returns pointer to the gate control block, or NULL if not found
93 **
94 *******************************************************************************/
nfa_hciu_find_gate_by_owner(tNFA_HANDLE app_handle)95 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle)
96 {
97 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
98 int xx = 0;
99
100 for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
101 {
102 if (pg->gate_owner == app_handle)
103 return (pg);
104 }
105
106 return (NULL);
107 }
108
109 /*******************************************************************************
110 **
111 ** Function nfa_hciu_find_gate_with_nopipes_by_owner
112 **
113 ** Description Find the the first gate control block with no pipes
114 ** for the given owner
115 **
116 ** Returns pointer to the gate control block, or NULL if not found
117 **
118 *******************************************************************************/
nfa_hciu_find_gate_with_nopipes_by_owner(tNFA_HANDLE app_handle)119 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle)
120 {
121 tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
122 int xx = 0;
123
124 for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
125 {
126 if ( (pg->gate_owner == app_handle)
127 &&(pg->pipe_inx_mask == 0) )
128 return (pg);
129 }
130
131 return (NULL);
132 }
133
134 /*******************************************************************************
135 **
136 ** Function nfa_hciu_count_pipes_on_gate
137 **
138 ** Description Count the number of pipes on the given gate
139 **
140 ** Returns the number of pipes on the gate
141 **
142 *******************************************************************************/
nfa_hciu_count_pipes_on_gate(tNFA_HCI_DYN_GATE * p_gate)143 UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
144 {
145 int xx = 0;
146 UINT32 mask = 1;
147 UINT8 count = 0;
148
149 for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++)
150 {
151 if ( p_gate->pipe_inx_mask & mask )
152 count++;
153
154 mask = mask << 1;
155 }
156
157 return (count);
158 }
159
160 /*******************************************************************************
161 **
162 ** Function nfa_hciu_count_open_pipes_on_gate
163 **
164 ** Description Count the number of opened pipes on the given gate
165 **
166 ** Returns the number of pipes in OPENED state on the gate
167 **
168 *******************************************************************************/
nfa_hciu_count_open_pipes_on_gate(tNFA_HCI_DYN_GATE * p_gate)169 UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
170 {
171 tNFA_HCI_DYN_PIPE *pp = nfa_hci_cb.cfg.dyn_pipes;
172 int xx = 0;
173 UINT32 mask = 1;
174 UINT8 count = 0;
175
176 for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
177 {
178 /* For each pipe on this gate, check if it is open */
179 if ((p_gate->pipe_inx_mask & mask) && (pp->pipe_state == NFA_HCI_PIPE_OPENED))
180 count++;
181
182 mask = mask << 1;
183 }
184
185 return (count);
186 }
187
188 /*******************************************************************************
189 **
190 ** Function nfa_hciu_get_gate_owner
191 **
192 ** Description Find the application that owns a gate
193 **
194 ** Returns application handle
195 **
196 *******************************************************************************/
nfa_hciu_get_gate_owner(UINT8 gate_id)197 tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id)
198 {
199 tNFA_HCI_DYN_GATE *pg;
200
201 if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) == NULL)
202 return (NFA_HANDLE_INVALID);
203
204 return (pg->gate_owner);
205 }
206
207 /*******************************************************************************
208 **
209 ** Function nfa_hciu_get_pipe_owner
210 **
211 ** Description Find the application that owns a pipe
212 **
213 ** Returns application handle
214 **
215 *******************************************************************************/
nfa_hciu_get_pipe_owner(UINT8 pipe_id)216 tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id)
217 {
218 tNFA_HCI_DYN_PIPE *pp;
219 tNFA_HCI_DYN_GATE *pg;
220
221 if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
222 return (NFA_HANDLE_INVALID);
223
224 if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) == NULL)
225 return (NFA_HANDLE_INVALID);
226
227 return (pg->gate_owner);
228 }
229
230
231 /*******************************************************************************
232 **
233 ** Function nfa_hciu_alloc_gate
234 **
235 ** Description Allocate an gate control block
236 **
237 ** Returns pointer to the allocated gate, or NULL if cannot allocate
238 **
239 *******************************************************************************/
nfa_hciu_alloc_gate(UINT8 gate_id,tNFA_HANDLE app_handle)240 tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle)
241 {
242 tNFA_HCI_DYN_GATE *pg;
243 int xx;
244 UINT8 app_inx = app_handle & NFA_HANDLE_MASK;
245
246
247 /* First, check if the application handle is valid */
248 if ((gate_id != NFA_HCI_CONNECTIVITY_GATE)
249 &&
250 ( ((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI)
251 ||(app_inx >= NFA_HCI_MAX_APP_CB)
252 ||(nfa_hci_cb.p_app_cback[app_inx] == NULL) ))
253 {
254 return (NULL);
255 }
256
257 if (gate_id != 0)
258 {
259 if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL)
260 return (pg);
261 }
262 else
263 {
264 /* If gate_id is 0, we need to assign a free one */
265 /* Loop through all possible gate IDs checking if they are already used */
266 for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id < NFA_HCI_LAST_PROP_GATE; gate_id++)
267 {
268 /* Skip connectivity gate */
269 if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++;
270
271 /* Check if the gate is already allocated */
272 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
273 if (pg->gate_id == gate_id)
274 break;
275 /* If the gate is not allocated, use the gate */
276 if (xx == NFA_HCI_MAX_GATE_CB)
277 break;
278 }
279 if (gate_id == NFA_HCI_LAST_PROP_GATE)
280 {
281 NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u App Handle: 0x%04x", gate_id, app_handle);
282 return (NULL);
283 }
284 }
285
286 /* Now look for a free control block */
287 for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
288 {
289 if (pg->gate_id == 0)
290 {
291 /* Found a free gate control block */
292 pg->gate_id = gate_id;
293 pg->gate_owner = app_handle;
294 pg->pipe_inx_mask = 0;
295
296 NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d app_handle: 0x%04x", gate_id, app_handle);
297
298 nfa_hci_cb.nv_write_needed = TRUE;
299 return (pg);
300 }
301 }
302
303 /* If here, no free gate control block */
304 NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB Gate ID: %u App Handle: 0x%04x", gate_id, app_handle);
305 return (NULL);
306 }
307
308 /*******************************************************************************
309 **
310 ** Function nfa_hciu_send_msg
311 **
312 ** Description This function will fragment the given packet, if necessary
313 ** and send it on the given pipe.
314 **
315 ** Returns status
316 **
317 *******************************************************************************/
nfa_hciu_send_msg(UINT8 pipe_id,UINT8 type,UINT8 instruction,UINT16 msg_len,UINT8 * p_msg)318 tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg)
319 {
320 BT_HDR *p_buf;
321 UINT8 *p_data;
322 BOOLEAN first_pkt = TRUE;
323 UINT16 data_len;
324 tNFA_STATUS status = NFA_STATUS_OK;
325 UINT16 max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
326
327 #if (BT_TRACE_VERBOSE == TRUE)
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), 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, NFA_HCI_CMD_RSP_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_find_pipe_by_owner
633 **
634 ** Description Find the first pipe associated with the given app
635 **
636 ** Returns pointer to pipe, or NULL if none found
637 **
638 *******************************************************************************/
nfa_hciu_find_pipe_by_owner(tNFA_HANDLE app_handle)639 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_owner (tNFA_HANDLE app_handle)
640 {
641 tNFA_HCI_DYN_GATE *pg;
642 tNFA_HCI_DYN_PIPE *pp;
643 int xx;
644
645 NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle);
646
647 /* Loop through all pipes looking for the owner */
648 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
649 {
650 if (pp->pipe_id != 0)
651 {
652 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
653 &&(pg->gate_owner == app_handle) )
654 return (pp);
655 }
656 }
657
658 /* If here, not found */
659 return (NULL);
660 }
661
662 /*******************************************************************************
663 **
664 ** Function nfa_hciu_find_pipe_on_gate
665 **
666 ** Description Find the first pipe associated with the given gate
667 **
668 ** Returns pointer to pipe, or NULL if none found
669 **
670 *******************************************************************************/
nfa_hciu_find_pipe_on_gate(UINT8 gate_id)671 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_on_gate (UINT8 gate_id)
672 {
673 tNFA_HCI_DYN_GATE *pg;
674 tNFA_HCI_DYN_PIPE *pp;
675 int xx;
676
677 NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_on_gate () Gate:0x%x", gate_id);
678
679 /* Loop through all pipes looking for the owner */
680 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
681 {
682 if (pp->pipe_id != 0)
683 {
684 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
685 &&(pg->gate_id == gate_id) )
686 return (pp);
687 }
688 }
689
690 /* If here, not found */
691 return (NULL);
692 }
693
694 /*******************************************************************************
695 **
696 ** Function nfa_hciu_is_active_host
697 **
698 ** Description Check if the host is currently active
699 **
700 ** Returns TRUE, if the host is active in the host network
701 ** FALSE, if the host is not active in the host network
702 **
703 *******************************************************************************/
nfa_hciu_is_active_host(UINT8 host_id)704 BOOLEAN nfa_hciu_is_active_host (UINT8 host_id)
705 {
706 UINT8 xx;
707
708 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
709 {
710 if (nfa_hci_cb.inactive_host[xx] == host_id)
711 return FALSE;
712 }
713
714 return TRUE;
715 }
716
717 /*******************************************************************************
718 **
719 ** Function nfa_hciu_is_host_reseting
720 **
721 ** Description Check if the host is currently reseting
722 **
723 ** Returns TRUE, if the host is reseting
724 ** FALSE, if the host is not reseting
725 **
726 *******************************************************************************/
nfa_hciu_is_host_reseting(UINT8 host_id)727 BOOLEAN nfa_hciu_is_host_reseting (UINT8 host_id)
728 {
729 UINT8 xx;
730
731 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
732 {
733 if (nfa_hci_cb.reset_host[xx] == host_id)
734 return TRUE;
735 }
736
737 return FALSE;
738 }
739
740 /*******************************************************************************
741 **
742 ** Function nfa_hciu_is_no_host_resetting
743 **
744 ** Description Check if no host is reseting
745 **
746 ** Returns TRUE, if no host is resetting at this time
747 ** FALSE, if one or more host is resetting
748 **
749 *******************************************************************************/
nfa_hciu_is_no_host_resetting(void)750 BOOLEAN nfa_hciu_is_no_host_resetting (void)
751 {
752 UINT8 xx;
753
754 for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
755 {
756 if (nfa_hci_cb.reset_host[xx] != 0)
757 return FALSE;
758 }
759
760 return TRUE;
761 }
762
763 /*******************************************************************************
764 **
765 ** Function nfa_hciu_find_active_pipe_on_gate
766 **
767 ** Description Find the first active pipe associated with the given gate
768 **
769 ** Returns pointer to pipe, or NULL if none found
770 **
771 *******************************************************************************/
nfa_hciu_find_active_pipe_on_gate(UINT8 gate_id)772 tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id)
773 {
774 tNFA_HCI_DYN_GATE *pg;
775 tNFA_HCI_DYN_PIPE *pp;
776 int xx;
777
778 NFA_TRACE_DEBUG1 ("nfa_hciu_find_active_pipe_on_gate () Gate:0x%x", gate_id);
779
780 /* Loop through all pipes looking for the owner */
781 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
782 {
783 if ( (pp->pipe_id != 0)
784 &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE)
785 &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE)
786 &&(nfa_hciu_is_active_host (pp->dest_host)) )
787 {
788 if ( ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
789 &&(pg->gate_id == gate_id) )
790 return (pp);
791 }
792 }
793
794 /* If here, not found */
795 return (NULL);
796 }
797
798 /*******************************************************************************
799 **
800 ** Function nfa_hciu_release_pipe
801 **
802 ** Description remove the specified pipe
803 **
804 ** Returns NFA_HCI_ANY_OK, if removed
805 ** NFA_HCI_ANY_E_NOK, if otherwise
806 **
807 *******************************************************************************/
nfa_hciu_release_pipe(UINT8 pipe_id)808 tNFA_HCI_RESPONSE nfa_hciu_release_pipe (UINT8 pipe_id)
809 {
810 tNFA_HCI_DYN_GATE *p_gate;
811 tNFA_HCI_DYN_PIPE *p_pipe;
812 UINT8 pipe_index;
813
814 NFA_TRACE_EVENT1 ("nfa_hciu_release_pipe: %u", pipe_id);
815
816 if ((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
817 return (NFA_HCI_ANY_E_NOK);
818
819 if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)
820 {
821 NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe_id);
822 return (NFA_HCI_ANY_E_NOK);
823 }
824
825 pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
826
827 if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
828 {
829 /* Remove pipe from ID management gate */
830 nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
831 }
832 else
833 {
834 if ((p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate)) == NULL)
835 {
836 /* Mark the pipe control block as free */
837 p_pipe->pipe_id = 0;
838 return (NFA_HCI_ANY_E_NOK);
839 }
840
841 /* Remove pipe from gate */
842 p_gate->pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
843 }
844
845 /* Reset pipe control block */
846 memset (p_pipe,0,sizeof (tNFA_HCI_DYN_PIPE));
847 nfa_hci_cb.nv_write_needed = TRUE;
848 return NFA_HCI_ANY_OK;
849 }
850
851 /*******************************************************************************
852 **
853 ** Function nfa_hciu_remove_all_pipes_from_host
854 **
855 ** Description remove all the pipes that are connected to a specific host
856 **
857 ** Returns None
858 **
859 *******************************************************************************/
nfa_hciu_remove_all_pipes_from_host(UINT8 host)860 void nfa_hciu_remove_all_pipes_from_host (UINT8 host)
861 {
862 tNFA_HCI_DYN_GATE *pg;
863 tNFA_HCI_DYN_PIPE *pp;
864 int xx;
865 tNFA_HCI_EVT_DATA evt_data;
866
867 NFA_TRACE_EVENT1 ("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
868
869 /* Remove all pipes from the specified host connected to all generic gates */
870 for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
871 {
872 if ( (pp->pipe_id == 0)
873 ||
874 ( (host != 0)
875 &&((pp->dest_host != host) || (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE))) )
876 continue;
877
878 if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
879 {
880 evt_data.deleted.status = NFA_STATUS_OK;
881 evt_data.deleted.pipe = pp->pipe_id;
882
883 nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
884 }
885 nfa_hciu_release_pipe (pp->pipe_id);
886 }
887 }
888
889 /*******************************************************************************
890 **
891 ** Function nfa_hciu_send_create_pipe_cmd
892 **
893 ** Description Create dynamic pipe between the specified gates
894 **
895 ** Returns status
896 **
897 *******************************************************************************/
nfa_hciu_send_create_pipe_cmd(UINT8 source_gate,UINT8 dest_host,UINT8 dest_gate)898 tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate)
899 {
900 tNFA_STATUS status;
901 UINT8 data[3];
902
903 data[0] = source_gate;
904 data[1] = dest_host;
905 data[2] = dest_gate;
906
907 NFA_TRACE_DEBUG3 ("nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, dest_gate:%d", source_gate, dest_host, dest_gate);
908
909 status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CREATE_PIPE, 3, data);
910
911 return status;
912 }
913
914 /*******************************************************************************
915 **
916 ** Function nfa_hciu_send_delete_pipe_cmd
917 **
918 ** Description Delete the dynamic pipe
919 **
920 ** Returns None
921 **
922 *******************************************************************************/
nfa_hciu_send_delete_pipe_cmd(UINT8 pipe)923 tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe)
924 {
925 tNFA_STATUS status;
926
927 NFA_TRACE_DEBUG1 ("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
928
929 if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)
930 {
931 NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe);
932 return (NFA_HCI_ANY_E_NOK);
933 }
934 nfa_hci_cb.pipe_in_use = pipe;
935
936 status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
937
938 return status;
939 }
940
941
942 /*******************************************************************************
943 **
944 ** Function nfa_hciu_send_clear_all_pipe_cmd
945 **
946 ** Description delete all the dynamic pipe connected to device host,
947 ** to close all static pipes connected to device host,
948 ** and to set registry values related to static pipes to
949 ** theri default values.
950 **
951 ** Returns None
952 **
953 *******************************************************************************/
nfa_hciu_send_clear_all_pipe_cmd(void)954 tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void)
955 {
956 tNFA_STATUS status;
957 UINT16 id_ref_data = 0x0102;
958
959 NFA_TRACE_DEBUG0 ("nfa_hciu_send_clear_all_pipe_cmd");
960
961 status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (UINT8 *) &id_ref_data);
962
963 return status;
964 }
965
966 /*******************************************************************************
967 **
968 ** Function nfa_hciu_send_open_pipe_cmd
969 **
970 ** Description Open a closed pipe
971 **
972 ** Returns status
973 **
974 *******************************************************************************/
nfa_hciu_send_open_pipe_cmd(UINT8 pipe)975 tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe)
976 {
977 tNFA_STATUS status;
978
979 nfa_hci_cb.pipe_in_use = pipe;
980
981 status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE, 0, NULL);
982
983 return status;
984 }
985
986 /*******************************************************************************
987 **
988 ** Function nfa_hciu_send_close_pipe_cmd
989 **
990 ** Description Close an opened pipe
991 **
992 ** Returns status
993 **
994 *******************************************************************************/
nfa_hciu_send_close_pipe_cmd(UINT8 pipe)995 tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe)
996 {
997 tNFA_STATUS status;
998
999 nfa_hci_cb.pipe_in_use = pipe;
1000
1001 status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE, 0, NULL);
1002
1003 return status;
1004 }
1005
1006 /*******************************************************************************
1007 **
1008 ** Function nfa_hciu_send_get_param_cmd
1009 **
1010 ** Description Read a parameter value from gate registry
1011 **
1012 ** Returns None
1013 **
1014 *******************************************************************************/
nfa_hciu_send_get_param_cmd(UINT8 pipe,UINT8 index)1015 tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index)
1016 {
1017 tNFA_STATUS status;
1018
1019 if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_GET_PARAMETER, 1, &index)) == NFC_STATUS_OK)
1020 nfa_hci_cb.param_in_use = index;
1021
1022 return status;
1023 }
1024
1025 /*******************************************************************************
1026 **
1027 ** Function nfa_hciu_send_set_param_cmd
1028 **
1029 ** Description Set a parameter value in a gate registry
1030 **
1031 ** Returns None
1032 **
1033 *******************************************************************************/
nfa_hciu_send_set_param_cmd(UINT8 pipe,UINT8 index,UINT8 length,UINT8 * p_data)1034 tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data)
1035 {
1036 tNFA_STATUS status;
1037 UINT8 data[255];
1038
1039 data[0] = index;
1040
1041 memcpy (&data[1], p_data, length);
1042
1043 if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER, (UINT16) (length + 1), data)) == NFC_STATUS_OK)
1044 nfa_hci_cb.param_in_use = index;
1045
1046 return status;
1047 }
1048
1049
1050 /*******************************************************************************
1051 **
1052 ** Function nfa_hciu_send_to_app
1053 **
1054 ** Description Send an event back to an application
1055 **
1056 ** Returns none
1057 **
1058 *******************************************************************************/
nfa_hciu_send_to_app(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt,tNFA_HANDLE app_handle)1059 void nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle)
1060 {
1061 UINT8 app_inx = app_handle & NFA_HANDLE_MASK;
1062
1063 /* First, check if the application handle is valid */
1064 if ( ((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI)
1065 &&(app_inx < NFA_HCI_MAX_APP_CB) )
1066 {
1067 if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
1068 {
1069 nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
1070 return;
1071 }
1072 }
1073
1074 if (app_handle != NFA_HANDLE_INVALID)
1075 {
1076 NFA_TRACE_WARNING2 ("nfa_hciu_send_to_app no callback, event: 0x%04x app_handle: 0x%04x",
1077 event, app_handle);
1078 }
1079 }
1080
1081 /*******************************************************************************
1082 **
1083 ** Function nfa_hciu_send_to_all_apps
1084 **
1085 ** Description Send an event back to all applications
1086 **
1087 ** Returns none
1088 **
1089 *******************************************************************************/
nfa_hciu_send_to_all_apps(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1090 void nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
1091 {
1092 UINT8 app_inx;
1093
1094 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
1095 {
1096 if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
1097 nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
1098 }
1099
1100 }
1101
1102 /*******************************************************************************
1103 **
1104 ** Function nfa_hciu_send_to_apps_handling_connectivity_evts
1105 **
1106 ** Description Send a connectivity event to all the application interested
1107 ** in connectivity events
1108 **
1109 ** Returns none
1110 **
1111 *******************************************************************************/
nfa_hciu_send_to_apps_handling_connectivity_evts(tNFA_HCI_EVT event,tNFA_HCI_EVT_DATA * p_evt)1112 void nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
1113 {
1114 UINT8 app_inx;
1115
1116 for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
1117 {
1118 if ( (nfa_hci_cb.p_app_cback[app_inx] != NULL)
1119 &&(nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
1120
1121 nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
1122 }
1123
1124 }
1125
1126 #if (BT_TRACE_VERBOSE == TRUE)
1127 /*******************************************************************************
1128 **
1129 ** Function nfa_hciu_get_response_name
1130 **
1131 ** Description This function returns the error code name.
1132 **
1133 ** NOTE conditionally compiled to save memory.
1134 **
1135 ** Returns pointer to the name
1136 **
1137 *******************************************************************************/
nfa_hciu_get_response_name(UINT8 rsp_code)1138 char *nfa_hciu_get_response_name (UINT8 rsp_code)
1139 {
1140 static char unknown[50];
1141
1142 switch (rsp_code)
1143 {
1144 case NFA_HCI_ANY_OK:
1145 return ("ANY_OK");
1146 case NFA_HCI_ANY_E_NOT_CONNECTED:
1147 return ("ANY_E_NOT_CONNECTED");
1148 case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
1149 return ("ANY_E_CMD_PAR_UNKNOWN");
1150 case NFA_HCI_ANY_E_NOK:
1151 return ("ANY_E_NOK");
1152 case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
1153 return ("ADM_E_NO_PIPES_AVAILABLE");
1154 case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
1155 return ("ANY_E_REG_PAR_UNKNOWN");
1156 case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
1157 return ("ANY_E_PIPE_NOT_OPENED");
1158 case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
1159 return ("ANY_E_CMD_NOT_SUPPORTED");
1160 case NFA_HCI_ANY_E_INHIBITED:
1161 return ("ANY_E_INHIBITED");
1162 case NFA_HCI_ANY_E_TIMEOUT:
1163 return ("ANY_E_TIMEOUT");
1164 case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
1165 return ("ANY_E_REG_ACCESS_DENIED");
1166 case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
1167 return ("ANY_E_PIPE_ACCESS_DENIED");
1168 default:
1169 sprintf (unknown, "?? Unknown: %u ?? ", rsp_code);
1170 return (unknown);
1171 }
1172 }
1173
1174 /*******************************************************************************
1175 **
1176 ** Function nfa_hciu_type_2_str
1177 **
1178 ** Description This function returns the type name.
1179 **
1180 ** Returns pointer to the name
1181 **
1182 *******************************************************************************/
nfa_hciu_type_2_str(UINT8 type)1183 char *nfa_hciu_type_2_str(UINT8 type)
1184 {
1185 static char unknown[40];
1186
1187 switch (type)
1188 {
1189 case NFA_HCI_COMMAND_TYPE:
1190 return ("COMMAND");
1191 case NFA_HCI_EVENT_TYPE:
1192 return ("EVENT");
1193 case NFA_HCI_RESPONSE_TYPE:
1194 return ("RESPONSE");
1195 default:
1196 sprintf (unknown, "?? Unknown: %u ?? ", type);
1197 return (unknown);
1198 }
1199 }
1200
1201 /*******************************************************************************
1202 **
1203 ** Function nfa_hciu_instr_2_str
1204 **
1205 ** Description This function returns the instruction name.
1206 **
1207 ** Returns pointer to the name
1208 **
1209 *******************************************************************************/
nfa_hciu_instr_2_str(UINT8 instruction)1210 char *nfa_hciu_instr_2_str (UINT8 instruction)
1211 {
1212 static char unknown[40];
1213
1214 switch (instruction)
1215 {
1216 case NFA_HCI_ANY_SET_PARAMETER:
1217 return ("ANY_SET_PARAMETER");
1218 case NFA_HCI_ANY_GET_PARAMETER:
1219 return ("ANY_GET_PARAMETER");
1220 case NFA_HCI_ANY_OPEN_PIPE:
1221 return ("ANY_OPEN_PIPE");
1222 case NFA_HCI_ANY_CLOSE_PIPE:
1223 return ("ANY_CLOSE_PIPE");
1224 case NFA_HCI_ADM_CREATE_PIPE:
1225 return ("ADM_CREATE_PIPE");
1226 case NFA_HCI_ADM_DELETE_PIPE:
1227 return ("ADM_DELETE_PIPE");
1228 case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
1229 return ("ADM_NOTIFY_PIPE_CREATED");
1230 case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
1231 return ("ADM_NOTIFY_PIPE_DELETED");
1232 case NFA_HCI_ADM_CLEAR_ALL_PIPE:
1233 return ("ADM_CLEAR_ALL_PIPE");
1234 case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
1235 return ("ADM_NOTIFY_ALL_PIPE_CLEARED");
1236 default:
1237 sprintf (unknown, "?? Unknown: %u ?? ", instruction);
1238 return (unknown);
1239 }
1240 }
1241
1242
1243 /*******************************************************************************
1244 **
1245 ** Function nfa_hciu_get_event_name
1246 **
1247 ** Description This function returns the event code name.
1248 **
1249 ** Returns pointer to the name
1250 **
1251 *******************************************************************************/
nfa_hciu_get_event_name(UINT16 event)1252 char *nfa_hciu_get_event_name (UINT16 event)
1253 {
1254 static char unknown[40];
1255
1256 switch (event)
1257 {
1258 case NFA_HCI_API_REGISTER_APP_EVT: return ("API_REGISTER");
1259 case NFA_HCI_API_DEREGISTER_APP_EVT: return ("API_DEREGISTER");
1260 case NFA_HCI_API_GET_APP_GATE_PIPE_EVT: return ("API_GET_GATE_LIST");
1261 case NFA_HCI_API_ALLOC_GATE_EVT: return ("API_ALLOC_GATE");
1262 case NFA_HCI_API_DEALLOC_GATE_EVT: return ("API_DEALLOC_GATE");
1263 case NFA_HCI_API_GET_HOST_LIST_EVT: return ("API_GET_HOST_LIST");
1264 case NFA_HCI_API_GET_REGISTRY_EVT: return ("API_GET_REG_VALUE");
1265 case NFA_HCI_API_SET_REGISTRY_EVT: return ("API_SET_REG_VALUE");
1266 case NFA_HCI_API_CREATE_PIPE_EVT: return ("API_CREATE_PIPE");
1267 case NFA_HCI_API_OPEN_PIPE_EVT: return ("API_OPEN_PIPE");
1268 case NFA_HCI_API_CLOSE_PIPE_EVT: return ("API_CLOSE_PIPE");
1269 case NFA_HCI_API_DELETE_PIPE_EVT: return ("API_DELETE_PIPE");
1270 case NFA_HCI_API_SEND_CMD_EVT: return ("API_SEND_COMMAND_EVT");
1271 case NFA_HCI_API_SEND_RSP_EVT: return ("API_SEND_RESPONSE_EVT");
1272 case NFA_HCI_API_SEND_EVENT_EVT: return ("API_SEND_EVENT_EVT");
1273 case NFA_HCI_RSP_NV_READ_EVT: return ("NV_READ_EVT");
1274 case NFA_HCI_RSP_NV_WRITE_EVT: return ("NV_WRITE_EVT");
1275 case NFA_HCI_RSP_TIMEOUT_EVT: return ("RESPONSE_TIMEOUT_EVT");
1276 case NFA_HCI_CHECK_QUEUE_EVT: return ("CHECK_QUEUE");
1277
1278 default:
1279 sprintf (unknown, "?? Unknown: %u ?? ", event);
1280 return (unknown);
1281 }
1282 }
1283
1284 /*******************************************************************************
1285 **
1286 ** Function nfa_hciu_get_state_name
1287 **
1288 ** Description This function returns the state name.
1289 **
1290 ** Returns pointer to the name
1291 **
1292 *******************************************************************************/
nfa_hciu_get_state_name(UINT8 state)1293 char *nfa_hciu_get_state_name (UINT8 state)
1294 {
1295 static char unknown[40];
1296
1297 switch (state)
1298 {
1299 case NFA_HCI_STATE_DISABLED: return ("DISABLED");
1300 case NFA_HCI_STATE_STARTUP: return ("STARTUP");
1301 case NFA_HCI_STATE_IDLE: return ("IDLE");
1302 case NFA_HCI_STATE_WAIT_RSP: return ("WAIT_RSP");
1303 case NFA_HCI_STATE_REMOVE_GATE: return ("REMOVE_GATE");
1304 case NFA_HCI_STATE_APP_DEREGISTER: return ("APP_DEREGISTER");
1305 case NFA_HCI_STATE_RESTORE: return ("RESTORE");
1306
1307
1308 default:
1309 sprintf (unknown, "?? Unknown: %u ?? ", state);
1310 return (unknown);
1311 }
1312 }
1313
1314 /*******************************************************************************
1315 **
1316 ** Function nfa_hciu_get_type_inst_names
1317 **
1318 ** Description This function returns command/response/event name.
1319 **
1320 ** Returns pointer to the name
1321 **
1322 *******************************************************************************/
nfa_hciu_get_type_inst_names(UINT8 pipe,UINT8 type,UINT8 inst)1323 char *nfa_hciu_get_type_inst_names (UINT8 pipe, UINT8 type, UINT8 inst)
1324 {
1325 static char buff[100];
1326 int xx;
1327
1328 xx = sprintf (buff, "Type: %s ", nfa_hciu_type_2_str (type));
1329
1330 switch (type)
1331 {
1332 case NFA_HCI_COMMAND_TYPE:
1333 sprintf (&buff[xx], "Inst: %s ", nfa_hciu_instr_2_str (inst));
1334 break;
1335 case NFA_HCI_EVENT_TYPE:
1336 sprintf (&buff[xx], "Evt: %s ", nfa_hciu_evt_2_str (pipe, inst));
1337 break;
1338 case NFA_HCI_RESPONSE_TYPE:
1339 sprintf (&buff[xx], "Resp: %s ", nfa_hciu_get_response_name (inst));
1340 break;
1341 default:
1342 sprintf (&buff[xx], "Inst: %u ", inst);
1343 break;
1344 }
1345 return (buff);
1346 }
1347
1348
1349
1350 /*******************************************************************************
1351 **
1352 ** Function nfa_hciu_instr_2_str
1353 **
1354 ** Description This function returns the instruction name.
1355 **
1356 ** Returns pointer to the name
1357 **
1358 *******************************************************************************/
nfa_hciu_evt_2_str(UINT8 pipe_id,UINT8 evt)1359 char *nfa_hciu_evt_2_str (UINT8 pipe_id, UINT8 evt)
1360 {
1361 static char unknown[40];
1362 tNFA_HCI_DYN_PIPE *p_pipe;
1363
1364 if ( (pipe_id != NFA_HCI_ADMIN_PIPE)
1365 &&(pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE)
1366 &&((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL) )
1367 {
1368 if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
1369 {
1370 switch (evt)
1371 {
1372 case NFA_HCI_EVT_CONNECTIVITY:
1373 return ("EVT_CONNECTIVITY");
1374 case NFA_HCI_EVT_TRANSACTION:
1375 return ("EVT_TRANSACTION");
1376 case NFA_HCI_EVT_OPERATION_ENDED:
1377 return ("EVT_OPERATION_ENDED");
1378 default:
1379 break;
1380 }
1381 }
1382 }
1383
1384 switch (evt)
1385 {
1386 case NFA_HCI_EVT_HCI_END_OF_OPERATION:
1387 return ("EVT_END_OF_OPERATION");
1388 case NFA_HCI_EVT_POST_DATA:
1389 return ("EVT_POST_DATA");
1390 case NFA_HCI_EVT_HOT_PLUG:
1391 return ("EVT_HOT_PLUG");
1392 default:
1393 sprintf (unknown, "?? Unknown: %u ?? ", evt);
1394 return (unknown);
1395 }
1396 }
1397 #endif
1398
1399
handle_debug_loopback(BT_HDR * p_buf,UINT8 pipe,UINT8 type,UINT8 instruction)1400 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction)
1401 {
1402 UINT8 *p = (UINT8 *) (p_buf + 1) + p_buf->offset;
1403 static UINT8 next_pipe = 0x10;
1404
1405 if (type == NFA_HCI_COMMAND_TYPE)
1406 {
1407 switch (instruction)
1408 {
1409 case NFA_HCI_ADM_CREATE_PIPE:
1410 p[6] = next_pipe++;
1411 p[5] = p[4];
1412 p[4] = p[3];
1413 p[3] = p[2];
1414 p[2] = 3;
1415 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1416 p_buf->len = p_buf->offset + 7;
1417 break;
1418
1419 case NFA_HCI_ANY_GET_PARAMETER:
1420 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1421 memcpy (&p[2], (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, NFA_HCI_SESSION_ID_LEN);
1422 p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
1423 break;
1424
1425 default:
1426 p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
1427 p_buf->len = p_buf->offset + 2;
1428 break;
1429 }
1430 }
1431 else if (type == NFA_HCI_RESPONSE_TYPE)
1432 {
1433 GKI_freebuf (p_buf);
1434 return;
1435 }
1436
1437 p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
1438 nfa_sys_sendmsg (p_buf);
1439 }
1440
1441