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 <cstdint>
27 
28 #include "bt_target.h"  // Must be first to define build configuration
29 #include "bt_trace.h"   // Legacy trace logging
30 
31 #include "bta/ag/bta_ag_int.h"
32 #include "device/include/controller.h"
33 #include "device/include/esco_parameters.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 == BTA_AG_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 = BTA_AG_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   } else if (event == BTM_ESCO_CHG_EVT) {
322     /* Received a change in the esco link */
323     APPL_TRACE_EVENT(
324         "%s: eSCO change event (inx %d): rtrans %d, "
325         "rxlen %d, txlen %d, txint %d",
326         __func__, p_data->chg_evt.sco_inx, p_data->chg_evt.retrans_window,
327         p_data->chg_evt.rx_pkt_len, p_data->chg_evt.tx_pkt_len,
328         p_data->chg_evt.tx_interval);
329   }
330 }
331 
332 /*******************************************************************************
333  *
334  * Function         bta_ag_cback_sco
335  *
336  * Description      Call application callback function with SCO event.
337  *
338  *
339  * Returns          void
340  *
341  ******************************************************************************/
bta_ag_cback_sco(tBTA_AG_SCB * p_scb,tBTA_AG_EVT event)342 static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, tBTA_AG_EVT event) {
343   tBTA_AG_HDR sco = {};
344   sco.handle = bta_ag_scb_to_idx(p_scb);
345   sco.app_id = p_scb->app_id;
346   /* call close cback */
347   (*bta_ag_cb.p_cback)(static_cast<tBTA_AG_EVT>(event), (tBTA_AG*)&sco);
348 }
349 
350 /*******************************************************************************
351  *
352  * Function         bta_ag_create_sco
353  *
354  * Description      Create a SCO connection for a given control block
355  *                  p_scb : Pointer to the target AG control block
356  *                  is_orig : Whether to initiate or listen for SCO connection
357  *
358  * Returns          void
359  *
360  ******************************************************************************/
bta_ag_create_sco(tBTA_AG_SCB * p_scb,bool is_orig)361 static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
362   LOG_DEBUG("BEFORE %s", p_scb->ToString().c_str());
363   tBTA_AG_PEER_CODEC esco_codec = BTA_AG_CODEC_CVSD;
364 
365   if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
366     LOG(WARNING) << __func__ << ": device " << p_scb->peer_addr
367                  << " is not active, active_device=" << active_device_addr;
368     if (bta_ag_cb.sco.p_curr_scb != nullptr &&
369         bta_ag_cb.sco.p_curr_scb->in_use && p_scb == bta_ag_cb.sco.p_curr_scb) {
370       do_in_main_thread(
371           FROM_HERE, base::Bind(&bta_ag_sm_execute, p_scb, BTA_AG_SCO_CLOSE_EVT,
372                                 tBTA_AG_DATA::kEmpty));
373     }
374     return;
375   }
376   /* Make sure this SCO handle is not already in use */
377   if (p_scb->sco_idx != BTM_INVALID_SCO_INDEX) {
378     APPL_TRACE_ERROR("%s: device %s, index 0x%04x already in use!", __func__,
379                      p_scb->peer_addr.ToString().c_str(), p_scb->sco_idx);
380     return;
381   }
382 
383 #if (DISABLE_WBS == FALSE)
384   if ((p_scb->sco_codec == BTA_AG_CODEC_MSBC) && !p_scb->codec_fallback)
385     esco_codec = BTA_AG_CODEC_MSBC;
386 #endif
387 
388   if (p_scb->codec_fallback) {
389     p_scb->codec_fallback = false;
390     /* Force AG to send +BCS for the next audio connection. */
391     p_scb->codec_updated = true;
392     /* Reset mSBC settings to T2 for the next audio connection */
393     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
394   }
395 
396   /* Initialize eSCO parameters */
397   enh_esco_params_t params = {};
398   /* If WBS included, use CVSD by default, index is 0 for CVSD by
399    * initialization. If eSCO codec is mSBC, index is T2 or T1 */
400   if (esco_codec == BTA_AG_CODEC_MSBC) {
401     if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
402       params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
403     } else {
404       params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
405     }
406   } else {
407     if (p_scb->features & BTA_AG_PEER_FEAT_ESCO_S4 &&
408         (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
409       // HFP >=1.7 eSCO
410       params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
411     } else {
412       // HFP <=1.6 eSCO
413       params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
414     }
415   }
416 
417   /* If initiating, setup parameters to start SCO/eSCO connection */
418   if (is_orig) {
419     bta_ag_cb.sco.is_local = true;
420     /* Set eSCO Mode */
421     BTM_SetEScoMode(&params);
422     bta_ag_cb.sco.p_curr_scb = p_scb;
423     /* save the current codec as sco_codec can be updated while SCO is open. */
424     p_scb->inuse_codec = esco_codec;
425 
426     /* tell sys to stop av if any */
427     bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
428 
429     /* Send pending commands to create SCO connection to peer */
430     bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
431     LOG_DEBUG("Initiating AG SCO inx 0x%04x, pkt types 0x%04x", p_scb->sco_idx,
432               params.packet_types);
433   } else {
434     /* Not initiating, go to listen mode */
435     tBTM_STATUS btm_status = BTM_CreateSco(
436         &p_scb->peer_addr, false, params.packet_types, &p_scb->sco_idx,
437         bta_ag_sco_conn_cback, bta_ag_sco_disc_cback);
438     if (btm_status == BTM_CMD_STARTED) {
439       BTM_RegForEScoEvts(p_scb->sco_idx, bta_ag_esco_connreq_cback);
440     }
441     LOG_DEBUG("Listening AG SCO inx 0x%04x status:%s pkt types 0x%04x",
442               p_scb->sco_idx, btm_status_text(btm_status).c_str(),
443               params.packet_types);
444   }
445   LOG_DEBUG("AFTER %s", p_scb->ToString().c_str());
446 }
447 
448 /*******************************************************************************
449  *
450  * Function         bta_ag_create_pending_sco
451  *
452  * Description      This Function is called after the pre-SCO vendor setup is
453  *                  done for the BTA to continue and send the HCI Commands for
454  *                  creating/accepting SCO connection with peer based on the
455  *                  is_local parameter.
456  *
457  * Returns          void
458  *
459  ******************************************************************************/
bta_ag_create_pending_sco(tBTA_AG_SCB * p_scb,bool is_local)460 static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
461   tBTA_AG_PEER_CODEC esco_codec = p_scb->inuse_codec;
462   enh_esco_params_t params = {};
463   bta_ag_cb.sco.p_curr_scb = p_scb;
464   bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
465 
466   /* Local device requested SCO connection to peer */
467   if (is_local) {
468     if (esco_codec == BTA_AG_CODEC_MSBC) {
469       if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
470         params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2);
471       } else {
472         params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1);
473       }
474     } else {
475       if (p_scb->features & BTA_AG_PEER_FEAT_ESCO_S4 &&
476           (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
477         // HFP >=1.7 eSCO
478         params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
479       } else {
480         // HFP <=1.6 eSCO
481         params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
482       }
483     }
484 
485     /* Bypass voice settings if enhanced SCO setup command is supported */
486     if (!(controller_get_interface()
487               ->supports_enhanced_setup_synchronous_connection())) {
488       if (esco_codec == BTA_AG_CODEC_MSBC) {
489         BTM_WriteVoiceSettings(BTM_VOICE_SETTING_TRANS);
490       } else {
491         BTM_WriteVoiceSettings(BTM_VOICE_SETTING_CVSD);
492       }
493     }
494 
495     if (BTM_CreateSco(&p_scb->peer_addr, true, params.packet_types,
496                       &p_scb->sco_idx, bta_ag_sco_conn_cback,
497                       bta_ag_sco_disc_cback) == BTM_CMD_STARTED) {
498       /* Initiating the connection, set the current sco handle */
499       bta_ag_cb.sco.cur_idx = p_scb->sco_idx;
500     }
501     APPL_TRACE_DEBUG("%s: initiated SCO connection", __func__);
502   } else {
503     // Local device accepted SCO connection from peer(HF)
504     // Because HF devices usually do not send AT+BAC and +BCS command,
505     // and there is no plan to implement corresponding command handlers,
506     // so we only accept CVSD connection from HF no matter what's
507     // requested.
508     if (p_scb->features & BTA_AG_PEER_FEAT_ESCO_S4 &&
509         (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
510       // HFP >=1.7 eSCO
511       params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S4);
512     } else {
513       // HFP <=1.6 eSCO
514       params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3);
515     }
516 
517     BTM_EScoConnRsp(p_scb->sco_idx, HCI_SUCCESS, &params);
518     APPL_TRACE_DEBUG("%s: listening for SCO connection", __func__);
519   }
520 }
521 
522 /*******************************************************************************
523  *
524  * Function         bta_ag_codec_negotiation_timer_cback
525  *
526  * Description
527  *
528  *
529  * Returns          void
530  *
531  ******************************************************************************/
bta_ag_codec_negotiation_timer_cback(void * data)532 static void bta_ag_codec_negotiation_timer_cback(void* data) {
533   LOG_WARN("Codec negotiation timeout");
534   tBTA_AG_SCB* p_scb = (tBTA_AG_SCB*)data;
535 
536   /* Announce that codec negotiation failed. */
537   bta_ag_sco_codec_nego(p_scb, false);
538 
539   /* call app callback */
540   bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
541 }
542 
543 /*******************************************************************************
544  *
545  * Function         bta_ag_codec_negotiate
546  *
547  * Description      Initiate codec negotiation by sending AT command.
548  *                  If not necessary, skip negotiation.
549  *
550  * Returns          void
551  *
552  ******************************************************************************/
bta_ag_codec_negotiate(tBTA_AG_SCB * p_scb)553 void bta_ag_codec_negotiate(tBTA_AG_SCB* p_scb) {
554   bta_ag_cb.sco.p_curr_scb = p_scb;
555   uint8_t* p_rem_feat = BTM_ReadRemoteFeatures(p_scb->peer_addr);
556   bool sdp_wbs_support = p_scb->peer_sdp_features & BTA_AG_FEAT_WBS_SUPPORT;
557 
558   if (p_rem_feat == nullptr) {
559     LOG_WARN("Skip codec negotiation, failed to read remote features");
560     bta_ag_sco_codec_nego(p_scb, false);
561     return;
562   }
563 
564   // Workaround for misbehaving HFs, which indicate which one is not support on
565   // Transparent Synchronous Data in Remote Supported Features, WBS in SDP and
566   // and Codec Negotiation in BRSF. Fluoride will assume CVSD codec by default.
567   // In Sony XAV AX100 car kit and Sony MW600 Headset case, which indicate
568   // Transparent Synchronous Data and WBS support, but no codec negotiation
569   // support, using mSBC codec can result background noise or no audio.
570   // In Skullcandy JIB case, which indicate WBS and codec negotiation support,
571   // but no Transparent Synchronous Data support, using mSBC codec can result
572   // SCO setup fail by Firmware reject.
573   if (!HCI_LMP_TRANSPNT_SUPPORTED(p_rem_feat) || !sdp_wbs_support ||
574       !(p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
575     LOG_INFO("Assume CVSD by default due to mask mismatch");
576     p_scb->sco_codec = UUID_CODEC_CVSD;
577   }
578 
579   if ((p_scb->codec_updated || p_scb->codec_fallback) &&
580       (p_scb->peer_features & BTA_AG_PEER_FEAT_CODEC)) {
581     LOG_INFO("Starting codec negotiation");
582     /* Change the power mode to Active until SCO open is completed. */
583     bta_sys_busy(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
584 
585     /* Send +BCS to the peer */
586     bta_ag_send_bcs(p_scb);
587 
588     /* Start timer to handle timeout */
589     alarm_set_on_mloop(p_scb->codec_negotiation_timer,
590                        BTA_AG_CODEC_NEGOTIATION_TIMEOUT_MS,
591                        bta_ag_codec_negotiation_timer_cback, p_scb);
592   } else {
593     /* use same codec type as previous SCO connection, skip codec negotiation */
594     LOG_INFO("Skip codec negotiation, using the same codec");
595     bta_ag_sco_codec_nego(p_scb, true);
596   }
597 }
598 
bta_ag_sco_event(tBTA_AG_SCB * p_scb,uint8_t event)599 static void bta_ag_sco_event(tBTA_AG_SCB* p_scb, uint8_t event) {
600   tBTA_AG_SCO_CB* p_sco = &bta_ag_cb.sco;
601   uint8_t previous_state = p_sco->state;
602   LOG_INFO("device:%s index:0x%04x state:%s[%d] event:%s[%d]",
603            PRIVATE_ADDRESS(p_scb->peer_addr), p_scb->sco_idx,
604            bta_ag_sco_state_str(p_sco->state), p_sco->state,
605            bta_ag_sco_evt_str(event), event);
606 
607   switch (p_sco->state) {
608     case BTA_AG_SCO_SHUTDOWN_ST:
609       switch (event) {
610         case BTA_AG_SCO_LISTEN_E:
611           /* create sco listen connection */
612           bta_ag_create_sco(p_scb, false);
613           p_sco->state = BTA_AG_SCO_LISTEN_ST;
614           break;
615 
616         default:
617           LOG_WARN("BTA_AG_SCO_SHUTDOWN_ST: Ignoring event %s[%d]",
618                    bta_ag_sco_evt_str(event), event);
619           break;
620       }
621       break;
622 
623     case BTA_AG_SCO_LISTEN_ST:
624       switch (event) {
625         case BTA_AG_SCO_LISTEN_E:
626           /* create sco listen connection (Additional channel) */
627           bta_ag_create_sco(p_scb, false);
628           break;
629 
630         case BTA_AG_SCO_OPEN_E:
631           /* remove listening connection */
632           bta_ag_remove_sco(p_scb, false);
633 
634 #if (DISABLE_WBS == FALSE)
635           /* start codec negotiation */
636           p_sco->state = BTA_AG_SCO_CODEC_ST;
637           bta_ag_codec_negotiate(p_scb);
638 #else
639           bta_ag_create_sco(p_scb, true);
640           p_sco->state = BTA_AG_SCO_OPENING_ST;
641 #endif
642           break;
643 
644         case BTA_AG_SCO_SHUTDOWN_E:
645           /* remove listening connection */
646           bta_ag_remove_sco(p_scb, false);
647 
648           if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
649 
650           /* If last SCO instance then finish shutting down */
651           if (!bta_ag_other_scb_open(p_scb)) {
652             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
653           }
654           break;
655 
656         case BTA_AG_SCO_CLOSE_E:
657           /* remove listening connection */
658           /* Ignore the event. Keep listening SCO for the active SLC */
659           LOG_WARN("BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
660                    bta_ag_sco_evt_str(event), event);
661           break;
662 
663         case BTA_AG_SCO_CONN_CLOSE_E:
664           /* sco failed; create sco listen connection */
665           bta_ag_create_sco(p_scb, false);
666           p_sco->state = BTA_AG_SCO_LISTEN_ST;
667           break;
668 
669         default:
670           LOG_WARN("BTA_AG_SCO_LISTEN_ST: Ignoring event %s[%d]",
671                    bta_ag_sco_evt_str(event), event);
672           break;
673       }
674       break;
675 
676     case BTA_AG_SCO_CODEC_ST:
677       switch (event) {
678         case BTA_AG_SCO_LISTEN_E:
679           /* create sco listen connection (Additional channel) */
680           bta_ag_create_sco(p_scb, false);
681           break;
682 
683         case BTA_AG_SCO_CN_DONE_E:
684           /* create sco connection to peer */
685           bta_ag_create_sco(p_scb, true);
686           p_sco->state = BTA_AG_SCO_OPENING_ST;
687           break;
688 
689         case BTA_AG_SCO_XFER_E:
690           /* save xfer scb */
691           p_sco->p_xfer_scb = p_scb;
692           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
693           break;
694 
695         case BTA_AG_SCO_SHUTDOWN_E:
696           /* remove listening connection */
697           bta_ag_remove_sco(p_scb, false);
698 
699           if (p_scb == p_sco->p_curr_scb) p_sco->p_curr_scb = nullptr;
700 
701           /* If last SCO instance then finish shutting down */
702           if (!bta_ag_other_scb_open(p_scb)) {
703             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
704           }
705           break;
706 
707         case BTA_AG_SCO_CLOSE_E:
708           /* sco open is not started yet. just go back to listening */
709           p_sco->state = BTA_AG_SCO_LISTEN_ST;
710           break;
711 
712         case BTA_AG_SCO_CONN_CLOSE_E:
713           /* sco failed; create sco listen connection */
714           bta_ag_create_sco(p_scb, false);
715           p_sco->state = BTA_AG_SCO_LISTEN_ST;
716           break;
717 
718         default:
719           LOG_WARN("BTA_AG_SCO_CODEC_ST: Ignoring event %s[%d]",
720                    bta_ag_sco_evt_str(event), event);
721           break;
722       }
723       break;
724 
725     case BTA_AG_SCO_OPENING_ST:
726       switch (event) {
727         case BTA_AG_SCO_LISTEN_E:
728           /* second headset has now joined */
729           /* create sco listen connection (Additional channel) */
730           if (p_scb != p_sco->p_curr_scb) {
731             bta_ag_create_sco(p_scb, false);
732           }
733           break;
734 
735 #if (DISABLE_WBS == FALSE)
736         case BTA_AG_SCO_REOPEN_E:
737           /* start codec negotiation */
738           p_sco->state = BTA_AG_SCO_CODEC_ST;
739           bta_ag_codec_negotiate(p_scb);
740           break;
741 #endif
742 
743         case BTA_AG_SCO_XFER_E:
744           /* save xfer scb */
745           p_sco->p_xfer_scb = p_scb;
746           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
747           break;
748 
749         case BTA_AG_SCO_CLOSE_E:
750           p_sco->state = BTA_AG_SCO_OPEN_CL_ST;
751           break;
752 
753         case BTA_AG_SCO_SHUTDOWN_E:
754           /* If not opening scb, just close it */
755           if (p_scb != p_sco->p_curr_scb) {
756             /* remove listening connection */
757             bta_ag_remove_sco(p_scb, false);
758           } else
759             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
760 
761           break;
762 
763         case BTA_AG_SCO_CONN_OPEN_E:
764           p_sco->state = BTA_AG_SCO_OPEN_ST;
765           break;
766 
767         case BTA_AG_SCO_CONN_CLOSE_E:
768           /* sco failed; create sco listen connection */
769           bta_ag_create_sco(p_scb, false);
770           p_sco->state = BTA_AG_SCO_LISTEN_ST;
771           break;
772 
773         default:
774           LOG_WARN("BTA_AG_SCO_OPENING_ST: Ignoring event %s[%d]",
775                    bta_ag_sco_evt_str(event), event);
776           break;
777       }
778       break;
779 
780     case BTA_AG_SCO_OPEN_CL_ST:
781       switch (event) {
782         case BTA_AG_SCO_XFER_E:
783           /* save xfer scb */
784           p_sco->p_xfer_scb = p_scb;
785 
786           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
787           break;
788 
789         case BTA_AG_SCO_OPEN_E:
790           p_sco->state = BTA_AG_SCO_OPENING_ST;
791           break;
792 
793         case BTA_AG_SCO_SHUTDOWN_E:
794           /* If not opening scb, just close it */
795           if (p_scb != p_sco->p_curr_scb) {
796             /* remove listening connection */
797             bta_ag_remove_sco(p_scb, false);
798           } else
799             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
800 
801           break;
802 
803         case BTA_AG_SCO_CONN_OPEN_E:
804           /* close sco connection */
805           bta_ag_remove_sco(p_scb, true);
806 
807           p_sco->state = BTA_AG_SCO_CLOSING_ST;
808           break;
809 
810         case BTA_AG_SCO_CONN_CLOSE_E:
811           /* sco failed; create sco listen connection */
812 
813           p_sco->state = BTA_AG_SCO_LISTEN_ST;
814           break;
815 
816         default:
817           LOG_WARN("BTA_AG_SCO_OPEN_CL_ST: Ignoring event %s[%d]",
818                    bta_ag_sco_evt_str(event), event);
819           break;
820       }
821       break;
822 
823     case BTA_AG_SCO_OPEN_XFER_ST:
824       switch (event) {
825         case BTA_AG_SCO_CLOSE_E:
826           /* close sco connection */
827           bta_ag_remove_sco(p_scb, true);
828 
829           p_sco->state = BTA_AG_SCO_CLOSING_ST;
830           break;
831 
832         case BTA_AG_SCO_SHUTDOWN_E:
833           /* remove all connection */
834           bta_ag_remove_sco(p_scb, false);
835           p_sco->state = BTA_AG_SCO_SHUTTING_ST;
836 
837           break;
838 
839         case BTA_AG_SCO_CONN_CLOSE_E:
840           /* closed sco; place in listen mode and
841              accept the transferred connection */
842           bta_ag_create_sco(p_scb, false); /* Back into listen mode */
843 
844           /* Accept sco connection with xfer scb */
845           bta_ag_sco_conn_rsp(p_sco->p_xfer_scb, &p_sco->conn_data);
846           p_sco->state = BTA_AG_SCO_OPENING_ST;
847           p_sco->p_curr_scb = p_sco->p_xfer_scb;
848           p_sco->cur_idx = p_sco->p_xfer_scb->sco_idx;
849           p_sco->p_xfer_scb = nullptr;
850           break;
851 
852         default:
853           LOG_WARN("BTA_AG_SCO_OPEN_XFER_ST: Ignoring event %s[%d]",
854                    bta_ag_sco_evt_str(event), event);
855           break;
856       }
857       break;
858 
859     case BTA_AG_SCO_OPEN_ST:
860       switch (event) {
861         case BTA_AG_SCO_LISTEN_E:
862           /* second headset has now joined */
863           /* create sco listen connection (Additional channel) */
864           if (p_scb != p_sco->p_curr_scb) {
865             bta_ag_create_sco(p_scb, false);
866           }
867           break;
868 
869         case BTA_AG_SCO_XFER_E:
870           /* close current sco connection */
871           bta_ag_remove_sco(p_sco->p_curr_scb, true);
872 
873           /* save xfer scb */
874           p_sco->p_xfer_scb = p_scb;
875 
876           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
877           break;
878 
879         case BTA_AG_SCO_CLOSE_E:
880           /* close sco connection if active */
881           if (bta_ag_remove_sco(p_scb, true)) {
882             p_sco->state = BTA_AG_SCO_CLOSING_ST;
883           }
884           break;
885 
886         case BTA_AG_SCO_SHUTDOWN_E:
887           /* remove all listening connections */
888           bta_ag_remove_sco(p_scb, false);
889 
890           /* If SCO was active on this scb, close it */
891           if (p_scb == p_sco->p_curr_scb) {
892             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
893           }
894           break;
895 
896         case BTA_AG_SCO_CONN_CLOSE_E:
897           /* peer closed sco; create sco listen connection */
898           bta_ag_create_sco(p_scb, false);
899           p_sco->state = BTA_AG_SCO_LISTEN_ST;
900           break;
901 
902         default:
903           LOG_WARN("BTA_AG_SCO_OPEN_ST: Ignoring event %s[%d]",
904                    bta_ag_sco_evt_str(event), event);
905           break;
906       }
907       break;
908 
909     case BTA_AG_SCO_CLOSING_ST:
910       switch (event) {
911         case BTA_AG_SCO_LISTEN_E:
912           /* create sco listen connection (Additional channel) */
913           if (p_scb != p_sco->p_curr_scb) {
914             bta_ag_create_sco(p_scb, false);
915           }
916           break;
917 
918         case BTA_AG_SCO_OPEN_E:
919           p_sco->state = BTA_AG_SCO_CLOSE_OP_ST;
920           break;
921 
922         case BTA_AG_SCO_XFER_E:
923           /* save xfer scb */
924           p_sco->p_xfer_scb = p_scb;
925 
926           p_sco->state = BTA_AG_SCO_CLOSE_XFER_ST;
927           break;
928 
929         case BTA_AG_SCO_SHUTDOWN_E:
930           /* If not closing scb, just close it */
931           if (p_scb != p_sco->p_curr_scb) {
932             /* remove listening connection */
933             bta_ag_remove_sco(p_scb, false);
934           } else
935             p_sco->state = BTA_AG_SCO_SHUTTING_ST;
936 
937           break;
938 
939         case BTA_AG_SCO_CONN_CLOSE_E:
940           /* peer closed sco; create sco listen connection */
941           bta_ag_create_sco(p_scb, false);
942 
943           p_sco->state = BTA_AG_SCO_LISTEN_ST;
944           break;
945 
946         default:
947           LOG_WARN("BTA_AG_SCO_CLOSING_ST: Ignoring event %s[%d]",
948                    bta_ag_sco_evt_str(event), event);
949           break;
950       }
951       break;
952 
953     case BTA_AG_SCO_CLOSE_OP_ST:
954       switch (event) {
955         case BTA_AG_SCO_CLOSE_E:
956           p_sco->state = BTA_AG_SCO_CLOSING_ST;
957           break;
958 
959         case BTA_AG_SCO_SHUTDOWN_E:
960           p_sco->state = BTA_AG_SCO_SHUTTING_ST;
961           break;
962 
963         case BTA_AG_SCO_CONN_CLOSE_E:
964           /* start codec negotiation */
965           p_sco->state = BTA_AG_SCO_CODEC_ST;
966           bta_ag_codec_negotiate(p_scb);
967           break;
968 
969         case BTA_AG_SCO_LISTEN_E:
970           /* create sco listen connection (Additional channel) */
971           if (p_scb != p_sco->p_curr_scb) {
972             bta_ag_create_sco(p_scb, false);
973           }
974           break;
975 
976         default:
977           LOG_WARN("BTA_AG_SCO_CLOSE_OP_ST: Ignoring event %s[%d]",
978                    bta_ag_sco_evt_str(event), event);
979           break;
980       }
981       break;
982 
983     case BTA_AG_SCO_CLOSE_XFER_ST:
984       switch (event) {
985         case BTA_AG_SCO_CONN_OPEN_E:
986           /* close sco connection so headset can be transferred
987              Probably entered this state from "opening state" */
988           bta_ag_remove_sco(p_scb, true);
989           break;
990 
991         case BTA_AG_SCO_CLOSE_E:
992           /* clear xfer scb */
993           p_sco->p_xfer_scb = nullptr;
994 
995           p_sco->state = BTA_AG_SCO_CLOSING_ST;
996           break;
997 
998         case BTA_AG_SCO_SHUTDOWN_E:
999           /* clear xfer scb */
1000           p_sco->p_xfer_scb = nullptr;
1001 
1002           p_sco->state = BTA_AG_SCO_SHUTTING_ST;
1003           break;
1004 
1005         case BTA_AG_SCO_CONN_CLOSE_E: {
1006           /* closed sco; place old sco in listen mode,
1007              take current sco out of listen, and
1008              create originating sco for current */
1009           bta_ag_create_sco(p_scb, false);
1010           bta_ag_remove_sco(p_sco->p_xfer_scb, false);
1011 
1012 #if (DISABLE_WBS == FALSE)
1013           /* start codec negotiation */
1014           p_sco->state = BTA_AG_SCO_CODEC_ST;
1015           tBTA_AG_SCB* p_cn_scb = p_sco->p_xfer_scb;
1016           p_sco->p_xfer_scb = nullptr;
1017           bta_ag_codec_negotiate(p_cn_scb);
1018 #else
1019           /* create sco connection to peer */
1020           bta_ag_create_sco(p_sco->p_xfer_scb, true);
1021           p_sco->p_xfer_scb = nullptr;
1022           p_sco->state = BTA_AG_SCO_OPENING_ST;
1023 #endif
1024           break;
1025         }
1026 
1027         default:
1028           LOG_WARN(" BTA_AG_SCO_CLOSE_XFER_ST: Ignoring event %s[%d]",
1029                    bta_ag_sco_evt_str(event), event);
1030           break;
1031       }
1032       break;
1033 
1034     case BTA_AG_SCO_SHUTTING_ST:
1035       switch (event) {
1036         case BTA_AG_SCO_CONN_OPEN_E:
1037           /* close sco connection; wait for conn close event */
1038           bta_ag_remove_sco(p_scb, true);
1039           break;
1040 
1041         case BTA_AG_SCO_CONN_CLOSE_E:
1042           /* If last SCO instance then finish shutting down */
1043           if (!bta_ag_other_scb_open(p_scb)) {
1044             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
1045           } else /* Other instance is still listening */
1046           {
1047             p_sco->state = BTA_AG_SCO_LISTEN_ST;
1048           }
1049 
1050           /* If SCO closed for other HS which is not being disconnected,
1051              then create listen sco connection for it as scb still open */
1052           if (bta_ag_scb_open(p_scb)) {
1053             bta_ag_create_sco(p_scb, false);
1054             p_sco->state = BTA_AG_SCO_LISTEN_ST;
1055           }
1056 
1057           if (p_scb == p_sco->p_curr_scb) {
1058             p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1059             p_sco->p_curr_scb = nullptr;
1060           }
1061           break;
1062 
1063         case BTA_AG_SCO_LISTEN_E:
1064           /* create sco listen connection (Additional channel) */
1065           if (p_scb != p_sco->p_curr_scb) {
1066             bta_ag_create_sco(p_scb, false);
1067           }
1068           break;
1069 
1070         case BTA_AG_SCO_SHUTDOWN_E:
1071           if (!bta_ag_other_scb_open(p_scb)) {
1072             p_sco->state = BTA_AG_SCO_SHUTDOWN_ST;
1073           } else /* Other instance is still listening */
1074           {
1075             p_sco->state = BTA_AG_SCO_LISTEN_ST;
1076           }
1077 
1078           if (p_scb == p_sco->p_curr_scb) {
1079             p_sco->p_curr_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1080             p_sco->p_curr_scb = nullptr;
1081           }
1082           break;
1083 
1084         default:
1085           LOG_WARN("BTA_AG_SCO_SHUTTING_ST: Ignoring event %s[%d]",
1086                    bta_ag_sco_evt_str(event), event);
1087           break;
1088       }
1089       break;
1090 
1091     default:
1092       break;
1093   }
1094   if (p_sco->state != previous_state) {
1095     LOG_WARN(
1096         "SCO_state_change: [%s(0x%02x)]->[%s(0x%02x)] "
1097         "after event [%s(0x%02x)]",
1098         bta_ag_sco_state_str(previous_state), previous_state,
1099         bta_ag_sco_state_str(p_sco->state), p_sco->state,
1100         bta_ag_sco_evt_str(event), event);
1101   }
1102 }
1103 
1104 /*******************************************************************************
1105  *
1106  * Function         bta_ag_sco_is_open
1107  *
1108  * Description      Check if sco is open for this scb.
1109  *
1110  *
1111  * Returns          true if sco open for this scb, false otherwise.
1112  *
1113  ******************************************************************************/
bta_ag_sco_is_open(tBTA_AG_SCB * p_scb)1114 bool bta_ag_sco_is_open(tBTA_AG_SCB* p_scb) {
1115   return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_ST) &&
1116           (bta_ag_cb.sco.p_curr_scb == p_scb));
1117 }
1118 
1119 /*******************************************************************************
1120  *
1121  * Function         bta_ag_sco_is_opening
1122  *
1123  * Description      Check if sco is in Opening state.
1124  *
1125  *
1126  * Returns          true if sco is in Opening state for this scb, false
1127  *                  otherwise.
1128  *
1129  ******************************************************************************/
bta_ag_sco_is_opening(tBTA_AG_SCB * p_scb)1130 bool bta_ag_sco_is_opening(tBTA_AG_SCB* p_scb) {
1131   return ((bta_ag_cb.sco.state == BTA_AG_SCO_OPENING_ST) &&
1132           (bta_ag_cb.sco.p_curr_scb == p_scb));
1133 }
1134 
1135 /*******************************************************************************
1136  *
1137  * Function         bta_ag_sco_listen
1138  *
1139  * Description
1140  *
1141  *
1142  * Returns          void
1143  *
1144  ******************************************************************************/
bta_ag_sco_listen(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1145 void bta_ag_sco_listen(tBTA_AG_SCB* p_scb,
1146                        UNUSED_ATTR const tBTA_AG_DATA& data) {
1147   LOG(INFO) << __func__ << ": " << p_scb->peer_addr;
1148   bta_ag_sco_event(p_scb, BTA_AG_SCO_LISTEN_E);
1149 }
1150 
1151 /*******************************************************************************
1152  *
1153  * Function         bta_ag_sco_open
1154  *
1155  * Description
1156  *
1157  *
1158  * Returns          void
1159  *
1160  ******************************************************************************/
bta_ag_sco_open(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1161 void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR const tBTA_AG_DATA& data) {
1162   if (!sco_allowed) {
1163     LOG(INFO) << __func__ << ": not opening sco, by policy";
1164     return;
1165   }
1166   /* if another scb using sco, this is a transfer */
1167   if (bta_ag_cb.sco.p_curr_scb && bta_ag_cb.sco.p_curr_scb != p_scb) {
1168     LOG(INFO) << __func__ << ": transfer "
1169               << bta_ag_cb.sco.p_curr_scb->peer_addr << " -> "
1170               << p_scb->peer_addr;
1171     bta_ag_sco_event(p_scb, BTA_AG_SCO_XFER_E);
1172   } else {
1173     /* else it is an open */
1174     LOG(INFO) << __func__ << ": open " << p_scb->peer_addr;
1175     bta_ag_sco_event(p_scb, BTA_AG_SCO_OPEN_E);
1176   }
1177 }
1178 
1179 /*******************************************************************************
1180  *
1181  * Function         bta_ag_sco_close
1182  *
1183  * Description
1184  *
1185  *
1186  * Returns          void
1187  *
1188  ******************************************************************************/
bta_ag_sco_close(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1189 void bta_ag_sco_close(tBTA_AG_SCB* p_scb,
1190                       UNUSED_ATTR const tBTA_AG_DATA& data) {
1191   /* if scb is in use */
1192   /* sco_idx is not allocated in SCO_CODEC_ST, still need to move to listen
1193    * state. */
1194   if ((p_scb->sco_idx != BTM_INVALID_SCO_INDEX) ||
1195       (bta_ag_cb.sco.state == BTA_AG_SCO_CODEC_ST)) {
1196     APPL_TRACE_DEBUG("bta_ag_sco_close: sco_inx = %d", p_scb->sco_idx);
1197     bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
1198   }
1199 }
1200 
1201 /*******************************************************************************
1202  *
1203  * Function         bta_ag_sco_codec_nego
1204  *
1205  * Description      Handles result of eSCO codec negotiation
1206  *
1207  *
1208  * Returns          void
1209  *
1210  ******************************************************************************/
bta_ag_sco_codec_nego(tBTA_AG_SCB * p_scb,bool result)1211 void bta_ag_sco_codec_nego(tBTA_AG_SCB* p_scb, bool result) {
1212   if (result) {
1213     /* Subsequent SCO connection will skip codec negotiation */
1214     LOG_INFO("Succeeded for index 0x%04x, device %s", p_scb->sco_idx,
1215              p_scb->peer_addr.ToString().c_str());
1216     p_scb->codec_updated = false;
1217     bta_ag_sco_event(p_scb, BTA_AG_SCO_CN_DONE_E);
1218   } else {
1219     /* codec negotiation failed */
1220     LOG_INFO("Failed for index 0x%04x, device %s", p_scb->sco_idx,
1221              p_scb->peer_addr.ToString().c_str());
1222     bta_ag_sco_event(p_scb, BTA_AG_SCO_CLOSE_E);
1223   }
1224 }
1225 
1226 /*******************************************************************************
1227  *
1228  * Function         bta_ag_sco_shutdown
1229  *
1230  * Description
1231  *
1232  *
1233  * Returns          void
1234  *
1235  ******************************************************************************/
bta_ag_sco_shutdown(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1236 void bta_ag_sco_shutdown(tBTA_AG_SCB* p_scb,
1237                          UNUSED_ATTR const tBTA_AG_DATA& data) {
1238   bta_ag_sco_event(p_scb, BTA_AG_SCO_SHUTDOWN_E);
1239 }
1240 
1241 /*******************************************************************************
1242  *
1243  * Function         bta_ag_sco_conn_open
1244  *
1245  * Description
1246  *
1247  *
1248  * Returns          void
1249  *
1250  ******************************************************************************/
bta_ag_sco_conn_open(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1251 void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb,
1252                           UNUSED_ATTR const tBTA_AG_DATA& data) {
1253   bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_OPEN_E);
1254 
1255   bta_sys_sco_open(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1256 
1257   /* call app callback */
1258   bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_OPEN_EVT);
1259 
1260   /* reset to mSBC T2 settings as the preferred */
1261   p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
1262 }
1263 
1264 /*******************************************************************************
1265  *
1266  * Function         bta_ag_sco_conn_close
1267  *
1268  * Description
1269  *
1270  *
1271  * Returns          void
1272  *
1273  ******************************************************************************/
bta_ag_sco_conn_close(tBTA_AG_SCB * p_scb,UNUSED_ATTR const tBTA_AG_DATA & data)1274 void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
1275                            UNUSED_ATTR const tBTA_AG_DATA& data) {
1276   /* clear current scb */
1277   bta_ag_cb.sco.p_curr_scb = nullptr;
1278   p_scb->sco_idx = BTM_INVALID_SCO_INDEX;
1279 
1280   /* codec_fallback is set when AG is initiator and connection failed for mSBC.
1281    * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
1282   if (p_scb->svc_conn &&
1283       (p_scb->codec_fallback ||
1284        (p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
1285         p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) {
1286     bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
1287   } else {
1288     /* Indicate if the closing of audio is because of transfer */
1289     bta_ag_sco_event(p_scb, BTA_AG_SCO_CONN_CLOSE_E);
1290 
1291     bta_sys_sco_close(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1292 
1293     /* if av got suspended by this call, let it resume. */
1294     /* In case call stays alive regardless of sco, av should not be affected. */
1295     if (((p_scb->call_ind == BTA_AG_CALL_INACTIVE) &&
1296          (p_scb->callsetup_ind == BTA_AG_CALLSETUP_NONE)) ||
1297         (p_scb->post_sco == BTA_AG_POST_SCO_CALL_END)) {
1298       bta_sys_sco_unuse(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1299     }
1300 
1301     /* call app callback */
1302     bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
1303     p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
1304   }
1305 }
1306 
1307 /*******************************************************************************
1308  *
1309  * Function         bta_ag_sco_conn_rsp
1310  *
1311  * Description      Process the SCO connection request
1312  *
1313  *
1314  * Returns          void
1315  *
1316  ******************************************************************************/
bta_ag_sco_conn_rsp(tBTA_AG_SCB * p_scb,tBTM_ESCO_CONN_REQ_EVT_DATA * p_data)1317 void bta_ag_sco_conn_rsp(tBTA_AG_SCB* p_scb,
1318                          tBTM_ESCO_CONN_REQ_EVT_DATA* p_data) {
1319   bta_ag_cb.sco.is_local = false;
1320 
1321   APPL_TRACE_DEBUG("%s: eSCO %d, state %d", __func__,
1322                    controller_get_interface()
1323                        ->supports_enhanced_setup_synchronous_connection(),
1324                    bta_ag_cb.sco.state);
1325 
1326   if (bta_ag_cb.sco.state == BTA_AG_SCO_LISTEN_ST ||
1327       bta_ag_cb.sco.state == BTA_AG_SCO_CLOSE_XFER_ST ||
1328       bta_ag_cb.sco.state == BTA_AG_SCO_OPEN_XFER_ST) {
1329     /* tell sys to stop av if any */
1330     bta_sys_sco_use(BTA_ID_AG, p_scb->app_id, p_scb->peer_addr);
1331     /* When HS initiated SCO, it cannot be WBS. */
1332   }
1333 
1334   /* If SCO open was initiated from HS, it must be CVSD */
1335   p_scb->inuse_codec = BTA_AG_CODEC_NONE;
1336   /* Send pending commands to create SCO connection to peer */
1337   bta_ag_create_pending_sco(p_scb, bta_ag_cb.sco.is_local);
1338 }
1339 
bta_ag_set_sco_allowed(bool value)1340 void bta_ag_set_sco_allowed(bool value) {
1341   sco_allowed = value;
1342   APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
1343 }
1344 
bta_ag_get_active_device()1345 const RawAddress& bta_ag_get_active_device() { return active_device_addr; }
1346 
bta_clear_active_device()1347 void bta_clear_active_device() { active_device_addr = RawAddress::kEmpty; }
1348 
bta_ag_api_set_active_device(const RawAddress & new_active_device)1349 void bta_ag_api_set_active_device(const RawAddress& new_active_device) {
1350   if (new_active_device.IsEmpty()) {
1351     APPL_TRACE_ERROR("%s: empty device", __func__);
1352     return;
1353   }
1354   active_device_addr = new_active_device;
1355 }
1356