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