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

Commit 65ab0e90 authored by shihchienc's avatar shihchienc Committed by Patrick Chang
Browse files

[HFP1.9] Update codec selction with LC3

1. add LC3 as a new option into codec selection
2. add LC3 codec settings selection

Tag: #feature
Bug: 277338500
Test: manual
Test: atest --host net_test_btif_stack net_test_stack_btu net_test_stack_btm -c
Change-Id: Ida7fa71e896725303eaac939637430bc4ef601a5
parent 24acfaa6
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@

#define LOG_TAG "bta_ag_cmd"

#include <base/logging.h>

#include <cstdint>
#include <cstring>

@@ -29,10 +31,10 @@
#include "osi/include/compat.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"  // UNUSED_ATTR
#include "osi/include/properties.h"
#include "stack/btm/btm_sco_hfp_hal.h"
#include "stack/include/port_api.h"

#include <base/logging.h>

/*****************************************************************************
 *  Constants
 ****************************************************************************/
@@ -467,6 +469,9 @@ static tBTA_AG_PEER_CODEC bta_ag_parse_bac(tBTA_AG_SCB* p_scb, char* p_s,
      case UUID_CODEC_MSBC:
        retval |= BTM_SCO_CODEC_MSBC;
        break;
      case UUID_CODEC_LC3:
        retval |= BTM_SCO_CODEC_LC3;
        break;
      default:
        APPL_TRACE_ERROR("Unknown Codec UUID(%d) received", uuid_codec);
        break;
@@ -1247,11 +1252,16 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
        p_scb->peer_codecs = bta_ag_parse_bac(p_scb, p_arg, p_end);
        p_scb->codec_updated = true;

        if (p_scb->peer_codecs & BTM_SCO_CODEC_MSBC) {
          p_scb->sco_codec = UUID_CODEC_MSBC;
        bool swb_supported = hfp_hal_interface::get_swb_supported();

        if ((p_scb->peer_codecs & BTM_SCO_CODEC_LC3) && swb_supported) {
          p_scb->sco_codec = BTM_SCO_CODEC_LC3;
          APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to LC3");
        } else if (p_scb->peer_codecs & BTM_SCO_CODEC_MSBC) {
          p_scb->sco_codec = BTM_SCO_CODEC_MSBC;
          APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to MSBC");
        } else {
          p_scb->sco_codec = UUID_CODEC_CVSD;
          p_scb->sco_codec = BTM_SCO_CODEC_CVSD;
          APPL_TRACE_DEBUG("Received AT+BAC, updating sco codec to CVSD");
        }
        /* The above logic sets the stack preferred codec based on local and
@@ -1285,6 +1295,9 @@ void bta_ag_at_hfp_cback(tBTA_AG_SCB* p_scb, uint16_t cmd, uint8_t arg_type,
        case UUID_CODEC_MSBC:
          codec_type = BTM_SCO_CODEC_MSBC;
          break;
        case UUID_CODEC_LC3:
          codec_type = BTM_SCO_CODEC_LC3;
          break;
        default:
          APPL_TRACE_ERROR("Unknown codec_uuid %d", int_arg);
          codec_type = 0xFFFF;
@@ -1774,6 +1787,9 @@ void bta_ag_send_bcs(tBTA_AG_SCB* p_scb) {
      case BTM_SCO_CODEC_MSBC:
        codec_uuid = UUID_CODEC_MSBC;
        break;
      case BTM_SCO_CODEC_LC3:
        codec_uuid = UUID_CODEC_LC3;
        break;
      default:
        APPL_TRACE_ERROR("bta_ag_send_bcs: unknown codec %d, use CVSD",
                         p_scb->sco_codec);
+1 −0
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ static tBTA_AG_SCB* bta_ag_scb_alloc(void) {
          alarm_new("bta_ag.scb_codec_negotiation_timer");
      /* 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;
      APPL_TRACE_DEBUG("bta_ag_scb_alloc %d", bta_ag_scb_to_idx(p_scb));
      break;
    }
+71 −21
Original line number Diff line number Diff line
@@ -190,7 +190,8 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {

  if (handle != 0) {
    /* Restore settings */
    if (bta_ag_cb.sco.p_curr_scb->inuse_codec == BTM_SCO_CODEC_MSBC) {
    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) {
      /* Bypass vendor specific and voice settings if enhanced eSCO supported */
      if (!(controller_get_interface()
                ->supports_enhanced_setup_synchronous_connection())) {
@@ -198,9 +199,26 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
      }

      /* If SCO open was initiated by AG and failed for mSBC T2, try mSBC T1
       * 'Safe setting' first. If T1 also fails, try CVSD */
       * 'Safe setting' first. If T1 also fails, try CVSD
       * same operations for LC3 settings */
      if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
        bta_ag_cb.sco.p_curr_scb->state = BTA_AG_SCO_CODEC_ST;
        if (bta_ag_cb.sco.p_curr_scb->inuse_codec == UUID_CODEC_LC3) {
          if (bta_ag_cb.sco.p_curr_scb->codec_lc3_settings ==
              BTA_AG_SCO_LC3_SETTINGS_T2) {
            APPL_TRACE_WARNING(
                "%s: eSCO/SCO failed to open, falling back to LC3 T1 settings",
                __func__);
            bta_ag_cb.sco.p_curr_scb->codec_lc3_settings =
                BTA_AG_SCO_LC3_SETTINGS_T1;
          } else {
            APPL_TRACE_WARNING(
                "%s: eSCO/SCO failed to open, falling back to CVSD settings",
                __func__);
            bta_ag_cb.sco.p_curr_scb->inuse_codec = UUID_CODEC_CVSD;
            bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
          }
        } else {
          if (bta_ag_cb.sco.p_curr_scb->codec_msbc_settings ==
              BTA_AG_SCO_MSBC_SETTINGS_T2) {
            APPL_TRACE_WARNING(
@@ -208,12 +226,15 @@ static void bta_ag_sco_disc_cback(uint16_t sco_idx) {
                __func__);
            bta_ag_cb.sco.p_curr_scb->codec_msbc_settings =
                BTA_AG_SCO_MSBC_SETTINGS_T1;

          } else {
            APPL_TRACE_WARNING(
                "%s: eSCO/SCO failed to open, falling back to CVSD", __func__);
            bta_ag_cb.sco.p_curr_scb->inuse_codec = UUID_CODEC_CVSD;
            bta_ag_cb.sco.p_curr_scb->codec_fallback = true;
          }
        }
      }
    } else if (bta_ag_sco_is_opening(bta_ag_cb.sco.p_curr_scb)) {
      APPL_TRACE_ERROR("%s: eSCO/SCO failed to open, no more fall back",
                       __func__);
@@ -357,7 +378,7 @@ static void bta_ag_cback_sco(tBTA_AG_SCB* p_scb, tBTA_AG_EVT event) {
 ******************************************************************************/
static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {
  LOG_DEBUG("BEFORE %s", p_scb->ToString().c_str());
  tBTA_AG_PEER_CODEC esco_codec = BTM_SCO_CODEC_CVSD;
  tBTA_AG_PEER_CODEC esco_codec = UUID_CODEC_CVSD;

  if (!bta_ag_sco_is_active_device(p_scb->peer_addr)) {
    LOG(WARNING) << __func__ << ": device " << p_scb->peer_addr
@@ -380,24 +401,41 @@ static void bta_ag_create_sco(tBTA_AG_SCB* p_scb, bool is_orig) {

#if (DISABLE_WBS == FALSE)
  if ((p_scb->sco_codec == BTM_SCO_CODEC_MSBC) && !p_scb->codec_fallback &&
      hfp_hal_interface::get_wbs_supported())
    esco_codec = BTM_SCO_CODEC_MSBC;
      hfp_hal_interface::get_wbs_supported()) {
    esco_codec = UUID_CODEC_MSBC;
  }
#endif

  if ((p_scb->sco_codec == BTM_SCO_CODEC_LC3) && !p_scb->codec_fallback &&
      hfp_hal_interface::get_swb_supported()) {
    esco_codec = UUID_CODEC_LC3;
  }

  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 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 */
    p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
  }

  bool offload = hfp_hal_interface::get_offload_enabled();
  /* Initialize eSCO parameters */
  enh_esco_params_t params = {};
  /* If WBS included, use CVSD by default, index is 0 for CVSD by
   * initialization. If eSCO codec is mSBC, index is T2 or T1 */
  if (esco_codec == BTM_SCO_CODEC_MSBC) {
  /* If SWB/WBS are excluded, use CVSD by default,
   * index is 0 for CVSD by initialization.
   * If eSCO codec is mSBC, index is T2 or T1.
   * If eSCO coedc is LC3, index is T2 or T1. */
  LOG_WARN("esco_codec: %d", (int)esco_codec);
  if (esco_codec == UUID_CODEC_LC3) {
    if (p_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T2) {
      params = esco_parameters_for_codec(ESCO_CODEC_LC3_T2, offload);
    } else {
      params = esco_parameters_for_codec(ESCO_CODEC_LC3_T1, offload);
    }
  } else if (esco_codec == UUID_CODEC_MSBC) {
    if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
      params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2, offload);
    } else {
@@ -470,7 +508,13 @@ static void bta_ag_create_pending_sco(tBTA_AG_SCB* p_scb, bool is_local) {

  /* Local device requested SCO connection to peer */
  if (is_local) {
    if (esco_codec == BTM_SCO_CODEC_MSBC) {
    if (esco_codec == UUID_CODEC_LC3) {
      if (p_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T2) {
        params = esco_parameters_for_codec(ESCO_CODEC_LC3_T2, offload);
      } else {
        params = esco_parameters_for_codec(ESCO_CODEC_LC3_T1, offload);
      }
    } else if (esco_codec == UUID_CODEC_MSBC) {
      if (p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T2) {
        params = esco_parameters_for_codec(ESCO_CODEC_MSBC_T2, offload);
      } else {
@@ -1283,6 +1327,8 @@ void bta_ag_sco_conn_open(tBTA_AG_SCB* p_scb,

  /* reset to mSBC T2 settings as the preferred */
  p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
  /* reset to LC3 T2 settings as the preferred */
  p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
}

/*******************************************************************************
@@ -1302,11 +1348,14 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
  p_scb->sco_idx = BTM_INVALID_SCO_INDEX;

  /* codec_fallback is set when AG is initiator and connection failed for mSBC.
   * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings */
   * OR if codec is msbc and T2 settings failed, then retry Safe T1 settings
   * same operations for LC3 settings */
  if (p_scb->svc_conn &&
      (p_scb->codec_fallback ||
       (p_scb->sco_codec == BTM_SCO_CODEC_MSBC &&
        p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1))) {
        p_scb->codec_msbc_settings == BTA_AG_SCO_MSBC_SETTINGS_T1) ||
       (p_scb->sco_codec == BTM_SCO_CODEC_LC3 &&
        p_scb->codec_lc3_settings == BTA_AG_SCO_LC3_SETTINGS_T1))) {
    bta_ag_sco_event(p_scb, BTA_AG_SCO_REOPEN_E);
  } else {
    /* Indicate if the closing of audio is because of transfer */
@@ -1325,6 +1374,7 @@ void bta_ag_sco_conn_close(tBTA_AG_SCB* p_scb,
    /* call app callback */
    bta_ag_cback_sco(p_scb, BTA_AG_AUDIO_CLOSE_EVT);
    p_scb->codec_msbc_settings = BTA_AG_SCO_MSBC_SETTINGS_T2;
    p_scb->codec_lc3_settings = BTA_AG_SCO_LC3_SETTINGS_T2;
  }
}