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