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