Home | History | Annotate | Download | only in hci
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2012 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  *  This file contains the utility functions for the NFA HCI.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "trace_api.h"
     26 #include "nfc_api.h"
     27 #include "nfa_sys.h"
     28 #include "nfa_sys_int.h"
     29 #include "nfa_hci_api.h"
     30 #include "nfa_hci_int.h"
     31 #include "nfa_nv_co.h"
     32 #include "nfa_mem_co.h"
     33 #include "nfa_hci_defs.h"
     34 
     35 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction);
     36 BOOLEAN HCI_LOOPBACK_DEBUG = FALSE;
     37 
     38 /*******************************************************************************
     39 **
     40 ** Function         nfa_hciu_find_pipe_by_pid
     41 **
     42 ** Description      look for the pipe control block based on pipe id
     43 **
     44 ** Returns          pointer to the pipe control block, or NULL if not found
     45 **
     46 *******************************************************************************/
     47 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_pid (UINT8 pipe_id)
     48 {
     49     tNFA_HCI_DYN_PIPE   *pp = nfa_hci_cb.cfg.dyn_pipes;
     50     int                 xx  = 0;
     51 
     52     /* Loop through looking for a match */
     53     for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
     54     {
     55         if (pp->pipe_id == pipe_id)
     56             return (pp);
     57     }
     58 
     59     /* If here, not found */
     60     return (NULL);
     61 }
     62 
     63 /*******************************************************************************
     64 **
     65 ** Function         nfa_hciu_find_gate_by_gid
     66 **
     67 ** Description      Find the gate control block for the given gate id
     68 **
     69 ** Returns          pointer to the gate control block, or NULL if not found
     70 **
     71 *******************************************************************************/
     72 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_gid (UINT8 gate_id)
     73 {
     74     tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
     75     int               xx  = 0;
     76 
     77     for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
     78     {
     79         if (pg->gate_id == gate_id)
     80             return (pg);
     81     }
     82 
     83     return (NULL);
     84 }
     85 
     86 /*******************************************************************************
     87 **
     88 ** Function         nfa_hciu_find_gate_by_owner
     89 **
     90 ** Description      Find the the first gate control block for the given owner
     91 **
     92 ** Returns          pointer to the gate control block, or NULL if not found
     93 **
     94 *******************************************************************************/
     95 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_by_owner (tNFA_HANDLE app_handle)
     96 {
     97     tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
     98     int               xx  = 0;
     99 
    100     for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    101     {
    102         if (pg->gate_owner == app_handle)
    103             return (pg);
    104     }
    105 
    106     return (NULL);
    107 }
    108 
    109 /*******************************************************************************
    110 **
    111 ** Function         nfa_hciu_find_gate_with_nopipes_by_owner
    112 **
    113 ** Description      Find the the first gate control block with no pipes
    114 **                  for the given owner
    115 **
    116 ** Returns          pointer to the gate control block, or NULL if not found
    117 **
    118 *******************************************************************************/
    119 tNFA_HCI_DYN_GATE *nfa_hciu_find_gate_with_nopipes_by_owner (tNFA_HANDLE app_handle)
    120 {
    121     tNFA_HCI_DYN_GATE *pg = nfa_hci_cb.cfg.dyn_gates;
    122     int               xx  = 0;
    123 
    124     for ( ; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    125     {
    126         if (  (pg->gate_owner    == app_handle)
    127             &&(pg->pipe_inx_mask == 0)  )
    128             return (pg);
    129     }
    130 
    131     return (NULL);
    132 }
    133 
    134 /*******************************************************************************
    135 **
    136 ** Function         nfa_hciu_count_pipes_on_gate
    137 **
    138 ** Description      Count the number of pipes on the given gate
    139 **
    140 ** Returns          the number of pipes on the gate
    141 **
    142 *******************************************************************************/
    143 UINT8 nfa_hciu_count_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
    144 {
    145     int               xx    = 0;
    146     UINT32            mask  = 1;
    147     UINT8             count = 0;
    148 
    149     for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++)
    150     {
    151         if ( p_gate->pipe_inx_mask & mask )
    152             count++;
    153 
    154         mask = mask << 1;
    155     }
    156 
    157     return (count);
    158 }
    159 
    160 /*******************************************************************************
    161 **
    162 ** Function         nfa_hciu_count_open_pipes_on_gate
    163 **
    164 ** Description      Count the number of opened pipes on the given gate
    165 **
    166 ** Returns          the number of pipes in OPENED state on the gate
    167 **
    168 *******************************************************************************/
    169 UINT8 nfa_hciu_count_open_pipes_on_gate (tNFA_HCI_DYN_GATE *p_gate)
    170 {
    171     tNFA_HCI_DYN_PIPE *pp   = nfa_hci_cb.cfg.dyn_pipes;
    172     int               xx    = 0;
    173     UINT32            mask  = 1;
    174     UINT8             count = 0;
    175 
    176     for ( ; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    177     {
    178         /* For each pipe on this gate, check if it is open */
    179         if ((p_gate->pipe_inx_mask & mask) && (pp->pipe_state == NFA_HCI_PIPE_OPENED))
    180             count++;
    181 
    182         mask = mask << 1;
    183     }
    184 
    185     return (count);
    186 }
    187 
    188 /*******************************************************************************
    189 **
    190 ** Function         nfa_hciu_get_gate_owner
    191 **
    192 ** Description      Find the application that owns a gate
    193 **
    194 ** Returns          application handle
    195 **
    196 *******************************************************************************/
    197 tNFA_HANDLE nfa_hciu_get_gate_owner (UINT8 gate_id)
    198 {
    199     tNFA_HCI_DYN_GATE   *pg;
    200 
    201     if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) == NULL)
    202         return (NFA_HANDLE_INVALID);
    203 
    204     return (pg->gate_owner);
    205 }
    206 
    207 /*******************************************************************************
    208 **
    209 ** Function         nfa_hciu_get_pipe_owner
    210 **
    211 ** Description      Find the application that owns a pipe
    212 **
    213 ** Returns          application handle
    214 **
    215 *******************************************************************************/
    216 tNFA_HANDLE nfa_hciu_get_pipe_owner (UINT8 pipe_id)
    217 {
    218     tNFA_HCI_DYN_PIPE   *pp;
    219     tNFA_HCI_DYN_GATE   *pg;
    220 
    221     if ((pp = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
    222         return (NFA_HANDLE_INVALID);
    223 
    224     if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) == NULL)
    225         return (NFA_HANDLE_INVALID);
    226 
    227     return (pg->gate_owner);
    228 }
    229 
    230 
    231 /*******************************************************************************
    232 **
    233 ** Function         nfa_hciu_alloc_gate
    234 **
    235 ** Description      Allocate an gate control block
    236 **
    237 ** Returns          pointer to the allocated gate, or NULL if cannot allocate
    238 **
    239 *******************************************************************************/
    240 tNFA_HCI_DYN_GATE *nfa_hciu_alloc_gate (UINT8 gate_id, tNFA_HANDLE app_handle)
    241 {
    242     tNFA_HCI_DYN_GATE   *pg;
    243     int                 xx;
    244     UINT8               app_inx = app_handle & NFA_HANDLE_MASK;
    245 
    246 
    247     /* First, check if the application handle is valid */
    248     if ((gate_id != NFA_HCI_CONNECTIVITY_GATE)
    249                     &&
    250         (  ((app_handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_HCI)
    251          ||(app_inx >= NFA_HCI_MAX_APP_CB)
    252          ||(nfa_hci_cb.p_app_cback[app_inx] == NULL)  ))
    253     {
    254         return (NULL);
    255     }
    256 
    257     if (gate_id != 0)
    258     {
    259         if ((pg = nfa_hciu_find_gate_by_gid (gate_id)) != NULL)
    260             return (pg);
    261     }
    262     else
    263     {
    264         /* If gate_id is 0, we need to assign a free one */
    265         /* Loop through all possible gate IDs checking if they are already used */
    266         for (gate_id = NFA_HCI_FIRST_HOST_SPECIFIC_GENERIC_GATE; gate_id < NFA_HCI_LAST_PROP_GATE; gate_id++)
    267         {
    268             /* Skip connectivity gate */
    269             if (gate_id == NFA_HCI_CONNECTIVITY_GATE) gate_id++;
    270 
    271             /* Check if the gate is already allocated */
    272             for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    273                 if (pg->gate_id == gate_id)
    274                     break;
    275             /* If the gate is not allocated, use the gate */
    276             if (xx == NFA_HCI_MAX_GATE_CB)
    277                 break;
    278         }
    279         if (gate_id == NFA_HCI_LAST_PROP_GATE)
    280         {
    281             NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no free Gate ID: %u  App Handle: 0x%04x", gate_id, app_handle);
    282             return (NULL);
    283         }
    284     }
    285 
    286     /* Now look for a free control block */
    287     for (xx = 0, pg = nfa_hci_cb.cfg.dyn_gates; xx < NFA_HCI_MAX_GATE_CB; xx++, pg++)
    288     {
    289         if (pg->gate_id == 0)
    290         {
    291             /* Found a free gate control block */
    292             pg->gate_id       = gate_id;
    293             pg->gate_owner    = app_handle;
    294             pg->pipe_inx_mask = 0;
    295 
    296             NFA_TRACE_DEBUG2 ("nfa_hciu_alloc_gate id:%d  app_handle: 0x%04x", gate_id, app_handle);
    297 
    298             nfa_hci_cb.nv_write_needed = TRUE;
    299             return (pg);
    300         }
    301     }
    302 
    303     /* If here, no free gate control block */
    304     NFA_TRACE_ERROR2 ("nfa_hci_alloc_gate - no CB  Gate ID: %u  App Handle: 0x%04x", gate_id, app_handle);
    305     return (NULL);
    306 }
    307 
    308 /*******************************************************************************
    309 **
    310 ** Function         nfa_hciu_send_msg
    311 **
    312 ** Description      This function will fragment the given packet, if necessary
    313 **                  and send it on the given pipe.
    314 **
    315 ** Returns          status
    316 **
    317 *******************************************************************************/
    318 tNFA_STATUS nfa_hciu_send_msg (UINT8 pipe_id, UINT8 type, UINT8 instruction, UINT16 msg_len, UINT8 *p_msg)
    319 {
    320     BT_HDR          *p_buf;
    321     UINT8           *p_data;
    322     BOOLEAN          first_pkt = TRUE;
    323     UINT16          data_len;
    324     tNFA_STATUS     status = NFA_STATUS_OK;
    325     UINT16          max_seg_hcp_pkt_size = nfa_hci_cb.buff_size - NCI_DATA_HDR_SIZE;
    326 
    327 #if (BT_TRACE_VERBOSE == TRUE)
    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), 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, NFA_HCI_CMD_RSP_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_find_pipe_by_owner
    633 **
    634 ** Description      Find the first pipe associated with the given app
    635 **
    636 ** Returns          pointer to pipe, or NULL if none found
    637 **
    638 *******************************************************************************/
    639 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_by_owner (tNFA_HANDLE app_handle)
    640 {
    641     tNFA_HCI_DYN_GATE   *pg;
    642     tNFA_HCI_DYN_PIPE   *pp;
    643     int                 xx;
    644 
    645     NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_by_owner () app_handle:0x%x", app_handle);
    646 
    647     /* Loop through all pipes looking for the owner */
    648     for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    649     {
    650         if (pp->pipe_id != 0)
    651         {
    652             if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
    653                 &&(pg->gate_owner == app_handle) )
    654                 return (pp);
    655         }
    656     }
    657 
    658     /* If here, not found */
    659     return (NULL);
    660 }
    661 
    662 /*******************************************************************************
    663 **
    664 ** Function         nfa_hciu_find_pipe_on_gate
    665 **
    666 ** Description      Find the first pipe associated with the given gate
    667 **
    668 ** Returns          pointer to pipe, or NULL if none found
    669 **
    670 *******************************************************************************/
    671 tNFA_HCI_DYN_PIPE *nfa_hciu_find_pipe_on_gate (UINT8 gate_id)
    672 {
    673     tNFA_HCI_DYN_GATE   *pg;
    674     tNFA_HCI_DYN_PIPE   *pp;
    675     int                 xx;
    676 
    677     NFA_TRACE_DEBUG1 ("nfa_hciu_find_pipe_on_gate () Gate:0x%x", gate_id);
    678 
    679     /* Loop through all pipes looking for the owner */
    680     for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    681     {
    682         if (pp->pipe_id != 0)
    683         {
    684             if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
    685                 &&(pg->gate_id == gate_id) )
    686                 return (pp);
    687         }
    688     }
    689 
    690     /* If here, not found */
    691     return (NULL);
    692 }
    693 
    694 /*******************************************************************************
    695 **
    696 ** Function         nfa_hciu_is_active_host
    697 **
    698 ** Description      Check if the host is currently active
    699 **
    700 ** Returns          TRUE, if the host is active in the host network
    701 **                  FALSE, if the host is not active in the host network
    702 **
    703 *******************************************************************************/
    704 BOOLEAN nfa_hciu_is_active_host (UINT8 host_id)
    705 {
    706     UINT8   xx;
    707 
    708     for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
    709     {
    710         if (nfa_hci_cb.inactive_host[xx] == host_id)
    711             return FALSE;
    712     }
    713 
    714     return TRUE;
    715 }
    716 
    717 /*******************************************************************************
    718 **
    719 ** Function         nfa_hciu_is_host_reseting
    720 **
    721 ** Description      Check if the host is currently reseting
    722 **
    723 ** Returns          TRUE, if the host is reseting
    724 **                  FALSE, if the host is not reseting
    725 **
    726 *******************************************************************************/
    727 BOOLEAN nfa_hciu_is_host_reseting (UINT8 host_id)
    728 {
    729     UINT8   xx;
    730 
    731     for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
    732     {
    733         if (nfa_hci_cb.reset_host[xx] == host_id)
    734             return TRUE;
    735     }
    736 
    737     return FALSE;
    738 }
    739 
    740 /*******************************************************************************
    741 **
    742 ** Function         nfa_hciu_is_no_host_resetting
    743 **
    744 ** Description      Check if no host is reseting
    745 **
    746 ** Returns          TRUE, if no host is resetting at this time
    747 **                  FALSE, if one or more host is resetting
    748 **
    749 *******************************************************************************/
    750 BOOLEAN nfa_hciu_is_no_host_resetting (void)
    751 {
    752     UINT8   xx;
    753 
    754     for (xx = 0; xx < NFA_HCI_MAX_HOST_IN_NETWORK; xx++)
    755     {
    756         if (nfa_hci_cb.reset_host[xx] != 0)
    757             return FALSE;
    758     }
    759 
    760     return TRUE;
    761 }
    762 
    763 /*******************************************************************************
    764 **
    765 ** Function         nfa_hciu_find_active_pipe_on_gate
    766 **
    767 ** Description      Find the first active pipe associated with the given gate
    768 **
    769 ** Returns          pointer to pipe, or NULL if none found
    770 **
    771 *******************************************************************************/
    772 tNFA_HCI_DYN_PIPE *nfa_hciu_find_active_pipe_on_gate (UINT8 gate_id)
    773 {
    774     tNFA_HCI_DYN_GATE   *pg;
    775     tNFA_HCI_DYN_PIPE   *pp;
    776     int                 xx;
    777 
    778     NFA_TRACE_DEBUG1 ("nfa_hciu_find_active_pipe_on_gate () Gate:0x%x", gate_id);
    779 
    780     /* Loop through all pipes looking for the owner */
    781     for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    782     {
    783         if (  (pp->pipe_id != 0)
    784             &&(pp->pipe_id >= NFA_HCI_FIRST_DYNAMIC_PIPE)
    785             &&(pp->pipe_id <= NFA_HCI_LAST_DYNAMIC_PIPE)
    786             &&(nfa_hciu_is_active_host (pp->dest_host))  )
    787         {
    788             if (  ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
    789                 &&(pg->gate_id == gate_id) )
    790                 return (pp);
    791         }
    792     }
    793 
    794     /* If here, not found */
    795     return (NULL);
    796 }
    797 
    798 /*******************************************************************************
    799 **
    800 ** Function         nfa_hciu_release_pipe
    801 **
    802 ** Description      remove the specified pipe
    803 **
    804 ** Returns          NFA_HCI_ANY_OK, if removed
    805 **                  NFA_HCI_ANY_E_NOK, if otherwise
    806 **
    807 *******************************************************************************/
    808 tNFA_HCI_RESPONSE nfa_hciu_release_pipe (UINT8 pipe_id)
    809 {
    810     tNFA_HCI_DYN_GATE   *p_gate;
    811     tNFA_HCI_DYN_PIPE   *p_pipe;
    812     UINT8               pipe_index;
    813 
    814     NFA_TRACE_EVENT1 ("nfa_hciu_release_pipe: %u", pipe_id);
    815 
    816     if ((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) == NULL)
    817         return (NFA_HCI_ANY_E_NOK);
    818 
    819     if (pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)
    820     {
    821         NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe_id);
    822         return (NFA_HCI_ANY_E_NOK);
    823     }
    824 
    825     pipe_index = (UINT8) (p_pipe - nfa_hci_cb.cfg.dyn_pipes);
    826 
    827     if (p_pipe->local_gate == NFA_HCI_IDENTITY_MANAGEMENT_GATE)
    828     {
    829         /* Remove pipe from ID management gate */
    830         nfa_hci_cb.cfg.id_mgmt_gate.pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
    831     }
    832     else
    833     {
    834         if ((p_gate = nfa_hciu_find_gate_by_gid (p_pipe->local_gate)) == NULL)
    835         {
    836             /* Mark the pipe control block as free */
    837             p_pipe->pipe_id = 0;
    838             return (NFA_HCI_ANY_E_NOK);
    839         }
    840 
    841         /* Remove pipe from gate */
    842         p_gate->pipe_inx_mask &= ~ (UINT32) (1 << pipe_index);
    843     }
    844 
    845     /* Reset pipe control block */
    846     memset (p_pipe,0,sizeof (tNFA_HCI_DYN_PIPE));
    847     nfa_hci_cb.nv_write_needed = TRUE;
    848     return NFA_HCI_ANY_OK;
    849 }
    850 
    851 /*******************************************************************************
    852 **
    853 ** Function         nfa_hciu_remove_all_pipes_from_host
    854 **
    855 ** Description      remove all the pipes that are connected to a specific host
    856 **
    857 ** Returns          None
    858 **
    859 *******************************************************************************/
    860 void nfa_hciu_remove_all_pipes_from_host (UINT8 host)
    861 {
    862     tNFA_HCI_DYN_GATE   *pg;
    863     tNFA_HCI_DYN_PIPE   *pp;
    864     int                 xx;
    865     tNFA_HCI_EVT_DATA   evt_data;
    866 
    867     NFA_TRACE_EVENT1 ("nfa_hciu_remove_all_pipes_from_host (0x%02x)", host);
    868 
    869     /* Remove all pipes from the specified host connected to all generic gates */
    870     for (xx = 0, pp = nfa_hci_cb.cfg.dyn_pipes; xx < NFA_HCI_MAX_PIPE_CB; xx++, pp++)
    871     {
    872         if (  (pp->pipe_id == 0)
    873                     ||
    874               (  (host != 0)
    875                &&((pp->dest_host != host) || (pp->pipe_id > NFA_HCI_LAST_DYNAMIC_PIPE)))  )
    876             continue;
    877 
    878         if ((pg = nfa_hciu_find_gate_by_gid (pp->local_gate)) != NULL)
    879         {
    880             evt_data.deleted.status = NFA_STATUS_OK;
    881             evt_data.deleted.pipe   = pp->pipe_id;
    882 
    883             nfa_hciu_send_to_app (NFA_HCI_DELETE_PIPE_EVT, &evt_data, pg->gate_owner);
    884         }
    885         nfa_hciu_release_pipe (pp->pipe_id);
    886     }
    887 }
    888 
    889 /*******************************************************************************
    890 **
    891 ** Function         nfa_hciu_send_create_pipe_cmd
    892 **
    893 ** Description      Create dynamic pipe between the specified gates
    894 **
    895 ** Returns          status
    896 **
    897 *******************************************************************************/
    898 tNFA_STATUS nfa_hciu_send_create_pipe_cmd (UINT8 source_gate, UINT8 dest_host, UINT8 dest_gate)
    899 {
    900     tNFA_STATUS         status;
    901     UINT8               data[3];
    902 
    903     data[0] = source_gate;
    904     data[1] = dest_host;
    905     data[2] = dest_gate;
    906 
    907     NFA_TRACE_DEBUG3 ("nfa_hciu_send_create_pipe_cmd source_gate:%d, dest_host:%d, dest_gate:%d", source_gate, dest_host, dest_gate);
    908 
    909     status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CREATE_PIPE, 3, data);
    910 
    911     return status;
    912 }
    913 
    914 /*******************************************************************************
    915 **
    916 ** Function         nfa_hciu_send_delete_pipe_cmd
    917 **
    918 ** Description      Delete the dynamic pipe
    919 **
    920 ** Returns          None
    921 **
    922 *******************************************************************************/
    923 tNFA_STATUS nfa_hciu_send_delete_pipe_cmd (UINT8 pipe)
    924 {
    925     tNFA_STATUS status;
    926 
    927     NFA_TRACE_DEBUG1 ("nfa_hciu_send_delete_pipe_cmd: %d", pipe);
    928 
    929     if (pipe > NFA_HCI_LAST_DYNAMIC_PIPE)
    930     {
    931         NFA_TRACE_DEBUG1 ("ignore pipe: %d", pipe);
    932         return (NFA_HCI_ANY_E_NOK);
    933     }
    934     nfa_hci_cb.pipe_in_use = pipe;
    935 
    936     status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_DELETE_PIPE, 1, &pipe);
    937 
    938     return status;
    939 }
    940 
    941 
    942 /*******************************************************************************
    943 **
    944 ** Function         nfa_hciu_send_clear_all_pipe_cmd
    945 **
    946 ** Description      delete all the dynamic pipe connected to device host,
    947 **                  to close all static pipes connected to device host,
    948 **                  and to set registry values related to static pipes to
    949 **                  theri default values.
    950 **
    951 ** Returns          None
    952 **
    953 *******************************************************************************/
    954 tNFA_STATUS nfa_hciu_send_clear_all_pipe_cmd (void)
    955 {
    956     tNFA_STATUS status;
    957     UINT16      id_ref_data = 0x0102;
    958 
    959     NFA_TRACE_DEBUG0 ("nfa_hciu_send_clear_all_pipe_cmd");
    960 
    961     status = nfa_hciu_send_msg (NFA_HCI_ADMIN_PIPE, NFA_HCI_COMMAND_TYPE, NFA_HCI_ADM_CLEAR_ALL_PIPE, 2, (UINT8 *) &id_ref_data);
    962 
    963     return status;
    964 }
    965 
    966 /*******************************************************************************
    967 **
    968 ** Function         nfa_hciu_send_open_pipe_cmd
    969 **
    970 ** Description      Open a closed pipe
    971 **
    972 ** Returns          status
    973 **
    974 *******************************************************************************/
    975 tNFA_STATUS nfa_hciu_send_open_pipe_cmd (UINT8 pipe)
    976 {
    977     tNFA_STATUS status;
    978 
    979     nfa_hci_cb.pipe_in_use = pipe;
    980 
    981     status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_OPEN_PIPE, 0, NULL);
    982 
    983     return status;
    984 }
    985 
    986 /*******************************************************************************
    987 **
    988 ** Function         nfa_hciu_send_close_pipe_cmd
    989 **
    990 ** Description      Close an opened pipe
    991 **
    992 ** Returns          status
    993 **
    994 *******************************************************************************/
    995 tNFA_STATUS nfa_hciu_send_close_pipe_cmd (UINT8 pipe)
    996 {
    997     tNFA_STATUS status;
    998 
    999     nfa_hci_cb.pipe_in_use = pipe;
   1000 
   1001     status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_CLOSE_PIPE, 0, NULL);
   1002 
   1003     return status;
   1004 }
   1005 
   1006 /*******************************************************************************
   1007 **
   1008 ** Function         nfa_hciu_send_get_param_cmd
   1009 **
   1010 ** Description      Read a parameter value from gate registry
   1011 **
   1012 ** Returns          None
   1013 **
   1014 *******************************************************************************/
   1015 tNFA_STATUS nfa_hciu_send_get_param_cmd (UINT8 pipe, UINT8 index)
   1016 {
   1017     tNFA_STATUS status;
   1018 
   1019     if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_GET_PARAMETER, 1, &index)) == NFC_STATUS_OK)
   1020         nfa_hci_cb.param_in_use = index;
   1021 
   1022     return status;
   1023 }
   1024 
   1025 /*******************************************************************************
   1026 **
   1027 ** Function         nfa_hciu_send_set_param_cmd
   1028 **
   1029 ** Description      Set a parameter value in a gate registry
   1030 **
   1031 ** Returns          None
   1032 **
   1033 *******************************************************************************/
   1034 tNFA_STATUS nfa_hciu_send_set_param_cmd (UINT8 pipe, UINT8 index, UINT8 length, UINT8 *p_data)
   1035 {
   1036     tNFA_STATUS status;
   1037     UINT8       data[255];
   1038 
   1039     data[0] = index;
   1040 
   1041     memcpy (&data[1], p_data, length);
   1042 
   1043     if ((status = nfa_hciu_send_msg (pipe, NFA_HCI_COMMAND_TYPE, NFA_HCI_ANY_SET_PARAMETER, (UINT16) (length + 1), data)) == NFC_STATUS_OK)
   1044         nfa_hci_cb.param_in_use = index;
   1045 
   1046     return status;
   1047 }
   1048 
   1049 
   1050 /*******************************************************************************
   1051 **
   1052 ** Function         nfa_hciu_send_to_app
   1053 **
   1054 ** Description      Send an event back to an application
   1055 **
   1056 ** Returns          none
   1057 **
   1058 *******************************************************************************/
   1059 void nfa_hciu_send_to_app (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt, tNFA_HANDLE app_handle)
   1060 {
   1061     UINT8   app_inx = app_handle & NFA_HANDLE_MASK;
   1062 
   1063     /* First, check if the application handle is valid */
   1064     if (  ((app_handle & NFA_HANDLE_GROUP_MASK) == NFA_HANDLE_GROUP_HCI)
   1065         &&(app_inx < NFA_HCI_MAX_APP_CB) )
   1066     {
   1067         if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
   1068         {
   1069             nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
   1070             return;
   1071         }
   1072     }
   1073 
   1074     if (app_handle != NFA_HANDLE_INVALID)
   1075     {
   1076         NFA_TRACE_WARNING2 ("nfa_hciu_send_to_app no callback,  event: 0x%04x  app_handle: 0x%04x",
   1077                             event, app_handle);
   1078     }
   1079 }
   1080 
   1081 /*******************************************************************************
   1082 **
   1083 ** Function         nfa_hciu_send_to_all_apps
   1084 **
   1085 ** Description      Send an event back to all applications
   1086 **
   1087 ** Returns          none
   1088 **
   1089 *******************************************************************************/
   1090 void nfa_hciu_send_to_all_apps (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
   1091 {
   1092     UINT8   app_inx;
   1093 
   1094     for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
   1095     {
   1096         if (nfa_hci_cb.p_app_cback[app_inx] != NULL)
   1097             nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
   1098     }
   1099 
   1100 }
   1101 
   1102 /*******************************************************************************
   1103 **
   1104 ** Function         nfa_hciu_send_to_apps_handling_connectivity_evts
   1105 **
   1106 ** Description      Send a connectivity event to all the application interested
   1107 **                  in connectivity events
   1108 **
   1109 ** Returns          none
   1110 **
   1111 *******************************************************************************/
   1112 void nfa_hciu_send_to_apps_handling_connectivity_evts (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA *p_evt)
   1113 {
   1114     UINT8   app_inx;
   1115 
   1116     for (app_inx = 0; app_inx < NFA_HCI_MAX_APP_CB; app_inx++)
   1117     {
   1118         if (  (nfa_hci_cb.p_app_cback[app_inx] != NULL)
   1119             &&(nfa_hci_cb.cfg.b_send_conn_evts[app_inx]))
   1120 
   1121             nfa_hci_cb.p_app_cback[app_inx] (event, p_evt);
   1122     }
   1123 
   1124 }
   1125 
   1126 #if (BT_TRACE_VERBOSE == TRUE)
   1127 /*******************************************************************************
   1128 **
   1129 ** Function         nfa_hciu_get_response_name
   1130 **
   1131 ** Description      This function returns the error code name.
   1132 **
   1133 ** NOTE             conditionally compiled to save memory.
   1134 **
   1135 ** Returns          pointer to the name
   1136 **
   1137 *******************************************************************************/
   1138 char *nfa_hciu_get_response_name (UINT8 rsp_code)
   1139 {
   1140     static char unknown[50];
   1141 
   1142     switch (rsp_code)
   1143     {
   1144     case NFA_HCI_ANY_OK:
   1145         return ("ANY_OK");
   1146     case NFA_HCI_ANY_E_NOT_CONNECTED:
   1147         return ("ANY_E_NOT_CONNECTED");
   1148     case NFA_HCI_ANY_E_CMD_PAR_UNKNOWN:
   1149         return ("ANY_E_CMD_PAR_UNKNOWN");
   1150     case NFA_HCI_ANY_E_NOK:
   1151         return ("ANY_E_NOK");
   1152     case NFA_HCI_ADM_E_NO_PIPES_AVAILABLE:
   1153         return ("ADM_E_NO_PIPES_AVAILABLE");
   1154     case NFA_HCI_ANY_E_REG_PAR_UNKNOWN:
   1155         return ("ANY_E_REG_PAR_UNKNOWN");
   1156     case NFA_HCI_ANY_E_PIPE_NOT_OPENED:
   1157         return ("ANY_E_PIPE_NOT_OPENED");
   1158     case NFA_HCI_ANY_E_CMD_NOT_SUPPORTED:
   1159         return ("ANY_E_CMD_NOT_SUPPORTED");
   1160     case NFA_HCI_ANY_E_INHIBITED:
   1161         return ("ANY_E_INHIBITED");
   1162     case NFA_HCI_ANY_E_TIMEOUT:
   1163         return ("ANY_E_TIMEOUT");
   1164     case NFA_HCI_ANY_E_REG_ACCESS_DENIED:
   1165         return ("ANY_E_REG_ACCESS_DENIED");
   1166     case NFA_HCI_ANY_E_PIPE_ACCESS_DENIED:
   1167         return ("ANY_E_PIPE_ACCESS_DENIED");
   1168     default:
   1169         sprintf (unknown, "?? Unknown: %u ?? ", rsp_code);
   1170         return (unknown);
   1171     }
   1172 }
   1173 
   1174 /*******************************************************************************
   1175 **
   1176 ** Function         nfa_hciu_type_2_str
   1177 **
   1178 ** Description      This function returns the type name.
   1179 **
   1180 ** Returns          pointer to the name
   1181 **
   1182 *******************************************************************************/
   1183 char *nfa_hciu_type_2_str(UINT8 type)
   1184 {
   1185     static char unknown[40];
   1186 
   1187     switch (type)
   1188     {
   1189     case NFA_HCI_COMMAND_TYPE:
   1190         return ("COMMAND");
   1191     case NFA_HCI_EVENT_TYPE:
   1192         return ("EVENT");
   1193     case NFA_HCI_RESPONSE_TYPE:
   1194         return ("RESPONSE");
   1195     default:
   1196         sprintf (unknown, "?? Unknown: %u ?? ", type);
   1197         return (unknown);
   1198     }
   1199 }
   1200 
   1201 /*******************************************************************************
   1202 **
   1203 ** Function         nfa_hciu_instr_2_str
   1204 **
   1205 ** Description      This function returns the instruction name.
   1206 **
   1207 ** Returns          pointer to the name
   1208 **
   1209 *******************************************************************************/
   1210 char *nfa_hciu_instr_2_str (UINT8 instruction)
   1211 {
   1212     static char unknown[40];
   1213 
   1214     switch (instruction)
   1215     {
   1216     case NFA_HCI_ANY_SET_PARAMETER:
   1217         return ("ANY_SET_PARAMETER");
   1218     case NFA_HCI_ANY_GET_PARAMETER:
   1219         return ("ANY_GET_PARAMETER");
   1220     case NFA_HCI_ANY_OPEN_PIPE:
   1221         return ("ANY_OPEN_PIPE");
   1222     case NFA_HCI_ANY_CLOSE_PIPE:
   1223         return ("ANY_CLOSE_PIPE");
   1224     case NFA_HCI_ADM_CREATE_PIPE:
   1225         return ("ADM_CREATE_PIPE");
   1226     case NFA_HCI_ADM_DELETE_PIPE:
   1227         return ("ADM_DELETE_PIPE");
   1228     case NFA_HCI_ADM_NOTIFY_PIPE_CREATED:
   1229         return ("ADM_NOTIFY_PIPE_CREATED");
   1230     case NFA_HCI_ADM_NOTIFY_PIPE_DELETED:
   1231         return ("ADM_NOTIFY_PIPE_DELETED");
   1232     case NFA_HCI_ADM_CLEAR_ALL_PIPE:
   1233         return ("ADM_CLEAR_ALL_PIPE");
   1234     case NFA_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED:
   1235         return ("ADM_NOTIFY_ALL_PIPE_CLEARED");
   1236     default:
   1237         sprintf (unknown, "?? Unknown: %u ?? ", instruction);
   1238         return (unknown);
   1239     }
   1240 }
   1241 
   1242 
   1243 /*******************************************************************************
   1244 **
   1245 ** Function         nfa_hciu_get_event_name
   1246 **
   1247 ** Description      This function returns the event code name.
   1248 **
   1249 ** Returns          pointer to the name
   1250 **
   1251 *******************************************************************************/
   1252 char *nfa_hciu_get_event_name (UINT16 event)
   1253 {
   1254     static char unknown[40];
   1255 
   1256     switch (event)
   1257     {
   1258     case NFA_HCI_API_REGISTER_APP_EVT:        return ("API_REGISTER");
   1259     case NFA_HCI_API_DEREGISTER_APP_EVT:      return ("API_DEREGISTER");
   1260     case NFA_HCI_API_GET_APP_GATE_PIPE_EVT:   return ("API_GET_GATE_LIST");
   1261     case NFA_HCI_API_ALLOC_GATE_EVT:          return ("API_ALLOC_GATE");
   1262     case NFA_HCI_API_DEALLOC_GATE_EVT:        return ("API_DEALLOC_GATE");
   1263     case NFA_HCI_API_GET_HOST_LIST_EVT:       return ("API_GET_HOST_LIST");
   1264     case NFA_HCI_API_GET_REGISTRY_EVT:        return ("API_GET_REG_VALUE");
   1265     case NFA_HCI_API_SET_REGISTRY_EVT:        return ("API_SET_REG_VALUE");
   1266     case NFA_HCI_API_CREATE_PIPE_EVT:         return ("API_CREATE_PIPE");
   1267     case NFA_HCI_API_OPEN_PIPE_EVT:           return ("API_OPEN_PIPE");
   1268     case NFA_HCI_API_CLOSE_PIPE_EVT:          return ("API_CLOSE_PIPE");
   1269     case NFA_HCI_API_DELETE_PIPE_EVT:         return ("API_DELETE_PIPE");
   1270     case NFA_HCI_API_SEND_CMD_EVT:            return ("API_SEND_COMMAND_EVT");
   1271     case NFA_HCI_API_SEND_RSP_EVT:            return ("API_SEND_RESPONSE_EVT");
   1272     case NFA_HCI_API_SEND_EVENT_EVT:          return ("API_SEND_EVENT_EVT");
   1273     case NFA_HCI_RSP_NV_READ_EVT:             return ("NV_READ_EVT");
   1274     case NFA_HCI_RSP_NV_WRITE_EVT:            return ("NV_WRITE_EVT");
   1275     case NFA_HCI_RSP_TIMEOUT_EVT:             return ("RESPONSE_TIMEOUT_EVT");
   1276     case NFA_HCI_CHECK_QUEUE_EVT:             return ("CHECK_QUEUE");
   1277 
   1278     default:
   1279         sprintf (unknown, "?? Unknown: %u ?? ", event);
   1280         return (unknown);
   1281     }
   1282 }
   1283 
   1284 /*******************************************************************************
   1285 **
   1286 ** Function         nfa_hciu_get_state_name
   1287 **
   1288 ** Description      This function returns the state name.
   1289 **
   1290 ** Returns          pointer to the name
   1291 **
   1292 *******************************************************************************/
   1293 char *nfa_hciu_get_state_name (UINT8 state)
   1294 {
   1295     static char unknown[40];
   1296 
   1297     switch (state)
   1298     {
   1299     case NFA_HCI_STATE_DISABLED:            return ("DISABLED");
   1300     case NFA_HCI_STATE_STARTUP:             return ("STARTUP");
   1301     case NFA_HCI_STATE_IDLE:                return ("IDLE");
   1302     case NFA_HCI_STATE_WAIT_RSP:            return ("WAIT_RSP");
   1303     case NFA_HCI_STATE_REMOVE_GATE:         return ("REMOVE_GATE");
   1304     case NFA_HCI_STATE_APP_DEREGISTER:      return ("APP_DEREGISTER");
   1305     case NFA_HCI_STATE_RESTORE:             return ("RESTORE");
   1306 
   1307 
   1308     default:
   1309         sprintf (unknown, "?? Unknown: %u ?? ", state);
   1310         return (unknown);
   1311     }
   1312 }
   1313 
   1314 /*******************************************************************************
   1315 **
   1316 ** Function         nfa_hciu_get_type_inst_names
   1317 **
   1318 ** Description      This function returns command/response/event name.
   1319 **
   1320 ** Returns          pointer to the name
   1321 **
   1322 *******************************************************************************/
   1323 char *nfa_hciu_get_type_inst_names (UINT8 pipe, UINT8 type, UINT8 inst)
   1324 {
   1325     static char buff[100];
   1326     int   xx;
   1327 
   1328     xx = sprintf (buff, "Type: %s  ", nfa_hciu_type_2_str (type));
   1329 
   1330     switch (type)
   1331     {
   1332     case NFA_HCI_COMMAND_TYPE:
   1333         sprintf (&buff[xx], "Inst: %s ", nfa_hciu_instr_2_str (inst));
   1334         break;
   1335     case NFA_HCI_EVENT_TYPE:
   1336         sprintf (&buff[xx], "Evt: %s ", nfa_hciu_evt_2_str (pipe, inst));
   1337         break;
   1338     case NFA_HCI_RESPONSE_TYPE:
   1339         sprintf (&buff[xx], "Resp: %s ", nfa_hciu_get_response_name (inst));
   1340         break;
   1341     default:
   1342         sprintf (&buff[xx], "Inst: %u ", inst);
   1343         break;
   1344     }
   1345     return (buff);
   1346 }
   1347 
   1348 
   1349 
   1350 /*******************************************************************************
   1351 **
   1352 ** Function         nfa_hciu_instr_2_str
   1353 **
   1354 ** Description      This function returns the instruction name.
   1355 **
   1356 ** Returns          pointer to the name
   1357 **
   1358 *******************************************************************************/
   1359 char *nfa_hciu_evt_2_str (UINT8 pipe_id, UINT8 evt)
   1360 {
   1361     static char         unknown[40];
   1362     tNFA_HCI_DYN_PIPE   *p_pipe;
   1363 
   1364     if (  (pipe_id != NFA_HCI_ADMIN_PIPE)
   1365         &&(pipe_id != NFA_HCI_LINK_MANAGEMENT_PIPE)
   1366         &&((p_pipe = nfa_hciu_find_pipe_by_pid (pipe_id)) != NULL)  )
   1367     {
   1368         if (p_pipe->local_gate == NFA_HCI_CONNECTIVITY_GATE)
   1369         {
   1370             switch (evt)
   1371             {
   1372             case NFA_HCI_EVT_CONNECTIVITY:
   1373                 return ("EVT_CONNECTIVITY");
   1374             case NFA_HCI_EVT_TRANSACTION:
   1375                 return ("EVT_TRANSACTION");
   1376             case NFA_HCI_EVT_OPERATION_ENDED:
   1377                 return ("EVT_OPERATION_ENDED");
   1378             default:
   1379                 break;
   1380             }
   1381         }
   1382     }
   1383 
   1384     switch (evt)
   1385     {
   1386     case NFA_HCI_EVT_HCI_END_OF_OPERATION:
   1387         return ("EVT_END_OF_OPERATION");
   1388     case NFA_HCI_EVT_POST_DATA:
   1389         return ("EVT_POST_DATA");
   1390     case NFA_HCI_EVT_HOT_PLUG:
   1391         return ("EVT_HOT_PLUG");
   1392     default:
   1393         sprintf (unknown, "?? Unknown: %u ?? ", evt);
   1394         return (unknown);
   1395     }
   1396 }
   1397 #endif
   1398 
   1399 
   1400 static void handle_debug_loopback (BT_HDR *p_buf, UINT8 pipe, UINT8 type, UINT8 instruction)
   1401 {
   1402     UINT8 *p = (UINT8 *) (p_buf + 1) + p_buf->offset;
   1403     static UINT8  next_pipe = 0x10;
   1404 
   1405     if (type == NFA_HCI_COMMAND_TYPE)
   1406     {
   1407         switch (instruction)
   1408         {
   1409         case NFA_HCI_ADM_CREATE_PIPE:
   1410             p[6] = next_pipe++;
   1411             p[5] = p[4];
   1412             p[4] = p[3];
   1413             p[3] = p[2];
   1414             p[2] = 3;
   1415             p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
   1416             p_buf->len = p_buf->offset + 7;
   1417             break;
   1418 
   1419         case NFA_HCI_ANY_GET_PARAMETER:
   1420             p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
   1421             memcpy (&p[2], (UINT8 *) nfa_hci_cb.cfg.admin_gate.session_id, NFA_HCI_SESSION_ID_LEN);
   1422             p_buf->len = p_buf->offset + 2 + NFA_HCI_SESSION_ID_LEN;
   1423             break;
   1424 
   1425         default:
   1426             p[1] = (NFA_HCI_RESPONSE_TYPE << 6) | NFA_HCI_ANY_OK;
   1427             p_buf->len = p_buf->offset + 2;
   1428             break;
   1429         }
   1430     }
   1431     else if (type == NFA_HCI_RESPONSE_TYPE)
   1432     {
   1433         GKI_freebuf (p_buf);
   1434         return;
   1435     }
   1436 
   1437     p_buf->event = NFA_HCI_CHECK_QUEUE_EVT;
   1438     nfa_sys_sendmsg (p_buf);
   1439 }
   1440 
   1441