Home | History | Annotate | Download | only in btm
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2000-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 functions that handle SCO connections. This includes
     22  *  operations such as connect, disconnect, change supported packet types.
     23  *
     24  ******************************************************************************/
     25 
     26 #include <string.h>
     27 #include "bt_types.h"
     28 #include "bt_target.h"
     29 #include "gki.h"
     30 #include "bt_types.h"
     31 #include "hcimsgs.h"
     32 #include "btu.h"
     33 #include "btm_api.h"
     34 #include "btm_int.h"
     35 #include "hcidefs.h"
     36 
     37 #if BTM_SCO_INCLUDED == TRUE
     38 
     39 /********************************************************************************/
     40 /*                 L O C A L    D A T A    D E F I N I T I O N S                */
     41 /********************************************************************************/
     42 
     43 #define SCO_ST_UNUSED           0
     44 #define SCO_ST_LISTENING        1
     45 #define SCO_ST_W4_CONN_RSP      2
     46 #define SCO_ST_CONNECTING       3
     47 #define SCO_ST_CONNECTED        4
     48 #define SCO_ST_DISCONNECTING    5
     49 #define SCO_ST_PEND_UNPARK      6
     50 #define SCO_ST_PEND_ROLECHANGE  7
     51 
     52 /********************************************************************************/
     53 /*              L O C A L    F U N C T I O N     P R O T O T Y P E S            */
     54 /********************************************************************************/
     55 
     56 static const tBTM_ESCO_PARAMS btm_esco_defaults =
     57 {
     58     BTM_64KBITS_RATE,               /* TX Bandwidth (64 kbits/sec)              */
     59     BTM_64KBITS_RATE,               /* RX Bandwidth (64 kbits/sec)              */
     60     0x000a,                         /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3)  */
     61     0x0060,                         /* Inp Linear, Air CVSD, 2s Comp, 16bit     */
     62     (BTM_SCO_PKT_TYPES_MASK_HV1 +   /* Packet Types                             */
     63      BTM_SCO_PKT_TYPES_MASK_HV2 +
     64      BTM_SCO_PKT_TYPES_MASK_HV3 +
     65      BTM_SCO_PKT_TYPES_MASK_EV3 +
     66      BTM_SCO_PKT_TYPES_MASK_EV4 +
     67      BTM_SCO_PKT_TYPES_MASK_EV5),
     68      BTM_ESCO_RETRANS_POWER        /* Retransmission Effort (Power)   */
     69 };
     70 
     71 /*******************************************************************************
     72 **
     73 ** Function         btm_sco_flush_sco_data
     74 **
     75 ** Description      This function is called to flush the SCO data for this channel.
     76 **
     77 ** Returns          void
     78 **
     79 *******************************************************************************/
     80 void btm_sco_flush_sco_data(UINT16 sco_inx)
     81 {
     82 #if BTM_SCO_HCI_INCLUDED == TRUE
     83 #if (BTM_MAX_SCO_LINKS>0)
     84     tSCO_CONN   *p ;
     85     BT_HDR      *p_buf;
     86 
     87     if (sco_inx < BTM_MAX_SCO_LINKS)
     88     {
     89         p = &btm_cb.sco_cb.sco_db[sco_inx];
     90         while (p->xmit_data_q.p_first)
     91         {
     92             if ((p_buf = (BT_HDR *)GKI_dequeue (&p->xmit_data_q)) != NULL)
     93                 GKI_freebuf (p_buf);
     94         }
     95     }
     96 #endif
     97 #endif
     98 }
     99 /*******************************************************************************
    100 **
    101 ** Function         btm_sco_init
    102 **
    103 ** Description      This function is called at BTM startup to initialize
    104 **
    105 ** Returns          void
    106 **
    107 *******************************************************************************/
    108 void btm_sco_init (void)
    109 {
    110 #if 0  /* cleared in btm_init; put back in if called from anywhere else! */
    111     memset (&btm_cb.sco_cb, 0, sizeof(tSCO_CB));
    112 #endif
    113     /* Initialize nonzero defaults */
    114     btm_cb.sco_cb.sco_disc_reason  = BTM_INVALID_SCO_DISC_REASON;
    115 
    116     btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */
    117     btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE;
    118 }
    119 
    120 /*******************************************************************************
    121 **
    122 ** Function         btm_esco_conn_rsp
    123 **
    124 ** Description      This function is called upon receipt of an (e)SCO connection
    125 **                  request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
    126 **                  the request. Parameters used to negotiate eSCO links.
    127 **                  If p_parms is NULL, then default values are used.
    128 **                  If the link type of the incoming request is SCO, then only
    129 **                  the tx_bw, max_latency, content format, and packet_types are
    130 **                  valid.  The hci_status parameter should be
    131 **                  ([0x0] to accept, [0x0d..0x0f] to reject)
    132 **
    133 ** Returns          void
    134 **
    135 *******************************************************************************/
    136 static void btm_esco_conn_rsp (UINT16 sco_inx, UINT8 hci_status, BD_ADDR bda,
    137                                tBTM_ESCO_PARAMS *p_parms)
    138 {
    139 #if (BTM_MAX_SCO_LINKS>0)
    140     tSCO_CONN        *p_sco = NULL;
    141     tBTM_ESCO_PARAMS *p_setup;
    142     UINT16            temp_pkt_types;
    143 
    144     if (sco_inx < BTM_MAX_SCO_LINKS)
    145         p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
    146 
    147     /* Reject the connect request if refused by caller or wrong state */
    148     if (hci_status != HCI_SUCCESS || p_sco == NULL)
    149     {
    150         if (p_sco)
    151         {
    152             p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
    153                                                                 : SCO_ST_UNUSED;
    154         }
    155 
    156         if (!btm_cb.sco_cb.esco_supported)
    157         {
    158             if (!btsnd_hcic_reject_conn (bda, hci_status))
    159             {
    160                 BTM_TRACE_ERROR0("Could not reject (e)SCO conn: No Buffer!!!");
    161             }
    162         }
    163         else
    164         {
    165             if (!btsnd_hcic_reject_esco_conn (bda, hci_status))
    166             {
    167                 BTM_TRACE_ERROR0("Could not reject (e)SCO conn: No Buffer!!!");
    168             }
    169         }
    170     }
    171     else    /* Connection is being accepted */
    172     {
    173         p_sco->state = SCO_ST_CONNECTING;
    174         if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_1_2)
    175         {
    176             p_setup = &p_sco->esco.setup;
    177             /* If parameters not specified use the default */
    178             if (p_parms)
    179                 *p_setup = *p_parms;
    180             else /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
    181             {
    182                 *p_setup = btm_cb.sco_cb.def_esco_parms;
    183             }
    184 
    185             temp_pkt_types = (p_setup->packet_types &
    186                               BTM_SCO_SUPPORTED_PKTS_MASK &
    187                               btm_cb.btm_sco_pkt_types_supported);
    188 
    189             /* Make sure at least one eSCO packet type is sent, else might confuse peer */
    190             /* Taking this out to confirm with BQB tests
    191             ** Real application would like to include this though, as many devices
    192             ** do not retry with SCO only if an eSCO connection fails.
    193             if (!(temp_pkt_types & BTM_ESCO_LINK_ONLY_MASK))
    194             {
    195                 temp_pkt_types |= BTM_SCO_PKT_TYPES_MASK_EV3;
    196             }
    197             */
    198             /* If SCO request, remove eSCO packet types (conformance) */
    199             if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO)
    200             {
    201                 temp_pkt_types &= BTM_SCO_LINK_ONLY_MASK;
    202 
    203                 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
    204                 {
    205                     temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
    206                 }
    207             }
    208              /* OR in any exception packet types if at least 2.0 version of spec */
    209             else if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
    210             {
    211                 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
    212                     (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
    213             }
    214 
    215             if (btsnd_hcic_accept_esco_conn (bda, p_setup->tx_bw, p_setup->rx_bw,
    216                                          p_setup->max_latency, p_setup->voice_contfmt,
    217                                              p_setup->retrans_effort, temp_pkt_types))
    218             {
    219                 p_setup->packet_types = temp_pkt_types;
    220             }
    221             else
    222             {
    223                 BTM_TRACE_ERROR0("Could not accept SCO conn: No Buffer!!!");
    224             }
    225         }
    226         else    /* Controller is version 1.1 or earlier */
    227         {
    228             btsnd_hcic_accept_conn (bda, 0);
    229         }
    230     }
    231 #endif
    232 }
    233 
    234 
    235 #if BTM_SCO_HCI_INCLUDED == TRUE
    236 /*******************************************************************************
    237 **
    238 ** Function         btm_sco_check_send_pkts
    239 **
    240 ** Description      This function is called to check if it can send packets
    241 **                  to the Host Controller.
    242 **
    243 ** Returns          void
    244 **
    245 *******************************************************************************/
    246 void btm_sco_check_send_pkts (UINT16 sco_inx)
    247 {
    248     BT_HDR  *p_buf;
    249     tSCO_CB  *p_cb = &btm_cb.sco_cb;
    250     tSCO_CONN   *p_ccb = &p_cb->sco_db[sco_inx];
    251 
    252     /* If there is data to send, send it now */
    253     while (p_ccb->xmit_data_q.p_first != NULL)
    254     {
    255         p_buf = NULL;
    256 
    257 #if BTM_SCO_HCI_DEBUG
    258         BTM_TRACE_DEBUG1 ("btm: [%d] buf in xmit_data_q", p_ccb->xmit_data_q.count );
    259 #endif
    260         p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_data_q);
    261 
    262         HCI_SCO_DATA_TO_LOWER (p_buf);
    263     }
    264 }
    265 #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
    266 
    267 /*******************************************************************************
    268 **
    269 ** Function         btm_route_sco_data
    270 **
    271 ** Description      Route received SCO data.
    272 **
    273 ** Returns          void
    274 **
    275 *******************************************************************************/
    276 void  btm_route_sco_data(BT_HDR *p_msg)
    277 {
    278 #if BTM_SCO_HCI_INCLUDED == TRUE
    279     UINT16      sco_inx, handle;
    280     UINT8       *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
    281     UINT8       pkt_size = 0;
    282     UINT8       pkt_status = 0;
    283 
    284     /* Extract Packet_Status_Flag and handle */
    285     STREAM_TO_UINT16 (handle, p);
    286     pkt_status = HCID_GET_EVENT(handle);
    287     handle   = HCID_GET_HANDLE (handle);
    288 
    289     STREAM_TO_UINT8 (pkt_size, p);
    290 
    291     if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS )
    292     {
    293         /* send data callback */
    294         if (!btm_cb.sco_cb.p_data_cb )
    295             /* if no data callback registered,  just free the buffer  */
    296             GKI_freebuf (p_msg);
    297         else
    298         {
    299             (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status);
    300         }
    301     }
    302     else /* no mapping handle SCO connection is active, free the buffer */
    303     {
    304         GKI_freebuf (p_msg);
    305     }
    306 #else
    307     GKI_freebuf(p_msg);
    308 #endif
    309 }
    310 
    311 
    312 
    313 /*******************************************************************************
    314 **
    315 ** Function         BTM_WriteScoData
    316 **
    317 ** Description      This function write SCO data to a specified instance. The data
    318 **                  to be written p_buf needs to carry an offset of
    319 **                  HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
    320 **                  exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set
    321 **                  to 60 and is configurable. Data longer than the maximum bytes
    322 **                  will be truncated.
    323 **
    324 ** Returns          BTM_SUCCESS: data write is successful
    325 **                  BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
    326 **                  BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet
    327 **                                      size.
    328 **                  BTM_NO_RESOURCES: no resources.
    329 **                  BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not
    330 **                                    routed via HCI.
    331 **
    332 **
    333 *******************************************************************************/
    334 tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
    335 {
    336 #if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_MAX_SCO_LINKS>0)
    337     tSCO_CONN   *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
    338     UINT8   *p;
    339     tBTM_STATUS     status = BTM_SUCCESS;
    340 
    341     if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
    342         p_ccb->state == SCO_ST_CONNECTED)
    343     {
    344         /* Ensure we have enough space in the buffer for the SCO and HCI headers */
    345         if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE)
    346         {
    347             BTM_TRACE_ERROR1 ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset);
    348             GKI_freebuf (p_buf);
    349             status = BTM_ILLEGAL_VALUE;
    350         }
    351         else    /* write HCI header */
    352         {
    353             /* Step back 3 bytes to add the headers */
    354             p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
    355             /* Set the pointer to the beginning of the data */
    356             p = (UINT8 *)(p_buf + 1) + p_buf->offset;
    357             /* add HCI handle */
    358             UINT16_TO_STREAM (p, p_ccb->hci_handle);
    359             /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
    360                and set warning status */
    361             if (p_buf->len > BTM_SCO_DATA_SIZE_MAX)
    362             {
    363                 p_buf->len = BTM_SCO_DATA_SIZE_MAX;
    364                 status = BTM_SCO_BAD_LENGTH;
    365             }
    366 
    367             UINT8_TO_STREAM (p, (UINT8)p_buf->len);
    368             p_buf->len += HCI_SCO_PREAMBLE_SIZE;
    369 
    370             GKI_enqueue (&p_ccb->xmit_data_q, p_buf);
    371 
    372             btm_sco_check_send_pkts (sco_inx);
    373         }
    374     }
    375     else
    376     {
    377         GKI_freebuf(p_buf);
    378 
    379         BTM_TRACE_WARNING2 ("BTM_WriteScoData, invalid sco index: %d at state [%d]",
    380             sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state);
    381         status = BTM_UNKNOWN_ADDR;
    382     }
    383 
    384     return (status);
    385 
    386 #else
    387     return (BTM_NO_RESOURCES);
    388 #endif
    389 }
    390 
    391 #if (BTM_MAX_SCO_LINKS>0)
    392 /*******************************************************************************
    393 **
    394 ** Function         btm_send_connect_request
    395 **
    396 ** Description      This function is called to respond to SCO connect indications
    397 **
    398 ** Returns          void
    399 **
    400 *******************************************************************************/
    401 static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
    402                                             tBTM_ESCO_PARAMS *p_setup)
    403 {
    404     UINT16 temp_pkt_types;
    405     UINT8 xx;
    406     tACL_CONN *p_acl;
    407 
    408     /* Send connect request depending on version of spec */
    409     if (!btm_cb.sco_cb.esco_supported)
    410     {
    411         if (!btsnd_hcic_add_SCO_conn (acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types)))
    412             return (BTM_NO_RESOURCES);
    413     }
    414     else
    415     {
    416         temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
    417                              btm_cb.btm_sco_pkt_types_supported);
    418 
    419         /* OR in any exception packet types if at least 2.0 version of spec */
    420         if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
    421         {
    422             temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
    423                 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
    424         }
    425 
    426         /* Finally, remove EDR eSCO if the remote device doesn't support it */
    427         /* UPF25:  Only SCO was brought up in this case */
    428         btm_handle_to_acl_index(acl_handle);
    429         if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS)
    430         {
    431             p_acl = &btm_cb.acl_db[xx];
    432             if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->features))
    433             {
    434 
    435                 BTM_TRACE_WARNING0("BTM Remote does not support 2-EDR eSCO");
    436                 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 |
    437                                    HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5);
    438             }
    439             if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->features))
    440             {
    441 
    442                 BTM_TRACE_WARNING0("BTM Remote does not support 3-EDR eSCO");
    443                 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
    444                                    HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
    445             }
    446         }
    447 
    448 
    449         BTM_TRACE_API6("      txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
    450             p_setup->tx_bw, p_setup->rx_bw,
    451             p_setup->max_latency, p_setup->voice_contfmt,
    452             p_setup->retrans_effort, temp_pkt_types);
    453 
    454         if (!btsnd_hcic_setup_esco_conn(acl_handle,
    455                                         p_setup->tx_bw,
    456                                         p_setup->rx_bw,
    457                                         p_setup->max_latency,
    458                                         p_setup->voice_contfmt,
    459                                         p_setup->retrans_effort,
    460                                         temp_pkt_types))
    461             return (BTM_NO_RESOURCES);
    462         else
    463             p_setup->packet_types = temp_pkt_types;
    464     }
    465 
    466     return (BTM_CMD_STARTED);
    467 }
    468 #endif
    469 
    470 /*******************************************************************************
    471 **
    472 ** Function         btm_set_sco_ind_cback
    473 **
    474 ** Description      This function is called to register for TCS SCO connect
    475 **                  indications.
    476 **
    477 ** Returns          void
    478 **
    479 *******************************************************************************/
    480 void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb )
    481 {
    482     btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
    483 }
    484 
    485 /*******************************************************************************
    486 **
    487 ** Function         btm_accept_sco_link
    488 **
    489 ** Description      This function is called to respond to TCS SCO connect
    490 **                  indications
    491 **
    492 ** Returns          void
    493 **
    494 *******************************************************************************/
    495 void btm_accept_sco_link(UINT16 sco_inx, tBTM_ESCO_PARAMS *p_setup,
    496                          tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb)
    497 {
    498 #if (BTM_MAX_SCO_LINKS>0)
    499     tSCO_CONN        *p_sco;
    500 
    501     if (sco_inx >= BTM_MAX_SCO_LINKS)
    502     {
    503         BTM_TRACE_ERROR1("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
    504         return;
    505     }
    506 
    507     /* Link role is ignored in for this message */
    508     p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
    509     p_sco->p_conn_cb = p_conn_cb;
    510     p_sco->p_disc_cb = p_disc_cb;
    511     p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
    512 
    513     BTM_TRACE_DEBUG1("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
    514 
    515     btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
    516 #else
    517     btm_reject_sco_link(sco_inx);
    518 #endif
    519 }
    520 
    521 /*******************************************************************************
    522 **
    523 ** Function         btm_reject_sco_link
    524 **
    525 ** Description      This function is called to respond to SCO connect indications
    526 **
    527 ** Returns          void
    528 **
    529 *******************************************************************************/
    530 void btm_reject_sco_link( UINT16 sco_inx )
    531 {
    532     btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
    533                       btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
    534 }
    535 
    536 /*******************************************************************************
    537 **
    538 ** Function         BTM_CreateSco
    539 **
    540 ** Description      This function is called to create an SCO connection. If the
    541 **                  "is_orig" flag is TRUE, the connection will be originated,
    542 **                  otherwise BTM will wait for the other side to connect.
    543 **
    544 **                  NOTE:  If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
    545 **                      parameter the default packet types is used.
    546 **
    547 ** Returns          BTM_UNKNOWN_ADDR if the ACL connection is not up
    548 **                  BTM_BUSY         if another SCO being set up to
    549 **                                   the same BD address
    550 **                  BTM_NO_RESOURCES if the max SCO limit has been reached
    551 **                  BTM_CMD_STARTED  if the connection establishment is started.
    552 **                                   In this case, "*p_sco_inx" is filled in
    553 **                                   with the sco index used for the connection.
    554 **
    555 *******************************************************************************/
    556 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types,
    557                            UINT16 *p_sco_inx, tBTM_SCO_CB *p_conn_cb,
    558                            tBTM_SCO_CB *p_disc_cb)
    559 {
    560 #if (BTM_MAX_SCO_LINKS > 0)
    561     tBTM_ESCO_PARAMS *p_setup;
    562     tSCO_CONN        *p = &btm_cb.sco_cb.sco_db[0];
    563     UINT16            xx;
    564     UINT16            acl_handle = 0;
    565     UINT16            temp_pkt_types;
    566     tACL_CONN        *p_acl;
    567 
    568 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE)
    569     tBTM_PM_MODE      md;
    570     tBTM_PM_PWR_MD    pm;
    571 #else
    572     UINT8             mode;
    573 #endif
    574 
    575     *p_sco_inx = BTM_INVALID_SCO_INDEX;
    576 
    577     /* If originating, ensure that there is an ACL connection to the BD Address */
    578     if (is_orig)
    579     {
    580         if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda)) == 0xFFFF))
    581             return (BTM_UNKNOWN_ADDR);
    582     }
    583 
    584     if (remote_bda)
    585     {
    586         /* If any SCO is being established to the remote BD address, refuse this */
    587         for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    588         {
    589             if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING)
    590                 || (p->state == SCO_ST_PEND_UNPARK))
    591                 && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)))
    592             {
    593                 return (BTM_BUSY);
    594             }
    595         }
    596     }
    597     else
    598     {
    599         /* Support only 1 wildcard BD address at a time */
    600         for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    601         {
    602             if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known))
    603                 return (BTM_BUSY);
    604         }
    605     }
    606 
    607     /* Now, try to find an unused control block, and kick off the SCO establishment */
    608     for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    609     {
    610         if (p->state == SCO_ST_UNUSED)
    611         {
    612             if (remote_bda)
    613             {
    614                 if (is_orig)
    615                 {
    616                     /* can not create SCO link if in park mode */
    617 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE)
    618                     if(BTM_ReadPowerMode(remote_bda, &md) == BTM_SUCCESS)
    619                     {
    620                         if (md == BTM_PM_MD_PARK || md == BTM_PM_MD_SNIFF)
    621                         {
    622 /* Coverity: FALSE-POSITIVE error from Coverity tool. Please do NOT remove following comment. */
    623 /* coverity[uninit_use_in_call] False-positive: setting the mode to BTM_PM_MD_ACTIVE only uses settings.mode
    624                                 the other data members of tBTM_PM_PWR_MD are ignored
    625 */
    626                             pm.mode = BTM_PM_MD_ACTIVE;
    627                             BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
    628                             p->state = SCO_ST_PEND_UNPARK;
    629                         }
    630                     }
    631 #elif BTM_PWR_MGR_INCLUDED == TRUE
    632                     if( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) )
    633                         return (BTM_WRONG_MODE);
    634 #else
    635                     if( (BTM_ReadAclMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_ACL_MODE_PARK) )
    636                         return (BTM_WRONG_MODE);
    637 #endif
    638                 }
    639                 memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
    640                 p->rem_bd_known = TRUE;
    641             }
    642             else
    643                 p->rem_bd_known = FALSE;
    644 
    645             /* Link role is ignored in for this message */
    646             if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE)
    647                 pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types;
    648 
    649             p_setup = &p->esco.setup;
    650             *p_setup = btm_cb.sco_cb.def_esco_parms;
    651             p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO)
    652                 ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types;
    653 
    654             temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
    655                              btm_cb.btm_sco_pkt_types_supported);
    656 
    657             /* OR in any exception packet types if at least 2.0 version of spec */
    658             if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
    659             {
    660                 if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO)
    661                 {
    662                     temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
    663                         (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
    664                 }
    665                 else    /* Only using SCO packet types; turn off EDR also */
    666                 {
    667                     temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
    668                 }
    669             }
    670 
    671             p_setup->packet_types = temp_pkt_types;
    672             p->p_conn_cb  = p_conn_cb;
    673             p->p_disc_cb  = p_disc_cb;
    674             p->hci_handle = BTM_INVALID_HCI_HANDLE;
    675             p->is_orig = is_orig;
    676 
    677             if( p->state != SCO_ST_PEND_UNPARK )
    678             {
    679                 if (is_orig)
    680                 {
    681                     /* If role change is in progress, do not proceed with SCO setup
    682                      * Wait till role change is complete */
    683                     p_acl = btm_bda_to_acl(remote_bda);
    684                     if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
    685                     {
    686                         BTM_TRACE_API1("Role Change is in progress for ACL handle 0x%04x",acl_handle);
    687                         p->state = SCO_ST_PEND_ROLECHANGE;
    688 
    689                     }
    690                 }
    691             }
    692 
    693             if( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE )
    694             {
    695                 if (is_orig)
    696                 {
    697                     BTM_TRACE_API2("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d",
    698                                     acl_handle, btm_cb.sco_cb.desired_sco_mode);
    699 
    700                     if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED)
    701                         return (BTM_NO_RESOURCES);
    702 
    703                     p->state = SCO_ST_CONNECTING;
    704                 }
    705                 else
    706                     p->state = SCO_ST_LISTENING;
    707             }
    708 
    709             *p_sco_inx = xx;
    710 
    711             return (BTM_CMD_STARTED);
    712         }
    713     }
    714 
    715 #endif
    716     /* If here, all SCO blocks in use */
    717     return (BTM_NO_RESOURCES);
    718 }
    719 
    720 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE)
    721 /*******************************************************************************
    722 **
    723 ** Function         btm_sco_chk_pend_unpark
    724 **
    725 ** Description      This function is called by BTIF when there is a mode change
    726 **                  event to see if there are SCO commands waiting for the unpark.
    727 **
    728 ** Returns          void
    729 **
    730 *******************************************************************************/
    731 void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle)
    732 {
    733 #if (BTM_MAX_SCO_LINKS>0)
    734     UINT16      xx;
    735     UINT16      acl_handle;
    736     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[0];
    737 
    738     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    739     {
    740         if ((p->state == SCO_ST_PEND_UNPARK) &&
    741             ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
    742 
    743         {
    744             BTM_TRACE_API3("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
    745                                     acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status);
    746 
    747             if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
    748                 p->state = SCO_ST_CONNECTING;
    749         }
    750     }
    751 #endif
    752 }
    753 #endif
    754 
    755 /*******************************************************************************
    756 **
    757 ** Function         btm_sco_chk_pend_rolechange
    758 **
    759 ** Description      This function is called by BTIF when there is a role change
    760 **                  event to see if there are SCO commands waiting for the role change.
    761 **
    762 ** Returns          void
    763 **
    764 *******************************************************************************/
    765 void btm_sco_chk_pend_rolechange (UINT16 hci_handle)
    766 {
    767 #if (BTM_MAX_SCO_LINKS>0)
    768     UINT16      xx;
    769     UINT16      acl_handle;
    770     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[0];
    771 
    772     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    773     {
    774         if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
    775             ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
    776 
    777         {
    778             BTM_TRACE_API1("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
    779 
    780             if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
    781                 p->state = SCO_ST_CONNECTING;
    782         }
    783     }
    784 #endif
    785 }
    786 
    787 /*******************************************************************************
    788 **
    789 ** Function         btm_sco_conn_req
    790 **
    791 ** Description      This function is called by BTIF when an SCO connection
    792 **                  request is received from a remote.
    793 **
    794 ** Returns          void
    795 **
    796 *******************************************************************************/
    797 void btm_sco_conn_req (BD_ADDR bda,  DEV_CLASS dev_class, UINT8 link_type)
    798 {
    799 #if (BTM_MAX_SCO_LINKS>0)
    800     tSCO_CB     *p_sco = &btm_cb.sco_cb;
    801     tSCO_CONN   *p = &p_sco->sco_db[0];
    802     UINT16      xx;
    803     tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
    804 
    805     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    806     {
    807         /*
    808          * If the sco state is in the SCO_ST_CONNECTING state, we still need
    809          * to return accept sco to avoid race conditon for sco creation
    810          */
    811         if (((p->state == SCO_ST_LISTENING && p->rem_bd_known) || p->state == SCO_ST_CONNECTING)
    812          && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
    813         {
    814             /* If this guy was a wildcard, he is not one any more */
    815             p->rem_bd_known = TRUE;
    816             p->esco.data.link_type = link_type;
    817             p->state = SCO_ST_W4_CONN_RSP;
    818             memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
    819 
    820             /* If no callback, auto-accept the connection if packet types match */
    821             if (!p->esco.p_esco_cback)
    822             {
    823                 /* If requesting eSCO reject if default parameters are SCO only */
    824                 if ((link_type == BTM_LINK_TYPE_ESCO
    825                     && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK)
    826                     && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK)
    827                        == BTM_SCO_EXCEPTION_PKTS_MASK))
    828 
    829                     /* Reject request if SCO is desired but no SCO packets delected */
    830                     || (link_type == BTM_LINK_TYPE_SCO
    831                     && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK)))
    832                 {
    833                     btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
    834                 }
    835                 else    /* Accept the request */
    836                 {
    837                     btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
    838                 }
    839             }
    840             else    /* Notify upper layer of connect indication */
    841             {
    842                 memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
    843                 memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
    844                 evt_data.link_type = link_type;
    845                 evt_data.sco_inx = xx;
    846                 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data);
    847             }
    848 
    849             return;
    850         }
    851     }
    852 
    853     /* TCS usage */
    854     if (btm_cb.sco_cb.app_sco_ind_cb)
    855     {
    856         /* Now, try to find an unused control block */
    857         for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    858         {
    859             if (p->state == SCO_ST_UNUSED)
    860             {
    861                 p->is_orig = FALSE;
    862                 p->state = SCO_ST_LISTENING;
    863 
    864                 p->esco.data.link_type = link_type;
    865                 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
    866                 p->rem_bd_known = TRUE;
    867                 break;
    868             }
    869         }
    870         if( xx < BTM_MAX_SCO_LINKS)
    871         {
    872             btm_cb.sco_cb.app_sco_ind_cb(xx);
    873             return;
    874         }
    875     }
    876 
    877 #endif
    878     /* If here, no one wants the SCO connection. Reject it */
    879     BTM_TRACE_WARNING0("btm_sco_conn_req: No one wants this SCO connection; rejecting it");
    880     btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
    881 }
    882 
    883 /*******************************************************************************
    884 **
    885 ** Function         btm_sco_connected
    886 **
    887 ** Description      This function is called by BTIF when an (e)SCO connection
    888 **                  is connected.
    889 **
    890 ** Returns          void
    891 **
    892 *******************************************************************************/
    893 void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
    894                         tBTM_ESCO_DATA *p_esco_data)
    895 {
    896 #if (BTM_MAX_SCO_LINKS>0)
    897     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[0];
    898     UINT16      xx;
    899     BOOLEAN     spt = FALSE;
    900     tBTM_CHG_ESCO_PARAMS parms;
    901 #endif
    902 
    903     btm_cb.sco_cb.sco_disc_reason = hci_status;
    904 
    905 #if (BTM_MAX_SCO_LINKS>0)
    906     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    907     {
    908         if (((p->state == SCO_ST_CONNECTING) ||
    909              (p->state == SCO_ST_LISTENING)  ||
    910              (p->state == SCO_ST_W4_CONN_RSP))
    911          && (p->rem_bd_known)
    912          && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
    913         {
    914             if (hci_status != HCI_SUCCESS)
    915             {
    916                 /* Report the error if originator, otherwise remain in Listen mode */
    917                 if (p->is_orig)
    918                 {
    919                     /* If role switch is pending, we need try again after role switch is complete */
    920                     if(hci_status == HCI_ERR_ROLE_SWITCH_PENDING)
    921                     {
    922                         BTM_TRACE_API1("Role Change pending for HCI handle 0x%04x",hci_handle);
    923                         p->state = SCO_ST_PEND_ROLECHANGE;
    924                     }
    925                     /* avoid calling disconnect callback because of sco creation race */
    926                     else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION)
    927                     {
    928                         p->state = SCO_ST_UNUSED;
    929                         (*p->p_disc_cb)(xx);
    930                     }
    931                 }
    932                 else
    933                 {
    934                     /* Notify the upper layer that incoming sco connection has failed. */
    935                     if (p->state == SCO_ST_CONNECTING)
    936                     {
    937                         p->state = SCO_ST_UNUSED;
    938                         (*p->p_disc_cb)(xx);
    939                     }
    940                     else
    941                         p->state = SCO_ST_LISTENING;
    942                 }
    943 
    944                 return;
    945             }
    946 
    947             if (p->state == SCO_ST_LISTENING)
    948                 spt = TRUE;
    949 
    950             p->state = SCO_ST_CONNECTED;
    951             p->hci_handle = hci_handle;
    952 
    953             if (!btm_cb.sco_cb.esco_supported)
    954             {
    955                 p->esco.data.link_type = BTM_LINK_TYPE_SCO;
    956                 if (spt)
    957                 {
    958                     parms.packet_types = p->esco.setup.packet_types;
    959                     /* Keep the other parameters the same for SCO */
    960                     parms.max_latency = p->esco.setup.max_latency;
    961                     parms.retrans_effort = p->esco.setup.retrans_effort;
    962 
    963                     BTM_ChangeEScoLinkParms(xx, &parms);
    964                 }
    965             }
    966             else
    967             {
    968                 if (p_esco_data)
    969                     p->esco.data = *p_esco_data;
    970             }
    971 
    972             (*p->p_conn_cb)(xx);
    973 
    974             return;
    975         }
    976     }
    977 #endif
    978 }
    979 
    980 
    981 /*******************************************************************************
    982 **
    983 ** Function         btm_find_scb_by_handle
    984 **
    985 ** Description      Look through all active SCO connection for a match based on the
    986 **                  HCI handle.
    987 **
    988 ** Returns          index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
    989 **                  no match.
    990 **
    991 *******************************************************************************/
    992 UINT16  btm_find_scb_by_handle (UINT16 handle)
    993 {
    994     int         xx;
    995     tSCO_CONN    *p = &btm_cb.sco_cb.sco_db[0];
    996 
    997     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
    998     {
    999         if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle))
   1000         {
   1001             return (xx);
   1002         }
   1003     }
   1004 
   1005     /* If here, no match found */
   1006     return (xx);
   1007 }
   1008 
   1009 /*******************************************************************************
   1010 **
   1011 ** Function         BTM_RemoveSco
   1012 **
   1013 ** Description      This function is called to remove a specific SCO connection.
   1014 **
   1015 ** Returns          status of the operation
   1016 **
   1017 *******************************************************************************/
   1018 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
   1019 {
   1020 #if (BTM_MAX_SCO_LINKS>0)
   1021     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[sco_inx];
   1022     UINT16       tempstate;
   1023 
   1024     /* Validity check */
   1025     if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
   1026         return (BTM_UNKNOWN_ADDR);
   1027 
   1028     /* If no HCI handle, simply drop the connection and return */
   1029     if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK)
   1030     {
   1031         p->hci_handle = BTM_INVALID_HCI_HANDLE;
   1032         p->state = SCO_ST_UNUSED;
   1033         p->esco.p_esco_cback = NULL;    /* Deregister the eSCO event callback */
   1034         return (BTM_SUCCESS);
   1035     }
   1036 
   1037     tempstate = p->state;
   1038     p->state = SCO_ST_DISCONNECTING;
   1039 
   1040     if (!btsnd_hcic_disconnect (p->hci_handle, HCI_ERR_PEER_USER))
   1041     {
   1042         p->state = tempstate;
   1043         return (BTM_NO_RESOURCES);
   1044     }
   1045 
   1046     return (BTM_CMD_STARTED);
   1047 #else
   1048     return (BTM_NO_RESOURCES);
   1049 #endif
   1050 }
   1051 
   1052 /*******************************************************************************
   1053 **
   1054 ** Function         btm_remove_sco_links
   1055 **
   1056 ** Description      This function is called to remove all sco links for an ACL link.
   1057 **
   1058 ** Returns          void
   1059 **
   1060 *******************************************************************************/
   1061 void btm_remove_sco_links (BD_ADDR bda)
   1062 {
   1063 #if (BTM_MAX_SCO_LINKS>0)
   1064     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[0];
   1065     UINT16       xx;
   1066 
   1067     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1068     {
   1069         if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
   1070         {
   1071             BTM_RemoveSco(xx);
   1072         }
   1073     }
   1074 #endif
   1075 }
   1076 
   1077 /*******************************************************************************
   1078 **
   1079 ** Function         btm_sco_removed
   1080 **
   1081 ** Description      This function is called by BTIF when an SCO connection
   1082 **                  is removed.
   1083 **
   1084 ** Returns          void
   1085 **
   1086 *******************************************************************************/
   1087 void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
   1088 {
   1089 #if (BTM_MAX_SCO_LINKS>0)
   1090     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[0];
   1091     UINT16      xx;
   1092 #endif
   1093 
   1094     btm_cb.sco_cb.sco_disc_reason = reason;
   1095 
   1096 #if (BTM_MAX_SCO_LINKS>0)
   1097     p = &btm_cb.sco_cb.sco_db[0];
   1098     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1099     {
   1100         if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle))
   1101         {
   1102             btm_sco_flush_sco_data(xx);
   1103 
   1104             p->state = SCO_ST_UNUSED;
   1105             p->hci_handle = BTM_INVALID_HCI_HANDLE;
   1106             p->rem_bd_known = FALSE;
   1107             p->esco.p_esco_cback = NULL;    /* Deregister eSCO callback */
   1108             (*p->p_disc_cb)(xx);
   1109 
   1110             return;
   1111         }
   1112     }
   1113 #endif
   1114 }
   1115 
   1116 
   1117 /*******************************************************************************
   1118 **
   1119 ** Function         btm_sco_acl_removed
   1120 **
   1121 ** Description      This function is called when an ACL connection is
   1122 **                  removed. If the BD address is NULL, it is assumed that
   1123 **                  the local device is down, and all SCO links are removed.
   1124 **                  If a specific BD address is passed, only SCO connections
   1125 **                  to that BD address are removed.
   1126 **
   1127 ** Returns          void
   1128 **
   1129 *******************************************************************************/
   1130 void btm_sco_acl_removed (BD_ADDR bda)
   1131 {
   1132 #if (BTM_MAX_SCO_LINKS>0)
   1133     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[0];
   1134     UINT16      xx;
   1135 
   1136     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1137     {
   1138         if (p->state != SCO_ST_UNUSED)
   1139         {
   1140             if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known))
   1141             {
   1142                 btm_sco_flush_sco_data(xx);
   1143 
   1144                 p->state = SCO_ST_UNUSED;
   1145                 p->esco.p_esco_cback = NULL;    /* Deregister eSCO callback */
   1146                 (*p->p_disc_cb)(xx);
   1147             }
   1148         }
   1149     }
   1150 #endif
   1151 }
   1152 
   1153 
   1154 /*******************************************************************************
   1155 **
   1156 ** Function         BTM_SetScoPacketTypes
   1157 **
   1158 ** Description      This function is called to set the packet types used for
   1159 **                  a specific SCO connection,
   1160 **
   1161 ** Parameters       pkt_types - One or more of the following
   1162 **                  BTM_SCO_PKT_TYPES_MASK_HV1
   1163 **                  BTM_SCO_PKT_TYPES_MASK_HV2
   1164 **                  BTM_SCO_PKT_TYPES_MASK_HV3
   1165 **                  BTM_SCO_PKT_TYPES_MASK_EV3
   1166 **                  BTM_SCO_PKT_TYPES_MASK_EV4
   1167 **                  BTM_SCO_PKT_TYPES_MASK_EV5
   1168 **                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
   1169 **                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
   1170 **                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
   1171 **                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
   1172 **
   1173 **                  BTM_SCO_LINK_ALL_MASK   - enables all supported types
   1174 **
   1175 ** Returns          status of the operation
   1176 **
   1177 *******************************************************************************/
   1178 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
   1179 {
   1180 #if (BTM_MAX_SCO_LINKS>0)
   1181     tBTM_CHG_ESCO_PARAMS parms;
   1182     tSCO_CONN           *p;
   1183 
   1184     /* Validity check */
   1185     if (sco_inx >= BTM_MAX_SCO_LINKS)
   1186         return (BTM_UNKNOWN_ADDR);
   1187 
   1188     p = &btm_cb.sco_cb.sco_db[sco_inx];
   1189     parms.packet_types = pkt_types;
   1190 
   1191     /* Keep the other parameters the same for SCO */
   1192     parms.max_latency = p->esco.setup.max_latency;
   1193     parms.retrans_effort = p->esco.setup.retrans_effort;
   1194 
   1195     return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
   1196 #else
   1197     return (BTM_UNKNOWN_ADDR);
   1198 #endif
   1199 }
   1200 
   1201 
   1202 /*******************************************************************************
   1203 **
   1204 ** Function         BTM_ReadScoPacketTypes
   1205 **
   1206 ** Description      This function is read the packet types used for a specific
   1207 **                  SCO connection.
   1208 **
   1209 ** Returns          Packet types supported for the connection
   1210 **                  One or more of the following (bitmask):
   1211 **                  BTM_SCO_PKT_TYPES_MASK_HV1
   1212 **                  BTM_SCO_PKT_TYPES_MASK_HV2
   1213 **                  BTM_SCO_PKT_TYPES_MASK_HV3
   1214 **                  BTM_SCO_PKT_TYPES_MASK_EV3
   1215 **                  BTM_SCO_PKT_TYPES_MASK_EV4
   1216 **                  BTM_SCO_PKT_TYPES_MASK_EV5
   1217 **                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
   1218 **                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
   1219 **                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
   1220 **                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
   1221 **
   1222 *******************************************************************************/
   1223 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
   1224 {
   1225 #if (BTM_MAX_SCO_LINKS>0)
   1226     tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
   1227 
   1228     /* Validity check */
   1229     if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
   1230         return (p->esco.setup.packet_types);
   1231     else
   1232         return (0);
   1233 #else
   1234     return (0);
   1235 #endif
   1236 }
   1237 
   1238 /*******************************************************************************
   1239 **
   1240 ** Function         BTM_ReadScoDiscReason
   1241 **
   1242 ** Description      This function is returns the reason why an (e)SCO connection
   1243 **                  has been removed. It contains the value until read, or until
   1244 **                  another (e)SCO connection has disconnected.
   1245 **
   1246 ** Returns          HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
   1247 **
   1248 *******************************************************************************/
   1249 UINT16 BTM_ReadScoDiscReason (void)
   1250 {
   1251     UINT16 res = btm_cb.sco_cb.sco_disc_reason;
   1252     btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
   1253     return (res);
   1254 }
   1255 
   1256 /*******************************************************************************
   1257 **
   1258 ** Function         BTM_ReadDeviceScoPacketTypes
   1259 **
   1260 ** Description      This function is read the SCO packet types that
   1261 **                  the device supports.
   1262 **
   1263 ** Returns          Packet types supported by the device.
   1264 **                  One or more of the following (bitmask):
   1265 **                  BTM_SCO_PKT_TYPES_MASK_HV1
   1266 **                  BTM_SCO_PKT_TYPES_MASK_HV2
   1267 **                  BTM_SCO_PKT_TYPES_MASK_HV3
   1268 **                  BTM_SCO_PKT_TYPES_MASK_EV3
   1269 **                  BTM_SCO_PKT_TYPES_MASK_EV4
   1270 **                  BTM_SCO_PKT_TYPES_MASK_EV5
   1271 **                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
   1272 **                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
   1273 **                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
   1274 **                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
   1275 **
   1276 *******************************************************************************/
   1277 UINT16 BTM_ReadDeviceScoPacketTypes (void)
   1278 {
   1279     return (btm_cb.btm_sco_pkt_types_supported);
   1280 }
   1281 
   1282 /*******************************************************************************
   1283 **
   1284 ** Function         BTM_ReadScoHandle
   1285 **
   1286 ** Description      This function is used to read the HCI handle used for a specific
   1287 **                  SCO connection,
   1288 **
   1289 ** Returns          handle for the connection, or 0xFFFF if invalid SCO index.
   1290 **
   1291 *******************************************************************************/
   1292 UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
   1293 {
   1294 #if (BTM_MAX_SCO_LINKS>0)
   1295     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[sco_inx];
   1296 
   1297     /* Validity check */
   1298     if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
   1299         return (p->hci_handle);
   1300     else
   1301         return (BTM_INVALID_HCI_HANDLE);
   1302 #else
   1303     return (BTM_INVALID_HCI_HANDLE);
   1304 #endif
   1305 }
   1306 
   1307 /*******************************************************************************
   1308 **
   1309 ** Function         BTM_ReadScoBdAddr
   1310 **
   1311 ** Description      This function is read the remote BD Address for a specific
   1312 **                  SCO connection,
   1313 **
   1314 ** Returns          pointer to BD address or NULL if not known
   1315 **
   1316 *******************************************************************************/
   1317 UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx)
   1318 {
   1319 #if (BTM_MAX_SCO_LINKS>0)
   1320     tSCO_CONN   *p = &btm_cb.sco_cb.sco_db[sco_inx];
   1321 
   1322     /* Validity check */
   1323     if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
   1324         return (p->esco.data.bd_addr);
   1325     else
   1326         return (NULL);
   1327 #else
   1328     return (NULL);
   1329 #endif
   1330 }
   1331 
   1332 /*******************************************************************************
   1333 **
   1334 ** Function         BTM_SetEScoMode
   1335 **
   1336 ** Description      This function sets up the negotiated parameters for SCO or
   1337 **                  eSCO, and sets as the default mode used for outgoing calls to
   1338 **                  BTM_CreateSco.  It does not change any currently active (e)SCO links.
   1339 **                  Note:  Incoming (e)SCO connections will always use packet types
   1340 **                      supported by the controller.  If eSCO is not desired the
   1341 **                      feature should be disabled in the controller's feature mask.
   1342 **
   1343 ** Returns          BTM_SUCCESS if the successful.
   1344 **                  BTM_BUSY if there are one or more active (e)SCO links.
   1345 **
   1346 *******************************************************************************/
   1347 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
   1348 {
   1349     tSCO_CB          *p_esco = &btm_cb.sco_cb;
   1350     tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms;
   1351 
   1352     if (p_esco->esco_supported)
   1353     {
   1354         if (p_parms)
   1355         {
   1356             if (sco_mode == BTM_LINK_TYPE_ESCO)
   1357                 *p_def = *p_parms;  /* Save as the default parameters */
   1358             else    /* Load only the SCO packet types */
   1359             {
   1360                 p_def->packet_types = p_parms->packet_types;
   1361                 p_def->tx_bw            = BTM_64KBITS_RATE;
   1362                 p_def->rx_bw            = BTM_64KBITS_RATE;
   1363                 p_def->max_latency      = 0x000a;
   1364                 p_def->voice_contfmt    = 0x0060;
   1365                 p_def->retrans_effort   = 0;
   1366 
   1367                 /* OR in any exception packet types if at least 2.0 version of spec */
   1368                 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
   1369                 {
   1370                     p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
   1371                 }
   1372             }
   1373         }
   1374         p_esco->desired_sco_mode = sco_mode;
   1375         BTM_TRACE_API1("BTM_SetEScoMode -> mode %d",  sco_mode);
   1376     }
   1377     else
   1378     {
   1379         p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO;
   1380         p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
   1381         p_def->retrans_effort = 0;
   1382         BTM_TRACE_API0("BTM_SetEScoMode -> mode SCO (eSCO not supported)");
   1383     }
   1384 
   1385     BTM_TRACE_DEBUG6("    txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x",
   1386                      p_def->tx_bw, p_def->rx_bw, p_def->max_latency,
   1387                      p_def->voice_contfmt, p_def->packet_types,
   1388                      p_def->retrans_effort);
   1389 
   1390     return (BTM_SUCCESS);
   1391 }
   1392 
   1393 
   1394 
   1395 /*******************************************************************************
   1396 **
   1397 ** Function         BTM_RegForEScoEvts
   1398 **
   1399 ** Description      This function registers a SCO event callback with the
   1400 **                  specified instance.  It should be used to received
   1401 **                  connection indication events and change of link parameter
   1402 **                  events.
   1403 **
   1404 ** Returns          BTM_SUCCESS if the successful.
   1405 **                  BTM_ILLEGAL_VALUE if there is an illegal sco_inx
   1406 **                  BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
   1407 **                          later or does not support eSCO.
   1408 **
   1409 *******************************************************************************/
   1410 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
   1411 {
   1412 #if (BTM_MAX_SCO_LINKS>0)
   1413     if (!btm_cb.sco_cb.esco_supported)
   1414     {
   1415         btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
   1416         return (BTM_MODE_UNSUPPORTED);
   1417     }
   1418 
   1419     if (sco_inx < BTM_MAX_SCO_LINKS &&
   1420         btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED)
   1421     {
   1422         btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
   1423         return (BTM_SUCCESS);
   1424     }
   1425     return (BTM_ILLEGAL_VALUE);
   1426 #else
   1427     return (BTM_MODE_UNSUPPORTED);
   1428 #endif
   1429 }
   1430 
   1431 /*******************************************************************************
   1432 **
   1433 ** Function         BTM_ReadEScoLinkParms
   1434 **
   1435 ** Description      This function returns the current eSCO link parameters for
   1436 **                  the specified handle.  This can be called anytime a connection
   1437 **                  is active, but is typically called after receiving the SCO
   1438 **                  opened callback.
   1439 **
   1440 **                  Note: If called over a 1.1 controller, only the packet types
   1441 **                        field has meaning.
   1442 **
   1443 ** Returns          BTM_SUCCESS if returned data is valid connection.
   1444 **                  BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
   1445 **
   1446 *******************************************************************************/
   1447 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
   1448 {
   1449 #if (BTM_MAX_SCO_LINKS>0)
   1450     BTM_TRACE_API1("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx);
   1451 
   1452     if (sco_inx < BTM_MAX_SCO_LINKS &&
   1453         btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED)
   1454     {
   1455         *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
   1456         return (BTM_SUCCESS);
   1457     }
   1458 #endif
   1459 
   1460     memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
   1461     return (BTM_WRONG_MODE);
   1462 }
   1463 
   1464 /*******************************************************************************
   1465 **
   1466 ** Function         BTM_ChangeEScoLinkParms
   1467 **
   1468 ** Description      This function requests renegotiation of the parameters on
   1469 **                  the current eSCO Link.  If any of the changes are accepted
   1470 **                  by the controllers, the BTM_ESCO_CHG_EVT event is sent in
   1471 **                  the tBTM_ESCO_CBACK function with the current settings of
   1472 **                  the link. The callback is registered through the call to
   1473 **                  BTM_SetEScoMode.
   1474 **
   1475 **                  Note: If called over a SCO link (including 1.1 controller),
   1476 **                        a change packet type request is sent out instead.
   1477 **
   1478 ** Returns          BTM_CMD_STARTED if command is successfully initiated.
   1479 **                  BTM_NO_RESOURCES - not enough resources to initiate command.
   1480 **                  BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
   1481 **
   1482 *******************************************************************************/
   1483 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
   1484 {
   1485 #if (BTM_MAX_SCO_LINKS>0)
   1486     tBTM_ESCO_PARAMS *p_setup;
   1487     tSCO_CONN        *p_sco;
   1488     UINT16            temp_pkt_types;
   1489 
   1490     /* Make sure sco handle is valid and on an active link */
   1491     if (sco_inx >= BTM_MAX_SCO_LINKS ||
   1492         btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
   1493         return (BTM_WRONG_MODE);
   1494 
   1495     p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
   1496     p_setup = &p_sco->esco.setup;
   1497 
   1498     /* If SCO connection OR eSCO not supported just send change packet types */
   1499     if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
   1500         !btm_cb.sco_cb.esco_supported)
   1501     {
   1502         p_setup->packet_types = p_parms->packet_types &
   1503             (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
   1504 
   1505 
   1506         BTM_TRACE_API2("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x",
   1507                          p_sco->hci_handle, p_setup->packet_types);
   1508 
   1509         if (!btsnd_hcic_change_conn_type (p_sco->hci_handle,
   1510                                      BTM_ESCO_2_SCO(p_setup->packet_types)))
   1511             return (BTM_NO_RESOURCES);
   1512     }
   1513     else
   1514     {
   1515         temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
   1516                              btm_cb.btm_sco_pkt_types_supported);
   1517 
   1518         /* OR in any exception packet types if at least 2.0 version of spec */
   1519         if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
   1520         {
   1521             temp_pkt_types |= ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
   1522                 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
   1523         }
   1524 
   1525         BTM_TRACE_API1("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle);
   1526         BTM_TRACE_API6("      txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
   1527                          p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency,
   1528                          p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types);
   1529 
   1530         /* When changing an existing link, only change latency, retrans, and pkts */
   1531         if (!btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw,
   1532                                         p_setup->rx_bw, p_parms->max_latency,
   1533                                         p_setup->voice_contfmt,
   1534                                         p_parms->retrans_effort,
   1535                                         temp_pkt_types))
   1536             return (BTM_NO_RESOURCES);
   1537         else
   1538             p_parms->packet_types = temp_pkt_types;
   1539     }
   1540 
   1541     return (BTM_CMD_STARTED);
   1542 #else
   1543     return (BTM_WRONG_MODE);
   1544 #endif
   1545 }
   1546 
   1547 /*******************************************************************************
   1548 **
   1549 ** Function         BTM_EScoConnRsp
   1550 **
   1551 ** Description      This function is called upon receipt of an (e)SCO connection
   1552 **                  request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
   1553 **                  the request. Parameters used to negotiate eSCO links.
   1554 **                  If p_parms is NULL, then values set through BTM_SetEScoMode
   1555 **                  are used.
   1556 **                  If the link type of the incoming request is SCO, then only
   1557 **                  the tx_bw, max_latency, content format, and packet_types are
   1558 **                  valid.  The hci_status parameter should be
   1559 **                  ([0x0] to accept, [0x0d..0x0f] to reject)
   1560 **
   1561 **
   1562 ** Returns          void
   1563 **
   1564 *******************************************************************************/
   1565 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms)
   1566 {
   1567 #if (BTM_MAX_SCO_LINKS>0)
   1568     if (sco_inx < BTM_MAX_SCO_LINKS &&
   1569         btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP)
   1570     {
   1571         btm_esco_conn_rsp(sco_inx, hci_status,
   1572                           btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr,
   1573                           p_parms);
   1574     }
   1575 #endif
   1576 }
   1577 
   1578 /*******************************************************************************
   1579 **
   1580 ** Function         btm_read_def_esco_mode
   1581 **
   1582 ** Description      This function copies the current default esco settings into
   1583 **                  the return buffer.
   1584 **
   1585 ** Returns          tBTM_SCO_TYPE
   1586 **
   1587 *******************************************************************************/
   1588 tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms)
   1589 {
   1590 #if (BTM_MAX_SCO_LINKS>0)
   1591     *p_parms = btm_cb.sco_cb.def_esco_parms;
   1592     return btm_cb.sco_cb.desired_sco_mode;
   1593 #else
   1594     return BTM_LINK_TYPE_SCO;
   1595 #endif
   1596 }
   1597 
   1598 /*******************************************************************************
   1599 **
   1600 ** Function         btm_esco_proc_conn_chg
   1601 **
   1602 ** Description      This function is called by BTIF when an SCO connection
   1603 **                  is changed.
   1604 **
   1605 ** Returns          void
   1606 **
   1607 *******************************************************************************/
   1608 void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval,
   1609                              UINT8 retrans_window, UINT16 rx_pkt_len,
   1610                              UINT16 tx_pkt_len)
   1611 {
   1612 #if (BTM_MAX_SCO_LINKS>0)
   1613     tSCO_CONN               *p = &btm_cb.sco_cb.sco_db[0];
   1614     tBTM_CHG_ESCO_EVT_DATA   data;
   1615     UINT16                   xx;
   1616 
   1617     BTM_TRACE_EVENT2("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
   1618                       handle, status);
   1619 
   1620     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1621     {
   1622         if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle)
   1623         {
   1624             /* If upper layer wants notification */
   1625             if (p->esco.p_esco_cback)
   1626             {
   1627                 memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
   1628                 data.hci_status = status;
   1629                 data.sco_inx = xx;
   1630                 data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
   1631                 data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
   1632                 data.tx_interval = p->esco.data.tx_interval = tx_interval;
   1633                 data.retrans_window = p->esco.data.retrans_window = retrans_window;
   1634 
   1635                 (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT,
   1636                                         (tBTM_ESCO_EVT_DATA *)&data);
   1637             }
   1638             return;
   1639         }
   1640     }
   1641 #endif
   1642 }
   1643 
   1644 /*******************************************************************************
   1645 **
   1646 ** Function         btm_is_sco_active
   1647 **
   1648 ** Description      This function is called to see if a SCO handle is already in
   1649 **                  use.
   1650 **
   1651 ** Returns          BOOLEAN
   1652 **
   1653 *******************************************************************************/
   1654 BOOLEAN btm_is_sco_active (UINT16 handle)
   1655 {
   1656 #if (BTM_MAX_SCO_LINKS>0)
   1657     UINT16     xx;
   1658     tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
   1659 
   1660     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1661     {
   1662         if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED)
   1663             return (TRUE);
   1664     }
   1665 #endif
   1666     return (FALSE);
   1667 }
   1668 
   1669 /*******************************************************************************
   1670 **
   1671 ** Function         BTM_GetNumScoLinks
   1672 **
   1673 ** Description      This function returns the number of active sco links.
   1674 **
   1675 ** Returns          UINT8
   1676 **
   1677 *******************************************************************************/
   1678 UINT8 BTM_GetNumScoLinks (void)
   1679 {
   1680 #if (BTM_MAX_SCO_LINKS>0)
   1681     tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
   1682     UINT16     xx;
   1683     UINT8      num_scos = 0;
   1684 
   1685     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1686     {
   1687         switch (p->state)
   1688         {
   1689         case SCO_ST_W4_CONN_RSP:
   1690         case SCO_ST_CONNECTING:
   1691         case SCO_ST_CONNECTED:
   1692         case SCO_ST_DISCONNECTING:
   1693         case SCO_ST_PEND_UNPARK:
   1694             num_scos++;
   1695         }
   1696     }
   1697     return (num_scos);
   1698 #else
   1699     return (0);
   1700 #endif
   1701 }
   1702 
   1703 
   1704 /*******************************************************************************
   1705 **
   1706 ** Function         btm_is_sco_active_by_bdaddr
   1707 **
   1708 ** Description      This function is called to see if a SCO active to a bd address.
   1709 **
   1710 ** Returns          BOOLEAN
   1711 **
   1712 *******************************************************************************/
   1713 BOOLEAN btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda)
   1714 {
   1715 #if (BTM_MAX_SCO_LINKS>0)
   1716     UINT8 xx;
   1717     tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
   1718 
   1719     /* If any SCO is being established to the remote BD address, refuse this */
   1720     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
   1721     {
   1722         if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED))
   1723         {
   1724             return (TRUE);
   1725         }
   1726     }
   1727 #endif
   1728     return (FALSE);
   1729 }
   1730 #else   /* SCO_EXCLUDED == TRUE (Link in stubs) */
   1731 
   1732 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig,
   1733                            UINT16 pkt_types, UINT16 *p_sco_inx,
   1734                            tBTM_SCO_CB *p_conn_cb,
   1735                            tBTM_SCO_CB *p_disc_cb) {return (BTM_NO_RESOURCES);}
   1736 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx) {return (BTM_NO_RESOURCES);}
   1737 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types) {return (BTM_NO_RESOURCES);}
   1738 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx) {return (0);}
   1739 UINT16 BTM_ReadDeviceScoPacketTypes (void) {return (0);}
   1740 UINT16 BTM_ReadScoHandle (UINT16 sco_inx) {return (BTM_INVALID_HCI_HANDLE);}
   1741 UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx) {return((UINT8 *) NULL);}
   1742 UINT16 BTM_ReadScoDiscReason (void) {return (BTM_INVALID_SCO_DISC_REASON);}
   1743 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) {return (BTM_MODE_UNSUPPORTED);}
   1744 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback) { return (BTM_ILLEGAL_VALUE);}
   1745 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms) { return (BTM_MODE_UNSUPPORTED);}
   1746 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms) { return (BTM_MODE_UNSUPPORTED);}
   1747 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) {}
   1748 UINT8 BTM_GetNumScoLinks (void)  {return (0);}
   1749 
   1750 #endif /* If SCO is being used */
   1751