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