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