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