nfa_hci_utils.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
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
37static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction);
38BOOLEAN 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*******************************************************************************/
49tNFA_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*******************************************************************************/
74tNFA_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*******************************************************************************/
97tNFA_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*******************************************************************************/
121tNFA_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*******************************************************************************/
145UINT8 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*******************************************************************************/
171UINT8 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*******************************************************************************/
199tNFA_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*******************************************************************************/
218tNFA_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*******************************************************************************/
242tNFA_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*******************************************************************************/
320tNFA_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*******************************************************************************/
422UINT8 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*******************************************************************************/
452tNFA_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*******************************************************************************/
491void 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*******************************************************************************/
522tNFA_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*******************************************************************************/
567tNFA_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*******************************************************************************/
606tNFA_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*******************************************************************************/
641tNFA_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*******************************************************************************/
673tNFA_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*******************************************************************************/
706BOOLEAN 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*******************************************************************************/
729BOOLEAN 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*******************************************************************************/
752BOOLEAN 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*******************************************************************************/
774tNFA_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*******************************************************************************/
810tNFA_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*******************************************************************************/
862void 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*******************************************************************************/
900tNFA_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*******************************************************************************/
925tNFA_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*******************************************************************************/
956tNFA_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*******************************************************************************/
977tNFA_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*******************************************************************************/
997tNFA_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*******************************************************************************/
1017tNFA_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*******************************************************************************/
1036tNFA_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*******************************************************************************/
1061void 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*******************************************************************************/
1092void 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*******************************************************************************/
1114void 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*******************************************************************************/
1140char *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*******************************************************************************/
1185char *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*******************************************************************************/
1212char *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*******************************************************************************/
1254char *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*******************************************************************************/
1295char *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*******************************************************************************/
1326char *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*******************************************************************************/
1362char *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
1403static 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