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