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, ¶ms);
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, ¶ms);
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