Home | History | Annotate | Download | only in hci
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2013 Broadcom Corporation
      4  *
      5  *  Licensed under the Apache License, Version 2.0 (the "License");
      6  *  you may not use this file except in compliance with the License.
      7  *  You may obtain a copy of the License at:
      8  *
      9  *  http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  *
     17  ******************************************************************************/
     18 
     19 
     20 /******************************************************************************
     21  *
     22  *  This file contains the utility functions for the NFA HCI.
     23  *
     24  ******************************************************************************/
     25 #include <string.h>
     26 #include "trace_api.h"
     27 #include "nfc_api.h"
     28 #include "nfa_sys.h"
     29 #include "nfa_sys_int.h"
     30 #include "nfa_dm_int.h"
     31 #include "nfa_hci_api.h"
     32 #include "nfa_hci_int.h"
     33 #include "nfa_nv_co.h"
     34 #include "nfa_mem_co.h"
     35 #include "nfa_hci_defs.h"
     36 
     37 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction);
     38 BOOLEAN HCI_LOOPBACK_DEBUG = FALSE;
     39 
     40 /*******************************************************************************
     41 **
     42 ** Function         nfa_hciu_find_pipe_by_pid
     43 **
     44 ** Description      look for the pipe control block based on pipe id
     45 **
     46 ** Returns          pointer to the pipe control block, or NULL if not found
     47 **
     48 *******************************************************************************/
     49 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id)
     50 {
     51     tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
     52     int                 xx  = 0;
     53 
     54     /* Loop through looking for a match */
     55     for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
     56     {
     57         if (pp->pipe_id == pipe_id)
     58             return (pp);
     59     }
     60 
     61     /* If here, not found */
     62     return (NULL);
     63 }
     64 
     65 /*******************************************************************************
     66 **
     67 ** Function         nfa_hciu_find_gate_by_gid
     68 **
     69 ** Description      Find the gate control block for the given gate id
     70 **
     71 ** Returns          pointer to the gate control block, or NULL if not found
     72 **
     73 *******************************************************************************/
     74 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id)
     75 {
     76     tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
     77     int               xx  = 0;
     78 
     79     for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
     80     {
     81         if (pg->gate_id == gate_id)
     82             return (pg);
     83     }
     84 
     85     return (NULL);
     86 }
     87 
     88 /*******************************************************************************
     89 **
     90 ** Function         nfa_hciu_find_gate_by_owner
     91 **
     92 ** Description      Find the the first gate control block for the given owner
     93 **
     94 ** Returns          pointer to the gate control block, or NULL if not found
     95 **
     96 *******************************************************************************/
     97 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle)
     98 {
     99     tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
    100     int               xx  = 0;
    101 
    102     for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    103     {
    104         if (pg->gate_owner == app_handle)
    105             return (pg);
    106     }
    107 
    108     return (NULL);
    109 }
    110 
    111 /*******************************************************************************
    112 **
    113 ** Function         nfa_hciu_find_gate_with_nopipes_by_owner
    114 **
    115 ** Description      Find the the first gate control block with no pipes
    116 **                  for the given owner
    117 **
    118 ** Returns          pointer to the gate control block, or NULL if not found
    119 **
    120 *******************************************************************************/
    121 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle)
    122 {
    123     tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
    124     int               xx  = 0;
    125 
    126     for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    127     {
    128         if (  (pg->gate_owner    == app_handle)
    129             &&(pg->pipe_inx_mask == 0)  )
    130             return (pg);
    131     }
    132 
    133     return (NULL);
    134 }
    135 
    136 /*******************************************************************************
    137 **
    138 ** Function         nfa_hciu_count_pipes_on_gate
    139 **
    140 ** Description      Count the number of pipes on the given gate
    141 **
    142 ** Returns          the number of pipes on the gate
    143 **
    144 *******************************************************************************/
    145 UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
    146 {
    147     int               xx    = 0;
    148     UINT32            mask  = 1;
    149     UINT8             count = 0;
    150 
    151     for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++)
    152     {
    153         if ( p_gate->pipe_inx_mask & mask )
    154             count++;
    155 
    156         mask = mask << 1;
    157     }
    158 
    159     return (count);
    160 }
    161 
    162 /*******************************************************************************
    163 **
    164 ** Function         nfa_hciu_count_open_pipes_on_gate
    165 **
    166 ** Description      Count the number of opened pipes on the given gate
    167 **
    168 ** Returns          the number of pipes in OPENED state on the gate
    169 **
    170 *******************************************************************************/
    171 UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
    172 {
    173     tNFA_HCI_DYN_PIPE *pp   = nfa_hci_cb.cfg.dyn_pipes;
    174     int               xx    = 0;
    175     UINT32            mask  = 1;
    176     UINT8             count = 0;
    177 
    178     for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    179     {
    180         /* For each pipe on this gate, check if it is open */
    181         if ((p_gate->pipe_inx_mask & mask) && (pp->pipe_state == NFA_HCI_PIPE_OPENED))
    182             count++;
    183 
    184         mask = mask << 1;
    185     }
    186 
    187     return (count);
    188 }
    189 
    190 /*******************************************************************************
    191 **
    192 ** Function         nfa_hciu_get_gate_owner
    193 **
    194 ** Description      Find the application that owns a gate
    195 **
    196 ** Returns          application handle
    197 **
    198 *******************************************************************************/
    199 tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id)
    200 {
    201     tNFA_HCI_DYN_GATE   *pg;
    202 
    203     if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) == NULL)
    204         return (NFA_HANDLE_INVALID);
    205 
    206     return (pg->gate_owner);
    207 }
    208 
    209 /*******************************************************************************
    210 **
    211 ** Function         nfa_hciu_get_pipe_owner
    212 **
    213 ** Description      Find the application that owns a pipe
    214 **
    215 ** Returns          application handle
    216 **
    217 *******************************************************************************/
    218 tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id)
    219 {
    220     tNFA_HCI_DYN_PIPE   *pp;
    221     tNFA_HCI_DYN_GATE   *pg;
    222 
    223     if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
    224         return (NFA_HANDLE_INVALID);
    225 
    226     if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) == NULL)
    227         return (NFA_HANDLE_INVALID);
    228 
    229     return (pg->gate_owner);
    230 }
    231 
    232 
    233 /*******************************************************************************
    234 **
    235 ** Function         nfa_hciu_alloc_gate
    236 **
    237 ** Description      Allocate an gate control block
    238 **
    239 ** Returns          pointer to the allocated gate, or NULL if cannot allocate
    240 **
    241 *******************************************************************************/
    242 tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle)
    243 {
    244     tNFA_HCI_DYN_GATE   *pg;
    245     int                 xx;
    246     UINT8               app_inx = app_handle & NFA_HANDLE_MASK;
    247 
    248 
    249     /* First, check if the application handle is valid */
    250     if ((gate_id != NFA_HCI_CONNECTIVITY_GATE)
    251                     &&
    252         (  ((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI)
    253          ||(app_inx >= NFA_HCI_MAX_APP_CB)
    254          ||(nfa_hci_cb.p_app_cback[app_inx] == NULL)  ))
    255     {
    256         return (NULL);
    257     }
    258 
    259     if (gate_id != 0)
    260     {
    261         if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL)
    262             return (pg);
    263     }
    264     else
    265     {
    266         /* If gate_id is 0, we need to assign a free one */
    267         /* Loop through all possible gate IDs checking if they are already used */
    268         for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id < NFA_HCI_LAST_PROP_GATE; gate_id++)
    269         {
    270             /* Skip connectivity gate */
    271             if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++;
    272 
    273             /* Check if the gate is already allocated */
    274             for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    275                 if (pg->gate_id == gate_id)
    276                     break;
    277             /* If the gate is not allocated, use the gate */
    278             if (xx == NFA_HCI_MAX_GATE_CB)
    279                 break;
    280         }
    281         if (gate_id == NFA_HCI_LAST_PROP_GATE)
    282         {
    283             NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u  App Handle: 0x%04x", gate_id, app_handle);
    284             return (NULL);
    285         }
    286     }
    287 
    288     /* Now look for a free control block */
    289     for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    290     {
    291         if (pg->gate_id == 0)
    292         {
    293             /* Found a free gate control block */
    294             pg->gate_id       = gate_id;
    295             pg->gate_owner    = app_handle;
    296             pg->pipe_inx_mask = 0;
    297 
    298             NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d  app_handle: 0x%04x", gate_id, app_handle);
    299 
    300             nfa_hci_cb.nv_write_needed = TRUE;
    301             return (pg);
    302         }
    303     }
    304 
    305     /* If here, no free gate control block */
    306     NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB  Gate ID: %u  App Handle: 0x%04x", gate_id, app_handle);
    307     return (NULL);
    308 }
    309 
    310 /*******************************************************************************
    311 **
    312 ** Function         nfa_hciu_send_msg
    313 **
    314 ** Description      This function will fragment the given packet, if necessary
    315 **                  and send it on the given pipe.
    316 **
    317 ** Returns          status
    318 **
    319 *******************************************************************************/
    320 tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg)
    321 {
    322     BT_HDR          *p_buf;
    323     UINT8           *p_data;
    324     BOOLEAN          first_pkt = TRUE;
    325     UINT16          data_len;
    326     tNFA_STATUS     status = NFA_STATUS_OK;
    327     UINT16          max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
    328 
    329 #if (BT_TRACE_VERBOSE == TRUE)
    330     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 *******************************************************************************/
    424 UINT8 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 *******************************************************************************/
    454 tNFA_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 *******************************************************************************/
    493 void 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 *******************************************************************************/
    524 tNFA_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 *******************************************************************************/
    569 tNFA_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 *******************************************************************************/
    608 tNFA_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 *******************************************************************************/
    643 tNFA_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 *******************************************************************************/
    675 tNFA_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 *******************************************************************************/
    708 BOOLEAN 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 *******************************************************************************/
    731 BOOLEAN 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 *******************************************************************************/
    754 BOOLEAN 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 *******************************************************************************/
    776 tNFA_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 *******************************************************************************/
    812 tNFA_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 *******************************************************************************/
    864 void 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 *******************************************************************************/
    902 tNFA_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 *******************************************************************************/
    927 tNFA_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 *******************************************************************************/
    958 tNFA_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 *******************************************************************************/
    979 tNFA_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 *******************************************************************************/
    999 tNFA_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 *******************************************************************************/
   1019 tNFA_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 *******************************************************************************/
   1038 tNFA_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 *******************************************************************************/
   1063 void 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 *******************************************************************************/
   1094 void 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 *******************************************************************************/
   1116 void 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 *******************************************************************************/
   1142 char *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 *******************************************************************************/
   1184 char *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 *******************************************************************************/
   1208 char *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 *******************************************************************************/
   1247 char *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 *******************************************************************************/
   1285 char *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 *******************************************************************************/
   1313 char *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 *******************************************************************************/
   1346 char *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 
   1385 static 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