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