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

Commit eb4b03ce authored by Yun-Hao Chung's avatar Yun-Hao Chung Committed by Yun-hao Chung
Browse files

Floss: Allow fallback to CVSD S1 from CVSD S3 or S4

According to HFP 1.9 spec 6.7.1.2, AG should retry S1 as a
'safe setting' when the previous setup was rejected.

This patch is needed for the below tests
HFP/AG/ACC/BV-22-C
HFP/AG/ACC/BV-23-C

Bug: 324157546
Bug: 332650199
Test: Run above qualification tests
Test: m -j
Tag: #floss

Change-Id: If57eb871cd08616807a346fab0a51cb910425dc5
parent 16a909f3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -395,8 +395,10 @@ void bta_ag_rfc_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& /* data */) {
  /* Clear these flags upon SLC teardown */
  p_scb->codec_updated = false;
  p_scb->codec_fallback = false;
  p_scb->trying_cvsd_safe_settings = false;
  p_scb->retransmission_effort_retries = 0;
  p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
  p_scb->codec_cvsd_settings = BTA_AG_SCO_CVSD_SETTINGS_S4;
  p_scb->codec_aptx_settings = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0;
  p_scb->is_aptx_swb_codec = false;
  p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
+10 −0
Original line number Diff line number Diff line
@@ -214,6 +214,12 @@ typedef struct {
  uint8_t scn;
} tBTA_AG_PROFILE;

typedef enum {
  BTA_AG_SCO_CVSD_SETTINGS_S4 = 0, /* preferred/default when codec is CVSD */
  BTA_AG_SCO_CVSD_SETTINGS_S3,
  BTA_AG_SCO_CVSD_SETTINGS_S1,
} tBTA_AG_SCO_CVSD_SETTINGS;

typedef enum {
  BTA_AG_SCO_MSBC_SETTINGS_T2 = 0, /* preferred/default when codec is mSBC */
  BTA_AG_SCO_MSBC_SETTINGS_T1,
@@ -285,12 +291,16 @@ struct tBTA_AG_SCB {
      inuse_codec;     /* codec being used for the current SCO connection */
  bool codec_updated;  /* set to true whenever the app updates codec type */
  bool codec_fallback; /* If sco nego fails for mSBC, fallback to CVSD */
  bool trying_cvsd_safe_settings; /* set to true whenever we are trying CVSD
                                     safe settings */
  uint8_t retransmission_effort_retries;         /* Retry eSCO
                                                  with retransmission_effort value*/
  tBTA_AG_SCO_MSBC_SETTINGS codec_msbc_settings; /* settings to be used for the
                                                    impending eSCO on WB */
  tBTA_AG_SCO_LC3_SETTINGS codec_lc3_settings;   /* settings to be used for the
                                                    impending eSCO on SWB */
  tBTA_AG_SCO_CVSD_SETTINGS codec_cvsd_settings; /* settings to be used for the
                                                    impending eSCO on CVSD */
  tBTA_AG_SCO_APTX_SWB_SETTINGS
      codec_aptx_settings; /* settings to be used for the
                              aptX Voice SWB eSCO */
+3 −0
Original line number Diff line number Diff line
@@ -149,6 +149,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
      p_scb->received_at_bac = false;
      p_scb->codec_updated = false;
      p_scb->codec_fallback = false;
      p_scb->trying_cvsd_safe_settings = false;
      p_scb->retransmission_effort_retries = 0;
      p_scb->peer_codecs = BTM_SCO_CODEC_CVSD;
      p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
@@ -160,6 +161,8 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
      p_scb->collision_timer = alarm_new("bta_ag.scb_collision_timer");
      p_scb->codec_negotiation_timer =
          alarm_new("bta_ag.scb_codec_negotiation_timer");
      /* reset to CVSD S4 settings as the preferred */
      p_scb->codec_cvsd_settings = BTA_AG_SCO_CVSD_SETTINGS_S4;
      /* set eSCO mSBC setting to T2 as the preferred */
      p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
      p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
+64 −15
Original line number Diff line number Diff line
@@ -220,7 +220,15 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {

    /* Restore settings */
    if (bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_MSBC ||
        bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_LC3 || aptx_voice) {
        bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_LC3 || aptx_voice ||
#if TARGET_FLOSS
        (true &&
#else
        (IS_FLAG_ENABLED(fix_hfp_qual_1_9) &&
#endif
         bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_CVSD &&
         bta_ag_cb.sco.p_curr_scb->codec_cvsd_settings !=
             BTA_AG_SCO_CVSD_SETTINGS_S1)) {
      /* Bypass vendor specific and voice settings if enhanced eSCO supported */
      if (!(bluetooth::shim::GetController()->IsSupported(
              bluetooth::hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION))) {
@@ -259,7 +267,8 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
            bta_ag_cb.sco.p_curr_scb->inuse_codec = UUID_CODEC_CVSD;
            bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
          }
        } else {
        } else if (bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_MSBC ||
                   aptx_voice) {
          if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings ==
              BTA_AG_SCO_MSBC_SETTINGS_T2) {
            log::warn(
@@ -272,6 +281,15 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
            bta_ag_cb.sco.p_curr_scb->inuse_codec = UUID_CODEC_CVSD;
            bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
          }
        } else {
          // Entering this block implies
          // - |fix_hfp_qual_1_9| is enabled or is in Floss, AND
          // - we just failed CVSD S2+.
          log::warn(
              "eSCO/SCO failed to open, falling back to CVSD S1 settings");
          bta_ag_cb.sco.p_curr_scb->codec_cvsd_settings =
              BTA_AG_SCO_CVSD_SETTINGS_S1;
          bta_ag_cb.sco.p_curr_scb->trying_cvsd_safe_settings = true;
        }
      }
    } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb) &&
@@ -478,10 +496,14 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
    esco_codec = UUID_CODEC_LC3;
  }

  p_scb->trying_cvsd_safe_settings = false;

  if (p_scb->codec_fallback) {
    p_scb->codec_fallback = false;
    /* Force AG to send +BCS for the next audio connection. */
    p_scb->codec_updated = true;
    /* reset to CVSD S4 settings as the preferred */
    p_scb->codec_cvsd_settings = BTA_AG_SCO_CVSD_SETTINGS_S4;
    /* Reset mSBC settings to T2 for the next audio connection */
    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
    /* Reset LC3 settings to T2 for the next audio connection */
@@ -522,6 +544,14 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
      params = esco_parameters_for_codec(ESCO_CODEC_SWB_Q0, true);
    }
  } else {
#if TARGET_FLOSS
    if (true &&
#else
    if (IS_FLAG_ENABLED(fix_hfp_qual_1_9) &&
#endif
        p_scb->codec_cvsd_settings == BTA_AG_SCO_CVSD_SETTINGS_S1) {
      params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S1, offload);
    } else {
      if ((p_scb->features & BTA_AG_FEAT_ESCO_S4) &&
          (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
        // HFP >=1.7 eSCO
@@ -531,6 +561,7 @@ void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
        params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3, offload);
      }
    }
  }

  updateCodecParametersFromProviderInfo(esco_codec, params);

