• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params);
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(&params);
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, &params);
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