Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d9dbb3d authored by Zach Johnson's avatar Zach Johnson Committed by Andre Eisenbach
Browse files

Allow blocking AG SCO connects by policy

Needed for devices that support both HFP AG and HFP HF.

btsnoop logs show the sequence of events leading to failure:
(corroborated by bt logcat)

1. ACL connection with remote phone established on handle 0x01
2. ACL connection with remote headset established on handle 0x02
3. Incoming call in HF role from phone
4. Phone call locally published to telecom
5. Answer incoming call
6. SCO connection established with phone in HF role
7. AG role with headset picks up on call state change to answered
   via BTA_AG_IN_CALL_CONN_RES
8. Inside handler for BTA_AG_IN_CALL_CONN_RES, bta_ag_sco_open called
   to establish the SCO connection in the AG role with the headset,
   stomping on the previous (wanted) SCO connection with the phone.

Fix is to publish the SCO audio route policy to fluoride, so we can
stop 8 from happening.

Bug: 32958838
Test: manual:
      received incoming call in HF role, audio worked both ways;
      recieved incoming MT call, headset audio in AG role worked both ways
Change-Id: I12961598e8200bd1d5adb46ee8ec3a802114b80a
parent b63e2798
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -276,3 +276,13 @@ void BTA_AgSetCodec(uint16_t handle, tBTA_AG_PEER_CODEC codec) {

  bta_sys_sendmsg(p_buf);
}

void BTA_AgSetScoAllowed(bool value) {
  tBTA_AG_API_SET_SCO_ALLOWED* p_buf = (tBTA_AG_API_SET_SCO_ALLOWED*)osi_malloc(
      sizeof(tBTA_AG_API_SET_SCO_ALLOWED));

  p_buf->hdr.event = BTA_AG_API_SET_SCO_ALLOWED_EVT;
  p_buf->value = value;

  bta_sys_sendmsg(p_buf);
}
+9 −1
Original line number Diff line number Diff line
@@ -99,7 +99,8 @@ enum {

  /* these events are handled outside of the state machine */
  BTA_AG_API_ENABLE_EVT,
  BTA_AG_API_DISABLE_EVT
  BTA_AG_API_DISABLE_EVT,
  BTA_AG_API_SET_SCO_ALLOWED_EVT
};

/* Actions to perform after a SCO event */
@@ -171,6 +172,12 @@ typedef struct {
  tBTA_AG_PEER_CODEC codec;
} tBTA_AG_API_SETCODEC;

/* data type for BTA_AG_API_SET_SCO_ALLOWED_EVT */
typedef struct {
  BT_HDR hdr;
  bool value;
} tBTA_AG_API_SET_SCO_ALLOWED;

/* data type for BTA_AG_DISC_RESULT_EVT */
typedef struct {
  BT_HDR hdr;
@@ -395,5 +402,6 @@ extern void bta_ag_send_ring(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
extern void bta_ag_ci_sco_data(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
extern void bta_ag_ci_rx_data(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
extern void bta_ag_rcvd_slc_ready(tBTA_AG_SCB* p_scb, tBTA_AG_DATA* p_data);
extern void bta_ag_set_sco_allowed(tBTA_AG_DATA* p_data);

#endif /* BTA_AG_INT_H */
+4 −0
Original line number Diff line number Diff line
@@ -798,6 +798,10 @@ bool bta_ag_hdl_event(BT_HDR* p_msg) {
      bta_ag_api_result((tBTA_AG_DATA*)p_msg);
      break;

    case BTA_AG_API_SET_SCO_ALLOWED_EVT:
      bta_ag_set_sco_allowed((tBTA_AG_DATA*)p_msg);
      break;

    /* all others reference scb by handle */
    default:
      p_scb = bta_ag_scb_by_idx(p_msg->layer_specific);
+12 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ static char* bta_ag_sco_evt_str(uint8_t event);
static char* bta_ag_sco_state_str(uint8_t state);
#endif

static bool sco_allowed = true;

#define BTA_AG_NO_EDR_ESCO                                       \
  (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \
   ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5)
@@ -1192,6 +1194,11 @@ void bta_ag_sco_listen(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) {
void bta_ag_sco_open(tBTA_AG_SCB* p_scb, UNUSED_ATTR tBTA_AG_DATA* p_data) {
  uint8_t event;

  if (!sco_allowed) {
    APPL_TRACE_DEBUG("%s not opening sco, by policy", __func__);
    return;
  }

  /* if another scb using sco, this is a transfer */
  if (bta_ag_cb.sco.p_curr_scb != NULL && bta_ag_cb.sco.p_curr_scb != p_scb) {
    event = BTA_AG_SCO_XFER_E;
@@ -1396,6 +1403,11 @@ void bta_ag_ci_sco_data(UNUSED_ATTR tBTA_AG_SCB* p_scb,
#endif
}

void bta_ag_set_sco_allowed(tBTA_AG_DATA* p_data) {
  sco_allowed = ((tBTA_AG_API_SET_SCO_ALLOWED*)p_data)->value;
  APPL_TRACE_DEBUG(sco_allowed ? "sco now allowed" : "sco now not allowed");
}

/*******************************************************************************
 *  Debugging functions
 ******************************************************************************/
+2 −0
Original line number Diff line number Diff line
@@ -583,4 +583,6 @@ void BTA_AgResult(uint16_t handle, tBTA_AG_RES result,
 ******************************************************************************/
void BTA_AgSetCodec(uint16_t handle, tBTA_AG_PEER_CODEC codec);

void BTA_AgSetScoAllowed(bool value);

#endif /* BTA_AG_API_H */
Loading