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