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_DEBUG("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     sco.sync_conn_handle = BTM_ReadScoHandle(p_scb->sco_idx);
479 
480     /* call close cback */
481     (*bta_ag_cb.p_cback)(event, (tBTA_AG *) &sco);
482 }
483 
484 /*******************************************************************************
485 **
486 ** Function         bta_ag_create_sco
487 **
488 ** Description      Create a sco connection and is is_orig is TRUE means AG originate
489 **                  this connection, if FALSE it's peer device originate the connection.
490 **
491 **
492 ** Returns          void
493 **
494 *******************************************************************************/
bta_ag_create_sco(tBTA_AG_SCB * p_scb,BOOLEAN is_orig)495 static void bta_ag_create_sco(tBTA_AG_SCB *p_scb, BOOLEAN is_orig)
496 {
497     tBTM_STATUS         status;
498     UINT8               *p_bd_addr = NULL;
499     tBTM_ESCO_PARAMS    params;
500     UINT8               codec_index = BTA_AG_ESCO_SETTING_IDX_CVSD;
501 #if (BTM_WBS_INCLUDED == TRUE)
502     tBTA_AG_PEER_CODEC  esco_codec = BTM_SCO_CODEC_CVSD;
503 #endif
504 #if (BTM_SCO_HCI_INCLUDED == TRUE)
505     tBTM_SCO_ROUTE_TYPE     sco_route;
506     tBTA_HFP_CODEC_INFO     codec_info = {BTA_HFP_SCO_CODEC_PCM};
507     UINT32                  pcm_sample_rate;
508 #endif
509 
510     /* Make sure this sco handle is not already in use */
511     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
512     {
513         APPL_TRACE_WARNING("bta_ag_create_sco: Index 0x%04x Already In Use!",
514                              p_scb->sco_idx);
515         return;
516     }
517 
518 #if (BTM_WBS_INCLUDED == TRUE)
519 
520     if ((p_scb->sco_codec == BTM_SCO_CODEC_MSBC) && !p_scb->codec_fallback && !p_scb->retry_with_sco_only)
521     {
522         esco_codec = BTM_SCO_CODEC_MSBC;
523     }
524     if (p_scb->codec_fallback)
525     {
526         p_scb->codec_fallback = FALSE;
527         /* Force AG to send +BCS for the next audio connection. */
528         p_scb->codec_updated = TRUE;
529     }
530     /* If WBS included, use CVSD by default, index is 0 for CVSD by initialization */
531     /* If eSCO codec is mSBC, index is T2 or T1 */
532     if (esco_codec == BTM_SCO_CODEC_MSBC)
533     {
534         if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2)
535         {
536             codec_index = BTA_AG_ESCO_SETTING_IDX_T2;
537         }
538         else
539         {
540             codec_index = BTA_AG_ESCO_SETTING_IDX_T1;
541         }
542     }
543     /* If eSCO codec is CVSD and eSC0 S4 is supported, index is S4 */
544     else if ((esco_codec == BTM_SCO_CODEC_CVSD) && (p_scb->features & BTA_AG_FEAT_ESCO_S4)
545                 && (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4))
546     {
547         codec_index = BTA_AG_ESCO_SETTING_IDX_S4;
548     }
549 
550 #else
551     if ((p_scb->features & BTA_AG_FEAT_ESCO_S4) && (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4))
552     {
553         codec_index = BTA_AG_ESCO_SETTING_IDX_S4;
554     }
555 #endif
556     params = bta_ag_esco_params[codec_index];
557 
558     if(bta_ag_cb.sco.param_updated) /* If we do not use the default parameters */
559         params = bta_ag_cb.sco.params;
560 
561     if(!bta_ag_cb.sco.param_updated)
562     {
563 #if (BTM_WBS_INCLUDED == TRUE)
564         if (esco_codec == BTM_SCO_CODEC_CVSD)   /* For CVSD */
565 #endif
566         {
567             if (codec_index == BTA_AG_ESCO_SETTING_IDX_CVSD)
568             {
569                 /* Use the application packet types (5 slot EV packets not allowed) */
570                 params.packet_types = p_bta_ag_cfg->sco_pkt_types     |
571                                     BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
572                                     BTM_SCO_PKT_TYPES_MASK_NO_3_EV5;
573             }
574         }
575     }
576 
577     /* if initiating, set current scb and peer bd addr */
578     if (is_orig)
579     {
580         /* Attempt to use eSCO if remote host supports HFP >= 1.5 */
581         /* Need to find out from SIG if HSP can use eSCO; for now use SCO */
582         if (p_scb->conn_service == BTA_AG_HFP && p_scb->peer_version >= HFP_VERSION_1_5 && !p_scb->retry_with_sco_only)
583         {
584             BTM_SetEScoMode(BTM_LINK_TYPE_ESCO, &params);
585             /* If ESCO or EDR ESCO, retry with SCO only in case of failure */
586             if((params.packet_types & BTM_ESCO_LINK_ONLY_MASK)
587                ||!((params.packet_types & ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^ BTA_AG_NO_EDR_ESCO))
588             {
589 #if (BTM_WBS_INCLUDED == TRUE)
590                 if (esco_codec != BTA_AG_CODEC_MSBC)
591                 {
592                     p_scb->retry_with_sco_only = TRUE;
593                     APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
594                 }
595                 else    /* Do not use SCO when using mSBC */
596                 {
597                     p_scb->retry_with_sco_only = FALSE;
598                     APPL_TRACE_API("Setting retry_with_sco_only to FALSE");
599                 }
600 #else
601                 p_scb->retry_with_sco_only = TRUE;
602                 APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
603 #endif
604             }
605         }
606         else
607         {
608             if(p_scb->retry_with_sco_only){
609                 APPL_TRACE_API("retrying with SCO only");
610             }
611             p_scb->retry_with_sco_only = FALSE;
612             BTM_SetEScoMode(BTM_LINK_TYPE_SCO, &params);
613         }
614 
615         bta_ag_cb.sco.p_curr_scb = p_scb;
616         /* tell sys to stop av if any */
617         bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
618 
619 #if (BTM_SCO_HCI_INCLUDED == TRUE)
620 #if (BTM_WBS_INCLUDED == TRUE)
621         /* Allow any platform specific pre-SCO set up to take place */
622         bta_ag_sco_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, SCO_STATE_SETUP, esco_codec);
623 
624         /* This setting may not be necessary */
625         /* To be verified with stable 2049 boards */
626         if (esco_codec == BTA_AG_CODEC_MSBC)
627             BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS);
628         else
629             BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
630         /* save the current codec because sco_codec can be updated while SCO is open. */
631         p_scb->inuse_codec = esco_codec;
632 #else
633         /* Allow any platform specific pre-SCO set up to take place */
634         bta_ag_sco_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, SCO_STATE_SETUP);
635 #endif
636 #endif
637 
638 #if (BTM_SCO_HCI_INCLUDED == TRUE)
639 #if (BTM_WBS_INCLUDED == TRUE)
640     if (esco_codec == BTA_AG_CODEC_MSBC)
641         pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_16K;
642 #endif
643         pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_8K;
644         sco_route = bta_ag_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id);
645 #endif
646 
647 
648 #if (BTM_SCO_HCI_INCLUDED == TRUE)
649         /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
650         BTM_ConfigScoPath(sco_route, bta_ag_sco_read_cback, NULL, TRUE);
651 #endif
652         bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
653     }
654     else{
655         p_scb->retry_with_sco_only = FALSE;
656     }
657 
658     p_bd_addr = p_scb->peer_addr;
659 
660     status = BTM_CreateSco(p_bd_addr, is_orig, params.packet_types, &p_scb->sco_idx, bta_ag_sco_conn_cback,
661                            bta_ag_sco_disc_cback);
662 
663     if (status == BTM_CMD_STARTED)
664     {
665         if (!is_orig)
666         {
667             BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
668         }
669         else    /* Initiating the connection, set the current sco handle */
670         {
671             bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
672         }
673     }
674 
675     APPL_TRACE_API("ag create sco: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
676                       is_orig, p_scb->sco_idx, status, params.packet_types);
677 }
678 
679 #if (BTM_WBS_INCLUDED == TRUE )
680 /*******************************************************************************
681 **
682 ** Function         bta_ag_attempt_msbc_safe_settings
683 **
684 ** Description      Checks if ESCO connection needs to be attempted using mSBC T1(safe) settings
685 **
686 **
687 ** Returns          TRUE if T1 settings has to be used, FALSE otherwise
688 **
689 *******************************************************************************/
bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB * p_scb)690 BOOLEAN bta_ag_attempt_msbc_safe_settings(tBTA_AG_SCB *p_scb)
691 {
692     if (p_scb->svc_conn && p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
693         p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1)
694         return TRUE;
695     else
696         return FALSE;
697 }
698 
699 /*******************************************************************************
700 **
701 ** Function         bta_ag_cn_timer_cback
702 **
703 ** Description
704 **
705 **
706 ** Returns          void
707 **
708 *******************************************************************************/
bta_ag_cn_timer_cback(TIMER_LIST_ENT * p_tle)709 static void bta_ag_cn_timer_cback (TIMER_LIST_ENT *p_tle)
710 {
711     tBTA_AG_SCB *p_scb;
712 
713     if (p_tle)
714     {
715         p_scb = (tBTA_AG_SCB *)p_tle->param;
716 
717         if (p_scb)
718         {
719             /* Announce that codec negotiation failed. */
720             bta_ag_sco_codec_nego(p_scb, FALSE);
721 
722             /* call app callback */
723             bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
724         }
725     }
726 }
727 
728 /*******************************************************************************
729 **
730 ** Function         bta_ag_codec_negotiate
731 **
732 ** Description      Initiate codec negotiation by sending AT command.
733 **                  If not necessary, skip negotiation.
734 **
735 ** Returns          void
736 **
737 *******************************************************************************/
bta_ag_codec_negotiate(tBTA_AG_SCB * p_scb)738 void bta_ag_codec_negotiate(tBTA_AG_SCB *p_scb)
739 {
740     bta_ag_cb.sco.p_curr_scb = p_scb;
741 
742     if ((p_scb->codec_updated || p_scb->codec_fallback ||
743         bta_ag_attempt_msbc_safe_settings(p_scb)) &&
744        (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC))
745     {
746         /* Change the power mode to Active until sco open is completed. */
747         bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
748 
749         /* Send +BCS to the peer */
750         bta_ag_send_bcs(p_scb, NULL);
751 
752         /* Start timer to handle timeout */
753         p_scb->cn_timer.p_cback = (TIMER_CBACK*)&bta_ag_cn_timer_cback;
754         p_scb->cn_timer.param = (INT32)p_scb;
755         bta_sys_start_timer(&p_scb->cn_timer, 0, BTA_AG_CODEC_NEGO_TIMEOUT);
756     }
757     else
758     {
759         /* use same codec type as previous SCO connection, skip codec negotiation */
760         APPL_TRACE_DEBUG("use same codec type as previous SCO connection,skip codec negotiation");
761         bta_ag_sco_codec_nego(p_scb, TRUE);
762     }
763 }
764 #endif
765 
766 /*******************************************************************************
767 **
768 ** Function         bta_ag_sco_event
769 **
770 ** Description      AG Sco State Machine
771 **
772 **
773 ** Returns          void
774 **
775 *******************************************************************************/
bta_ag_sco_event(tBTA_AG_SCB * p_scb,UINT8 event)776 static void bta_ag_sco_event(tBTA_AG_SCB *p_scb, UINT8 event)
777 {
778     tBTA_AG_SCO_CB *p_sco = &bta_ag_cb.sco;
779 #if (BTM_WBS_INCLUDED == TRUE)
780     tBTA_AG_SCB *p_cn_scb = NULL;   /* For codec negotiation */
781 #endif
782     UINT8   in_state = p_sco->state;
783     APPL_TRACE_EVENT("BTA ag sco evt (hdl 0x%04x): State %d (%s), Event %d (%s)",
784                         p_scb->sco_idx, p_sco->state,
785                         bta_ag_sco_state_str(p_sco->state), event, bta_ag_sco_evt_str(event));
786 
787 #if (BTM_SCO_HCI_INCLUDED == TRUE)
788     BT_HDR  *p_buf;
789     if (event == BTA_AG_SCO_CI_DATA_E)
790     {
791         UINT16 pkt_offset = 1 + HCI_SCO_PREAMBLE_SIZE;
792         UINT16 len_to_send = 0;
793         while (TRUE)
794         {
795             p_buf = osi_calloc(sizeof(BT_HDR) + pkt_offset + p_scb->out_pkt_len);
796             if (!p_buf) {
797                 APPL_TRACE_WARNING("%s, no mem", __FUNCTION__);
798                 break;
799             }
800             p_buf->offset = pkt_offset;
801             len_to_send = bta_ag_sco_co_out_data(p_buf->data + pkt_offset);
802             p_buf->len = len_to_send;
803             if (len_to_send == p_scb->out_pkt_len) {
804                 if (p_sco->state == BTA_AG_SCO_OPEN_ST) {
805                     tBTM_STATUS write_stat = BTM_WriteScoData(p_sco->p_curr_scb->sco_idx, p_buf);
806                     if (write_stat != BTM_SUCCESS) {
807                         break;
808                     }
809                 } else {
810                     osi_free(p_buf);
811                 }
812             } else {
813                 osi_free(p_buf);
814                 break;
815             }
816         }
817         return;
818     }
819 #endif
820 
821     /* State Machine Start */
822     switch (p_sco->state)
823     {
824         case BTA_AG_SCO_SHUTDOWN_ST:
825             switch (event)
826             {
827                 case BTA_AG_SCO_LISTEN_E:
828                     /* create sco listen connection */
829                     bta_ag_create_sco(p_scb, FALSE);
830                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
831                     break;
832 
833                 default:
834                     APPL_TRACE_WARNING("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %d", event);
835                     break;
836             }
837             break;
838 
839         case BTA_AG_SCO_LISTEN_ST:
840             switch (event)
841             {
842                 case BTA_AG_SCO_LISTEN_E:
843                     /* create sco listen connection (Additional channel) */
844                     bta_ag_create_sco(p_scb, FALSE);
845                     break;
846 
847                 case BTA_AG_SCO_OPEN_E:
848                     /* remove listening connection */
849                     bta_ag_remove_sco(p_scb, FALSE);
850 #if (BTM_WBS_INCLUDED == TRUE )
851                     /* start codec negotiation */
852                     p_sco->state = BTA_AG_SCO_CODEC_ST;
853                     p_cn_scb = p_scb;
854 #else
855                     /* create sco connection to peer */
856                     bta_ag_create_sco(p_scb, TRUE);
857                     p_sco->state = BTA_AG_SCO_OPENING_ST;
858 #endif
859                     break;
860 
861                 case BTA_AG_SCO_SHUTDOWN_E:
862                     /* remove listening connection */
863                     bta_ag_remove_sco(p_scb, FALSE);
864 
865                     if (p_scb == p_sco->p_curr_scb)
866                         p_sco->p_curr_scb = NULL;
867 
868                     /* If last SCO instance then finish shutting down */
869                     if (!bta_ag_other_scb_open(p_scb))
870                     {
871                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
872                     }
873                     break;
874 
875                 case BTA_AG_SCO_CLOSE_E:
876                     /* remove listening connection */
877                     /* Ignore the event. We need to keep listening SCO for the active SLC */
878                     APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
879                     break;
880 
881                 case BTA_AG_SCO_CONN_CLOSE_E:
882                     /* sco failed; create sco listen connection */
883                     bta_ag_create_sco(p_scb, FALSE);
884                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
885                     break;
886 
887                 default:
888                     APPL_TRACE_WARNING("BTA_AG_SCO_LISTEN_ST: Ignoring event %d", event);
889                     break;
890             }
891             break;
892 
893 #if (BTM_WBS_INCLUDED == TRUE )
894         case BTA_AG_SCO_CODEC_ST:
895             switch (event)
896             {
897                 case BTA_AG_SCO_LISTEN_E:
898                     /* create sco listen connection (Additional channel) */
899                     bta_ag_create_sco(p_scb, FALSE);
900                     break;
901 
902                 case BTA_AG_SCO_CN_DONE_E:
903                     /* create sco connection to peer */
904                     bta_ag_create_sco(p_scb, TRUE);
905                     p_sco->state = BTA_AG_SCO_OPENING_ST;
906                     break;
907 
908                 case BTA_AG_SCO_XFER_E:
909                     /* save xfer scb */
910                     p_sco->p_xfer_scb = p_scb;
911                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
912                     break;
913 
914                 case BTA_AG_SCO_SHUTDOWN_E:
915                     /* remove listening connection */
916                     bta_ag_remove_sco(p_scb, FALSE);
917 
918                     if (p_scb == p_sco->p_curr_scb)
919                         p_sco->p_curr_scb = NULL;
920 
921                     /* If last SCO instance then finish shutting down */
922                     if (!bta_ag_other_scb_open(p_scb))
923                     {
924                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
925                     }
926                     break;
927 
928                 case BTA_AG_SCO_CLOSE_E:
929                     /* sco open is not started yet. just go back to listening */
930                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
931                     break;
932 
933                 case BTA_AG_SCO_CONN_CLOSE_E:
934                     /* sco failed; create sco listen connection */
935                     bta_ag_create_sco(p_scb, FALSE);
936                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
937                     break;
938 
939                 default:
940                     APPL_TRACE_WARNING("BTA_AG_SCO_CODEC_ST: Ignoring event %d", event);
941                     break;
942             }
943             break;
944 #endif
945 
946         case BTA_AG_SCO_OPENING_ST:
947             switch (event)
948             {
949                 case BTA_AG_SCO_LISTEN_E:
950                     /* second headset has now joined */
951                     /* create sco listen connection (Additional channel) */
952                     if (p_scb != p_sco->p_curr_scb)
953                     {
954                         bta_ag_create_sco(p_scb, FALSE);
955                     }
956                     break;
957 
958 #if (BTM_WBS_INCLUDED == TRUE)
959                 case BTA_AG_SCO_REOPEN_E:
960                     /* start codec negotiation */
961                     p_sco->state = BTA_AG_SCO_CODEC_ST;
962                     p_cn_scb = p_scb;
963                     break;
964 #endif
965 
966                 case BTA_AG_SCO_XFER_E:
967                     /* save xfer scb */
968                     p_sco->p_xfer_scb = p_scb;
969                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
970                     break;
971 
972                 case BTA_AG_SCO_CLOSE_E:
973                     p_sco->state = BTA_AG_SCO_OPEN_CL_ST;
974                     break;
975 
976                 case BTA_AG_SCO_SHUTDOWN_E:
977                     /* If not opening scb, just close it */
978                     if (p_scb != p_sco->p_curr_scb)
979                     {
980                         /* remove listening connection */
981                         bta_ag_remove_sco(p_scb, FALSE);
982                     }
983                     else
984                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
985 
986                     break;
987 
988                 case BTA_AG_SCO_CONN_OPEN_E:
989                     p_sco->state = BTA_AG_SCO_OPEN_ST;
990                     break;
991 
992                 case BTA_AG_SCO_CONN_CLOSE_E:
993                     /* sco failed; create sco listen connection */
994                     bta_ag_create_sco(p_scb, FALSE);
995                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
996                     break;
997 
998                 default:
999                     APPL_TRACE_WARNING("BTA_AG_SCO_OPENING_ST: Ignoring event %d", event);
1000                     break;
1001             }
1002             break;
1003 
1004         case BTA_AG_SCO_OPEN_CL_ST:
1005             switch (event)
1006             {
1007                 case BTA_AG_SCO_XFER_E:
1008                     /* save xfer scb */
1009                     p_sco->p_xfer_scb = p_scb;
1010 
1011                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
1012                     break;
1013 
1014                 case BTA_AG_SCO_OPEN_E:
1015                     p_sco->state = BTA_AG_SCO_OPENING_ST;
1016                     break;
1017 
1018                 case BTA_AG_SCO_SHUTDOWN_E:
1019                     /* If not opening scb, just close it */
1020                     if (p_scb != p_sco->p_curr_scb)
1021                     {
1022                         /* remove listening connection */
1023                         bta_ag_remove_sco(p_scb, FALSE);
1024                     }
1025                     else
1026                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1027 
1028                     break;
1029 
1030                 case BTA_AG_SCO_CONN_OPEN_E:
1031                     /* close sco connection */
1032                     bta_ag_remove_sco(p_scb, TRUE);
1033 
1034                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
1035                     break;
1036 
1037                 case BTA_AG_SCO_CONN_CLOSE_E:
1038                     /* sco failed; create sco listen connection */
1039 
1040                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
1041                     break;
1042 
1043                 default:
1044                     APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %d", event);
1045                     break;
1046             }
1047             break;
1048 
1049         case BTA_AG_SCO_OPEN_XFER_ST:
1050             switch (event)
1051             {
1052                 case BTA_AG_SCO_CLOSE_E:
1053                     /* close sco connection */
1054                     bta_ag_remove_sco(p_scb, TRUE);
1055                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
1056                     break;
1057 
1058                 case BTA_AG_SCO_SHUTDOWN_E:
1059                     /* remove all connection */
1060                     bta_ag_remove_sco(p_scb, FALSE);
1061                     p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1062                     break;
1063 
1064                 case BTA_AG_SCO_CONN_CLOSE_E:
1065                     /* closed sco; place in listen mode and
1066                        accept the transferred connection */
1067                     bta_ag_create_sco(p_scb, FALSE);    /* Back into listen mode */
1068                     /* Accept sco connection with xfer scb */
1069                     bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data);
1070                     p_sco->state = BTA_AG_SCO_OPENING_ST;
1071                     p_sco->p_curr_scb = p_sco->p_xfer_scb;
1072                     p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx;
1073                     p_sco->p_xfer_scb = NULL;
1074                     break;
1075 
1076                 default:
1077                     APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %d", event);
1078                     break;
1079             }
1080             break;
1081 
1082         case BTA_AG_SCO_OPEN_ST:
1083             switch (event)
1084             {
1085                 case BTA_AG_SCO_LISTEN_E:
1086                     /* second headset has now joined */
1087                     /* create sco listen connection (Additional channel) */
1088                     if (p_scb != p_sco->p_curr_scb)
1089                     {
1090                         bta_ag_create_sco(p_scb, FALSE);
1091                     }
1092                     break;
1093 
1094                 case BTA_AG_SCO_XFER_E:
1095                     /* close current sco connection */
1096                     bta_ag_remove_sco(p_sco->p_curr_scb, TRUE);
1097                     /* save xfer scb */
1098                     p_sco->p_xfer_scb = p_scb;
1099                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
1100                     break;
1101 
1102                 case BTA_AG_SCO_CLOSE_E:
1103                     /* close sco connection if active */
1104                     if (bta_ag_remove_sco(p_scb, TRUE))
1105                     {
1106                         p_sco->state = BTA_AG_SCO_CLOSING_ST;
1107                     }
1108                     break;
1109 
1110                 case BTA_AG_SCO_SHUTDOWN_E:
1111                     /* remove all listening connections */
1112                     bta_ag_remove_sco(p_scb, FALSE);
1113                     /* If SCO was active on this scb, close it */
1114                     if (p_scb == p_sco->p_curr_scb)
1115                     {
1116                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1117                     }
1118                     break;
1119 
1120                 case BTA_AG_SCO_CONN_CLOSE_E:
1121                     /* peer closed sco; create sco listen connection */
1122                     bta_ag_create_sco(p_scb, FALSE);
1123                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
1124                     break;
1125 
1126                 default:
1127                     APPL_TRACE_WARNING("BTA_AG_SCO_OPEN_ST: Ignoring event %d", event);
1128                     break;
1129             }
1130             break;
1131 
1132         case BTA_AG_SCO_CLOSING_ST:
1133             switch (event)
1134             {
1135                 case BTA_AG_SCO_LISTEN_E:
1136                     /* create sco listen connection (Additional channel) */
1137                     if (p_scb != p_sco->p_curr_scb)
1138                     {
1139                         bta_ag_create_sco(p_scb, FALSE);
1140                     }
1141                     break;
1142 
1143                 case BTA_AG_SCO_OPEN_E:
1144                     p_sco->state = BTA_AG_SCO_CLOSE_OP_ST;
1145                     break;
1146 
1147                 case BTA_AG_SCO_XFER_E:
1148                     /* save xfer scb */
1149                     p_sco->p_xfer_scb = p_scb;
1150                     p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
1151                     break;
1152 
1153                 case BTA_AG_SCO_SHUTDOWN_E:
1154                     /* If not closing scb, just close it */
1155                     if (p_scb != p_sco->p_curr_scb)
1156                     {
1157                         /* remove listening connection */
1158                         bta_ag_remove_sco(p_scb, FALSE);
1159                     }
1160                     else
1161                         p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1162                     break;
1163 
1164                 case BTA_AG_SCO_CONN_CLOSE_E:
1165                     /* peer closed sco; create sco listen connection */
1166                     bta_ag_create_sco(p_scb, FALSE);
1167                     p_sco->state = BTA_AG_SCO_LISTEN_ST;
1168                     break;
1169 
1170                 default:
1171                     APPL_TRACE_WARNING("BTA_AG_SCO_CLOSING_ST: Ignoring event %d", event);
1172                     break;
1173             }
1174             break;
1175 
1176         case BTA_AG_SCO_CLOSE_OP_ST:
1177             switch (event)
1178             {
1179                 case BTA_AG_SCO_CLOSE_E:
1180                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
1181                     break;
1182 
1183                 case BTA_AG_SCO_SHUTDOWN_E:
1184                     p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1185                     break;
1186 
1187                 case BTA_AG_SCO_CONN_CLOSE_E:
1188 #if (BTM_WBS_INCLUDED == TRUE )
1189                     /* start codec negotiation */
1190                     p_sco->state = BTA_AG_SCO_CODEC_ST;
1191                     p_cn_scb = p_scb;
1192 #else
1193                     /* open sco connection */
1194                     bta_ag_create_sco(p_scb, TRUE);
1195                     p_sco->state = BTA_AG_SCO_OPENING_ST;
1196 #endif
1197                     break;
1198 
1199                 case BTA_AG_SCO_LISTEN_E:
1200                     /* create sco listen connection (Additional channel) */
1201                     if (p_scb != p_sco->p_curr_scb)
1202                     {
1203                         bta_ag_create_sco(p_scb, FALSE);
1204                     }
1205                     break;
1206 
1207                 default:
1208                     APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %d", event);
1209                     break;
1210             }
1211             break;
1212 
1213         case BTA_AG_SCO_CLOSE_XFER_ST:
1214             switch (event)
1215             {
1216                 case BTA_AG_SCO_CONN_OPEN_E:
1217                     /* close sco connection so headset can be transferred
1218                        Probably entered this state from "opening state" */
1219                     bta_ag_remove_sco(p_scb, TRUE);
1220                     break;
1221 
1222                 case BTA_AG_SCO_CLOSE_E:
1223                     /* clear xfer scb */
1224                     p_sco->p_xfer_scb = NULL;
1225                     p_sco->state = BTA_AG_SCO_CLOSING_ST;
1226                     break;
1227 
1228                 case BTA_AG_SCO_SHUTDOWN_E:
1229                     /* clear xfer scb */
1230                     p_sco->p_xfer_scb = NULL;
1231                     p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1232                     break;
1233 
1234                 case BTA_AG_SCO_CONN_CLOSE_E:
1235                     /* closed sco; place old sco in listen mode,
1236                        take current sco out of listen, and
1237                        create originating sco for current */
1238                     bta_ag_create_sco(p_scb, FALSE);
1239                     bta_ag_remove_sco(p_sco->p_xfer_scb, FALSE);
1240 
1241 #if (BTM_WBS_INCLUDED == TRUE)
1242                     /* start codec negotiation */
1243                     p_sco->state = BTA_AG_SCO_CODEC_ST;
1244                     p_cn_scb = p_sco->p_xfer_scb;
1245                     p_sco->p_xfer_scb = NULL;
1246 #else
1247                     /* create sco connection to peer */
1248                     bta_ag_create_sco(p_sco->p_xfer_scb, TRUE);
1249                     p_sco->p_xfer_scb = NULL;
1250                     p_sco->state = BTA_AG_SCO_OPENING_ST;
1251 #endif
1252                     break;
1253 
1254                 default:
1255                     APPL_TRACE_WARNING("BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %d", event);
1256                     break;
1257             }
1258             break;
1259 
1260         case BTA_AG_SCO_SHUTTING_ST:
1261             switch (event)
1262             {
1263                 case BTA_AG_SCO_CONN_OPEN_E:
1264                     /* close sco connection; wait for conn close event */
1265                     bta_ag_remove_sco(p_scb, TRUE);
1266                     break;
1267 
1268                 case BTA_AG_SCO_CONN_CLOSE_E:
1269                     /* If last SCO instance then finish shutting down */
1270                     if (!bta_ag_other_scb_open(p_scb))
1271                     {
1272                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
1273                     }
1274                     else    /* Other instance is still listening */
1275                     {
1276                         p_sco->state = BTA_AG_SCO_LISTEN_ST;
1277                     }
1278 
1279                     /* If SCO closed for other HS which is not being disconnected,
1280                        then create listen sco connection for it as scb still open */
1281                     if (bta_ag_scb_open(p_scb))
1282                     {
1283                         bta_ag_create_sco(p_scb, FALSE);
1284                         p_sco->state = BTA_AG_SCO_LISTEN_ST;
1285                     }
1286 
1287                     if (p_scb == p_sco->p_curr_scb)
1288                     {
1289                         p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1290                         p_sco->p_curr_scb = NULL;
1291                     }
1292                     break;
1293 
1294                 case BTA_AG_SCO_LISTEN_E:
1295                     /* create sco listen connection (Additional channel) */
1296                     if (p_scb != p_sco->p_curr_scb)
1297                     {
1298                         bta_ag_create_sco(p_scb, FALSE);
1299                     }
1300                     break;
1301 
1302                 case BTA_AG_SCO_SHUTDOWN_E:
1303                     if (!bta_ag_other_scb_open(p_scb))
1304                     {
1305                         p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
1306                     }
1307                     else    /* Other instance is still listening */
1308                     {
1309                         p_sco->state = BTA_AG_SCO_LISTEN_ST;
1310                     }
1311 
1312                     if (p_scb == p_sco->p_curr_scb)
1313                     {
1314                         p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1315                         p_sco->p_curr_scb = NULL;
1316                     }
1317                     break;
1318 
1319                 default:
1320                     APPL_TRACE_WARNING("BTA_AG_SCO_SHUTTING_ST: Ignoring event %d", event);
1321                     break;
1322             }
1323             break;
1324 
1325         default:
1326             break;
1327     }
1328 
1329     if (p_sco->state != in_state)
1330     {
1331         APPL_TRACE_EVENT("BTA AG SCO State Change: [%s] -> [%s] after Event [%s]",
1332                       bta_ag_sco_state_str(in_state),
1333                       bta_ag_sco_state_str(p_sco->state),
1334                       bta_ag_sco_evt_str(event));
1335     }
1336 
1337 #if (BTM_WBS_INCLUDED == TRUE)
1338     if (p_cn_scb)
1339     {
1340         bta_ag_codec_negotiate(p_cn_scb);
1341     }
1342 #endif
1343 }
1344 
1345 /*******************************************************************************
1346 **
1347 ** Function         bta_ag_sco_is_open
1348 **
1349 ** Description      Check if sco is open for this scb.
1350 **
1351 **
1352 ** Returns          TRUE if sco open for this scb, FALSE otherwise.
1353 **
1354 *******************************************************************************/
bta_ag_sco_is_open(tBTA_AG_SCB * p_scb)1355 BOOLEAN bta_ag_sco_is_open(tBTA_AG_SCB *p_scb)
1356 {
1357     return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) &&
1358             (bta_ag_cb.sco.p_curr_scb == p_scb));
1359 }
1360 
1361 /*******************************************************************************
1362 **
1363 ** Function         bta_ag_sco_is_opening
1364 **
1365 ** Description      Check if sco is in Opening state.
1366 **
1367 **
1368 ** Returns          TRUE if sco is in Opening state for this scb, FALSE otherwise.
1369 **
1370 *******************************************************************************/
bta_ag_sco_is_opening(tBTA_AG_SCB * p_scb)1371 BOOLEAN bta_ag_sco_is_opening(tBTA_AG_SCB *p_scb)
1372 {
1373 #if (BTM_WBS_INCLUDED == TRUE )
1374     return (((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) ||
1375             (bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST)) &&
1376             (bta_ag_cb.sco.p_curr_scb == p_scb));
1377 #else
1378     return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
1379             (bta_ag_cb.sco.p_curr_scb == p_scb));
1380 #endif
1381 }
1382 
1383 /*******************************************************************************
1384 **
1385 ** Function         bta_ag_sco_listen
1386 **
1387 ** Description
1388 **
1389 **
1390 ** Returns          void
1391 **
1392 *******************************************************************************/
bta_ag_sco_listen(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1393 void bta_ag_sco_listen(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1394 {
1395     UNUSED(p_data);
1396     bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E);
1397 }
1398 
1399 /*******************************************************************************
1400 **
1401 ** Function         bta_ag_sco_open
1402 **
1403 ** Description
1404 **
1405 **
1406 ** Returns          void
1407 **
1408 *******************************************************************************/
bta_ag_sco_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1409 void bta_ag_sco_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1410 {
1411     UINT8 event;
1412     UNUSED(p_data);
1413 
1414     /* if another scb using sco, this is a transfer */
1415     if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb)
1416     {
1417         event = BTA_AG_SCO_XFER_E;
1418     }
1419     /* else it is an open */
1420     else
1421     {
1422         event = BTA_AG_SCO_OPEN_E;
1423     }
1424 
1425     bta_ag_sco_event(p_scb, event);
1426 }
1427 
1428 /*******************************************************************************
1429 **
1430 ** Function         bta_ag_sco_close
1431 **
1432 ** Description
1433 **
1434 **
1435 ** Returns          void
1436 **
1437 *******************************************************************************/
bta_ag_sco_close(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1438 void bta_ag_sco_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1439 {
1440     UNUSED(p_data);
1441 
1442     /* if scb is in use */
1443 #if (BTM_WBS_INCLUDED == TRUE )
1444     /* sco_idx is not allocated in SCO_CODEC_ST, we still need to move to listening state. */
1445     if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) || (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST))
1446 #else
1447     if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX)
1448 #endif
1449     {
1450         APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
1451         bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
1452     }
1453 }
1454 
1455 #if (BTM_WBS_INCLUDED == TRUE )
1456 
1457 /*******************************************************************************
1458 **
1459 ** Function         bta_ag_sco_codec_nego
1460 **
1461 ** Description
1462 **
1463 **
1464 ** Returns          void
1465 **
1466 *******************************************************************************/
bta_ag_sco_codec_nego(tBTA_AG_SCB * p_scb,BOOLEAN result)1467 void bta_ag_sco_codec_nego(tBTA_AG_SCB *p_scb, BOOLEAN result)
1468 {
1469     if(result == TRUE)
1470     {
1471         /* Subsequent sco connection will skip codec negotiation */
1472         p_scb->codec_updated = FALSE;
1473 
1474         bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E);
1475     }
1476     else    /* codec negotiation failed */
1477         bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
1478 }
1479 #endif
1480 
1481 /*******************************************************************************
1482 **
1483 ** Function         bta_ag_pkt_stat_nums
1484 **
1485 ** Description      Get the number of packet states
1486 **
1487 **
1488 ** Returns          void
1489 **
1490 *******************************************************************************/
bta_ag_pkt_stat_nums(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1491 void bta_ag_pkt_stat_nums(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1492 {
1493     UNUSED(p_scb);
1494 
1495 #if (BTM_SCO_HCI_INCLUDED == TRUE)
1496     tBTA_AG_PKT_STAT_NUMS pkt_stat_nums;
1497     uint16_t sync_conn_handle = p_data->pkt_stat.sync_conn_handle;
1498     BTM_PktStatNumsGet(sync_conn_handle, (tBTM_SCO_PKT_STAT_NUMS *) &pkt_stat_nums);
1499 
1500     /* call app cback */
1501     if (bta_ag_cb.p_cback) {
1502         (*bta_ag_cb.p_cback)(BTA_AG_PKT_NUMS_GET_EVT, (tBTA_AG*) &pkt_stat_nums);
1503     }
1504 #endif
1505 }
1506 
1507 /*******************************************************************************
1508 **
1509 ** Function         bta_ag_sco_shutdown
1510 **
1511 ** Description
1512 **
1513 **
1514 ** Returns          void
1515 **
1516 *******************************************************************************/
bta_ag_sco_shutdown(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1517 void bta_ag_sco_shutdown(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1518 {
1519     UNUSED(p_data);
1520 
1521     bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
1522 }
1523 
1524 /*******************************************************************************
1525 **
1526 ** Function         bta_ag_sco_conn_open
1527 **
1528 ** Description
1529 **
1530 **
1531 ** Returns          void
1532 **
1533 *******************************************************************************/
bta_ag_sco_conn_open(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1534 void bta_ag_sco_conn_open(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1535 {
1536     UNUSED(p_data);
1537 
1538     bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E);
1539 
1540     bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1541 
1542 #if (BTM_SCO_HCI_INCLUDED == TRUE)
1543 
1544 #if (BTM_WBS_INCLUDED == TRUE)
1545     bta_ag_sco_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, SCO_STATE_ON, p_scb->inuse_codec);
1546 #else
1547     bta_ag_sco_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, SCO_STATE_ON);
1548 #endif
1549     /* open SCO codec if SCO is routed through transport */
1550     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);
1551 #endif
1552 
1553 #if (BTM_WBS_INCLUDED == TRUE)
1554     /* call app callback */
1555     if (p_scb->sco_codec == BTA_AG_CODEC_MSBC) {
1556         bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_MSBC_OPEN_EVT);
1557     } else {
1558         bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
1559     }
1560 #else
1561     bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
1562 #endif
1563     p_scb->retry_with_sco_only = FALSE;
1564 #if (BTM_WBS_INCLUDED == TRUE)
1565     /* reset to mSBC T2 settings as the preferred */
1566     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
1567 #endif
1568 }
1569 
1570 /*******************************************************************************
1571 **
1572 ** Function         bta_ag_sco_conn_close
1573 **
1574 ** Description      This function is called when a SCO connection is closed
1575 **
1576 **
1577 ** Returns          void
1578 **
1579 *******************************************************************************/
bta_ag_sco_conn_close(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1580 void bta_ag_sco_conn_close(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1581 {
1582 #if (BTM_SCO_HCI_INCLUDED == TRUE)
1583     UINT16 handle = bta_ag_scb_to_idx(p_scb);
1584 #endif
1585     UNUSED(p_data);
1586 
1587     /* clear current scb */
1588     bta_ag_cb.sco.p_curr_scb = NULL;
1589     p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1590 
1591 #if (BTM_WBS_INCLUDED == TRUE)
1592     /* codec_fallback is set when AG is initiator and connection failed for mSBC. */
1593     /* OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
1594     if ((p_scb->codec_fallback && p_scb->svc_conn) ||
1595          bta_ag_attempt_msbc_safe_settings(p_scb))
1596     {
1597         bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
1598     }
1599     else if (p_scb->retry_with_sco_only && p_scb->svc_conn)
1600     {
1601         /* retry_with_sco_only is set when AG is initiator and connection failed for eSCO */
1602         bta_ag_create_sco(p_scb, TRUE);
1603     }
1604 #else
1605     /* retry_with_sco_only, will be set only when AG is initiator
1606     ** and AG is first trying to establish an eSCO connection */
1607     if (p_scb->retry_with_sco_only && p_scb->svc_conn)
1608     {
1609         bta_ag_create_sco(p_scb, TRUE);
1610     }
1611 #endif
1612     else
1613     {
1614 #if (BTM_SCO_HCI_INCLUDED == TRUE)
1615         sco_state_t sco_state = bta_ag_cb.sco.p_xfer_scb ? SCO_STATE_OFF_TRANSFER : SCO_STATE_OFF;
1616 #if (BTM_WBS_INCLUDED == TRUE)
1617         /* Indicate if the closing of audio is because of transfer */
1618         bta_ag_sco_audio_state(handle, p_scb->app_id, sco_state, p_scb->inuse_codec);
1619 #else
1620         /* Indicate if the closing of audio is because of transfer */
1621         bta_ag_sco_audio_state(handle, p_scb->app_id, sco_state);
1622 #endif
1623 #endif
1624         bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
1625 
1626         bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1627 
1628         /* if av got suspended by this call, let it resume. */
1629         /* In case call stays alive regardless of sco, av should not be affected. */
1630         if(((p_scb->call_ind == BTA_AG_CALL_INACTIVE) && (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE))
1631             || (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END))
1632         {
1633             bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1634         }
1635 
1636         /* call app callback */
1637         bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
1638 #if (BTM_WBS_INCLUDED == TRUE)
1639         p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
1640 #endif
1641     }
1642     p_scb->retry_with_sco_only = FALSE;
1643 }
1644 
1645 /*******************************************************************************
1646 **
1647 ** Function         bta_ag_sco_conn_rsp
1648 **
1649 ** Description      Process the SCO connection request
1650 **
1651 **
1652 ** Returns          void
1653 **
1654 *******************************************************************************/
bta_ag_sco_conn_rsp(tBTA_AG_SCB * p_scb,tBTM_ESCO_CONN_REQ_EVT_DATA * p_data)1655 void bta_ag_sco_conn_rsp(tBTA_AG_SCB *p_scb, tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
1656 {
1657     tBTM_ESCO_PARAMS    resp;
1658     UINT8               hci_status = HCI_SUCCESS;
1659 #if (BTM_SCO_HCI_INCLUDED == TRUE)
1660     tBTA_HFP_CODEC_INFO codec_info = {BTA_HFP_SCO_CODEC_PCM};
1661     UINT32              pcm_sample_rate;
1662 #endif
1663 
1664     if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST     ||
1665         bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
1666         bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST)
1667     {
1668         /* If script overrided sco parameter by BTA_CMD_SET_ESCO_PARAM */
1669         if (bta_ag_cb.sco.param_updated)
1670         {
1671             resp = bta_ag_cb.sco.params;
1672         }
1673         else
1674         {
1675             resp.rx_bw = BTM_64KBITS_RATE;
1676             resp.tx_bw = BTM_64KBITS_RATE;
1677             resp.max_latency = 10;
1678             resp.voice_contfmt = 0x60;
1679             resp.retrans_effort = BTM_ESCO_RETRANS_POWER;
1680 
1681             if (p_data->link_type == BTM_LINK_TYPE_SCO)
1682             {
1683                 resp.retrans_effort = BTM_ESCO_RETRANS_OFF;
1684                 resp.packet_types = (BTM_SCO_PKT_TYPES_MASK_HV1      |
1685                                      BTM_SCO_PKT_TYPES_MASK_HV3      |
1686                                      BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 |
1687                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
1688                                      BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
1689                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
1690             }
1691             else    /* Allow controller to use all types available except 5-slot EDR */
1692             {
1693                 if ((p_scb->features & BTA_AG_FEAT_ESCO_S4) &&
1694                         (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4))
1695                 {
1696                     resp.max_latency = 12;
1697                     resp.retrans_effort = BTM_ESCO_RETRANS_QUALITY;
1698                 }
1699 
1700                 resp.packet_types = (BTM_SCO_PKT_TYPES_MASK_EV3      |
1701                                      BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
1702                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
1703                                      BTM_SCO_PKT_TYPES_MASK_NO_3_EV5);
1704             }
1705         }
1706 
1707         /* tell sys to stop av if any */
1708         bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1709 
1710 #if (BTM_SCO_HCI_INCLUDED == TRUE)
1711 #if (BTM_WBS_INCLUDED == TRUE)
1712         /* When HS initiated SCO, it cannot be WBS. */
1713         /* Allow any platform specific pre-SCO set up to take place */
1714         bta_ag_sco_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, SCO_STATE_SETUP, BTA_AG_CODEC_CVSD);
1715 #else
1716         /* Allow any platform specific pre-SCO set up to take place */
1717         bta_ag_sco_audio_state(bta_ag_scb_to_idx(p_scb), p_scb->app_id, SCO_STATE_SETUP);
1718 #endif
1719         pcm_sample_rate = BTA_HFP_SCO_SAMP_RATE_8K;
1720         /* initialize SCO setup, no voice setting for AG, data rate <==> sample rate */
1721         BTM_ConfigScoPath(bta_ag_sco_co_init(pcm_sample_rate, pcm_sample_rate, &codec_info, p_scb->app_id),
1722                                             bta_ag_sco_read_cback, NULL, TRUE);
1723 #endif
1724     }
1725     else
1726         hci_status = HCI_ERR_HOST_REJECT_DEVICE;
1727 
1728 #if (BTM_WBS_INCLUDED == TRUE)
1729     /* If SCO open was initiated from HS, it must be CVSD */
1730     p_scb->inuse_codec = BTA_AG_CODEC_NONE;
1731 #endif
1732     BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp);
1733 }
1734 
1735 /*******************************************************************************
1736 **
1737 ** Function         bta_ag_ci_sco_data
1738 **
1739 ** Description      Process the SCO data ready callin event
1740 **
1741 **
1742 ** Returns          void
1743 **
1744 *******************************************************************************/
bta_ag_ci_sco_data(tBTA_AG_SCB * p_scb,tBTA_AG_DATA * p_data)1745 void bta_ag_ci_sco_data(tBTA_AG_SCB *p_scb, tBTA_AG_DATA *p_data)
1746 {
1747     UNUSED(p_scb);
1748     UNUSED(p_data);
1749 
1750 #if (BTM_SCO_HCI_INCLUDED == TRUE )
1751     bta_ag_sco_event(p_scb, BTA_AG_SCO_CI_DATA_E);
1752 #endif
1753 }
1754 
1755 /*******************************************************************************
1756 **
1757 ** Function         bta_ag_set_esco_param
1758 **
1759 ** Description      Update esco parameters from script wrapper.
1760 **
1761 **
1762 ** Returns          void
1763 **
1764 *******************************************************************************/
bta_ag_set_esco_param(BOOLEAN set_reset,tBTM_ESCO_PARAMS * param)1765 void bta_ag_set_esco_param(BOOLEAN set_reset, tBTM_ESCO_PARAMS *param)
1766 {
1767     if(set_reset == FALSE)    /* reset the parameters to default */
1768     {
1769         bta_ag_cb.sco.param_updated = FALSE;
1770         APPL_TRACE_DEBUG("bta_ag_set_esco_param : Resetting ESCO parameters to default");
1771     }
1772     else
1773     {
1774         bta_ag_cb.sco.param_updated = TRUE;
1775         bta_ag_cb.sco.params = *param;
1776         APPL_TRACE_DEBUG("bta_ag_set_esco_param : Setting ESCO parameters");
1777     }
1778 }
1779 
1780 /*******************************************************************************
1781 **  Debugging functions
1782 *******************************************************************************/
bta_ag_sco_evt_str(UINT8 event)1783 static char *bta_ag_sco_evt_str(UINT8 event)
1784 {
1785     switch (event)
1786     {
1787     case BTA_AG_SCO_LISTEN_E:
1788         return "Listen Request";
1789     case BTA_AG_SCO_OPEN_E:
1790         return "Open Request";
1791     case BTA_AG_SCO_XFER_E:
1792         return "Transfer Request";
1793 #if (BTM_WBS_INCLUDED == TRUE )
1794     case BTA_AG_SCO_CN_DONE_E:
1795         return "Codec Negotiation Done";
1796     case BTA_AG_SCO_REOPEN_E:
1797         return "Reopen Request";
1798 #endif
1799     case BTA_AG_SCO_CLOSE_E:
1800         return "Close Request";
1801     case BTA_AG_SCO_SHUTDOWN_E:
1802         return "Shutdown Request";
1803     case BTA_AG_SCO_CONN_OPEN_E:
1804         return "Opened";
1805     case BTA_AG_SCO_CONN_CLOSE_E:
1806         return "Closed";
1807     case BTA_AG_SCO_CI_DATA_E  :
1808         return "Sco Data";
1809     default:
1810         return "Unknown SCO Event";
1811     }
1812 }
1813 
bta_ag_sco_state_str(UINT8 state)1814 static char *bta_ag_sco_state_str(UINT8 state)
1815 {
1816     switch (state)
1817     {
1818         case BTA_AG_SCO_SHUTDOWN_ST:
1819             return "Shutdown";
1820         case BTA_AG_SCO_LISTEN_ST:
1821             return "Listening";
1822 #if (BTM_WBS_INCLUDED == TRUE )
1823         case BTA_AG_SCO_CODEC_ST:
1824             return "Codec Negotiation";
1825 #endif
1826         case BTA_AG_SCO_OPENING_ST:
1827             return "Opening";
1828         case BTA_AG_SCO_OPEN_CL_ST:
1829             return "Open while closing";
1830         case BTA_AG_SCO_OPEN_XFER_ST:
1831             return "Opening while Transferring";
1832         case BTA_AG_SCO_OPEN_ST:
1833             return "Open";
1834         case BTA_AG_SCO_CLOSING_ST:
1835             return "Closing";
1836         case BTA_AG_SCO_CLOSE_OP_ST:
1837             return "Close while Opening";
1838         case BTA_AG_SCO_CLOSE_XFER_ST:
1839             return "Close while Transferring";
1840         case BTA_AG_SCO_SHUTTING_ST:
1841             return "Shutting Down";
1842         default:
1843             return "Unknown SCO State";
1844     }
1845 }
1846 
1847 #endif //#if (BTA_AG_INCLUDED == TRUE)
1848