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