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