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