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