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