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