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