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