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