• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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