Home | History | Annotate | Download | only in ag
      1 /******************************************************************************
      2  *
      3  *  Copyright 2004-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 for managing the SCO connection used in AG.
     22  *
     23  ******************************************************************************/
     24 
     25 #include <cstddef>
     26 
     27 #include "bt_common.h"
     28 #include "bta_ag_api.h"
     29 #include "bta_ag_int.h"
     30 #include "bta_api.h"
     31 #include "btm_api.h"
     32 #include "device/include/controller.h"
     33 #include "device/include/esco_parameters.h"
     34 #include "osi/include/osi.h"
     35 #include "utl.h"
     36 
     37 /* Codec negotiation timeout */
     38 #ifndef BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS
     39 #define BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS (3 * 1000) /* 3 seconds */
     40 #endif
     41 
     42 static bool sco_allowed = true;
     43 static RawAddress active_device_addr = {};
     44 
     45 /* sco events */
     46 enum {
     47   BTA_AG_SCO_LISTEN_E,       /* listen request */
     48   BTA_AG_SCO_OPEN_E,         /* open request */
     49   BTA_AG_SCO_XFER_E,         /* transfer request */
     50   BTA_AG_SCO_CN_DONE_E, /* codec negotiation done */
     51   BTA_AG_SCO_REOPEN_E,  /* Retry with other codec when failed */
     52   BTA_AG_SCO_CLOSE_E,      /* close request */
     53   BTA_AG_SCO_SHUTDOWN_E,   /* shutdown request */
     54   BTA_AG_SCO_CONN_OPEN_E,  /* sco open */
     55   BTA_AG_SCO_CONN_CLOSE_E, /* sco closed */
     56 };
     57 
     58 #define CASE_RETURN_STR(const) \
     59   case const:                  \
     60     return #const;
     61 
     62 static const char* bta_ag_sco_evt_str(uint8_t event) {
     63   switch (event) {
     64     CASE_RETURN_STR(BTA_AG_SCO_LISTEN_E)
     65     CASE_RETURN_STR(BTA_AG_SCO_OPEN_E)
     66     CASE_RETURN_STR(BTA_AG_SCO_XFER_E)
     67     CASE_RETURN_STR(BTA_AG_SCO_CN_DONE_E)
     68     CASE_RETURN_STR(BTA_AG_SCO_REOPEN_E)
     69     CASE_RETURN_STR(BTA_AG_SCO_CLOSE_E)
     70     CASE_RETURN_STR(BTA_AG_SCO_SHUTDOWN_E)
     71     CASE_RETURN_STR(BTA_AG_SCO_CONN_OPEN_E)
     72     CASE_RETURN_STR(BTA_AG_SCO_CONN_CLOSE_E)
     73     default:
     74       return "Unknown SCO Event";
     75   }
     76 }
     77 
     78 static const char* bta_ag_sco_state_str(uint8_t state) {
     79   switch (state) {
     80     CASE_RETURN_STR(BTA_AG_SCO_SHUTDOWN_ST)
     81     CASE_RETURN_STR(BTA_AG_SCO_LISTEN_ST)
     82     CASE_RETURN_STR(BTA_AG_SCO_CODEC_ST)
     83     CASE_RETURN_STR(BTA_AG_SCO_OPENING_ST)
     84     CASE_RETURN_STR(BTA_AG_SCO_OPEN_CL_ST)
     85     CASE_RETURN_STR(BTA_AG_SCO_OPEN_XFER_ST)
     86     CASE_RETURN_STR(BTA_AG_SCO_OPEN_ST)
     87     CASE_RETURN_STR(BTA_AG_SCO_CLOSING_ST)
     88     CASE_RETURN_STR(BTA_AG_SCO_CLOSE_OP_ST)
     89     CASE_RETURN_STR(BTA_AG_SCO_CLOSE_XFER_ST)
     90     CASE_RETURN_STR(BTA_AG_SCO_SHUTTING_ST)
     91     default:
     92       return "Unknown SCO State";
     93   }
     94 }
     95 
     96 /**
     97  * Check if bd_addr is the current active device.
     98  *
     99  * @param bd_addr target device address
    100  * @return True if bd_addr is the current active device, False otherwise or if
    101  * no active device is set (i.e. active_device_addr is empty)
    102  */
    103 bool bta_ag_sco_is_active_device(const RawAddress& bd_addr) {
    104   return !active_device_addr.IsEmpty() && active_device_addr == bd_addr;
    105 }
    106 
    107 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local);
    108 
    109 /*******************************************************************************
    110  *
    111  * Function         bta_ag_sco_conn_cback
    112  *
    113  * Description      BTM SCO connection callback.
    114  *
    115  *
    116  * Returns          void
    117  *
    118  ******************************************************************************/
    119 static void bta_ag_sco_conn_cback(uint16_t sco_idx) {
    120   uint16_t handle;
    121   tBTA_AG_SCB* p_scb;
    122 
    123   /* match callback to scb; first check current sco scb */
    124   if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) {
    125     handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
    126   }
    127   /* then check for scb connected to this peer */
    128   else {
    129     /* Check if SLC is up */
    130     handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_idx));
    131     p_scb = bta_ag_scb_by_idx(handle);
    132     if (p_scb && !p_scb->svc_conn) handle = 0;
    133   }
    134 
    135   if (handle != 0) {
    136     do_in_bta_thread(FROM_HERE,
    137                      base::Bind(&bta_ag_sm_execute_by_handle, handle,
    138                                 BTA_AG_SCO_OPEN_EVT, tBTA_AG_DATA::kEmpty));
    139   } else {
    140     /* no match found; disconnect sco, init sco variables */
    141     bta_ag_cb.sco.p_curr_scb = nullptr;
    142     bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
    143     BTM_RemoveSco(sco_idx);
    144   }
    145 }
    146 
    147 /*******************************************************************************
    148  *
    149  * Function         bta_ag_sco_disc_cback
    150  *
    151  * Description      BTM SCO disconnection callback.
    152  *
    153  *
    154  * Returns          void
    155  *
    156  ******************************************************************************/
    157 static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
    158   uint16_t handle = 0;
    159 
    160   APPL_TRACE_DEBUG(
    161       "bta_ag_sco_disc_cback(): sco_idx: 0x%x  p_cur_scb: 0x%08x  sco.state: "
    162       "%d",
    163       sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state);
    164 
    165   APPL_TRACE_DEBUG(
    166       "bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x  in_use: %u  sco_idx: 0x%x "
    167       " sco state: %u",
    168       &bta_ag_cb.scb[0], bta_ag_cb.scb[0].in_use, bta_ag_cb.scb[0].sco_idx,
    169       bta_ag_cb.scb[0].state);
    170   APPL_TRACE_DEBUG(
    171       "bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x  in_use: %u  sco_idx: 0x%x "
    172       " sco state: %u",
    173       &bta_ag_cb.scb[1], bta_ag_cb.scb[1].in_use, bta_ag_cb.scb[1].sco_idx,
    174       bta_ag_cb.scb[1].state);
    175 
    176   /* match callback to scb */
    177   if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) {
    178     /* We only care about callbacks for the active SCO */
    179     if (bta_ag_cb.sco.p_curr_scb->sco_idx != sco_idx) {
    180       if (bta_ag_cb.sco.p_curr_scb->sco_idx != 0xFFFF) return;
    181     }
    182     handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
    183   }
    184 
    185   if (handle != 0) {
    186 
    187     /* Restore settings */
    188     if (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC) {
    189       /* Bypass vendor specific and voice settings if enhanced eSCO supported */
    190       if (!(controller_get_interface()
    191                 ->supports_enhanced_setup_synchronous_connection())) {
    192         BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
    193       }
    194 
    195       /* If SCO open was initiated by AG and failed for mSBC T2, try mSBC T1
    196        * 'Safe setting' first. If T1 also fails, try CVSD */
    197       if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
    198         bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST;
    199         if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings ==
    200             BTA_AG_SCO_MSBC_SETTINGS_T2) {
    201           APPL_TRACE_WARNING(
    202               "%s: eSCO/SCO failed to open, falling back to mSBC T1 settings",
    203               __func__);
    204           bta_ag_cb.sco.p_curr_scb->codec_msbc_settings =
    205               BTA_AG_SCO_MSBC_SETTINGS_T1;
    206         } else {
    207           APPL_TRACE_WARNING(
    208               "%s: eSCO/SCO failed to open, falling back to CVSD", __func__);
    209           bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
    210         }
    211       }
    212     } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
    213       APPL_TRACE_ERROR("%s: eSCO/SCO failed to open, no more fall back",
    214                        __func__);
    215     }
    216 
    217     bta_ag_cb.sco.p_curr_scb->inuse_codec = BTA_AG_CODEC_NONE;
    218 
    219     do_in_bta_thread(FROM_HERE,
    220                      base::Bind(&bta_ag_sm_execute_by_handle, handle,
    221                                 BTA_AG_SCO_CLOSE_EVT, tBTA_AG_DATA::kEmpty));
    222   } else {
    223     /* no match found */
    224     APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback");
    225 
    226     /* sco could be closed after scb dealloc'ed */
    227     if (bta_ag_cb.sco.p_curr_scb != nullptr) {
    228       bta_ag_cb.sco.p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
    229       bta_ag_cb.sco.p_curr_scb = nullptr;
    230       bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
    231     }
    232   }
    233 }
    234 
    235 /*******************************************************************************
    236  *
    237  * Function         bta_ag_remove_sco
    238  *
    239  * Description      Removes the specified SCO from the system.
    240  *                  If only_active is true, then SCO is only removed if
    241  *                  connected
    242  *
    243  * Returns          bool   - true if SCO removal was started
    244  *
    245  ******************************************************************************/
    246 static bool bta_ag_remove_sco(tBTA_AG_SCB* p_scb, bool only_active) {
    247   if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
    248     if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx) {
    249       tBTM_STATUS status = BTM_RemoveSco(p_scb->sco_idx);
    250       APPL_TRACE_DEBUG("%s: SCO index 0x%04x, status %d", __func__,
    251                        p_scb->sco_idx, status);
    252       if (status == BTM_CMD_STARTED) {
    253         /* SCO is connected; set current control block */
    254         bta_ag_cb.sco.p_curr_scb = p_scb;
    255         return true;
    256       } else if ((status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR)) {
    257         /* If no connection reset the SCO handle */
    258         p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
    259       }
    260     }
    261   }
    262   return false;
    263 }
    264 
    265 /*******************************************************************************
    266  *
    267  * Function         bta_ag_esco_connreq_cback
    268  *
    269  * Description      BTM eSCO connection requests and eSCO change requests
    270  *                  Only the connection requests are processed by BTA.
    271  *
    272  * Returns          void
    273  *
    274  ******************************************************************************/
    275 static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event,
    276                                       tBTM_ESCO_EVT_DATA* p_data) {
    277   /* Only process connection requests */
    278   if (event == BTM_ESCO_CONN_REQ_EVT) {
    279     uint16_t sco_inx = p_data->conn_evt.sco_inx;
    280     const RawAddress* remote_bda = BTM_ReadScoBdAddr(sco_inx);
    281     tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(bta_ag_idx_by_bdaddr(remote_bda));
    282     if (remote_bda && bta_ag_sco_is_active_device(*remote_bda) && p_scb &&
    283         p_scb->svc_conn) {
    284       p_scb->sco_idx = sco_inx;
    285 
    286       /* If no other SCO active, allow this one */
    287       if (!bta_ag_cb.sco.p_curr_scb) {
    288         APPL_TRACE_EVENT("%s: Accept Conn Request (sco_inx 0x%04x)", __func__,
    289                          sco_inx);
    290         bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
    291 
    292         bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST;
    293         bta_ag_cb.sco.p_curr_scb = p_scb;
    294         bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
    295       } else {
    296         /* Begin a transfer: Close current SCO before responding */
    297         APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER");
    298         bta_ag_cb.sco.p_xfer_scb = p_scb;
    299         bta_ag_cb.sco.conn_data = p_data->conn_evt;
    300         bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST;
    301 
    302         if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, true)) {
    303           APPL_TRACE_ERROR(
    304               "%s: Nothing to remove,so accept Conn Request(sco_inx 0x%04x)",
    305               __func__, sco_inx);
    306           bta_ag_cb.sco.p_xfer_scb = nullptr;
    307           bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST;
    308 
    309           bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
    310         }
    311       }
    312     } else {
    313       LOG(WARNING) << __func__
    314                    << ": reject incoming SCO connection, remote_bda="
    315                    << (remote_bda ? *remote_bda : RawAddress::kEmpty)
    316                    << ", active_bda=" << active_device_addr << ", current_bda="
    317                    << (p_scb ? p_scb->peer_addr : RawAddress::kEmpty);
    318       BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
    319                       (enh_esco_params_t*)nullptr);
    320     }
    321   } else if (event == BTM_ESCO_CHG_EVT) {
    322     /* Received a change in the esco link */
    323     APPL_TRACE_EVENT(
    324         "%s: eSCO change event (inx %d): rtrans %d, "
    325         "rxlen %d, txlen %d, txint %d",
    326         __func__, p_data->chg_evt.sco_inx, p_data->chg_evt.retrans_window,
    327         p_data->chg_evt.rx_pkt_len, p_data->chg_evt.tx_pkt_len,
    328         p_data->chg_evt.tx_interval);
    329   }
    330 }
    331 
    332 /*******************************************************************************
    333  *
    334  * Function         bta_ag_cback_sco
    335  *
    336  * Description      Call application callback function with SCO event.
    337  *
    338  *
    339  * Returns          void
    340  *
    341  ******************************************************************************/
    342 static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, uint8_t event) {
    343   tBTA_AG_HDR sco = {};
    344   sco.handle = bta_ag_scb_to_idx(p_scb);
    345   sco.app_id = p_scb->app_id;
    346   /* call close cback */
    347   (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&sco);
    348 }
    349 
    350 /*******************************************************************************
    351  *
    352  * Function         bta_ag_create_sco
    353  *
    354  * Description      Create a SCO connection for a given control block
    355  *                  p_scb : Pointer to the target AG control block
    356  *                  is_orig : Whether to initiate or listen for SCO connection
    357  *
    358  * Returns          void
    359  *
    360  ******************************************************************************/
    361 static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
    362   APPL_TRACE_DEBUG(
    363       "%s: BEFORE codec_updated=%d, codec_fallback=%d, "
    364       "sco_codec=%d, peer_codec=%d, msbc_settings=%d, device=%s",
    365       __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec,
    366       p_scb->peer_codecs, p_scb->codec_msbc_settings,
    367       p_scb->peer_addr.ToString().c_str());
    368   tBTA_AG_PEER_CODEC esco_codec = BTA_AG_CODEC_CVSD;
    369 
    370   if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
    371     LOG(WARNING) << __func__ << ": device " << p_scb->peer_addr
    372                  << " is not active, active_device=" << active_device_addr;
    373     return;
    374   }
    375   /* Make sure this SCO handle is not already in use */
    376   if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
    377     APPL_TRACE_ERROR("%s: device %s, index 0x%04x already in use!", __func__,
    378                      p_scb->peer_addr.ToString().c_str(), p_scb->sco_idx);
    379     return;
    380   }
    381 
    382   if ((p_scb->sco_codec == BTA_AG_CODEC_MSBC) && !p_scb->codec_fallback)
    383     esco_codec = BTA_AG_CODEC_MSBC;
    384 
    385   if (p_scb->codec_fallback) {
    386     p_scb->codec_fallback = false;
    387     /* Force AG to send +BCS for the next audio connection. */
    388     p_scb->codec_updated = true;
    389     /* Reset mSBC settings to T2 for the next audio connection */
    390     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
    391   }
    392 
    393   esco_codec_t codec_index = ESCO_CODEC_CVSD;
    394   /* If WBS included, use CVSD by default, index is 0 for CVSD by
    395    * initialization. If eSCO codec is mSBC, index is T2 or T1 */
    396   if (esco_codec == BTA_AG_CODEC_MSBC) {
    397     if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
    398       codec_index = ESCO_CODEC_MSBC_T2;
    399     } else {
    400       codec_index = ESCO_CODEC_MSBC_T1;
    401     }
    402   }
    403 
    404   /* Initialize eSCO parameters */
    405   enh_esco_params_t params = esco_parameters_for_codec(codec_index);
    406   /* For CVSD */
    407   if (esco_codec == BTM_SCO_CODEC_CVSD) {
    408     /* Use the applicable packet types
    409       (3-EV3 not allowed due to errata 2363) */
    410     params.packet_types =
    411         p_bta_ag_cfg->sco_pkt_types | ESCO_PKT_TYPES_MASK_NO_3_EV3;
    412     if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) ||
    413         (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) {
    414       params.max_latency_ms = 10;
    415       params.retransmission_effort = ESCO_RETRANSMISSION_POWER;
    416     }
    417   }
    418 
    419   /* If initiating, setup parameters to start SCO/eSCO connection */
    420   if (is_orig) {
    421     bta_ag_cb.sco.is_local = true;
    422     /* Set eSCO Mode */
    423     BTM_SetEScoMode(&params);
    424     bta_ag_cb.sco.p_curr_scb = p_scb;
    425     /* save the current codec as sco_codec can be updated while SCO is open. */
    426     p_scb->inuse_codec = esco_codec;
    427 
    428     /* tell sys to stop av if any */
    429     bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    430 
    431     /* Send pending commands to create SCO connection to peer */
    432     bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
    433     APPL_TRACE_API("%s: orig %d, inx 0x%04x, pkt types 0x%04x", __func__,
    434                    is_orig, p_scb->sco_idx, params.packet_types);
    435   } else {
    436     /* Not initiating, go to listen mode */
    437     tBTM_STATUS status = BTM_CreateSco(
    438         &p_scb->peer_addr, false, params.packet_types, &p_scb->sco_idx,
    439         bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
    440     if (status == BTM_CMD_STARTED) {
    441       BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
    442     }
    443 
    444     APPL_TRACE_API("%s: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
    445                    __func__, is_orig, p_scb->sco_idx, status,
    446                    params.packet_types);
    447   }
    448   APPL_TRACE_DEBUG(
    449       "%s: AFTER codec_updated=%d, codec_fallback=%d, "
    450       "sco_codec=%d, peer_codec=%d, msbc_settings=%d, device=%s",
    451       __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec,
    452       p_scb->peer_codecs, p_scb->codec_msbc_settings,
    453       p_scb->peer_addr.ToString().c_str());
    454 }
    455 
    456 /*******************************************************************************
    457  *
    458  * Function         bta_ag_create_pending_sco
    459  *
    460  * Description      This Function is called after the pre-SCO vendor setup is
    461  *                  done for the BTA to continue and send the HCI Commands for
    462  *                  creating/accepting SCO connection with peer based on the
    463  *                  is_local parameter.
    464  *
    465  * Returns          void
    466  *
    467  ******************************************************************************/
    468 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
    469   tBTA_AG_PEER_CODEC esco_codec = p_scb->inuse_codec;
    470   enh_esco_params_t params = {};
    471   bta_ag_cb.sco.p_curr_scb = p_scb;
    472   bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
    473 
    474   /* Local device requested SCO connection to peer */
    475   if (is_local) {
    476     if (esco_codec == BTA_AG_CODEC_MSBC) {
    477       if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
    478         params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
    479       } else
    480         params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
    481     } else {
    482       params = esco_parameters_for_codec(ESCO_CODEC_CVSD);
    483       if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) ||
    484           (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) {
    485         params.max_latency_ms = 10;
    486         params.retransmission_effort = ESCO_RETRANSMISSION_POWER;
    487       }
    488     }
    489 
    490     /* Bypass voice settings if enhanced SCO setup command is supported */
    491     if (!(controller_get_interface()
    492               ->supports_enhanced_setup_synchronous_connection())) {
    493       if (esco_codec == BTA_AG_CODEC_MSBC) {
    494         BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS);
    495       } else {
    496         BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
    497       }
    498     }
    499 
    500     if (BTM_CreateSco(&p_scb->peer_addr, true, params.packet_types,
    501                       &p_scb->sco_idx, bta_ag_sco_conn_cback,
    502                       bta_ag_sco_disc_cback) == BTM_CMD_STARTED) {
    503       /* Initiating the connection, set the current sco handle */
    504       bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
    505     }
    506     APPL_TRACE_DEBUG("%s: initiated SCO connection", __func__);
    507   } else {
    508     /* Local device accepted SCO connection from peer */
    509     params = esco_parameters_for_codec(ESCO_CODEC_CVSD);
    510     if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) ||
    511         (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) {
    512       params.max_latency_ms = 10;
    513       params.retransmission_effort = ESCO_RETRANSMISSION_POWER;
    514     }
    515 
    516     BTM_EScoConnRsp(p_scb->sco_idx, HCI_SUCCESS, &params);
    517     APPL_TRACE_DEBUG("%s: listening for SCO connection", __func__);
    518   }
    519 }
    520 
    521 /*******************************************************************************
    522  *
    523  * Function         bta_ag_codec_negotiation_timer_cback
    524  *
    525  * Description
    526  *
    527  *
    528  * Returns          void
    529  *
    530  ******************************************************************************/
    531 static void bta_ag_codec_negotiation_timer_cback(void* data) {
    532   APPL_TRACE_DEBUG("%s", __func__);
    533   tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data;
    534 
    535   /* Announce that codec negotiation failed. */
    536   bta_ag_sco_codec_nego(p_scb, false);
    537 
    538   /* call app callback */
    539   bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
    540 }
    541 
    542 /*******************************************************************************
    543  *
    544  * Function         bta_ag_codec_negotiate
    545  *
    546  * Description      Initiate codec negotiation by sending AT command.
    547  *                  If not necessary, skip negotiation.
    548  *
    549  * Returns          void
    550  *
    551  ******************************************************************************/
    552 void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
    553   APPL_TRACE_DEBUG("%s", __func__);
    554   bta_ag_cb.sco.p_curr_scb = p_scb;
    555 
    556   if ((p_scb->codec_updated || p_scb->codec_fallback) &&
    557       (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
    558     /* Change the power mode to Active until SCO open is completed. */
    559     bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    560 
    561     /* Send +BCS to the peer */
    562     bta_ag_send_bcs(p_scb);
    563 
    564     /* Start timer to handle timeout */
    565     alarm_set_on_mloop(p_scb->codec_negotiation_timer,
    566                        BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS,
    567                        bta_ag_codec_negotiation_timer_cback, p_scb);
    568   } else {
    569     /* use same codec type as previous SCO connection, skip codec negotiation */
    570     APPL_TRACE_DEBUG(
    571         "use same codec type as previous SCO connection,skip codec "
    572         "negotiation");
    573     bta_ag_sco_codec_nego(p_scb, true);
    574   }
    575 }
    576 
    577 /*******************************************************************************
    578  *
    579  * Function         bta_ag_sco_event
    580  *
    581  * Description
    582  *
    583  *
    584  * Returns          void
    585  *
    586  ******************************************************************************/
    587 static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) {
    588   tBTA_AG_SCO_CB* p_sco = &bta_ag_cb.sco;
    589   uint8_t previous_state = p_sco->state;
    590   APPL_TRACE_EVENT("%s: index=0x%04x, device=%s, state=%s[%d], event=%s[%d]",
    591                    __func__, p_scb->sco_idx,
    592                    p_scb->peer_addr.ToString().c_str(),
    593                    bta_ag_sco_state_str(p_sco->state), p_sco->state,
    594                    bta_ag_sco_evt_str(event), event);
    595 
    596   switch (p_sco->state) {
    597     case BTA_AG_SCO_SHUTDOWN_ST:
    598       switch (event) {
    599         case BTA_AG_SCO_LISTEN_E:
    600           /* create sco listen connection */
    601           bta_ag_create_sco(p_scb, false);
    602           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    603           break;
    604 
    605         default:
    606           APPL_TRACE_WARNING(
    607               "%s: BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %s[%d]", __func__,
    608               bta_ag_sco_evt_str(event), event);
    609           break;
    610       }
    611       break;
    612 
    613     case BTA_AG_SCO_LISTEN_ST:
    614       switch (event) {
    615         case BTA_AG_SCO_LISTEN_E:
    616           /* create sco listen connection (Additional channel) */
    617           bta_ag_create_sco(p_scb, false);
    618           break;
    619 
    620         case BTA_AG_SCO_OPEN_E:
    621           /* remove listening connection */
    622           bta_ag_remove_sco(p_scb, false);
    623 
    624           /* start codec negotiation */
    625           p_sco->state = BTA_AG_SCO_CODEC_ST;
    626           bta_ag_codec_negotiate(p_scb);
    627           break;
    628 
    629         case BTA_AG_SCO_SHUTDOWN_E:
    630           /* remove listening connection */
    631           bta_ag_remove_sco(p_scb, false);
    632 
    633           if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
    634 
    635           /* If last SCO instance then finish shutting down */
    636           if (!bta_ag_other_scb_open(p_scb)) {
    637             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
    638           }
    639           break;
    640 
    641         case BTA_AG_SCO_CLOSE_E:
    642           /* remove listening connection */
    643           /* Ignore the event. Keep listening SCO for the active SLC
    644            */
    645           APPL_TRACE_WARNING("%s: BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
    646                              __func__, bta_ag_sco_evt_str(event), event);
    647           break;
    648 
    649         case BTA_AG_SCO_CONN_CLOSE_E:
    650           /* sco failed; create sco listen connection */
    651           bta_ag_create_sco(p_scb, false);
    652           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    653           break;
    654 
    655         default:
    656           APPL_TRACE_WARNING("%s: BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
    657                              __func__, bta_ag_sco_evt_str(event), event);
    658           break;
    659       }
    660       break;
    661 
    662     case BTA_AG_SCO_CODEC_ST:
    663       switch (event) {
    664         case BTA_AG_SCO_LISTEN_E:
    665           /* create sco listen connection (Additional channel) */
    666           bta_ag_create_sco(p_scb, false);
    667           break;
    668 
    669         case BTA_AG_SCO_CN_DONE_E:
    670           /* create sco connection to peer */
    671           bta_ag_create_sco(p_scb, true);
    672           p_sco->state = BTA_AG_SCO_OPENING_ST;
    673           break;
    674 
    675         case BTA_AG_SCO_XFER_E:
    676           /* save xfer scb */
    677           p_sco->p_xfer_scb = p_scb;
    678           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    679           break;
    680 
    681         case BTA_AG_SCO_SHUTDOWN_E:
    682           /* remove listening connection */
    683           bta_ag_remove_sco(p_scb, false);
    684 
    685           if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
    686 
    687           /* If last SCO instance then finish shutting down */
    688           if (!bta_ag_other_scb_open(p_scb)) {
    689             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
    690           }
    691           break;
    692 
    693         case BTA_AG_SCO_CLOSE_E:
    694           /* sco open is not started yet. just go back to listening */
    695           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    696           break;
    697 
    698         case BTA_AG_SCO_CONN_CLOSE_E:
    699           /* sco failed; create sco listen connection */
    700           bta_ag_create_sco(p_scb, false);
    701           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    702           break;
    703 
    704         default:
    705           APPL_TRACE_WARNING("%s: BTA_AG_SCO_CODEC_ST: Ignoring event %s[%d]",
    706                              __func__, bta_ag_sco_evt_str(event), event);
    707           break;
    708       }
    709       break;
    710 
    711     case BTA_AG_SCO_OPENING_ST:
    712       switch (event) {
    713         case BTA_AG_SCO_LISTEN_E:
    714           /* second headset has now joined */
    715           /* create sco listen connection (Additional channel) */
    716           if (p_scb != p_sco->p_curr_scb) {
    717             bta_ag_create_sco(p_scb, false);
    718           }
    719           break;
    720 
    721         case BTA_AG_SCO_REOPEN_E:
    722           /* start codec negotiation */
    723           p_sco->state = BTA_AG_SCO_CODEC_ST;
    724           bta_ag_codec_negotiate(p_scb);
    725           break;
    726 
    727         case BTA_AG_SCO_XFER_E:
    728           /* save xfer scb */
    729           p_sco->p_xfer_scb = p_scb;
    730           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    731           break;
    732 
    733         case BTA_AG_SCO_CLOSE_E:
    734           p_sco->state = BTA_AG_SCO_OPEN_CL_ST;
    735           break;
    736 
    737         case BTA_AG_SCO_SHUTDOWN_E:
    738           /* If not opening scb, just close it */
    739           if (p_scb != p_sco->p_curr_scb) {
    740             /* remove listening connection */
    741             bta_ag_remove_sco(p_scb, false);
    742           } else
    743             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    744 
    745           break;
    746 
    747         case BTA_AG_SCO_CONN_OPEN_E:
    748           p_sco->state = BTA_AG_SCO_OPEN_ST;
    749           break;
    750 
    751         case BTA_AG_SCO_CONN_CLOSE_E:
    752           /* sco failed; create sco listen connection */
    753           bta_ag_create_sco(p_scb, false);
    754           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    755           break;
    756 
    757         default:
    758           APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPENING_ST: Ignoring event %s[%d]",
    759                              __func__, bta_ag_sco_evt_str(event), event);
    760           break;
    761       }
    762       break;
    763 
    764     case BTA_AG_SCO_OPEN_CL_ST:
    765       switch (event) {
    766         case BTA_AG_SCO_XFER_E:
    767           /* save xfer scb */
    768           p_sco->p_xfer_scb = p_scb;
    769 
    770           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    771           break;
    772 
    773         case BTA_AG_SCO_OPEN_E:
    774           p_sco->state = BTA_AG_SCO_OPENING_ST;
    775           break;
    776 
    777         case BTA_AG_SCO_SHUTDOWN_E:
    778           /* If not opening scb, just close it */
    779           if (p_scb != p_sco->p_curr_scb) {
    780             /* remove listening connection */
    781             bta_ag_remove_sco(p_scb, false);
    782           } else
    783             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    784 
    785           break;
    786 
    787         case BTA_AG_SCO_CONN_OPEN_E:
    788           /* close sco connection */
    789           bta_ag_remove_sco(p_scb, true);
    790 
    791           p_sco->state = BTA_AG_SCO_CLOSING_ST;
    792           break;
    793 
    794         case BTA_AG_SCO_CONN_CLOSE_E:
    795           /* sco failed; create sco listen connection */
    796 
    797           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    798           break;
    799 
    800         default:
    801           APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_CL_ST: Ignoring event %s[%d]",
    802                              __func__, bta_ag_sco_evt_str(event), event);
    803           break;
    804       }
    805       break;
    806 
    807     case BTA_AG_SCO_OPEN_XFER_ST:
    808       switch (event) {
    809         case BTA_AG_SCO_CLOSE_E:
    810           /* close sco connection */
    811           bta_ag_remove_sco(p_scb, true);
    812 
    813           p_sco->state = BTA_AG_SCO_CLOSING_ST;
    814           break;
    815 
    816         case BTA_AG_SCO_SHUTDOWN_E:
    817           /* remove all connection */
    818           bta_ag_remove_sco(p_scb, false);
    819           p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    820 
    821           break;
    822 
    823         case BTA_AG_SCO_CONN_CLOSE_E:
    824           /* closed sco; place in listen mode and
    825              accept the transferred connection */
    826           bta_ag_create_sco(p_scb, false); /* Back into listen mode */
    827 
    828           /* Accept sco connection with xfer scb */
    829           bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data);
    830           p_sco->state = BTA_AG_SCO_OPENING_ST;
    831           p_sco->p_curr_scb = p_sco->p_xfer_scb;
    832           p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx;
    833           p_sco->p_xfer_scb = nullptr;
    834           break;
    835 
    836         default:
    837           APPL_TRACE_WARNING(
    838               "%s: BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %s[%d]", __func__,
    839               bta_ag_sco_evt_str(event), event);
    840           break;
    841       }
    842       break;
    843 
    844     case BTA_AG_SCO_OPEN_ST:
    845       switch (event) {
    846         case BTA_AG_SCO_LISTEN_E:
    847           /* second headset has now joined */
    848           /* create sco listen connection (Additional channel) */
    849           if (p_scb != p_sco->p_curr_scb) {
    850             bta_ag_create_sco(p_scb, false);
    851           }
    852           break;
    853 
    854         case BTA_AG_SCO_XFER_E:
    855           /* close current sco connection */
    856           bta_ag_remove_sco(p_sco->p_curr_scb, true);
    857 
    858           /* save xfer scb */
    859           p_sco->p_xfer_scb = p_scb;
    860 
    861           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    862           break;
    863 
    864         case BTA_AG_SCO_CLOSE_E:
    865           /* close sco connection if active */
    866           if (bta_ag_remove_sco(p_scb, true)) {
    867             p_sco->state = BTA_AG_SCO_CLOSING_ST;
    868           }
    869           break;
    870 
    871         case BTA_AG_SCO_SHUTDOWN_E:
    872           /* remove all listening connections */
    873           bta_ag_remove_sco(p_scb, false);
    874 
    875           /* If SCO was active on this scb, close it */
    876           if (p_scb == p_sco->p_curr_scb) {
    877             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    878           }
    879           break;
    880 
    881         case BTA_AG_SCO_CONN_CLOSE_E:
    882           /* peer closed sco; create sco listen connection */
    883           bta_ag_create_sco(p_scb, false);
    884           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    885           break;
    886 
    887         default:
    888           APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_ST: Ignoring event %s[%d]",
    889                              __func__, bta_ag_sco_evt_str(event), event);
    890           break;
    891       }
    892       break;
    893 
    894     case BTA_AG_SCO_CLOSING_ST:
    895       switch (event) {
    896         case BTA_AG_SCO_LISTEN_E:
    897           /* create sco listen connection (Additional channel) */
    898           if (p_scb != p_sco->p_curr_scb) {
    899             bta_ag_create_sco(p_scb, false);
    900           }
    901           break;
    902 
    903         case BTA_AG_SCO_OPEN_E:
    904           p_sco->state = BTA_AG_SCO_CLOSE_OP_ST;
    905           break;
    906 
    907         case BTA_AG_SCO_XFER_E:
    908           /* save xfer scb */
    909           p_sco->p_xfer_scb = p_scb;
    910 
    911           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    912           break;
    913 
    914         case BTA_AG_SCO_SHUTDOWN_E:
    915           /* If not closing scb, just close it */
    916           if (p_scb != p_sco->p_curr_scb) {
    917             /* remove listening connection */
    918             bta_ag_remove_sco(p_scb, false);
    919           } else
    920             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    921 
    922           break;
    923 
    924         case BTA_AG_SCO_CONN_CLOSE_E:
    925           /* peer closed sco; create sco listen connection */
    926           bta_ag_create_sco(p_scb, false);
    927 
    928           p_sco->state = BTA_AG_SCO_LISTEN_ST;
    929           break;
    930 
    931         default:
    932           APPL_TRACE_WARNING("%s: BTA_AG_SCO_CLOSING_ST: Ignoring event %s[%d]",
    933                              __func__, bta_ag_sco_evt_str(event), event);
    934           break;
    935       }
    936       break;
    937 
    938     case BTA_AG_SCO_CLOSE_OP_ST:
    939       switch (event) {
    940         case BTA_AG_SCO_CLOSE_E:
    941           p_sco->state = BTA_AG_SCO_CLOSING_ST;
    942           break;
    943 
    944         case BTA_AG_SCO_SHUTDOWN_E:
    945           p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    946           break;
    947 
    948         case BTA_AG_SCO_CONN_CLOSE_E:
    949           /* start codec negotiation */
    950           p_sco->state = BTA_AG_SCO_CODEC_ST;
    951           bta_ag_codec_negotiate(p_scb);
    952           break;
    953 
    954         case BTA_AG_SCO_LISTEN_E:
    955           /* create sco listen connection (Additional channel) */
    956           if (p_scb != p_sco->p_curr_scb) {
    957             bta_ag_create_sco(p_scb, false);
    958           }
    959           break;
    960 
    961         default:
    962           APPL_TRACE_WARNING(
    963               "%s: BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %s[%d]", __func__,
    964               bta_ag_sco_evt_str(event), event);
    965           break;
    966       }
    967       break;
    968 
    969     case BTA_AG_SCO_CLOSE_XFER_ST:
    970       switch (event) {
    971         case BTA_AG_SCO_CONN_OPEN_E:
    972           /* close sco connection so headset can be transferred
    973              Probably entered this state from "opening state" */
    974           bta_ag_remove_sco(p_scb, true);
    975           break;
    976 
    977         case BTA_AG_SCO_CLOSE_E:
    978           /* clear xfer scb */
    979           p_sco->p_xfer_scb = nullptr;
    980 
    981           p_sco->state = BTA_AG_SCO_CLOSING_ST;
    982           break;
    983 
    984         case BTA_AG_SCO_SHUTDOWN_E:
    985           /* clear xfer scb */
    986           p_sco->p_xfer_scb = nullptr;
    987 
    988           p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    989           break;
    990 
    991         case BTA_AG_SCO_CONN_CLOSE_E: {
    992           /* closed sco; place old sco in listen mode,
    993              take current sco out of listen, and
    994              create originating sco for current */
    995           bta_ag_create_sco(p_scb, false);
    996           bta_ag_remove_sco(p_sco->p_xfer_scb, false);
    997 
    998           /* start codec negotiation */
    999           p_sco->state = BTA_AG_SCO_CODEC_ST;
   1000           tBTA_AG_SCB* p_cn_scb = p_sco->p_xfer_scb;
   1001           p_sco->p_xfer_scb = nullptr;
   1002           bta_ag_codec_negotiate(p_cn_scb);
   1003           break;
   1004         }
   1005 
   1006         default:
   1007           APPL_TRACE_WARNING(
   1008               "%s: BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %s[%d]", __func__,
   1009               bta_ag_sco_evt_str(event), event);
   1010           break;
   1011       }
   1012       break;
   1013 
   1014     case BTA_AG_SCO_SHUTTING_ST:
   1015       switch (event) {
   1016         case BTA_AG_SCO_CONN_OPEN_E:
   1017           /* close sco connection; wait for conn close event */
   1018           bta_ag_remove_sco(p_scb, true);
   1019           break;
   1020 
   1021         case BTA_AG_SCO_CONN_CLOSE_E:
   1022           /* If last SCO instance then finish shutting down */
   1023           if (!bta_ag_other_scb_open(p_scb)) {
   1024             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
   1025           } else /* Other instance is still listening */
   1026           {
   1027             p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1028           }
   1029 
   1030           /* If SCO closed for other HS which is not being disconnected,
   1031              then create listen sco connection for it as scb still open */
   1032           if (bta_ag_scb_open(p_scb)) {
   1033             bta_ag_create_sco(p_scb, false);
   1034             p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1035           }
   1036 
   1037           if (p_scb == p_sco->p_curr_scb) {
   1038             p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
   1039             p_sco->p_curr_scb = nullptr;
   1040           }
   1041           break;
   1042 
   1043         case BTA_AG_SCO_LISTEN_E:
   1044           /* create sco listen connection (Additional channel) */
   1045           if (p_scb != p_sco->p_curr_scb) {
   1046             bta_ag_create_sco(p_scb, false);
   1047           }
   1048           break;
   1049 
   1050         case BTA_AG_SCO_SHUTDOWN_E:
   1051           if (!bta_ag_other_scb_open(p_scb)) {
   1052             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
   1053           } else /* Other instance is still listening */
   1054           {
   1055             p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1056           }
   1057 
   1058           if (p_scb == p_sco->p_curr_scb) {
   1059             p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
   1060             p_sco->p_curr_scb = nullptr;
   1061           }
   1062           break;
   1063 
   1064         default:
   1065           APPL_TRACE_WARNING(
   1066               "%s: BTA_AG_SCO_SHUTTING_ST: Ignoring event %s[%d]", __func__,
   1067               bta_ag_sco_evt_str(event), event);
   1068           break;
   1069       }
   1070       break;
   1071 
   1072     default:
   1073       break;
   1074   }
   1075   if (p_sco->state != previous_state) {
   1076     APPL_TRACE_EVENT(
   1077         "%s: SCO_state_change: [%s(0x%02x)]->[%s(0x%02x)] "
   1078         "after event [%s(0x%02x)]",
   1079         __func__, bta_ag_sco_state_str(previous_state), previous_state,
   1080         bta_ag_sco_state_str(p_sco->state), p_sco->state,
   1081         bta_ag_sco_evt_str(event), event);
   1082   }
   1083 }
   1084 
   1085 /*******************************************************************************
   1086  *
   1087  * Function         bta_ag_sco_is_open
   1088  *
   1089  * Description      Check if sco is open for this scb.
   1090  *
   1091  *
   1092  * Returns          true if sco open for this scb, false otherwise.
   1093  *
   1094  ******************************************************************************/
   1095 bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb) {
   1096   return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) &&
   1097           (bta_ag_cb.sco.p_curr_scb == p_scb));
   1098 }
   1099 
   1100 /*******************************************************************************
   1101  *
   1102  * Function         bta_ag_sco_is_opening
   1103  *
   1104  * Description      Check if sco is in Opening state.
   1105  *
   1106  *
   1107  * Returns          true if sco is in Opening state for this scb, false
   1108  *                  otherwise.
   1109  *
   1110  ******************************************************************************/
   1111 bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb) {
   1112   return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
   1113           (bta_ag_cb.sco.p_curr_scb == p_scb));
   1114 }
   1115 
   1116 /*******************************************************************************
   1117  *
   1118  * Function         bta_ag_sco_listen
   1119  *
   1120  * Description
   1121  *
   1122  *
   1123  * Returns          void
   1124  *
   1125  ******************************************************************************/
   1126 void bta_ag_sco_listen(tBTA_AG_SCB* p_scb,
   1127                        UNUSED_ATTR const tBTA_AG_DATA& data) {
   1128   LOG(INFO) << __func__ << ": " << p_scb->peer_addr;
   1129   bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E);
   1130 }
   1131 
   1132 /*******************************************************************************
   1133  *
   1134  * Function         bta_ag_sco_open
   1135  *
   1136  * Description
   1137  *
   1138  *
   1139  * Returns          void
   1140  *
   1141  ******************************************************************************/
   1142 void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
   1143   if (!sco_allowed) {
   1144     LOG(INFO) << __func__ << ": not opening sco, by policy";
   1145     return;
   1146   }
   1147   /* if another scb using sco, this is a transfer */
   1148   if (bta_ag_cb.sco.p_curr_scb && bta_ag_cb.sco.p_curr_scb != p_scb) {
   1149     LOG(INFO) << __func__ << ": tranfer " << bta_ag_cb.sco.p_curr_scb->peer_addr
   1150               << " -> " << p_scb->peer_addr;
   1151     bta_ag_sco_event(p_scb, BTA_AG_SCO_XFER_E);
   1152   } else {
   1153     /* else it is an open */
   1154     LOG(INFO) << __func__ << ": open " << p_scb->peer_addr;
   1155     bta_ag_sco_event(p_scb, BTA_AG_SCO_OPEN_E);
   1156   }
   1157 }
   1158 
   1159 /*******************************************************************************
   1160  *
   1161  * Function         bta_ag_sco_close
   1162  *
   1163  * Description
   1164  *
   1165  *
   1166  * Returns          void
   1167  *
   1168  ******************************************************************************/
   1169 void bta_ag_sco_close(tBTA_AG_SCB* p_scb,
   1170                       UNUSED_ATTR const tBTA_AG_DATA& data) {
   1171   /* if scb is in use */
   1172   /* sco_idx is not allocated in SCO_CODEC_ST, still need to move to listen
   1173    * state. */
   1174   if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) ||
   1175       (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) {
   1176     APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
   1177     bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
   1178   }
   1179 }
   1180 
   1181 /*******************************************************************************
   1182  *
   1183  * Function         bta_ag_sco_codec_nego
   1184  *
   1185  * Description      Handles result of eSCO codec negotiation
   1186  *
   1187  *
   1188  * Returns          void
   1189  *
   1190  ******************************************************************************/
   1191 void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result) {
   1192   if (result) {
   1193     /* Subsequent SCO connection will skip codec negotiation */
   1194     APPL_TRACE_DEBUG("%s: Succeeded for index 0x%04x, device %s", __func__,
   1195                      p_scb->sco_idx, p_scb->peer_addr.ToString().c_str());
   1196     p_scb->codec_updated = false;
   1197     bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E);
   1198   } else {
   1199     /* codec negotiation failed */
   1200     APPL_TRACE_ERROR("%s: Failed for index 0x%04x, device %s", __func__,
   1201                      p_scb->sco_idx, p_scb->peer_addr.ToString().c_str());
   1202     bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
   1203   }
   1204 }
   1205 
   1206 /*******************************************************************************
   1207  *
   1208  * Function         bta_ag_sco_shutdown
   1209  *
   1210  * Description
   1211  *
   1212  *
   1213  * Returns          void
   1214  *
   1215  ******************************************************************************/
   1216 void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb,
   1217                          UNUSED_ATTR const tBTA_AG_DATA& data) {
   1218   bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
   1219 }
   1220 
   1221 /*******************************************************************************
   1222  *
   1223  * Function         bta_ag_sco_conn_open
   1224  *
   1225  * Description
   1226  *
   1227  *
   1228  * Returns          void
   1229  *
   1230  ******************************************************************************/
   1231 void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb,
   1232                           UNUSED_ATTR const tBTA_AG_DATA& data) {
   1233   bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E);
   1234 
   1235   bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1236 
   1237   /* call app callback */
   1238   bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
   1239 
   1240   /* reset to mSBC T2 settings as the preferred */
   1241   p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
   1242 }
   1243 
   1244 /*******************************************************************************
   1245  *
   1246  * Function         bta_ag_sco_conn_close
   1247  *
   1248  * Description
   1249  *
   1250  *
   1251  * Returns          void
   1252  *
   1253  ******************************************************************************/
   1254 void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
   1255                            UNUSED_ATTR const tBTA_AG_DATA& data) {
   1256   /* clear current scb */
   1257   bta_ag_cb.sco.p_curr_scb = nullptr;
   1258   p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
   1259 
   1260   /* codec_fallback is set when AG is initiator and connection failed for mSBC.
   1261    * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
   1262   if (p_scb->svc_conn &&
   1263       (p_scb->codec_fallback ||
   1264        (p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
   1265         p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) {
   1266     bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
   1267   } else {
   1268     /* Indicate if the closing of audio is because of transfer */
   1269     bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
   1270 
   1271     bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1272 
   1273     /* if av got suspended by this call, let it resume. */
   1274     /* In case call stays alive regardless of sco, av should not be affected. */
   1275     if (((p_scb->call_ind == BTA_AG_CALL_INACTIVE) &&
   1276          (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) ||
   1277         (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)) {
   1278       bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1279     }
   1280 
   1281     /* call app callback */
   1282     bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
   1283     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
   1284   }
   1285 }
   1286 
   1287 /*******************************************************************************
   1288  *
   1289  * Function         bta_ag_sco_conn_rsp
   1290  *
   1291  * Description      Process the SCO connection request
   1292  *
   1293  *
   1294  * Returns          void
   1295  *
   1296  ******************************************************************************/
   1297 void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb,
   1298                          tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) {
   1299   bta_ag_cb.sco.is_local = false;
   1300 
   1301   APPL_TRACE_DEBUG("%s: eSCO %d, state %d", __func__,
   1302                    controller_get_interface()
   1303                        ->supports_enhanced_setup_synchronous_connection(),
   1304                    bta_ag_cb.sco.state);
   1305 
   1306   if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST ||
   1307       bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
   1308       bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) {
   1309     /* tell sys to stop av if any */
   1310     bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1311     /* When HS initiated SCO, it cannot be WBS. */
   1312   }
   1313 
   1314   /* If SCO open was initiated from HS, it must be CVSD */
   1315   p_scb->inuse_codec = BTA_AG_CODEC_NONE;
   1316   /* Send pending commands to create SCO connection to peer */
   1317   bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
   1318 }
   1319 
   1320 void bta_ag_set_sco_allowed(bool value) {
   1321   sco_allowed = value;
   1322   APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
   1323 }
   1324 
   1325 const RawAddress& bta_ag_get_active_device() { return active_device_addr; }
   1326 
   1327 void bta_clear_active_device() { active_device_addr = RawAddress::kEmpty; }
   1328 
   1329 void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
   1330   if (new_active_device.IsEmpty()) {
   1331     APPL_TRACE_ERROR("%s: empty device", __func__);
   1332     return;
   1333   }
   1334   active_device_addr = new_active_device;
   1335 }
   1336