1 /******************************************************************************
2 *
3 * Copyright 2004-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains functions for managing the SCO connection used in AG.
22 *
23 ******************************************************************************/
24
25 #include <cstddef>
26
27 #include "bt_common.h"
28 #include "bta_ag_api.h"
29 #include "bta_ag_int.h"
30 #include "bta_api.h"
31 #include "btm_api.h"
32 #include "device/include/controller.h"
33 #include "device/include/esco_parameters.h"
34 #include "osi/include/osi.h"
35 #include "stack/include/btu.h"
36 #include "utl.h"
37
38 /* Codec negotiation timeout */
39 #ifndef BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS
40 #define BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS (3 * 1000) /* 3 seconds */
41 #endif
42
43 static bool sco_allowed = true;
44 static RawAddress active_device_addr = {};
45
46 /* sco events */
47 enum {
48 BTA_AG_SCO_LISTEN_E, /* listen request */
49 BTA_AG_SCO_OPEN_E, /* open request */
50 BTA_AG_SCO_XFER_E, /* transfer request */
51 BTA_AG_SCO_CN_DONE_E, /* codec negotiation done */
52 BTA_AG_SCO_REOPEN_E, /* Retry with other codec when failed */
53 BTA_AG_SCO_CLOSE_E, /* close request */
54 BTA_AG_SCO_SHUTDOWN_E, /* shutdown request */
55 BTA_AG_SCO_CONN_OPEN_E, /* sco open */
56 BTA_AG_SCO_CONN_CLOSE_E, /* sco closed */
57 };
58
59 #define CASE_RETURN_STR(const) \
60 case const: \
61 return #const;
62
bta_ag_sco_evt_str(uint8_t event)63 static const char* bta_ag_sco_evt_str(uint8_t event) {
64 switch (event) {
65 CASE_RETURN_STR(BTA_AG_SCO_LISTEN_E)
66 CASE_RETURN_STR(BTA_AG_SCO_OPEN_E)
67 CASE_RETURN_STR(BTA_AG_SCO_XFER_E)
68 CASE_RETURN_STR(BTA_AG_SCO_CN_DONE_E)
69 CASE_RETURN_STR(BTA_AG_SCO_REOPEN_E)
70 CASE_RETURN_STR(BTA_AG_SCO_CLOSE_E)
71 CASE_RETURN_STR(BTA_AG_SCO_SHUTDOWN_E)
72 CASE_RETURN_STR(BTA_AG_SCO_CONN_OPEN_E)
73 CASE_RETURN_STR(BTA_AG_SCO_CONN_CLOSE_E)
74 default:
75 return "Unknown SCO Event";
76 }
77 }
78
bta_ag_sco_state_str(uint8_t state)79 static const char* bta_ag_sco_state_str(uint8_t state) {
80 switch (state) {
81 CASE_RETURN_STR(BTA_AG_SCO_SHUTDOWN_ST)
82 CASE_RETURN_STR(BTA_AG_SCO_LISTEN_ST)
83 CASE_RETURN_STR(BTA_AG_SCO_CODEC_ST)
84 CASE_RETURN_STR(BTA_AG_SCO_OPENING_ST)
85 CASE_RETURN_STR(BTA_AG_SCO_OPEN_CL_ST)
86 CASE_RETURN_STR(BTA_AG_SCO_OPEN_XFER_ST)
87 CASE_RETURN_STR(BTA_AG_SCO_OPEN_ST)
88 CASE_RETURN_STR(BTA_AG_SCO_CLOSING_ST)
89 CASE_RETURN_STR(BTA_AG_SCO_CLOSE_OP_ST)
90 CASE_RETURN_STR(BTA_AG_SCO_CLOSE_XFER_ST)
91 CASE_RETURN_STR(BTA_AG_SCO_SHUTTING_ST)
92 default:
93 return "Unknown SCO State";
94 }
95 }
96
97 /**
98 * Check if bd_addr is the current active device.
99 *
100 * @param bd_addr target device address
101 * @return True if bd_addr is the current active device, False otherwise or if
102 * no active device is set (i.e. active_device_addr is empty)
103 */
bta_ag_sco_is_active_device(const RawAddress & bd_addr)104 bool bta_ag_sco_is_active_device(const RawAddress& bd_addr) {
105 return !active_device_addr.IsEmpty() && active_device_addr == bd_addr;
106 }
107
108 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local);
109
110 /*******************************************************************************
111 *
112 * Function bta_ag_sco_conn_cback
113 *
114 * Description BTM SCO connection callback.
115 *
116 *
117 * Returns void
118 *
119 ******************************************************************************/
bta_ag_sco_conn_cback(uint16_t sco_idx)120 static void bta_ag_sco_conn_cback(uint16_t sco_idx) {
121 uint16_t handle;
122 tBTA_AG_SCB* p_scb;
123
124 /* match callback to scb; first check current sco scb */
125 if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) {
126 handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
127 }
128 /* then check for scb connected to this peer */
129 else {
130 /* Check if SLC is up */
131 handle = bta_ag_idx_by_bdaddr(BTM_ReadScoBdAddr(sco_idx));
132 p_scb = bta_ag_scb_by_idx(handle);
133 if (p_scb && !p_scb->svc_conn) handle = 0;
134 }
135
136 if (handle != 0) {
137 do_in_main_thread(FROM_HERE,
138 base::Bind(&bta_ag_sm_execute_by_handle, handle,
139 BTA_AG_SCO_OPEN_EVT, tBTA_AG_DATA::kEmpty));
140 } else {
141 /* no match found; disconnect sco, init sco variables */
142 bta_ag_cb.sco.p_curr_scb = nullptr;
143 bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
144 BTM_RemoveSco(sco_idx);
145 }
146 }
147
148 /*******************************************************************************
149 *
150 * Function bta_ag_sco_disc_cback
151 *
152 * Description BTM SCO disconnection callback.
153 *
154 *
155 * Returns void
156 *
157 ******************************************************************************/
bta_ag_sco_disc_cback(uint16_t sco_idx)158 static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
159 uint16_t handle = 0;
160
161 APPL_TRACE_DEBUG(
162 "bta_ag_sco_disc_cback(): sco_idx: 0x%x p_cur_scb: 0x%08x sco.state: "
163 "%d",
164 sco_idx, bta_ag_cb.sco.p_curr_scb, bta_ag_cb.sco.state);
165
166 APPL_TRACE_DEBUG(
167 "bta_ag_sco_disc_cback(): scb[0] addr: 0x%08x in_use: %u sco_idx: 0x%x "
168 " sco state: %u",
169 &bta_ag_cb.scb[0], bta_ag_cb.scb[0].in_use, bta_ag_cb.scb[0].sco_idx,
170 bta_ag_cb.scb[0].state);
171 APPL_TRACE_DEBUG(
172 "bta_ag_sco_disc_cback(): scb[1] addr: 0x%08x in_use: %u sco_idx: 0x%x "
173 " sco state: %u",
174 &bta_ag_cb.scb[1], bta_ag_cb.scb[1].in_use, bta_ag_cb.scb[1].sco_idx,
175 bta_ag_cb.scb[1].state);
176
177 /* match callback to scb */
178 if (bta_ag_cb.sco.p_curr_scb != nullptr && bta_ag_cb.sco.p_curr_scb->in_use) {
179 /* We only care about callbacks for the active SCO */
180 if (bta_ag_cb.sco.p_curr_scb->sco_idx != sco_idx) {
181 if (bta_ag_cb.sco.p_curr_scb->sco_idx != 0xFFFF) return;
182 }
183 handle = bta_ag_scb_to_idx(bta_ag_cb.sco.p_curr_scb);
184 }
185
186 if (handle != 0) {
187
188 /* Restore settings */
189 if (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTA_AG_CODEC_MSBC) {
190 /* Bypass vendor specific and voice settings if enhanced eSCO supported */
191 if (!(controller_get_interface()
192 ->supports_enhanced_setup_synchronous_connection())) {
193 BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
194 }
195
196 /* If SCO open was initiated by AG and failed for mSBC T2, try mSBC T1
197 * 'Safe setting' first. If T1 also fails, try CVSD */
198 if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
199 bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST;
200 if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings ==
201 BTA_AG_SCO_MSBC_SETTINGS_T2) {
202 APPL_TRACE_WARNING(
203 "%s: eSCO/SCO failed to open, falling back to mSBC T1 settings",
204 __func__);
205 bta_ag_cb.sco.p_curr_scb->codec_msbc_settings =
206 BTA_AG_SCO_MSBC_SETTINGS_T1;
207 } else {
208 APPL_TRACE_WARNING(
209 "%s: eSCO/SCO failed to open, falling back to CVSD", __func__);
210 bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
211 }
212 }
213 } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
214 APPL_TRACE_ERROR("%s: eSCO/SCO failed to open, no more fall back",
215 __func__);
216 }
217
218 bta_ag_cb.sco.p_curr_scb->inuse_codec = BTA_AG_CODEC_NONE;
219
220 do_in_main_thread(FROM_HERE,
221 base::Bind(&bta_ag_sm_execute_by_handle, handle,
222 BTA_AG_SCO_CLOSE_EVT, tBTA_AG_DATA::kEmpty));
223 } else {
224 /* no match found */
225 APPL_TRACE_DEBUG("no scb for ag_sco_disc_cback");
226
227 /* sco could be closed after scb dealloc'ed */
228 if (bta_ag_cb.sco.p_curr_scb != nullptr) {
229 bta_ag_cb.sco.p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
230 bta_ag_cb.sco.p_curr_scb = nullptr;
231 bta_ag_cb.sco.state = BTA_AG_SCO_SHUTDOWN_ST;
232 }
233 }
234 }
235
236 /*******************************************************************************
237 *
238 * Function bta_ag_remove_sco
239 *
240 * Description Removes the specified SCO from the system.
241 * If only_active is true, then SCO is only removed if
242 * connected
243 *
244 * Returns bool - true if SCO removal was started
245 *
246 ******************************************************************************/
bta_ag_remove_sco(tBTA_AG_SCB * p_scb,bool only_active)247 static bool bta_ag_remove_sco(tBTA_AG_SCB* p_scb, bool only_active) {
248 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
249 if (!only_active || p_scb->sco_idx == bta_ag_cb.sco.cur_idx) {
250 tBTM_STATUS status = BTM_RemoveSco(p_scb->sco_idx);
251 APPL_TRACE_DEBUG("%s: SCO index 0x%04x, status %d", __func__,
252 p_scb->sco_idx, status);
253 if (status == BTM_CMD_STARTED) {
254 /* SCO is connected; set current control block */
255 bta_ag_cb.sco.p_curr_scb = p_scb;
256 return true;
257 } else if ((status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR)) {
258 /* If no connection reset the SCO handle */
259 p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
260 }
261 }
262 }
263 return false;
264 }
265
266 /*******************************************************************************
267 *
268 * Function bta_ag_esco_connreq_cback
269 *
270 * Description BTM eSCO connection requests and eSCO change requests
271 * Only the connection requests are processed by BTA.
272 *
273 * Returns void
274 *
275 ******************************************************************************/
bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event,tBTM_ESCO_EVT_DATA * p_data)276 static void bta_ag_esco_connreq_cback(tBTM_ESCO_EVT event,
277 tBTM_ESCO_EVT_DATA* p_data) {
278 /* Only process connection requests */
279 if (event == BTM_ESCO_CONN_REQ_EVT) {
280 uint16_t sco_inx = p_data->conn_evt.sco_inx;
281 const RawAddress* remote_bda = BTM_ReadScoBdAddr(sco_inx);
282 tBTA_AG_SCB* p_scb = bta_ag_scb_by_idx(bta_ag_idx_by_bdaddr(remote_bda));
283 if (remote_bda && bta_ag_sco_is_active_device(*remote_bda) && p_scb &&
284 p_scb->svc_conn) {
285 p_scb->sco_idx = sco_inx;
286
287 /* If no other SCO active, allow this one */
288 if (!bta_ag_cb.sco.p_curr_scb) {
289 APPL_TRACE_EVENT("%s: Accept Conn Request (sco_inx 0x%04x)", __func__,
290 sco_inx);
291 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
292
293 bta_ag_cb.sco.state = BTA_AG_SCO_OPENING_ST;
294 bta_ag_cb.sco.p_curr_scb = p_scb;
295 bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
296 } else {
297 /* Begin a transfer: Close current SCO before responding */
298 APPL_TRACE_DEBUG("bta_ag_esco_connreq_cback: Begin XFER");
299 bta_ag_cb.sco.p_xfer_scb = p_scb;
300 bta_ag_cb.sco.conn_data = p_data->conn_evt;
301 bta_ag_cb.sco.state = BTA_AG_SCO_OPEN_XFER_ST;
302
303 if (!bta_ag_remove_sco(bta_ag_cb.sco.p_curr_scb, true)) {
304 APPL_TRACE_ERROR(
305 "%s: Nothing to remove,so accept Conn Request(sco_inx 0x%04x)",
306 __func__, sco_inx);
307 bta_ag_cb.sco.p_xfer_scb = nullptr;
308 bta_ag_cb.sco.state = BTA_AG_SCO_LISTEN_ST;
309
310 bta_ag_sco_conn_rsp(p_scb, &p_data->conn_evt);
311 }
312 }
313 } else {
314 LOG(WARNING) << __func__
315 << ": reject incoming SCO connection, remote_bda="
316 << (remote_bda ? *remote_bda : RawAddress::kEmpty)
317 << ", active_bda=" << active_device_addr << ", current_bda="
318 << (p_scb ? p_scb->peer_addr : RawAddress::kEmpty);
319 BTM_EScoConnRsp(p_data->conn_evt.sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
320 (enh_esco_params_t*)nullptr);
321 }
322 } else if (event == BTM_ESCO_CHG_EVT) {
323 /* Received a change in the esco link */
324 APPL_TRACE_EVENT(
325 "%s: eSCO change event (inx %d): rtrans %d, "
326 "rxlen %d, txlen %d, txint %d",
327 __func__, p_data->chg_evt.sco_inx, p_data->chg_evt.retrans_window,
328 p_data->chg_evt.rx_pkt_len, p_data->chg_evt.tx_pkt_len,
329 p_data->chg_evt.tx_interval);
330 }
331 }
332
333 /*******************************************************************************
334 *
335 * Function bta_ag_cback_sco
336 *
337 * Description Call application callback function with SCO event.
338 *
339 *
340 * Returns void
341 *
342 ******************************************************************************/
bta_ag_cback_sco(tBTA_AG_SCB * p_scb,uint8_t event)343 static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, uint8_t event) {
344 tBTA_AG_HDR sco = {};
345 sco.handle = bta_ag_scb_to_idx(p_scb);
346 sco.app_id = p_scb->app_id;
347 /* call close cback */
348 (*bta_ag_cb.p_cback)(event, (tBTA_AG*)&sco);
349 }
350
351 /*******************************************************************************
352 *
353 * Function bta_ag_create_sco
354 *
355 * Description Create a SCO connection for a given control block
356 * p_scb : Pointer to the target AG control block
357 * is_orig : Whether to initiate or listen for SCO connection
358 *
359 * Returns void
360 *
361 ******************************************************************************/
bta_ag_create_sco(tBTA_AG_SCB * p_scb,bool is_orig)362 static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
363 APPL_TRACE_DEBUG(
364 "%s: BEFORE codec_updated=%d, codec_fallback=%d, "
365 "sco_codec=%d, peer_codec=%d, msbc_settings=%d, device=%s",
366 __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec,
367 p_scb->peer_codecs, p_scb->codec_msbc_settings,
368 p_scb->peer_addr.ToString().c_str());
369 tBTA_AG_PEER_CODEC esco_codec = BTA_AG_CODEC_CVSD;
370
371 if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
372 LOG(WARNING) << __func__ << ": device " << p_scb->peer_addr
373 << " is not active, active_device=" << active_device_addr;
374 if (bta_ag_cb.sco.p_curr_scb != nullptr &&
375 bta_ag_cb.sco.p_curr_scb->in_use && p_scb == bta_ag_cb.sco.p_curr_scb) {
376 do_in_main_thread(
377 FROM_HERE, base::Bind(&bta_ag_sm_execute, p_scb, BTA_AG_SCO_CLOSE_EVT,
378 tBTA_AG_DATA::kEmpty));
379 }
380 return;
381 }
382 /* Make sure this SCO handle is not already in use */
383 if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
384 APPL_TRACE_ERROR("%s: device %s, index 0x%04x already in use!", __func__,
385 p_scb->peer_addr.ToString().c_str(), p_scb->sco_idx);
386 return;
387 }
388
389 #if (DISABLE_WBS == FALSE)
390 if ((p_scb->sco_codec == BTA_AG_CODEC_MSBC) && !p_scb->codec_fallback)
391 esco_codec = BTA_AG_CODEC_MSBC;
392 #endif
393
394 if (p_scb->codec_fallback) {
395 p_scb->codec_fallback = false;
396 /* Force AG to send +BCS for the next audio connection. */
397 p_scb->codec_updated = true;
398 /* Reset mSBC settings to T2 for the next audio connection */
399 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
400 }
401
402 esco_codec_t codec_index = ESCO_CODEC_CVSD;
403 /* If WBS included, use CVSD by default, index is 0 for CVSD by
404 * initialization. If eSCO codec is mSBC, index is T2 or T1 */
405 if (esco_codec == BTA_AG_CODEC_MSBC) {
406 if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
407 codec_index = ESCO_CODEC_MSBC_T2;
408 } else {
409 codec_index = ESCO_CODEC_MSBC_T1;
410 }
411 }
412
413 /* Initialize eSCO parameters */
414 enh_esco_params_t params = esco_parameters_for_codec(codec_index);
415 /* For CVSD */
416 if (esco_codec == BTM_SCO_CODEC_CVSD) {
417 /* Use the applicable packet types
418 (3-EV3 not allowed due to errata 2363) */
419 params.packet_types =
420 p_bta_ag_cfg->sco_pkt_types | ESCO_PKT_TYPES_MASK_NO_3_EV3;
421 if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) ||
422 (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) {
423 params.max_latency_ms = 10;
424 params.retransmission_effort = ESCO_RETRANSMISSION_POWER;
425 }
426 }
427
428 /* If initiating, setup parameters to start SCO/eSCO connection */
429 if (is_orig) {
430 bta_ag_cb.sco.is_local = true;
431 /* Set eSCO Mode */
432 BTM_SetEScoMode(¶ms);
433 bta_ag_cb.sco.p_curr_scb = p_scb;
434 /* save the current codec as sco_codec can be updated while SCO is open. */
435 p_scb->inuse_codec = esco_codec;
436
437 /* tell sys to stop av if any */
438 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
439
440 /* Send pending commands to create SCO connection to peer */
441 bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
442 APPL_TRACE_API("%s: orig %d, inx 0x%04x, pkt types 0x%04x", __func__,
443 is_orig, p_scb->sco_idx, params.packet_types);
444 } else {
445 /* Not initiating, go to listen mode */
446 tBTM_STATUS status = BTM_CreateSco(
447 &p_scb->peer_addr, false, params.packet_types, &p_scb->sco_idx,
448 bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
449 if (status == BTM_CMD_STARTED) {
450 BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
451 }
452
453 APPL_TRACE_API("%s: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
454 __func__, is_orig, p_scb->sco_idx, status,
455 params.packet_types);
456 }
457 APPL_TRACE_DEBUG(
458 "%s: AFTER codec_updated=%d, codec_fallback=%d, "
459 "sco_codec=%d, peer_codec=%d, msbc_settings=%d, device=%s",
460 __func__, p_scb->codec_updated, p_scb->codec_fallback, p_scb->sco_codec,
461 p_scb->peer_codecs, p_scb->codec_msbc_settings,
462 p_scb->peer_addr.ToString().c_str());
463 }
464
465 /*******************************************************************************
466 *
467 * Function bta_ag_create_pending_sco
468 *
469 * Description This Function is called after the pre-SCO vendor setup is
470 * done for the BTA to continue and send the HCI Commands for
471 * creating/accepting SCO connection with peer based on the
472 * is_local parameter.
473 *
474 * Returns void
475 *
476 ******************************************************************************/
bta_ag_create_pending_sco(tBTA_AG_SCB * p_scb,bool is_local)477 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
478 tBTA_AG_PEER_CODEC esco_codec = p_scb->inuse_codec;
479 enh_esco_params_t params = {};
480 bta_ag_cb.sco.p_curr_scb = p_scb;
481 bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
482
483 /* Local device requested SCO connection to peer */
484 if (is_local) {
485 if (esco_codec == BTA_AG_CODEC_MSBC) {
486 if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
487 params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
488 } else
489 params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
490 } else {
491 params = esco_parameters_for_codec(ESCO_CODEC_CVSD);
492 if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) ||
493 (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) {
494 params.max_latency_ms = 10;
495 params.retransmission_effort = ESCO_RETRANSMISSION_POWER;
496 }
497 }
498
499 /* Bypass voice settings if enhanced SCO setup command is supported */
500 if (!(controller_get_interface()
501 ->supports_enhanced_setup_synchronous_connection())) {
502 if (esco_codec == BTA_AG_CODEC_MSBC) {
503 BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS);
504 } else {
505 BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
506 }
507 }
508
509 if (BTM_CreateSco(&p_scb->peer_addr, true, params.packet_types,
510 &p_scb->sco_idx, bta_ag_sco_conn_cback,
511 bta_ag_sco_disc_cback) == BTM_CMD_STARTED) {
512 /* Initiating the connection, set the current sco handle */
513 bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
514 }
515 APPL_TRACE_DEBUG("%s: initiated SCO connection", __func__);
516 } else {
517 /* Local device accepted SCO connection from peer */
518 params = esco_parameters_for_codec(ESCO_CODEC_CVSD);
519 if ((!(p_scb->features & BTA_AG_FEAT_ESCO)) ||
520 (!(p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO))) {
521 params.max_latency_ms = 10;
522 params.retransmission_effort = ESCO_RETRANSMISSION_POWER;
523 }
524
525 BTM_EScoConnRsp(p_scb->sco_idx, HCI_SUCCESS, ¶ms);
526 APPL_TRACE_DEBUG("%s: listening for SCO connection", __func__);
527 }
528 }
529
530 /*******************************************************************************
531 *
532 * Function bta_ag_codec_negotiation_timer_cback
533 *
534 * Description
535 *
536 *
537 * Returns void
538 *
539 ******************************************************************************/
bta_ag_codec_negotiation_timer_cback(void * data)540 static void bta_ag_codec_negotiation_timer_cback(void* data) {
541 APPL_TRACE_DEBUG("%s", __func__);
542 tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data;
543
544 /* Announce that codec negotiation failed. */
545 bta_ag_sco_codec_nego(p_scb, false);
546
547 /* call app callback */
548 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
549 }
550
551 /*******************************************************************************
552 *
553 * Function bta_ag_codec_negotiate
554 *
555 * Description Initiate codec negotiation by sending AT command.
556 * If not necessary, skip negotiation.
557 *
558 * Returns void
559 *
560 ******************************************************************************/
bta_ag_codec_negotiate(tBTA_AG_SCB * p_scb)561 void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
562 APPL_TRACE_DEBUG("%s", __func__);
563 bta_ag_cb.sco.p_curr_scb = p_scb;
564 uint8_t* p_rem_feat = BTM_ReadRemoteFeatures(p_scb->peer_addr);
565 bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
566
567 if (p_rem_feat == nullptr) {
568 LOG(WARNING) << __func__
569 << ": Fail to read remote feature, skip codec negotiation";
570 bta_ag_sco_codec_nego(p_scb, false);
571 return;
572 }
573
574 // Workaround for misbehaving HFs, which indicate which one is not support on
575 // Transparent Synchronous Data in Remote Supported Features, WBS in SDP and
576 // and Codec Negotiation in BRSF. Fluoride will assume CVSD codec by default.
577 // In Sony XAV AX100 car kit and Sony MW600 Headset case, which indicate
578 // Transparent Synchronous Data and WBS support, but no codec negotiation
579 // support, using mSBC codec can result background noise or no audio.
580 // In Skullcandy JIB case, which indicate WBS and codec negotiation support,
581 // but no Transparent Synchronous Data support, using mSBC codec can result
582 // SCO setup fail by Firmware reject.
583 if (!HCI_LMP_TRANSPNT_SUPPORTED(p_rem_feat) || !sdp_wbs_support ||
584 !(p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
585 p_scb->sco_codec = UUID_CODEC_CVSD;
586 }
587
588 if ((p_scb->codec_updated || p_scb->codec_fallback) &&
589 (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
590 /* Change the power mode to Active until SCO open is completed. */
591 bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
592
593 /* Send +BCS to the peer */
594 bta_ag_send_bcs(p_scb);
595
596 /* Start timer to handle timeout */
597 alarm_set_on_mloop(p_scb->codec_negotiation_timer,
598 BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS,
599 bta_ag_codec_negotiation_timer_cback, p_scb);
600 } else {
601 /* use same codec type as previous SCO connection, skip codec negotiation */
602 APPL_TRACE_DEBUG(
603 "use same codec type as previous SCO connection,skip codec "
604 "negotiation");
605 bta_ag_sco_codec_nego(p_scb, true);
606 }
607 }
608
609 /*******************************************************************************
610 *
611 * Function bta_ag_sco_event
612 *
613 * Description
614 *
615 *
616 * Returns void
617 *
618 ******************************************************************************/
bta_ag_sco_event(tBTA_AG_SCB * p_scb,uint8_t event)619 static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) {
620 tBTA_AG_SCO_CB* p_sco = &bta_ag_cb.sco;
621 uint8_t previous_state = p_sco->state;
622 APPL_TRACE_EVENT("%s: index=0x%04x, device=%s, state=%s[%d], event=%s[%d]",
623 __func__, p_scb->sco_idx,
624 p_scb->peer_addr.ToString().c_str(),
625 bta_ag_sco_state_str(p_sco->state), p_sco->state,
626 bta_ag_sco_evt_str(event), event);
627
628 switch (p_sco->state) {
629 case BTA_AG_SCO_SHUTDOWN_ST:
630 switch (event) {
631 case BTA_AG_SCO_LISTEN_E:
632 /* create sco listen connection */
633 bta_ag_create_sco(p_scb, false);
634 p_sco->state = BTA_AG_SCO_LISTEN_ST;
635 break;
636
637 default:
638 APPL_TRACE_WARNING(
639 "%s: BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %s[%d]", __func__,
640 bta_ag_sco_evt_str(event), event);
641 break;
642 }
643 break;
644
645 case BTA_AG_SCO_LISTEN_ST:
646 switch (event) {
647 case BTA_AG_SCO_LISTEN_E:
648 /* create sco listen connection (Additional channel) */
649 bta_ag_create_sco(p_scb, false);
650 break;
651
652 case BTA_AG_SCO_OPEN_E:
653 /* remove listening connection */
654 bta_ag_remove_sco(p_scb, false);
655
656 #if (DISABLE_WBS == FALSE)
657 /* start codec negotiation */
658 p_sco->state = BTA_AG_SCO_CODEC_ST;
659 bta_ag_codec_negotiate(p_scb);
660 #else
661 bta_ag_create_sco(p_scb, true);
662 p_sco->state = BTA_AG_SCO_OPENING_ST;
663 #endif
664 break;
665
666 case BTA_AG_SCO_SHUTDOWN_E:
667 /* remove listening connection */
668 bta_ag_remove_sco(p_scb, false);
669
670 if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
671
672 /* If last SCO instance then finish shutting down */
673 if (!bta_ag_other_scb_open(p_scb)) {
674 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
675 }
676 break;
677
678 case BTA_AG_SCO_CLOSE_E:
679 /* remove listening connection */
680 /* Ignore the event. Keep listening SCO for the active SLC
681 */
682 APPL_TRACE_WARNING("%s: BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
683 __func__, bta_ag_sco_evt_str(event), event);
684 break;
685
686 case BTA_AG_SCO_CONN_CLOSE_E:
687 /* sco failed; create sco listen connection */
688 bta_ag_create_sco(p_scb, false);
689 p_sco->state = BTA_AG_SCO_LISTEN_ST;
690 break;
691
692 default:
693 APPL_TRACE_WARNING("%s: BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
694 __func__, bta_ag_sco_evt_str(event), event);
695 break;
696 }
697 break;
698
699 case BTA_AG_SCO_CODEC_ST:
700 switch (event) {
701 case BTA_AG_SCO_LISTEN_E:
702 /* create sco listen connection (Additional channel) */
703 bta_ag_create_sco(p_scb, false);
704 break;
705
706 case BTA_AG_SCO_CN_DONE_E:
707 /* create sco connection to peer */
708 bta_ag_create_sco(p_scb, true);
709 p_sco->state = BTA_AG_SCO_OPENING_ST;
710 break;
711
712 case BTA_AG_SCO_XFER_E:
713 /* save xfer scb */
714 p_sco->p_xfer_scb = p_scb;
715 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
716 break;
717
718 case BTA_AG_SCO_SHUTDOWN_E:
719 /* remove listening connection */
720 bta_ag_remove_sco(p_scb, false);
721
722 if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
723
724 /* If last SCO instance then finish shutting down */
725 if (!bta_ag_other_scb_open(p_scb)) {
726 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
727 }
728 break;
729
730 case BTA_AG_SCO_CLOSE_E:
731 /* sco open is not started yet. just go back to listening */
732 p_sco->state = BTA_AG_SCO_LISTEN_ST;
733 break;
734
735 case BTA_AG_SCO_CONN_CLOSE_E:
736 /* sco failed; create sco listen connection */
737 bta_ag_create_sco(p_scb, false);
738 p_sco->state = BTA_AG_SCO_LISTEN_ST;
739 break;
740
741 default:
742 APPL_TRACE_WARNING("%s: BTA_AG_SCO_CODEC_ST: Ignoring event %s[%d]",
743 __func__, bta_ag_sco_evt_str(event), event);
744 break;
745 }
746 break;
747
748 case BTA_AG_SCO_OPENING_ST:
749 switch (event) {
750 case BTA_AG_SCO_LISTEN_E:
751 /* second headset has now joined */
752 /* create sco listen connection (Additional channel) */
753 if (p_scb != p_sco->p_curr_scb) {
754 bta_ag_create_sco(p_scb, false);
755 }
756 break;
757
758 #if (DISABLE_WBS == FALSE)
759 case BTA_AG_SCO_REOPEN_E:
760 /* start codec negotiation */
761 p_sco->state = BTA_AG_SCO_CODEC_ST;
762 bta_ag_codec_negotiate(p_scb);
763 break;
764 #endif
765
766 case BTA_AG_SCO_XFER_E:
767 /* save xfer scb */
768 p_sco->p_xfer_scb = p_scb;
769 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
770 break;
771
772 case BTA_AG_SCO_CLOSE_E:
773 p_sco->state = BTA_AG_SCO_OPEN_CL_ST;
774 break;
775
776 case BTA_AG_SCO_SHUTDOWN_E:
777 /* If not opening scb, just close it */
778 if (p_scb != p_sco->p_curr_scb) {
779 /* remove listening connection */
780 bta_ag_remove_sco(p_scb, false);
781 } else
782 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
783
784 break;
785
786 case BTA_AG_SCO_CONN_OPEN_E:
787 p_sco->state = BTA_AG_SCO_OPEN_ST;
788 break;
789
790 case BTA_AG_SCO_CONN_CLOSE_E:
791 /* sco failed; create sco listen connection */
792 bta_ag_create_sco(p_scb, false);
793 p_sco->state = BTA_AG_SCO_LISTEN_ST;
794 break;
795
796 default:
797 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPENING_ST: Ignoring event %s[%d]",
798 __func__, bta_ag_sco_evt_str(event), event);
799 break;
800 }
801 break;
802
803 case BTA_AG_SCO_OPEN_CL_ST:
804 switch (event) {
805 case BTA_AG_SCO_XFER_E:
806 /* save xfer scb */
807 p_sco->p_xfer_scb = p_scb;
808
809 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
810 break;
811
812 case BTA_AG_SCO_OPEN_E:
813 p_sco->state = BTA_AG_SCO_OPENING_ST;
814 break;
815
816 case BTA_AG_SCO_SHUTDOWN_E:
817 /* If not opening scb, just close it */
818 if (p_scb != p_sco->p_curr_scb) {
819 /* remove listening connection */
820 bta_ag_remove_sco(p_scb, false);
821 } else
822 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
823
824 break;
825
826 case BTA_AG_SCO_CONN_OPEN_E:
827 /* close sco connection */
828 bta_ag_remove_sco(p_scb, true);
829
830 p_sco->state = BTA_AG_SCO_CLOSING_ST;
831 break;
832
833 case BTA_AG_SCO_CONN_CLOSE_E:
834 /* sco failed; create sco listen connection */
835
836 p_sco->state = BTA_AG_SCO_LISTEN_ST;
837 break;
838
839 default:
840 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_CL_ST: Ignoring event %s[%d]",
841 __func__, bta_ag_sco_evt_str(event), event);
842 break;
843 }
844 break;
845
846 case BTA_AG_SCO_OPEN_XFER_ST:
847 switch (event) {
848 case BTA_AG_SCO_CLOSE_E:
849 /* close sco connection */
850 bta_ag_remove_sco(p_scb, true);
851
852 p_sco->state = BTA_AG_SCO_CLOSING_ST;
853 break;
854
855 case BTA_AG_SCO_SHUTDOWN_E:
856 /* remove all connection */
857 bta_ag_remove_sco(p_scb, false);
858 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
859
860 break;
861
862 case BTA_AG_SCO_CONN_CLOSE_E:
863 /* closed sco; place in listen mode and
864 accept the transferred connection */
865 bta_ag_create_sco(p_scb, false); /* Back into listen mode */
866
867 /* Accept sco connection with xfer scb */
868 bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data);
869 p_sco->state = BTA_AG_SCO_OPENING_ST;
870 p_sco->p_curr_scb = p_sco->p_xfer_scb;
871 p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx;
872 p_sco->p_xfer_scb = nullptr;
873 break;
874
875 default:
876 APPL_TRACE_WARNING(
877 "%s: BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %s[%d]", __func__,
878 bta_ag_sco_evt_str(event), event);
879 break;
880 }
881 break;
882
883 case BTA_AG_SCO_OPEN_ST:
884 switch (event) {
885 case BTA_AG_SCO_LISTEN_E:
886 /* second headset has now joined */
887 /* create sco listen connection (Additional channel) */
888 if (p_scb != p_sco->p_curr_scb) {
889 bta_ag_create_sco(p_scb, false);
890 }
891 break;
892
893 case BTA_AG_SCO_XFER_E:
894 /* close current sco connection */
895 bta_ag_remove_sco(p_sco->p_curr_scb, true);
896
897 /* save xfer scb */
898 p_sco->p_xfer_scb = p_scb;
899
900 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
901 break;
902
903 case BTA_AG_SCO_CLOSE_E:
904 /* close sco connection if active */
905 if (bta_ag_remove_sco(p_scb, true)) {
906 p_sco->state = BTA_AG_SCO_CLOSING_ST;
907 }
908 break;
909
910 case BTA_AG_SCO_SHUTDOWN_E:
911 /* remove all listening connections */
912 bta_ag_remove_sco(p_scb, false);
913
914 /* If SCO was active on this scb, close it */
915 if (p_scb == p_sco->p_curr_scb) {
916 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
917 }
918 break;
919
920 case BTA_AG_SCO_CONN_CLOSE_E:
921 /* peer closed sco; create sco listen connection */
922 bta_ag_create_sco(p_scb, false);
923 p_sco->state = BTA_AG_SCO_LISTEN_ST;
924 break;
925
926 default:
927 APPL_TRACE_WARNING("%s: BTA_AG_SCO_OPEN_ST: Ignoring event %s[%d]",
928 __func__, bta_ag_sco_evt_str(event), event);
929 break;
930 }
931 break;
932
933 case BTA_AG_SCO_CLOSING_ST:
934 switch (event) {
935 case BTA_AG_SCO_LISTEN_E:
936 /* create sco listen connection (Additional channel) */
937 if (p_scb != p_sco->p_curr_scb) {
938 bta_ag_create_sco(p_scb, false);
939 }
940 break;
941
942 case BTA_AG_SCO_OPEN_E:
943 p_sco->state = BTA_AG_SCO_CLOSE_OP_ST;
944 break;
945
946 case BTA_AG_SCO_XFER_E:
947 /* save xfer scb */
948 p_sco->p_xfer_scb = p_scb;
949
950 p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
951 break;
952
953 case BTA_AG_SCO_SHUTDOWN_E:
954 /* If not closing scb, just close it */
955 if (p_scb != p_sco->p_curr_scb) {
956 /* remove listening connection */
957 bta_ag_remove_sco(p_scb, false);
958 } else
959 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
960
961 break;
962
963 case BTA_AG_SCO_CONN_CLOSE_E:
964 /* peer closed sco; create sco listen connection */
965 bta_ag_create_sco(p_scb, false);
966
967 p_sco->state = BTA_AG_SCO_LISTEN_ST;
968 break;
969
970 default:
971 APPL_TRACE_WARNING("%s: BTA_AG_SCO_CLOSING_ST: Ignoring event %s[%d]",
972 __func__, bta_ag_sco_evt_str(event), event);
973 break;
974 }
975 break;
976
977 case BTA_AG_SCO_CLOSE_OP_ST:
978 switch (event) {
979 case BTA_AG_SCO_CLOSE_E:
980 p_sco->state = BTA_AG_SCO_CLOSING_ST;
981 break;
982
983 case BTA_AG_SCO_SHUTDOWN_E:
984 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
985 break;
986
987 case BTA_AG_SCO_CONN_CLOSE_E:
988 /* start codec negotiation */
989 p_sco->state = BTA_AG_SCO_CODEC_ST;
990 bta_ag_codec_negotiate(p_scb);
991 break;
992
993 case BTA_AG_SCO_LISTEN_E:
994 /* create sco listen connection (Additional channel) */
995 if (p_scb != p_sco->p_curr_scb) {
996 bta_ag_create_sco(p_scb, false);
997 }
998 break;
999
1000 default:
1001 APPL_TRACE_WARNING(
1002 "%s: BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %s[%d]", __func__,
1003 bta_ag_sco_evt_str(event), event);
1004 break;
1005 }
1006 break;
1007
1008 case BTA_AG_SCO_CLOSE_XFER_ST:
1009 switch (event) {
1010 case BTA_AG_SCO_CONN_OPEN_E:
1011 /* close sco connection so headset can be transferred
1012 Probably entered this state from "opening state" */
1013 bta_ag_remove_sco(p_scb, true);
1014 break;
1015
1016 case BTA_AG_SCO_CLOSE_E:
1017 /* clear xfer scb */
1018 p_sco->p_xfer_scb = nullptr;
1019
1020 p_sco->state = BTA_AG_SCO_CLOSING_ST;
1021 break;
1022
1023 case BTA_AG_SCO_SHUTDOWN_E:
1024 /* clear xfer scb */
1025 p_sco->p_xfer_scb = nullptr;
1026
1027 p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1028 break;
1029
1030 case BTA_AG_SCO_CONN_CLOSE_E: {
1031 /* closed sco; place old sco in listen mode,
1032 take current sco out of listen, and
1033 create originating sco for current */
1034 bta_ag_create_sco(p_scb, false);
1035 bta_ag_remove_sco(p_sco->p_xfer_scb, false);
1036
1037 #if (DISABLE_WBS == FALSE)
1038 /* start codec negotiation */
1039 p_sco->state = BTA_AG_SCO_CODEC_ST;
1040 tBTA_AG_SCB* p_cn_scb = p_sco->p_xfer_scb;
1041 p_sco->p_xfer_scb = nullptr;
1042 bta_ag_codec_negotiate(p_cn_scb);
1043 #else
1044 /* create sco connection to peer */
1045 bta_ag_create_sco(p_sco->p_xfer_scb, true);
1046 p_sco->p_xfer_scb = nullptr;
1047 p_sco->state = BTA_AG_SCO_OPENING_ST;
1048 #endif
1049 break;
1050 }
1051
1052 default:
1053 APPL_TRACE_WARNING(
1054 "%s: BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %s[%d]", __func__,
1055 bta_ag_sco_evt_str(event), event);
1056 break;
1057 }
1058 break;
1059
1060 case BTA_AG_SCO_SHUTTING_ST:
1061 switch (event) {
1062 case BTA_AG_SCO_CONN_OPEN_E:
1063 /* close sco connection; wait for conn close event */
1064 bta_ag_remove_sco(p_scb, true);
1065 break;
1066
1067 case BTA_AG_SCO_CONN_CLOSE_E:
1068 /* If last SCO instance then finish shutting down */
1069 if (!bta_ag_other_scb_open(p_scb)) {
1070 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
1071 } else /* Other instance is still listening */
1072 {
1073 p_sco->state = BTA_AG_SCO_LISTEN_ST;
1074 }
1075
1076 /* If SCO closed for other HS which is not being disconnected,
1077 then create listen sco connection for it as scb still open */
1078 if (bta_ag_scb_open(p_scb)) {
1079 bta_ag_create_sco(p_scb, false);
1080 p_sco->state = BTA_AG_SCO_LISTEN_ST;
1081 }
1082
1083 if (p_scb == p_sco->p_curr_scb) {
1084 p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1085 p_sco->p_curr_scb = nullptr;
1086 }
1087 break;
1088
1089 case BTA_AG_SCO_LISTEN_E:
1090 /* create sco listen connection (Additional channel) */
1091 if (p_scb != p_sco->p_curr_scb) {
1092 bta_ag_create_sco(p_scb, false);
1093 }
1094 break;
1095
1096 case BTA_AG_SCO_SHUTDOWN_E:
1097 if (!bta_ag_other_scb_open(p_scb)) {
1098 p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
1099 } else /* Other instance is still listening */
1100 {
1101 p_sco->state = BTA_AG_SCO_LISTEN_ST;
1102 }
1103
1104 if (p_scb == p_sco->p_curr_scb) {
1105 p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1106 p_sco->p_curr_scb = nullptr;
1107 }
1108 break;
1109
1110 default:
1111 APPL_TRACE_WARNING(
1112 "%s: BTA_AG_SCO_SHUTTING_ST: Ignoring event %s[%d]", __func__,
1113 bta_ag_sco_evt_str(event), event);
1114 break;
1115 }
1116 break;
1117
1118 default:
1119 break;
1120 }
1121 if (p_sco->state != previous_state) {
1122 APPL_TRACE_EVENT(
1123 "%s: SCO_state_change: [%s(0x%02x)]->[%s(0x%02x)] "
1124 "after event [%s(0x%02x)]",
1125 __func__, bta_ag_sco_state_str(previous_state), previous_state,
1126 bta_ag_sco_state_str(p_sco->state), p_sco->state,
1127 bta_ag_sco_evt_str(event), event);
1128 }
1129 }
1130
1131 /*******************************************************************************
1132 *
1133 * Function bta_ag_sco_is_open
1134 *
1135 * Description Check if sco is open for this scb.
1136 *
1137 *
1138 * Returns true if sco open for this scb, false otherwise.
1139 *
1140 ******************************************************************************/
bta_ag_sco_is_open(tBTA_AG_SCB * p_scb)1141 bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb) {
1142 return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) &&
1143 (bta_ag_cb.sco.p_curr_scb == p_scb));
1144 }
1145
1146 /*******************************************************************************
1147 *
1148 * Function bta_ag_sco_is_opening
1149 *
1150 * Description Check if sco is in Opening state.
1151 *
1152 *
1153 * Returns true if sco is in Opening state for this scb, false
1154 * otherwise.
1155 *
1156 ******************************************************************************/
bta_ag_sco_is_opening(tBTA_AG_SCB * p_scb)1157 bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb) {
1158 return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
1159 (bta_ag_cb.sco.p_curr_scb == p_scb));
1160 }
1161
1162 /*******************************************************************************
1163 *
1164 * Function bta_ag_sco_listen
1165 *
1166 * Description
1167 *
1168 *
1169 * Returns void
1170 *
1171 ******************************************************************************/
bta_ag_sco_listen(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1172 void bta_ag_sco_listen(tBTA_AG_SCB* p_scb,
1173 UNUSED_ATTR const tBTA_AG_DATA& data) {
1174 LOG(INFO) << __func__ << ": " << p_scb->peer_addr;
1175 bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E);
1176 }
1177
1178 /*******************************************************************************
1179 *
1180 * Function bta_ag_sco_open
1181 *
1182 * Description
1183 *
1184 *
1185 * Returns void
1186 *
1187 ******************************************************************************/
bta_ag_sco_open(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1188 void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
1189 if (!sco_allowed) {
1190 LOG(INFO) << __func__ << ": not opening sco, by policy";
1191 return;
1192 }
1193 /* if another scb using sco, this is a transfer */
1194 if (bta_ag_cb.sco.p_curr_scb && bta_ag_cb.sco.p_curr_scb != p_scb) {
1195 LOG(INFO) << __func__ << ": tranfer " << bta_ag_cb.sco.p_curr_scb->peer_addr
1196 << " -> " << p_scb->peer_addr;
1197 bta_ag_sco_event(p_scb, BTA_AG_SCO_XFER_E);
1198 } else {
1199 /* else it is an open */
1200 LOG(INFO) << __func__ << ": open " << p_scb->peer_addr;
1201 bta_ag_sco_event(p_scb, BTA_AG_SCO_OPEN_E);
1202 }
1203 }
1204
1205 /*******************************************************************************
1206 *
1207 * Function bta_ag_sco_close
1208 *
1209 * Description
1210 *
1211 *
1212 * Returns void
1213 *
1214 ******************************************************************************/
bta_ag_sco_close(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1215 void bta_ag_sco_close(tBTA_AG_SCB* p_scb,
1216 UNUSED_ATTR const tBTA_AG_DATA& data) {
1217 /* if scb is in use */
1218 /* sco_idx is not allocated in SCO_CODEC_ST, still need to move to listen
1219 * state. */
1220 if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) ||
1221 (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) {
1222 APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
1223 bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
1224 }
1225 }
1226
1227 /*******************************************************************************
1228 *
1229 * Function bta_ag_sco_codec_nego
1230 *
1231 * Description Handles result of eSCO codec negotiation
1232 *
1233 *
1234 * Returns void
1235 *
1236 ******************************************************************************/
bta_ag_sco_codec_nego(tBTA_AG_SCB * p_scb,bool result)1237 void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result) {
1238 if (result) {
1239 /* Subsequent SCO connection will skip codec negotiation */
1240 APPL_TRACE_DEBUG("%s: Succeeded for index 0x%04x, device %s", __func__,
1241 p_scb->sco_idx, p_scb->peer_addr.ToString().c_str());
1242 p_scb->codec_updated = false;
1243 bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E);
1244 } else {
1245 /* codec negotiation failed */
1246 APPL_TRACE_ERROR("%s: Failed for index 0x%04x, device %s", __func__,
1247 p_scb->sco_idx, p_scb->peer_addr.ToString().c_str());
1248 bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
1249 }
1250 }
1251
1252 /*******************************************************************************
1253 *
1254 * Function bta_ag_sco_shutdown
1255 *
1256 * Description
1257 *
1258 *
1259 * Returns void
1260 *
1261 ******************************************************************************/
bta_ag_sco_shutdown(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1262 void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb,
1263 UNUSED_ATTR const tBTA_AG_DATA& data) {
1264 bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
1265 }
1266
1267 /*******************************************************************************
1268 *
1269 * Function bta_ag_sco_conn_open
1270 *
1271 * Description
1272 *
1273 *
1274 * Returns void
1275 *
1276 ******************************************************************************/
bta_ag_sco_conn_open(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1277 void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb,
1278 UNUSED_ATTR const tBTA_AG_DATA& data) {
1279 bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E);
1280
1281 bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1282
1283 /* call app callback */
1284 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
1285
1286 /* reset to mSBC T2 settings as the preferred */
1287 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
1288 }
1289
1290 /*******************************************************************************
1291 *
1292 * Function bta_ag_sco_conn_close
1293 *
1294 * Description
1295 *
1296 *
1297 * Returns void
1298 *
1299 ******************************************************************************/
bta_ag_sco_conn_close(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1300 void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
1301 UNUSED_ATTR const tBTA_AG_DATA& data) {
1302 /* clear current scb */
1303 bta_ag_cb.sco.p_curr_scb = nullptr;
1304 p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1305
1306 /* codec_fallback is set when AG is initiator and connection failed for mSBC.
1307 * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
1308 if (p_scb->svc_conn &&
1309 (p_scb->codec_fallback ||
1310 (p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
1311 p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) {
1312 bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
1313 } else {
1314 /* Indicate if the closing of audio is because of transfer */
1315 bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
1316
1317 bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1318
1319 /* if av got suspended by this call, let it resume. */
1320 /* In case call stays alive regardless of sco, av should not be affected. */
1321 if (((p_scb->call_ind == BTA_AG_CALL_INACTIVE) &&
1322 (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) ||
1323 (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)) {
1324 bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1325 }
1326
1327 /* call app callback */
1328 bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
1329 p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
1330 }
1331 }
1332
1333 /*******************************************************************************
1334 *
1335 * Function bta_ag_sco_conn_rsp
1336 *
1337 * Description Process the SCO connection request
1338 *
1339 *
1340 * Returns void
1341 *
1342 ******************************************************************************/
bta_ag_sco_conn_rsp(tBTA_AG_SCB * p_scb,tBTM_ESCO_CONN_REQ_EVT_DATA * p_data)1343 void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb,
1344 tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) {
1345 bta_ag_cb.sco.is_local = false;
1346
1347 APPL_TRACE_DEBUG("%s: eSCO %d, state %d", __func__,
1348 controller_get_interface()
1349 ->supports_enhanced_setup_synchronous_connection(),
1350 bta_ag_cb.sco.state);
1351
1352 if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST ||
1353 bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
1354 bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) {
1355 /* tell sys to stop av if any */
1356 bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1357 /* When HS initiated SCO, it cannot be WBS. */
1358 }
1359
1360 /* If SCO open was initiated from HS, it must be CVSD */
1361 p_scb->inuse_codec = BTA_AG_CODEC_NONE;
1362 /* Send pending commands to create SCO connection to peer */
1363 bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
1364 }
1365
bta_ag_set_sco_allowed(bool value)1366 void bta_ag_set_sco_allowed(bool value) {
1367 sco_allowed = value;
1368 APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
1369 }
1370
bta_ag_get_active_device()1371 const RawAddress& bta_ag_get_active_device() { return active_device_addr; }
1372
bta_clear_active_device()1373 void bta_clear_active_device() { active_device_addr = RawAddress::kEmpty; }
1374
bta_ag_api_set_active_device(const RawAddress & new_active_device)1375 void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
1376 if (new_active_device.IsEmpty()) {
1377 APPL_TRACE_ERROR("%s: empty device", __func__);
1378 return;
1379 }
1380 active_device_addr = new_active_device;
1381 }
1382