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