@@ -647,6 +678,14 @@ void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
        params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T1, offload);
      }
    } else {
#if TARGET_FLOSS
      if (true &&
#else
      if (IS_FLAG_ENABLED(fix_hfp_qual_1_9) &&
#endif
          p_scb->codec_cvsd_settings == BTA_AG_SCO_CVSD_SETTINGS_S1) {
        params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S1, offload);
      } else {
        if ((p_scb->features & BTA_AG_FEAT_ESCO_S4) &&
            (p_scb->peer_features & BTA_AG_PEER_FEAT_ESCO_S4)) {
          // HFP >=1.7 eSCO
@@ -656,6 +695,7 @@ void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {
          params = esco_parameters_for_codec(ESCO_CODEC_CVSD_S3, offload);
        }
      }
    }

    /* Bypass voice settings if enhanced SCO setup command is supported */
    if (!(bluetooth::shim::GetController()->IsSupported(
@@ -1551,7 +1591,15 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& /* data */) {
        p_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T1) ||
       (IS_FLAG_ENABLED(retry_esco_with_zero_retransmission_effort) &&
        p_scb->retransmission_effort_retries == 1) ||
       aptx_voice)) {
       aptx_voice ||
#if TARGET_FLOSS
       (true &&
#else
       (IS_FLAG_ENABLED(fix_hfp_qual_1_9) &&
#endif
        p_scb->sco_codec == BTM_SCO_CODEC_CVSD &&
        p_scb->codec_cvsd_settings == BTA_AG_SCO_CVSD_SETTINGS_S1 &&
        p_scb->trying_cvsd_safe_settings))) {
    bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
  } else {
    /* Indicate if the closing of audio is because of transfer */
@@ -1569,6 +1617,7 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb, const tBTA_AG_DATA& /* data */) {

    /* call app callback */
    bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
    p_scb->codec_cvsd_settings = BTA_AG_SCO_CVSD_SETTINGS_S4;
    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
    p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
    p_scb->codec_aptx_settings = BTA_AG_SCO_APTX_SWB_SETTINGS_Q0;
+3 −2
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ typedef enum {

typedef enum {
  SCO_CODEC_CVSD_D1 = 0,
  ESCO_CODEC_CVSD_S1,
  ESCO_CODEC_CVSD_S3,
  ESCO_CODEC_CVSD_S4,
  ESCO_CODEC_MSBC_T1,
@@ -45,8 +46,8 @@ typedef enum {
  ESCO_CODEC_UNKNOWN,  // For testing
} esco_codec_t;

#define ESCO_LEGACY_NUM_CODECS 7
#define ESCO_NUM_CODECS 11
#define ESCO_LEGACY_NUM_CODECS 8
#define ESCO_NUM_CODECS 12

// Coding Formats (BT 4.1 or later Assigned numbers)
#define ESCO_CODING_FORMAT_ULAW ((uint8_t)0x00)     /* u-Law log    */
Loading