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 "bta_api.h"
     26 #include "bta_ag_api.h"
     27 #include "bta_ag_co.h"
     28 #if (BTM_SCO_HCI_INCLUDED == TRUE )
     29 #include "bta_dm_co.h"
     30 #endif
     31 #include "bta_ag_int.h"
     32 #include "btm_api.h"
     33 #include "gki.h"
     34 #include "utl.h"
     35 
     36 #ifndef BTA_AG_SCO_DEBUG
     37 #define BTA_AG_SCO_DEBUG FALSE
     38 #endif
     39 
     40 #ifndef BTA_AG_CODEC_NEGO_TIMEOUT
     41 #define BTA_AG_CODEC_NEGO_TIMEOUT   3000
     42 #endif
     43 
     44 #if BTA_AG_SCO_DEBUG == TRUE
     45 static char *bta_ag_sco_evt_str(UINT8 event);
     46 static char *bta_ag_sco_state_str(UINT8 state);
     47 #endif
     48 
     49 #define BTA_AG_NO_EDR_ESCO  (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | \
     50                              BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | \
     51                              BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \
     52                              BTM_SCO_PKT_TYPES_MASK_NO_3_EV5)
     53 
     54 /* sco events */
     55 enum
     56 {
     57     BTA_AG_SCO_LISTEN_E,        /* listen request */
     58     BTA_AG_SCO_OPEN_E,          /* open request */
     59     BTA_AG_SCO_XFER_E,          /* transfer request */
     60 #if (BTM_WBS_INCLUDED == TRUE )
     61     BTA_AG_SCO_CN_DONE_E,       /* codec negotiation done */
     62     BTA_AG_SCO_REOPEN_E,        /* Retry with other codec when failed */
     63 #endif
     64     BTA_AG_SCO_CLOSE_E,         /* close request */
     65     BTA_AG_SCO_SHUTDOWN_E,      /* shutdown request */
     66     BTA_AG_SCO_CONN_OPEN_E,     /* sco open */
     67     BTA_AG_SCO_CONN_CLOSE_E,    /* sco closed */
     68     BTA_AG_SCO_CI_DATA_E        /* SCO data ready */
     69 };
     70 
     71 #if (BTM_WBS_INCLUDED == TRUE )
     72 #define BTA_AG_NUM_CODECS   3
     73 #define BTA_AG_ESCO_SETTING_IDX_CVSD    0   /* eSCO setting for CVSD */
     74 #define BTA_AG_ESCO_SETTING_IDX_T1      1   /* eSCO setting for mSBC T1 */
     75 #define BTA_AG_ESCO_SETTING_IDX_T2      2   /* eSCO setting for mSBC T2 */
     76 
     77 static const tBTM_ESCO_PARAMS bta_ag_esco_params[BTA_AG_NUM_CODECS] =
     78 {
     79     /* CVSD */
     80     {
     81         BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec)              */
     82         BTM_64KBITS_RATE,                   /* RX Bandwidth (64 kbits/sec)              */
     83         0x000a,                             /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3)  */
     84         BTM_VOICE_SETTING_CVSD,             /* Inp Linear, Air CVSD, 2s Comp, 16bit     */
     85        (BTM_SCO_PKT_TYPES_MASK_HV1      +  /* Packet Types                             */
     86         BTM_SCO_PKT_TYPES_MASK_HV2      +
     87         BTM_SCO_PKT_TYPES_MASK_HV3      +
     88         BTM_SCO_PKT_TYPES_MASK_EV3      +
     89         BTM_SCO_PKT_TYPES_MASK_EV4      +
     90         BTM_SCO_PKT_TYPES_MASK_EV5      +
     91         BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 +
     92         BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
     93         BTM_ESCO_RETRANS_POWER       /* Retransmission effort                      */
     94     },
     95     /* mSBC  T1 */
     96     {
     97         BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec), 8000        */
     98         BTM_64KBITS_RATE,                   /* RX Bandwidth (64 kbits/sec), 8000        */
     99         8,                                  /* 8 ms                                     */
    100         BTM_VOICE_SETTING_TRANS,            /* Inp Linear, Transparent, 2s Comp, 16bit  */
    101        (BTM_SCO_PKT_TYPES_MASK_EV3      |   /* Packet Types : EV3 + NO_2_EV3            */
    102         BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
    103         BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
    104         BTM_SCO_PKT_TYPES_MASK_NO_3_EV5 |
    105         BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 ),
    106         BTM_ESCO_RETRANS_QUALITY       /* Retransmission effort                      */
    107     },
    108     /* mSBC T2*/
    109     {
    110         BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec), 8000        */
    111         BTM_64KBITS_RATE,                   /* RX Bandwidth (64 kbits/sec), 8000        */
    112         13,                                 /* 13 ms                                    */
    113         BTM_VOICE_SETTING_TRANS,            /* Inp Linear, Transparent, 2s Comp, 16bit  */
    114        (BTM_SCO_PKT_TYPES_MASK_EV3      |   /* Packet Types : EV3 + 2-EV3               */
    115         BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
    116         BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
    117         BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
    118         BTM_ESCO_RETRANS_QUALITY       /* Retransmission effort                      */
    119     }
    120 };
    121 #else
    122 /* WBS not included, CVSD by default */
    123 static const tBTM_ESCO_PARAMS bta_ag_esco_params =
    124 {
    125     BTM_64KBITS_RATE,                   /* TX Bandwidth (64 kbits/sec)              */
    126     BTM_64KBITS_RATE,                   /* RX Bandwidth (64 kbits/sec)              */
    127     0x000a,                             /* 10 ms (HS/HF can use EV3, 2-EV3, 3-EV3)  */
    128     0x0060,                             /* Inp Linear, Air CVSD, 2s Comp, 16bit     */
    129     (BTM_SCO_PKT_TYPES_MASK_HV1      +  /* Packet Types                             */
    130      BTM_SCO_PKT_TYPES_MASK_HV2      +
    131      BTM_SCO_PKT_TYPES_MASK_HV3      +
    132      BTM_SCO_PKT_TYPES_MASK_EV3      +
    133      BTM_SCO_PKT_TYPES_MASK_EV4      +
    134      BTM_SCO_PKT_TYPES_MASK_EV5      +
    135      BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 +
    136      BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
    137      BTM_ESCO_RETRANS_POWER       /* Retransmission effort                      */
    138 };
    139 #endif
    140 
    141 /*******************************************************************************
    142 **
    143 ** Function         bta_ag_sco_conn_cback
    144 **
    145 ** Description      BTM SCO connection callback.
    146 **
    147 **
    148 ** Returns          void
    149 **
    150 *******************************************************************************/
    151 static void bta_ag_sco_conn_cback(UINT16 sco_idx)
    152 {
    153     UINT16  handle;
    154     BT_HDR  *p_buf;
    155     tBTA_AG_SCB *p_scb;
    156 
    157     /* match callback to scb; first check current sco scb */
    158     if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb->in_use)
    159     {
    160         handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
    161     }
    162     /* then check for scb connected to this peer */
    163     else
    164     {
    165         /* Check if SLC is up */
    166         handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_idx));
    167         p_scb = bta_ag_scb_by_idx(handle);
    168         if(p_scb && !p_scb->svc_conn)
    169             handle = 0;
    170     }
    171 
    172     if (handle != 0)
    173     {
    174         if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    175         {
    176             p_buf->event = BTA_AG_SCO_OPEN_EVT;
    177             p_buf->layer_specific = handle;
    178             bta_sys_sendmsg(p_buf);
    179         }
    180     }
    181     /* no match found; disconnect sco, init sco variables */
    182     else
    183     {
    184         bta_ag_cb.sco.p_curr_scb = NULL;
    185         bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
    186         BTM_RemoveSco(sco_idx);
    187     }
    188 }
    189 
    190 /*******************************************************************************
    191 **
    192 ** Function         bta_ag_sco_disc_cback
    193 **
    194 ** Description      BTM SCO disconnection callback.
    195 **
    196 **
    197 ** Returns          void
    198 **
    199 *******************************************************************************/
    200 static void bta_ag_sco_disc_cback(UINT16 sco_idx)
    201 {
    202     BT_HDR  *p_buf;
    203     UINT16  handle = 0;
    204 
    205     APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): sco_idx: 0x%x  p_cur_scb: 0x%08x  sco.state: %d", sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state);
    206 
    207     APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x  in_use: %u  sco_idx: 0x%x  sco state: %u",
    208                        &bta_ag_cb.scb[0], bta_ag_cb.scb[0].in_use, bta_ag_cb.scb[0].sco_idx, bta_ag_cb.scb[0].state);
    209     APPL_TRACE_DEBUG ("bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x  in_use: %u  sco_idx: 0x%x  sco state: %u",
    210                        &bta_ag_cb.scb[1], bta_ag_cb.scb[1].in_use, bta_ag_cb.scb[1].sco_idx, bta_ag_cb.scb[1].state);
    211 
    212     /* match callback to scb */
    213     if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb->in_use)
    214     {
    215         /* We only care about callbacks for the active SCO */
    216         if (bta_ag_cb.sco.p_curr_scb->sco_idx != sco_idx)
    217         {
    218             if (bta_ag_cb.sco.p_curr_scb->sco_idx != 0xFFFF)
    219                 return;
    220         }
    221         handle  = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
    222     }
    223 
    224     if (handle != 0)
    225     {
    226 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    227         tBTM_STATUS status = BTM_ConfigScoPath(BTM_SCO_ROUTE_PCM, NULL, NULL, TRUE);
    228         APPL_TRACE_DEBUG("bta_ag_sco_disc_cback sco close config status = %d", status);
    229         /* SCO clean up here */
    230         bta_dm_sco_co_close();
    231 #endif
    232 
    233 #if (BTM_WBS_INCLUDED == TRUE )
    234         /* Restore settings */
    235         if(bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC)
    236         {
    237             /* set_sco_codec(BTM_SCO_CODEC_NONE); we should get a close */
    238             BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD);
    239 
    240             /* If SCO open was initiated by AG and failed for mSBC, then attempt
    241             mSBC with T1 settings i.e. 'Safe Settings'. If this fails, then switch to CVSD */
    242             if (bta_ag_sco_is_opening (bta_ag_cb.sco.p_curr_scb))
    243             {
    244                 if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
    245                 {
    246                      APPL_TRACE_DEBUG("Fallback to mSBC T1 settings");
    247                      bta_ag_cb.sco.p_curr_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T1;
    248                 }
    249                 else
    250                 {
    251                     APPL_TRACE_DEBUG("Fallback to CVSD settings");
    252                     bta_ag_cb.sco.p_curr_scb->codec_fallback = TRUE;
    253                 }
    254             }
    255         }
    256 
    257         bta_ag_cb.sco.p_curr_scb->inuse_codec = BTA_AG_CODEC_NONE;
    258 #endif
    259 
    260         if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    261         {
    262             p_buf->event = BTA_AG_SCO_CLOSE_EVT;
    263             p_buf->layer_specific = handle;
    264             bta_sys_sendmsg(p_buf);
    265         }
    266     }
    267     /* no match found */
    268     else
    269     {
    270         APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback");
    271 
    272         /* sco could be closed after scb dealloc'ed */
    273         if (bta_ag_cb.sco.p_curr_scb != NULL)
    274         {
    275             bta_ag_cb.sco.p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
    276             bta_ag_cb.sco.p_curr_scb = NULL;
    277             bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
    278         }
    279     }
    280 }
    281 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    282 /*******************************************************************************
    283 **
    284 ** Function         bta_ag_sco_read_cback
    285 **
    286 ** Description      Callback function is the callback function for incoming
    287 **                  SCO data over HCI.
    288 **
    289 ** Returns          void
    290 **
    291 *******************************************************************************/
    292 static void bta_ag_sco_read_cback (UINT16 sco_inx, BT_HDR *p_data, tBTM_SCO_DATA_FLAG status)
    293 {
    294     if (status != BTM_SCO_DATA_CORRECT)
    295     {
    296         APPL_TRACE_DEBUG("bta_ag_sco_read_cback: status(%d)", status);
    297     }
    298 
    299     /* Callout function must free the data. */
    300     bta_dm_sco_co_in_data (p_data, status);
    301 }
    302 #endif
    303 /*******************************************************************************
    304 **
    305 ** Function         bta_ag_remove_sco
    306 **
    307 ** Description      Removes the specified SCO from the system.
    308 **                  If only_active is TRUE, then SCO is only removed if connected
    309 **
    310 ** Returns          BOOLEAN   - TRUE if Sco removal was started
    311 **
    312 *******************************************************************************/
    313 static BOOLEAN bta_ag_remove_sco(tBTA_AG_SCB *p_scb, BOOLEAN only_active)
    314 {
    315     BOOLEAN     removed_started = FALSE;
    316     tBTM_STATUS	status;
    317 
    318     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
    319     {
    320         if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx)
    321         {
    322             status = BTM_RemoveSco(p_scb->sco_idx);
    323 
    324             APPL_TRACE_DEBUG("ag remove sco: inx 0x%04x, status:0x%x", p_scb->sco_idx, status);
    325 
    326             if (status == BTM_CMD_STARTED)
    327             {
    328                 /* Sco is connected; set current control block */
    329                 bta_ag_cb.sco.p_curr_scb = p_scb;
    330 
    331                 removed_started = TRUE;
    332             }
    333             /* If no connection reset the sco handle */
    334             else if ( (status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR) )
    335             {
    336                 p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
    337             }
    338         }
    339     }
    340     return removed_started;
    341 }
    342 
    343 
    344 /*******************************************************************************
    345 **
    346 ** Function         bta_ag_esco_connreq_cback
    347 **
    348 ** Description      BTM eSCO connection requests and eSCO change requests
    349 **                  Only the connection requests are processed by BTA.
    350 **
    351 ** Returns          void
    352 **
    353 *******************************************************************************/
    354 static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *p_data)
    355 {
    356     tBTA_AG_SCB         *p_scb;
    357     UINT16               handle;
    358     UINT16               sco_inx = p_data->conn_evt.sco_inx;
    359 
    360     /* Only process connection requests */
    361     if (event == BTM_ESCO_CONN_REQ_EVT)
    362     {
    363         if ((handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_inx))) != 0 &&
    364             ((p_scb = bta_ag_scb_by_idx(handle)) != NULL) && p_scb->svc_conn)
    365         {
    366             p_scb->sco_idx = sco_inx;
    367 
    368             /* If no other SCO active, allow this one */
    369             if (!bta_ag_cb.sco.p_curr_scb)
    370             {
    371                 APPL_TRACE_EVENT("bta_ag_esco_connreq_cback: Accept Conn Request (sco_inx 0x%04x)", sco_inx);
    372                 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
    373 
    374                 bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST;
    375                 bta_ag_cb.sco.p_curr_scb = p_scb;
    376                 bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
    377             }
    378             else    /* Begin a transfer: Close current SCO before responding */
    379             {
    380                 APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER");
    381                 bta_ag_cb.sco.p_xfer_scb = p_scb;
    382                 bta_ag_cb.sco.conn_data = p_data->conn_evt;
    383                 bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST;
    384 
    385                 if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, TRUE))
    386                 {
    387                     APPL_TRACE_ERROR("bta_ag_esco_connreq_cback: Nothing to remove so accept Conn Request (sco_inx 0x%04x)", sco_inx);
    388                     bta_ag_cb.sco.p_xfer_scb = NULL;
    389                     bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST;
    390 
    391                     bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
    392                 }
    393             }
    394         }
    395         /* If error occurred send reject response immediately */
    396         else
    397         {
    398             APPL_TRACE_WARNING("no scb for bta_ag_esco_connreq_cback or no resources");
    399             BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES, NULL);
    400         }
    401     }
    402     /* Received a change in the esco link */
    403     else if (event == BTM_ESCO_CHG_EVT)
    404     {
    405         APPL_TRACE_EVENT("eSCO change event (inx %d): rtrans %d, rxlen %d, txlen %d, txint %d",
    406             p_data->chg_evt.sco_inx,
    407             p_data->chg_evt.retrans_window, p_data->chg_evt.rx_pkt_len,
    408             p_data->chg_evt.tx_pkt_len, p_data->chg_evt.tx_interval);
    409     }
    410 }
    411 
    412 /*******************************************************************************
    413 **
    414 ** Function         bta_ag_cback_sco
    415 **
    416 ** Description      Call application callback function with SCO event.
    417 **
    418 **
    419 ** Returns          void
    420 **
    421 *******************************************************************************/
    422 static void bta_ag_cback_sco(tBTA_AG_SCB *p_scb, UINT8 event)
    423 {
    424     tBTA_AG_HDR    sco;
    425 
    426     sco.handle = bta_ag_scb_to_idx(p_scb);
    427     sco.app_id = p_scb->app_id;
    428 
    429     /* call close cback */
    430     (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &sco);
    431 }
    432 
    433 /*******************************************************************************
    434 **
    435 ** Function         bta_ag_create_sco
    436 **
    437 ** Description
    438 **
    439 **
    440 ** Returns          void
    441 **
    442 *******************************************************************************/
    443 static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
    444 {
    445     tBTM_STATUS       status;
    446     UINT8            *p_bd_addr = NULL;
    447     tBTM_ESCO_PARAMS params;
    448 #if (BTM_WBS_INCLUDED == TRUE )
    449     tBTA_AG_PEER_CODEC  esco_codec = BTM_SCO_CODEC_CVSD;
    450     int codec_index = 0;
    451 #endif
    452 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    453     tBTM_SCO_ROUTE_TYPE sco_route;
    454     tBTA_CODEC_INFO     codec_info = {BTA_SCO_CODEC_PCM};
    455     UINT32              pcm_sample_rate;
    456 #endif
    457 
    458     /* Make sure this sco handle is not already in use */
    459     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
    460     {
    461         APPL_TRACE_WARNING("bta_ag_create_sco: Index 0x%04x Already In Use!",
    462                              p_scb->sco_idx);
    463         return;
    464     }
    465 
    466 #if (BTM_WBS_INCLUDED == TRUE )
    467     if ((p_scb->sco_codec == BTM_SCO_CODEC_MSBC) &&
    468         !p_scb->codec_fallback &&
    469         !p_scb->retry_with_sco_only)
    470         esco_codec = BTM_SCO_CODEC_MSBC;
    471 
    472     if (p_scb->codec_fallback)
    473     {
    474         p_scb->codec_fallback = FALSE;
    475 
    476         /* Force AG to send +BCS for the next audio connection. */
    477         p_scb->codec_updated = TRUE;
    478     }
    479 
    480     /* If WBS included, use CVSD by default, index is 0 for CVSD by initialization */
    481     /* If eSCO codec is mSBC, index is T2 or T1 */
    482     if (esco_codec == BTM_SCO_CODEC_MSBC)
    483     {
    484         if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
    485         {
    486             codec_index = BTA_AG_ESCO_SETTING_IDX_T2;
    487         }
    488         else
    489         {
    490             codec_index = BTA_AG_ESCO_SETTING_IDX_T1;
    491         }
    492     }
    493 
    494     params = bta_ag_esco_params[codec_index];
    495 #else
    496     /* When WBS is not included, use CVSD by default */
    497     params = bta_ag_esco_params;
    498 #endif
    499 
    500     if(bta_ag_cb.sco.param_updated) /* If we do not use the default parameters */
    501         params = bta_ag_cb.sco.params;
    502 
    503     if(!bta_ag_cb.sco.param_updated)
    504     {
    505 #if (BTM_WBS_INCLUDED == TRUE)
    506         if (esco_codec == BTM_SCO_CODEC_CVSD)   /* For CVSD */
    507 #endif
    508         {
    509             /* Use the application packet types (5 slot EV packets not allowed) */
    510             params.packet_types = p_bta_ag_cfg->sco_pkt_types     |
    511                                   BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
    512                                   BTM_SCO_PKT_TYPES_MASK_NO_3_EV5;
    513         }
    514     }
    515 
    516     /* if initiating set current scb and peer bd addr */
    517     if (is_orig)
    518     {
    519         /* Attempt to use eSCO if remote host supports HFP >= 1.5 */
    520         /* Need to find out from SIG if HSP can use eSCO; for now use SCO */
    521         if (p_scb->conn_service == BTA_AG_HFP && p_scb->peer_version >= HFP_VERSION_1_5 && !p_scb->retry_with_sco_only)
    522         {
    523 
    524             BTM_SetEScoMode(BTM_LINK_TYPE_ESCO, &params);
    525             /* If ESCO or EDR ESCO, retry with SCO only in case of failure */
    526             if((params.packet_types & BTM_ESCO_LINK_ONLY_MASK)
    527                ||!((params.packet_types & ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^ BTA_AG_NO_EDR_ESCO))
    528             {
    529 #if (BTM_WBS_INCLUDED == TRUE )
    530                 if (esco_codec != BTA_AG_CODEC_MSBC)
    531                 {
    532                     p_scb->retry_with_sco_only = TRUE;
    533                     APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
    534                 }
    535                 else    /* Do not use SCO when using mSBC */
    536                 {
    537                     p_scb->retry_with_sco_only = FALSE;
    538                     APPL_TRACE_API("Setting retry_with_sco_only to FALSE");
    539                 }
    540 #else
    541                 p_scb->retry_with_sco_only = TRUE;
    542                 APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
    543 #endif
    544             }
    545         }
    546         else
    547         {
    548             if(p_scb->retry_with_sco_only)
    549                 APPL_TRACE_API("retrying with SCO only");
    550             p_scb->retry_with_sco_only = FALSE;
    551 
    552             BTM_SetEScoMode(BTM_LINK_TYPE_SCO, &params);
    553         }
    554 
    555         bta_ag_cb.sco.p_curr_scb = p_scb;
    556 
    557         /* tell sys to stop av if any */
    558         bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    559 
    560 #if (BTM_WBS_INCLUDED == TRUE )
    561         /* Allow any platform specific pre-SCO set up to take place */
    562         bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP,\
    563         esco_codec);
    564 
    565         /* This setting may not be necessary */
    566         /* To be verified with stable 2049 boards */
    567         if (esco_codec == BTA_AG_CODEC_MSBC)
    568             BTM_WriteVoiceSettings (BTM_VOICE_SETTING_TRANS);
    569         else
    570             BTM_WriteVoiceSettings (BTM_VOICE_SETTING_CVSD);
    571         /* save the current codec because sco_codec can be updated while SCO is open. */
    572         p_scb->inuse_codec = esco_codec;
    573 #else
    574         /* Allow any platform specific pre-SCO set up to take place */
    575         bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP);
    576 #endif
    577 
    578 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    579 #if (BTM_WBS_INCLUDED == TRUE)
    580         if (esco_codec == BTA_AG_CODEC_MSBC)
    581             pcm_sample_rate = BTA_DM_SCO_SAMP_RATE_16K;
    582         else
    583 #endif
    584             pcm_sample_rate = BTA_DM_SCO_SAMP_RATE_8K;
    585 
    586         sco_route = bta_dm_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id);
    587 #endif
    588 
    589 
    590 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    591         /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
    592         BTM_ConfigScoPath(sco_route, bta_ag_sco_read_cback, NULL, TRUE);
    593 #endif
    594         bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
    595     }
    596     else
    597         p_scb->retry_with_sco_only = FALSE;
    598 
    599     p_bd_addr = p_scb->peer_addr;
    600 
    601     status = BTM_CreateSco(p_bd_addr, is_orig, params.packet_types,
    602                            &p_scb->sco_idx, bta_ag_sco_conn_cback,
    603                            bta_ag_sco_disc_cback);
    604     if (status == BTM_CMD_STARTED)
    605     {
    606         if (!is_orig)
    607         {
    608             BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
    609         }
    610         else    /* Initiating the connection, set the current sco handle */
    611         {
    612             bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
    613         }
    614     }
    615 
    616     APPL_TRACE_API("ag create sco: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
    617                       is_orig, p_scb->sco_idx, status, params.packet_types);
    618 }
    619 
    620 #if (BTM_WBS_INCLUDED == TRUE )
    621 /*******************************************************************************
    622 **
    623 ** Function         bta_ag_attempt_msbc_safe_settings
    624 **
    625 ** Description    Checks if ESCO connection needs to be attempted using mSBC T1(safe) settings
    626 **
    627 **
    628 ** Returns          TRUE if T1 settings has to be used, FALSE otherwise
    629 **
    630 *******************************************************************************/
    631 BOOLEAN bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB *p_scb)
    632 {
    633     if (p_scb->svc_conn && p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
    634         p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1)
    635         return TRUE;
    636     else
    637         return FALSE;
    638 }
    639 
    640 /*******************************************************************************
    641 **
    642 ** Function         bta_ag_cn_timer_cback
    643 **
    644 ** Description
    645 **
    646 **
    647 ** Returns          void
    648 **
    649 *******************************************************************************/
    650 static void bta_ag_cn_timer_cback (TIMER_LIST_ENT *p_tle)
    651 {
    652     tBTA_AG_SCB *p_scb;
    653 
    654     if (p_tle)
    655     {
    656         p_scb = (tBTA_AG_SCB *)p_tle->param;
    657 
    658         if (p_scb)
    659         {
    660             /* Announce that codec negotiation failed. */
    661             bta_ag_sco_codec_nego(p_scb, FALSE);
    662 
    663             /* call app callback */
    664             bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
    665         }
    666     }
    667 }
    668 
    669 /*******************************************************************************
    670 **
    671 ** Function         bta_ag_codec_negotiate
    672 **
    673 ** Description      Initiate codec negotiation by sending AT command.
    674 **                  If not necessary, skip negotiation.
    675 **
    676 ** Returns          void
    677 **
    678 *******************************************************************************/
    679 void bta_ag_codec_negotiate(tBTA_AG_SCB *p_scb)
    680 {
    681     bta_ag_cb.sco.p_curr_scb = p_scb;
    682 
    683     if ((p_scb->codec_updated || p_scb->codec_fallback ||
    684         bta_ag_attempt_msbc_safe_settings(p_scb)) &&
    685        (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC))
    686     {
    687         /* Change the power mode to Active until sco open is completed. */
    688         bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
    689 
    690         /* Send +BCS to the peer */
    691         bta_ag_send_bcs(p_scb, NULL);
    692 
    693         /* Start timer to handle timeout */
    694         p_scb->cn_timer.p_cback = (TIMER_CBACK*)&bta_ag_cn_timer_cback;
    695         p_scb->cn_timer.param = (INT32)p_scb;
    696         bta_sys_start_timer(&p_scb->cn_timer, 0, BTA_AG_CODEC_NEGO_TIMEOUT);
    697     }
    698     else
    699     {
    700         /* use same codec type as previous SCO connection, skip codec negotiation */
    701         APPL_TRACE_DEBUG("use same codec type as previous SCO connection,skip codec negotiation");
    702         bta_ag_sco_codec_nego(p_scb, TRUE);
    703     }
    704 }
    705 #endif /* (BTM_WBS_INCLUDED == TRUE ) */
    706 
    707 /*******************************************************************************
    708 **
    709 ** Function         bta_ag_sco_event
    710 **
    711 ** Description
    712 **
    713 **
    714 ** Returns          void
    715 **
    716 *******************************************************************************/
    717 static void bta_ag_sco_event(tBTA_AG_SCB *p_scb, UINT8 event)
    718 {
    719     tBTA_AG_SCO_CB *p_sco = &bta_ag_cb.sco;
    720 #if (BTM_WBS_INCLUDED == TRUE )
    721     tBTA_AG_SCB *p_cn_scb = NULL;   /* For codec negotiation */
    722 #endif
    723 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    724     BT_HDR  *p_buf;
    725 #endif
    726 #if BTA_AG_SCO_DEBUG == TRUE
    727     UINT8   in_state = p_sco->state;
    728 
    729     APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d (%s), Event %d (%s)",
    730                         p_scb->sco_idx,
    731                         p_sco->state, bta_ag_sco_state_str(p_sco->state),
    732                         event, bta_ag_sco_evt_str(event));
    733 #else
    734     APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d, Event %d",
    735                       p_scb->sco_idx, p_sco->state, event);
    736 #endif
    737 
    738 #if (BTM_SCO_HCI_INCLUDED == TRUE )
    739     if (event == BTA_AG_SCO_CI_DATA_E)
    740     {
    741         while (TRUE)
    742         {
    743             bta_dm_sco_co_out_data(&p_buf);
    744             if (p_buf)
    745             {
    746                 if (p_sco->state == BTA_AG_SCO_OPEN_ST)
    747                     BTM_WriteScoData(p_sco->p_curr_scb->sco_idx, p_buf);
    748                 else
    749                     GKI_freebuf(p_buf);
    750             }
    751             else
    752                 break;
    753         }
    754 
    755         return;
    756     }
    757 #endif
    758 
    759     switch (p_sco->state)
    760     {
    761         case BTA_AG_SCO_SHUTDOWN_ST:
    762             switch (event)
    763             {
    764                 case BTA_AG_SCO_LISTEN_E:
    765                     /* create sco listen connection */
    766                     bta_ag_create_sco(p_scb, FALSE);
    767                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
    768                     break;
    769 
    770                 default:
    771                     APPL_TRACE_WARNING("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %d", event);
    772                     break;
    773             }
    774             break;
    775 
    776         case BTA_AG_SCO_LISTEN_ST:
    777             switch (event)
    778             {
    779                 case BTA_AG_SCO_LISTEN_E:
    780                     /* create sco listen connection (Additional channel) */
    781                     bta_ag_create_sco(p_scb, FALSE);
    782                     break;
    783 
    784                 case BTA_AG_SCO_OPEN_E:
    785                     /* remove listening connection */
    786                     bta_ag_remove_sco(p_scb, FALSE);
    787 
    788 #if (BTM_WBS_INCLUDED == TRUE )
    789                     /* start codec negotiation */
    790                     p_sco->state = BTA_AG_SCO_CODEC_ST;
    791                     p_cn_scb = p_scb;
    792 #else
    793                     /* create sco connection to peer */
    794                     bta_ag_create_sco(p_scb, TRUE);
    795                     p_sco->state = BTA_AG_SCO_OPENING_ST;
    796 #endif
    797                     break;
    798 
    799                 case BTA_AG_SCO_SHUTDOWN_E:
    800                     /* remove listening connection */
    801                     bta_ag_remove_sco(p_scb, FALSE);
    802 
    803                     if (p_scb == p_sco->p_curr_scb)
    804                         p_sco->p_curr_scb = NULL;
    805 
    806                     /* If last SCO instance then finish shutting down */
    807                     if (!bta_ag_other_scb_open(p_scb))
    808                     {
    809                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
    810                     }
    811                     break;
    812 
    813                 case BTA_AG_SCO_CLOSE_E:
    814                     /* remove listening connection */
    815                     /* Ignore the event. We need to keep listening SCO for the active SLC */
    816                     APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
    817                     break;
    818 
    819                 case BTA_AG_SCO_CONN_CLOSE_E:
    820                     /* sco failed; create sco listen connection */
    821                     bta_ag_create_sco(p_scb, FALSE);
    822                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
    823                     break;
    824 
    825                 default:
    826                     APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
    827                     break;
    828             }
    829             break;
    830 
    831 #if (BTM_WBS_INCLUDED == TRUE )
    832         case BTA_AG_SCO_CODEC_ST:
    833             switch (event)
    834             {
    835                 case BTA_AG_SCO_LISTEN_E:
    836                     /* create sco listen connection (Additional channel) */
    837                     bta_ag_create_sco(p_scb, FALSE);
    838                     break;
    839 
    840                 case BTA_AG_SCO_CN_DONE_E:
    841                     /* create sco connection to peer */
    842                     bta_ag_create_sco(p_scb, TRUE);
    843                     p_sco->state = BTA_AG_SCO_OPENING_ST;
    844                     break;
    845 
    846                 case BTA_AG_SCO_XFER_E:
    847                     /* save xfer scb */
    848                     p_sco->p_xfer_scb = p_scb;
    849                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    850                     break;
    851 
    852                 case BTA_AG_SCO_SHUTDOWN_E:
    853                     /* remove listening connection */
    854                     bta_ag_remove_sco(p_scb, FALSE);
    855 
    856                     if (p_scb == p_sco->p_curr_scb)
    857                         p_sco->p_curr_scb = NULL;
    858 
    859                     /* If last SCO instance then finish shutting down */
    860                     if (!bta_ag_other_scb_open(p_scb))
    861                     {
    862                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
    863                     }
    864                     break;
    865 
    866                 case BTA_AG_SCO_CLOSE_E:
    867                     /* sco open is not started yet. just go back to listening */
    868                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
    869                     break;
    870 
    871                 case BTA_AG_SCO_CONN_CLOSE_E:
    872                     /* sco failed; create sco listen connection */
    873                     bta_ag_create_sco(p_scb, FALSE);
    874                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
    875                     break;
    876 
    877                 default:
    878                     APPL_TRACE_WARNING("BTA_AG_SCO_CODEC_ST: Ignoring event %d", event);
    879                     break;
    880             }
    881             break;
    882 #endif
    883 
    884         case BTA_AG_SCO_OPENING_ST:
    885             switch (event)
    886             {
    887                 case BTA_AG_SCO_LISTEN_E:
    888                     /* second headset has now joined */
    889                     /* create sco listen connection (Additional channel) */
    890                     if (p_scb != p_sco->p_curr_scb)
    891                     {
    892                         bta_ag_create_sco(p_scb, FALSE);
    893                     }
    894                     break;
    895 
    896 #if (BTM_WBS_INCLUDED == TRUE)
    897                 case BTA_AG_SCO_REOPEN_E:
    898                     /* start codec negotiation */
    899                     p_sco->state = BTA_AG_SCO_CODEC_ST;
    900                     p_cn_scb = p_scb;
    901                     break;
    902 #endif
    903 
    904                 case BTA_AG_SCO_XFER_E:
    905                     /* save xfer scb */
    906                     p_sco->p_xfer_scb = p_scb;
    907                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    908                     break;
    909 
    910                 case BTA_AG_SCO_CLOSE_E:
    911                     p_sco->state = BTA_AG_SCO_OPEN_CL_ST;
    912                     break;
    913 
    914                 case BTA_AG_SCO_SHUTDOWN_E:
    915                     /* If not opening scb, just close it */
    916                     if (p_scb != p_sco->p_curr_scb)
    917                     {
    918                         /* remove listening connection */
    919                         bta_ag_remove_sco(p_scb, FALSE);
    920                     }
    921                     else
    922                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    923 
    924                     break;
    925 
    926                 case BTA_AG_SCO_CONN_OPEN_E:
    927                     p_sco->state = BTA_AG_SCO_OPEN_ST;
    928                     break;
    929 
    930                 case BTA_AG_SCO_CONN_CLOSE_E:
    931                     /* sco failed; create sco listen connection */
    932                     bta_ag_create_sco(p_scb, FALSE);
    933                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
    934                     break;
    935 
    936                 default:
    937                     APPL_TRACE_WARNING("BTA_AG_SCO_OPENING_ST: Ignoring event %d", event);
    938                     break;
    939             }
    940             break;
    941 
    942         case BTA_AG_SCO_OPEN_CL_ST:
    943             switch (event)
    944             {
    945                 case BTA_AG_SCO_XFER_E:
    946                     /* save xfer scb */
    947                     p_sco->p_xfer_scb = p_scb;
    948 
    949                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
    950                     break;
    951 
    952                 case BTA_AG_SCO_OPEN_E:
    953                     p_sco->state = BTA_AG_SCO_OPENING_ST;
    954                     break;
    955 
    956                 case BTA_AG_SCO_SHUTDOWN_E:
    957                     /* If not opening scb, just close it */
    958                     if (p_scb != p_sco->p_curr_scb)
    959                     {
    960                         /* remove listening connection */
    961                         bta_ag_remove_sco(p_scb, FALSE);
    962                     }
    963                     else
    964                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
    965 
    966                     break;
    967 
    968                 case BTA_AG_SCO_CONN_OPEN_E:
    969                     /* close sco connection */
    970                     bta_ag_remove_sco(p_scb, TRUE);
    971 
    972                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
    973                     break;
    974 
    975                 case BTA_AG_SCO_CONN_CLOSE_E:
    976                     /* sco failed; create sco listen connection */
    977 
    978                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
    979                     break;
    980 
    981                 default:
    982                     APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %d", event);
    983                     break;
    984             }
    985             break;
    986 
    987         case BTA_AG_SCO_OPEN_XFER_ST:
    988             switch (event)
    989             {
    990                 case BTA_AG_SCO_CLOSE_E:
    991                     /* close sco connection */
    992                     bta_ag_remove_sco(p_scb, TRUE);
    993 
    994                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
    995                     break;
    996 
    997                 case BTA_AG_SCO_SHUTDOWN_E:
    998                     /* remove all connection */
    999                     bta_ag_remove_sco(p_scb, FALSE);
   1000                     p_sco->state = BTA_AG_SCO_SHUTTING_ST;
   1001 
   1002                     break;
   1003 
   1004                 case BTA_AG_SCO_CONN_CLOSE_E:
   1005                     /* closed sco; place in listen mode and
   1006                        accept the transferred connection */
   1007                     bta_ag_create_sco(p_scb, FALSE);    /* Back into listen mode */
   1008 
   1009                     /* Accept sco connection with xfer scb */
   1010                     bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data);
   1011                     p_sco->state = BTA_AG_SCO_OPENING_ST;
   1012                     p_sco->p_curr_scb = p_sco->p_xfer_scb;
   1013                     p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx;
   1014                     p_sco->p_xfer_scb = NULL;
   1015                      break;
   1016 
   1017                 default:
   1018                     APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %d", event);
   1019                     break;
   1020             }
   1021             break;
   1022 
   1023         case BTA_AG_SCO_OPEN_ST:
   1024             switch (event)
   1025             {
   1026                 case BTA_AG_SCO_LISTEN_E:
   1027                     /* second headset has now joined */
   1028                     /* create sco listen connection (Additional channel) */
   1029                     if (p_scb != p_sco->p_curr_scb)
   1030                     {
   1031                         bta_ag_create_sco(p_scb, FALSE);
   1032                     }
   1033                     break;
   1034 
   1035                 case BTA_AG_SCO_XFER_E:
   1036                     /* close current sco connection */
   1037                     bta_ag_remove_sco(p_sco->p_curr_scb, TRUE);
   1038 
   1039                     /* save xfer scb */
   1040                     p_sco->p_xfer_scb = p_scb;
   1041 
   1042                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
   1043                     break;
   1044 
   1045                 case BTA_AG_SCO_CLOSE_E:
   1046                     /* close sco connection if active */
   1047                     if (bta_ag_remove_sco(p_scb, TRUE))
   1048                     {
   1049                         p_sco->state = BTA_AG_SCO_CLOSING_ST;
   1050                     }
   1051                     break;
   1052 
   1053                 case BTA_AG_SCO_SHUTDOWN_E:
   1054                     /* remove all listening connections */
   1055                     bta_ag_remove_sco(p_scb, FALSE);
   1056 
   1057                     /* If SCO was active on this scb, close it */
   1058                     if (p_scb == p_sco->p_curr_scb)
   1059                     {
   1060                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
   1061                     }
   1062                     break;
   1063 
   1064                 case BTA_AG_SCO_CONN_CLOSE_E:
   1065                     /* peer closed sco; create sco listen connection */
   1066                     bta_ag_create_sco(p_scb, FALSE);
   1067                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1068                     break;
   1069 
   1070                 default:
   1071                     APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_ST: Ignoring event %d", event);
   1072                     break;
   1073             }
   1074             break;
   1075 
   1076         case BTA_AG_SCO_CLOSING_ST:
   1077             switch (event)
   1078             {
   1079                 case BTA_AG_SCO_LISTEN_E:
   1080                     /* create sco listen connection (Additional channel) */
   1081                     if (p_scb != p_sco->p_curr_scb)
   1082                     {
   1083                         bta_ag_create_sco(p_scb, FALSE);
   1084                     }
   1085                     break;
   1086 
   1087                 case BTA_AG_SCO_OPEN_E:
   1088                     p_sco->state = BTA_AG_SCO_CLOSE_OP_ST;
   1089                     break;
   1090 
   1091                 case BTA_AG_SCO_XFER_E:
   1092                     /* save xfer scb */
   1093                     p_sco->p_xfer_scb = p_scb;
   1094 
   1095                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
   1096                     break;
   1097 
   1098                 case BTA_AG_SCO_SHUTDOWN_E:
   1099                     /* If not closing scb, just close it */
   1100                     if (p_scb != p_sco->p_curr_scb)
   1101                     {
   1102                         /* remove listening connection */
   1103                         bta_ag_remove_sco(p_scb, FALSE);
   1104                     }
   1105                     else
   1106                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
   1107 
   1108                     break;
   1109 
   1110                 case BTA_AG_SCO_CONN_CLOSE_E:
   1111                     /* peer closed sco; create sco listen connection */
   1112                     bta_ag_create_sco(p_scb, FALSE);
   1113 
   1114                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1115                     break;
   1116 
   1117                 default:
   1118                     APPL_TRACE_WARNING("BTA_AG_SCO_CLOSING_ST: Ignoring event %d", event);
   1119                     break;
   1120             }
   1121             break;
   1122 
   1123         case BTA_AG_SCO_CLOSE_OP_ST:
   1124             switch (event)
   1125             {
   1126                 case BTA_AG_SCO_CLOSE_E:
   1127                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
   1128                     break;
   1129 
   1130                 case BTA_AG_SCO_SHUTDOWN_E:
   1131                     p_sco->state = BTA_AG_SCO_SHUTTING_ST;
   1132                     break;
   1133 
   1134                 case BTA_AG_SCO_CONN_CLOSE_E:
   1135 #if (BTM_WBS_INCLUDED == TRUE )
   1136                     /* start codec negotiation */
   1137                     p_sco->state = BTA_AG_SCO_CODEC_ST;
   1138                     p_cn_scb = p_scb;
   1139 #else
   1140                     /* open sco connection */
   1141                     bta_ag_create_sco(p_scb, TRUE);
   1142                     p_sco->state = BTA_AG_SCO_OPENING_ST;
   1143 #endif
   1144                     break;
   1145 
   1146                 case BTA_AG_SCO_LISTEN_E:
   1147                     /* create sco listen connection (Additional channel) */
   1148                     if (p_scb != p_sco->p_curr_scb)
   1149                     {
   1150                         bta_ag_create_sco(p_scb, FALSE);
   1151                     }
   1152                     break;
   1153 
   1154                 default:
   1155                     APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %d", event);
   1156                     break;
   1157             }
   1158             break;
   1159 
   1160         case BTA_AG_SCO_CLOSE_XFER_ST:
   1161             switch (event)
   1162             {
   1163                 case BTA_AG_SCO_CONN_OPEN_E:
   1164                     /* close sco connection so headset can be transferred
   1165                        Probably entered this state from "opening state" */
   1166                     bta_ag_remove_sco(p_scb, TRUE);
   1167                     break;
   1168 
   1169                 case BTA_AG_SCO_CLOSE_E:
   1170                     /* clear xfer scb */
   1171                     p_sco->p_xfer_scb = NULL;
   1172 
   1173                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
   1174                     break;
   1175 
   1176                 case BTA_AG_SCO_SHUTDOWN_E:
   1177                     /* clear xfer scb */
   1178                     p_sco->p_xfer_scb = NULL;
   1179 
   1180                     p_sco->state = BTA_AG_SCO_SHUTTING_ST;
   1181                     break;
   1182 
   1183                 case BTA_AG_SCO_CONN_CLOSE_E:
   1184                     /* closed sco; place old sco in listen mode,
   1185                        take current sco out of listen, and
   1186                        create originating sco for current */
   1187                     bta_ag_create_sco(p_scb, FALSE);
   1188                     bta_ag_remove_sco(p_sco->p_xfer_scb, FALSE);
   1189 
   1190 #if (BTM_WBS_INCLUDED == TRUE )
   1191                     /* start codec negotiation */
   1192                     p_sco->state = BTA_AG_SCO_CODEC_ST;
   1193                     p_cn_scb = p_sco->p_xfer_scb;
   1194                     p_sco->p_xfer_scb = NULL;
   1195 #else
   1196                     /* create sco connection to peer */
   1197                     bta_ag_create_sco(p_sco->p_xfer_scb, TRUE);
   1198                     p_sco->p_xfer_scb = NULL;
   1199                     p_sco->state = BTA_AG_SCO_OPENING_ST;
   1200 #endif
   1201                     break;
   1202 
   1203                 default:
   1204                     APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %d", event);
   1205                     break;
   1206             }
   1207             break;
   1208 
   1209         case BTA_AG_SCO_SHUTTING_ST:
   1210             switch (event)
   1211             {
   1212                 case BTA_AG_SCO_CONN_OPEN_E:
   1213                     /* close sco connection; wait for conn close event */
   1214                     bta_ag_remove_sco(p_scb, TRUE);
   1215                     break;
   1216 
   1217                 case BTA_AG_SCO_CONN_CLOSE_E:
   1218                     /* If last SCO instance then finish shutting down */
   1219                     if (!bta_ag_other_scb_open(p_scb))
   1220                     {
   1221                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
   1222                     }
   1223                     else    /* Other instance is still listening */
   1224                     {
   1225                         p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1226                     }
   1227 
   1228                     if (p_scb == p_sco->p_curr_scb)
   1229                     {
   1230                         p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
   1231                         p_sco->p_curr_scb = NULL;
   1232                     }
   1233                     break;
   1234 
   1235                 case BTA_AG_SCO_LISTEN_E:
   1236                     /* create sco listen connection (Additional channel) */
   1237                     if (p_scb != p_sco->p_curr_scb)
   1238                     {
   1239                         bta_ag_create_sco(p_scb, FALSE);
   1240                     }
   1241                     break;
   1242 
   1243                 case BTA_AG_SCO_SHUTDOWN_E:
   1244                     if (!bta_ag_other_scb_open(p_scb))
   1245                     {
   1246                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
   1247                     }
   1248                     else    /* Other instance is still listening */
   1249                     {
   1250                         p_sco->state = BTA_AG_SCO_LISTEN_ST;
   1251                     }
   1252 
   1253                     if (p_scb == p_sco->p_curr_scb)
   1254                     {
   1255                         p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
   1256                         p_sco->p_curr_scb = NULL;
   1257                     }
   1258                     break;
   1259 
   1260                 default:
   1261                     APPL_TRACE_WARNING("BTA_AG_SCO_SHUTTING_ST: Ignoring event %d", event);
   1262                     break;
   1263             }
   1264             break;
   1265 
   1266         default:
   1267             break;
   1268     }
   1269 #if BTA_AG_SCO_DEBUG == TRUE
   1270     if (p_sco->state != in_state)
   1271     {
   1272         APPL_TRACE_EVENT("BTA AG SCO State Change: [%s] -> [%s] after Event [%s]",
   1273                       bta_ag_sco_state_str(in_state),
   1274                       bta_ag_sco_state_str(p_sco->state),
   1275                       bta_ag_sco_evt_str(event));
   1276     }
   1277 #endif
   1278 
   1279 #if (BTM_WBS_INCLUDED == TRUE )
   1280     if (p_cn_scb)
   1281     {
   1282         bta_ag_codec_negotiate(p_cn_scb);
   1283     }
   1284 #endif
   1285 }
   1286 
   1287 /*******************************************************************************
   1288 **
   1289 ** Function         bta_ag_sco_is_open
   1290 **
   1291 ** Description      Check if sco is open for this scb.
   1292 **
   1293 **
   1294 ** Returns          TRUE if sco open for this scb, FALSE otherwise.
   1295 **
   1296 *******************************************************************************/
   1297 BOOLEAN bta_ag_sco_is_open(tBTA_AG_SCB *p_scb)
   1298 {
   1299     return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) &&
   1300             (bta_ag_cb.sco.p_curr_scb == p_scb));
   1301 }
   1302 
   1303 /*******************************************************************************
   1304 **
   1305 ** Function         bta_ag_sco_is_opening
   1306 **
   1307 ** Description      Check if sco is in Opening state.
   1308 **
   1309 **
   1310 ** Returns          TRUE if sco is in Opening state for this scb, FALSE otherwise.
   1311 **
   1312 *******************************************************************************/
   1313 BOOLEAN bta_ag_sco_is_opening(tBTA_AG_SCB *p_scb)
   1314 {
   1315 #if (BTM_WBS_INCLUDED == TRUE )
   1316     return (((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) ||
   1317             (bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST)) &&
   1318             (bta_ag_cb.sco.p_curr_scb == p_scb));
   1319 #else
   1320     return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
   1321             (bta_ag_cb.sco.p_curr_scb == p_scb));
   1322 #endif
   1323 }
   1324 
   1325 /*******************************************************************************
   1326 **
   1327 ** Function         bta_ag_sco_listen
   1328 **
   1329 ** Description
   1330 **
   1331 **
   1332 ** Returns          void
   1333 **
   1334 *******************************************************************************/
   1335 void bta_ag_sco_listen(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1336 {
   1337     UNUSED(p_data);
   1338     bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E);
   1339 }
   1340 
   1341 /*******************************************************************************
   1342 **
   1343 ** Function         bta_ag_sco_open
   1344 **
   1345 ** Description
   1346 **
   1347 **
   1348 ** Returns          void
   1349 **
   1350 *******************************************************************************/
   1351 void bta_ag_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1352 {
   1353     UINT8 event;
   1354     UNUSED(p_data);
   1355 
   1356     /* if another scb using sco, this is a transfer */
   1357     if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb)
   1358     {
   1359         event = BTA_AG_SCO_XFER_E;
   1360     }
   1361     /* else it is an open */
   1362     else
   1363     {
   1364         event = BTA_AG_SCO_OPEN_E;
   1365     }
   1366 
   1367     bta_ag_sco_event(p_scb, event);
   1368 }
   1369 
   1370 /*******************************************************************************
   1371 **
   1372 ** Function         bta_ag_sco_close
   1373 **
   1374 ** Description
   1375 **
   1376 **
   1377 ** Returns          void
   1378 **
   1379 *******************************************************************************/
   1380 void bta_ag_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1381 {
   1382     UNUSED(p_data);
   1383 
   1384     /* if scb is in use */
   1385 #if (BTM_WBS_INCLUDED == TRUE )
   1386     /* sco_idx is not allocated in SCO_CODEC_ST, we still need to move to listening state. */
   1387     if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) || (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST))
   1388 #else
   1389     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
   1390 #endif
   1391     {
   1392         APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
   1393         bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
   1394     }
   1395 }
   1396 
   1397 #if (BTM_WBS_INCLUDED == TRUE )
   1398 
   1399 /*******************************************************************************
   1400 **
   1401 ** Function         bta_ag_sco_codec_nego
   1402 **
   1403 ** Description
   1404 **
   1405 **
   1406 ** Returns          void
   1407 **
   1408 *******************************************************************************/
   1409 void bta_ag_sco_codec_nego(tBTA_AG_SCB *p_scb, BOOLEAN result)
   1410 {
   1411     if(result == TRUE)
   1412     {
   1413         /* Subsequent sco connection will skip codec negotiation */
   1414         p_scb->codec_updated = FALSE;
   1415 
   1416         bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E);
   1417     }
   1418     else    /* codec negotiation failed */
   1419         bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
   1420 }
   1421 #endif
   1422 
   1423 /*******************************************************************************
   1424 **
   1425 ** Function         bta_ag_sco_shutdown
   1426 **
   1427 ** Description
   1428 **
   1429 **
   1430 ** Returns          void
   1431 **
   1432 *******************************************************************************/
   1433 void bta_ag_sco_shutdown(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1434 {
   1435     UNUSED(p_data);
   1436 
   1437     bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
   1438 }
   1439 
   1440 /*******************************************************************************
   1441 **
   1442 ** Function         bta_ag_sco_conn_open
   1443 **
   1444 ** Description
   1445 **
   1446 **
   1447 ** Returns          void
   1448 **
   1449 *******************************************************************************/
   1450 void bta_ag_sco_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1451 {
   1452     UNUSED(p_data);
   1453 
   1454     bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E);
   1455 
   1456     bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1457 
   1458 #if (BTM_WBS_INCLUDED == TRUE)
   1459     bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_ON,
   1460                           p_scb->inuse_codec);
   1461 #else
   1462     bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_ON);
   1463 #endif
   1464 
   1465 #if (BTM_SCO_HCI_INCLUDED == TRUE )
   1466     /* open SCO codec if SCO is routed through transport */
   1467     bta_dm_sco_co_open(bta_ag_scb_to_idx(p_scb), BTA_SCO_OUT_PKT_SIZE, BTA_AG_CI_SCO_DATA_EVT);
   1468 #endif
   1469 
   1470     /* call app callback */
   1471     bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
   1472 
   1473     p_scb->retry_with_sco_only = FALSE;
   1474 #if (BTM_WBS_INCLUDED == TRUE)
   1475     /* reset to mSBC T2 settings as the preferred */
   1476     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
   1477 #endif
   1478 }
   1479 
   1480 /*******************************************************************************
   1481 **
   1482 ** Function         bta_ag_sco_conn_close
   1483 **
   1484 ** Description
   1485 **
   1486 **
   1487 ** Returns          void
   1488 **
   1489 *******************************************************************************/
   1490 void bta_ag_sco_conn_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1491 {
   1492     UINT16 handle = bta_ag_scb_to_idx(p_scb);
   1493     UNUSED(p_data);
   1494 
   1495     /* clear current scb */
   1496     bta_ag_cb.sco.p_curr_scb = NULL;
   1497     p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
   1498 
   1499 #if (BTM_WBS_INCLUDED == TRUE)
   1500     /* codec_fallback is set when AG is initiator and connection failed for mSBC. */
   1501     /* OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
   1502     if ((p_scb->codec_fallback && p_scb->svc_conn) ||
   1503          bta_ag_attempt_msbc_safe_settings(p_scb))
   1504     {
   1505         bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
   1506     }
   1507     else if (p_scb->retry_with_sco_only && p_scb->svc_conn)
   1508     {
   1509         /* retry_with_sco_only is set when AG is initiator and connection failed for eSCO */
   1510         bta_ag_create_sco(p_scb, TRUE);
   1511     }
   1512 #else
   1513     /* retry_with_sco_only, will be set only when AG is initiator
   1514     ** and AG is first trying to establish an eSCO connection */
   1515     if (p_scb->retry_with_sco_only && p_scb->svc_conn)
   1516     {
   1517         bta_ag_create_sco(p_scb, TRUE);
   1518     }
   1519 #endif
   1520     else
   1521     {
   1522 #if (BTM_WBS_INCLUDED == TRUE)
   1523         /* Indicate if the closing of audio is because of transfer */
   1524         bta_ag_co_audio_state(handle, p_scb->app_id,(bta_ag_cb.sco.p_xfer_scb)?\
   1525         BTA_AG_CO_AUD_STATE_OFF_XFER:BTA_AG_CO_AUD_STATE_OFF,p_scb->inuse_codec);
   1526 #else
   1527         /* Indicate if the closing of audio is because of transfer */
   1528         bta_ag_co_audio_state(handle, p_scb->app_id,(bta_ag_cb.sco.p_xfer_scb)?\
   1529         BTA_AG_CO_AUD_STATE_OFF_XFER:BTA_AG_CO_AUD_STATE_OFF);
   1530 #endif
   1531         bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
   1532 
   1533         bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1534 
   1535         /* if av got suspended by this call, let it resume. */
   1536         /* In case call stays alive regardless of sco, av should not be affected. */
   1537         if(((p_scb->call_ind == BTA_AG_CALL_INACTIVE) && (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE))
   1538             || (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END))
   1539         {
   1540             bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1541         }
   1542 
   1543         /* call app callback */
   1544         bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
   1545 #if (BTM_WBS_INCLUDED == TRUE)
   1546         p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
   1547 #endif
   1548     }
   1549     p_scb->retry_with_sco_only = FALSE;
   1550 }
   1551 
   1552 /*******************************************************************************
   1553 **
   1554 ** Function         bta_ag_sco_conn_rsp
   1555 **
   1556 ** Description      Process the SCO connection request
   1557 **
   1558 **
   1559 ** Returns          void
   1560 **
   1561 *******************************************************************************/
   1562 void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
   1563 {
   1564     tBTM_ESCO_PARAMS    resp;
   1565     UINT8               hci_status = HCI_SUCCESS;
   1566 #if (BTM_SCO_HCI_INCLUDED == TRUE )
   1567     tBTA_CODEC_INFO     codec_info = {BTA_SCO_CODEC_PCM};
   1568     UINT32              pcm_sample_rate;
   1569 #endif
   1570 
   1571     if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST     ||
   1572         bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
   1573         bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST)
   1574     {
   1575         /* If script overrided sco parameter by BTA_CMD_SET_ESCO_PARAM */
   1576         if (bta_ag_cb.sco.param_updated)
   1577         {
   1578             resp = bta_ag_cb.sco.params;
   1579         }
   1580         else
   1581         {
   1582             resp.rx_bw = BTM_64KBITS_RATE;
   1583             resp.tx_bw = BTM_64KBITS_RATE;
   1584             resp.max_latency = 10;
   1585             resp.voice_contfmt = 0x60;
   1586             resp.retrans_effort = BTM_ESCO_RETRANS_POWER;
   1587 
   1588             if (p_data->link_type == BTM_LINK_TYPE_SCO)
   1589             {
   1590                 resp.packet_types = (BTM_SCO_LINK_ONLY_MASK          |
   1591                                      BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 |
   1592                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
   1593                                      BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
   1594                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
   1595             }
   1596             else    /* Allow controller to use all types available except 5-slot EDR */
   1597             {
   1598                 resp.packet_types = (BTM_SCO_LINK_ALL_PKT_MASK |
   1599                                      BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
   1600                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
   1601             }
   1602         }
   1603 
   1604         /* tell sys to stop av if any */
   1605         bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
   1606 
   1607 #if (BTM_WBS_INCLUDED == FALSE )
   1608         /* Allow any platform specific pre-SCO set up to take place */
   1609         bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP);
   1610 #else
   1611         /* When HS initiated SCO, it cannot be WBS. */
   1612         /* Allow any platform specific pre-SCO set up to take place */
   1613         bta_ag_co_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, BTA_AG_CO_AUD_STATE_SETUP,
   1614                               BTA_AG_CODEC_CVSD);
   1615 #endif
   1616 
   1617 #if (BTM_SCO_HCI_INCLUDED == TRUE )
   1618         pcm_sample_rate = BTA_DM_SCO_SAMP_RATE_8K;
   1619 
   1620         /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
   1621         BTM_ConfigScoPath(bta_dm_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id),
   1622             bta_ag_sco_read_cback, NULL, TRUE);
   1623 #endif
   1624     }
   1625     else
   1626         hci_status = HCI_ERR_HOST_REJECT_DEVICE;
   1627 
   1628 #if (BTM_WBS_INCLUDED == TRUE )
   1629     /* If SCO open was initiated from HS, it must be CVSD */
   1630     p_scb->inuse_codec = BTA_AG_CODEC_NONE;
   1631 #endif
   1632 
   1633     BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp);
   1634 }
   1635 
   1636 /*******************************************************************************
   1637 **
   1638 ** Function         bta_ag_ci_sco_data
   1639 **
   1640 ** Description      Process the SCO data ready callin event
   1641 **
   1642 **
   1643 ** Returns          void
   1644 **
   1645 *******************************************************************************/
   1646 void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
   1647 {
   1648     UNUSED(p_scb);
   1649     UNUSED(p_data);
   1650 
   1651 #if (BTM_SCO_HCI_INCLUDED == TRUE )
   1652     bta_ag_sco_event(p_scb, BTA_AG_SCO_CI_DATA_E);
   1653 #endif
   1654 }
   1655 
   1656 /*******************************************************************************
   1657 **
   1658 ** Function         bta_ag_set_esco_param
   1659 **
   1660 ** Description      Update esco parameters from script wrapper.
   1661 **
   1662 **
   1663 ** Returns          void
   1664 **
   1665 *******************************************************************************/
   1666 void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param)
   1667 {
   1668     if(set_reset == FALSE)    /* reset the parameters to default */
   1669     {
   1670         bta_ag_cb.sco.param_updated = FALSE;
   1671         APPL_TRACE_DEBUG("bta_ag_set_esco_param : Resetting ESCO parameters to default");
   1672     }
   1673     else
   1674     {
   1675         bta_ag_cb.sco.param_updated = TRUE;
   1676         bta_ag_cb.sco.params = *param;
   1677         APPL_TRACE_DEBUG("bta_ag_set_esco_param : Setting ESCO parameters");
   1678     }
   1679 }
   1680 
   1681 /*******************************************************************************
   1682 **  Debugging functions
   1683 *******************************************************************************/
   1684 
   1685 #if BTA_AG_SCO_DEBUG == TRUE
   1686 static char *bta_ag_sco_evt_str(UINT8 event)
   1687 {
   1688     switch (event)
   1689     {
   1690     case BTA_AG_SCO_LISTEN_E:
   1691         return "Listen Request";
   1692     case BTA_AG_SCO_OPEN_E:
   1693         return "Open Request";
   1694     case BTA_AG_SCO_XFER_E:
   1695         return "Transfer Request";
   1696 #if (BTM_WBS_INCLUDED == TRUE )
   1697     case BTA_AG_SCO_CN_DONE_E:
   1698         return "Codec Negotiation Done";
   1699     case BTA_AG_SCO_REOPEN_E:
   1700         return "Reopen Request";
   1701 #endif
   1702     case BTA_AG_SCO_CLOSE_E:
   1703         return "Close Request";
   1704     case BTA_AG_SCO_SHUTDOWN_E:
   1705         return "Shutdown Request";
   1706     case BTA_AG_SCO_CONN_OPEN_E:
   1707         return "Opened";
   1708     case BTA_AG_SCO_CONN_CLOSE_E:
   1709         return "Closed";
   1710     case BTA_AG_SCO_CI_DATA_E  :
   1711         return "Sco Data";
   1712     default:
   1713         return "Unknown SCO Event";
   1714     }
   1715 }
   1716 
   1717 static char *bta_ag_sco_state_str(UINT8 state)
   1718 {
   1719     switch (state)
   1720     {
   1721     case BTA_AG_SCO_SHUTDOWN_ST:
   1722         return "Shutdown";
   1723     case BTA_AG_SCO_LISTEN_ST:
   1724         return "Listening";
   1725 #if (BTM_WBS_INCLUDED == TRUE )
   1726     case BTA_AG_SCO_CODEC_ST:
   1727         return "Codec Negotiation";
   1728 #endif
   1729     case BTA_AG_SCO_OPENING_ST:
   1730         return "Opening";
   1731     case BTA_AG_SCO_OPEN_CL_ST:
   1732         return "Open while closing";
   1733     case BTA_AG_SCO_OPEN_XFER_ST:
   1734         return "Opening while Transferring";
   1735     case BTA_AG_SCO_OPEN_ST:
   1736         return "Open";
   1737     case BTA_AG_SCO_CLOSING_ST:
   1738         return "Closing";
   1739     case BTA_AG_SCO_CLOSE_OP_ST:
   1740         return "Close while Opening";
   1741     case BTA_AG_SCO_CLOSE_XFER_ST:
   1742         return "Close while Transferring";
   1743     case BTA_AG_SCO_SHUTTING_ST:
   1744         return "Shutting Down";
   1745     default:
   1746         return "Unknown SCO State";
   1747     }
   1748 }
   1749 
   1750 #endif
   1751