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