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