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