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