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