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

Commit 92e987dd authored by Henri Chataing's avatar Henri Chataing Committed by Gerrit Code Review
Browse files

Merge changes I4ad12b13,Ieb1409ca into main

* changes:
  system/stack/avdt: Return correct error code in avdt_scb_hdl_setconfig_cmd
  system/stack: Use correct error codes in A2dpCodecConfigAacBase::setCodecConfig
parents 3d8f3429 c6803a06
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1209,8 +1209,11 @@ cc_test {
    shared_libs: [
        "libcrypto",
        "libcutils",
        "server_configurable_flags",
    ],
    static_libs: [
        "bluetooth_flags_c_lib",
        "libaconfig_storage_read_api_cc",
        "libbase",
        "libbluetooth-types",
        "libbluetooth_crypto_toolbox",
+9 −4
Original line number Diff line number Diff line
@@ -233,7 +233,7 @@ static tA2DP_STATUS A2DP_ParseInfoAac(tA2DP_AAC_CIE* p_ie, const uint8_t* p_code
      return A2DP_INVALID_SAMPLING_FREQUENCY;
    }
    if (A2DP_BitsSet(p_ie->channelMode) == A2DP_SET_ZERO_BIT) {
      return A2DP_INVALID_CHANNEL_MODE;
      return A2DP_INVALID_CHANNELS;
    }

    return A2DP_SUCCESS;
@@ -246,7 +246,7 @@ static tA2DP_STATUS A2DP_ParseInfoAac(tA2DP_AAC_CIE* p_ie, const uint8_t* p_code
    return A2DP_INVALID_SAMPLING_FREQUENCY;
  }
  if (A2DP_BitsSet(p_ie->channelMode) != A2DP_SET_ONE_BIT) {
    return A2DP_INVALID_CHANNEL_MODE;
    return A2DP_INVALID_CHANNELS;
  }

  return A2DP_SUCCESS;
@@ -307,7 +307,7 @@ static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilityAac(const tA2DP_AAC_CIE* p_ca

  /* Channel Mode */
  if ((cfg_cie.channelMode & p_cap->channelMode) == 0) {
    return A2DP_NOT_SUPPORTED_CHANNEL_MODE;
    return A2DP_NOT_SUPPORTED_CHANNELS;
  }

  return A2DP_SUCCESS;
@@ -966,8 +966,13 @@ tA2DP_STATUS A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_
  //
  memset(&result_config_cie, 0, sizeof(result_config_cie));

  if ((peer_info_cie.objectType & p_a2dp_aac_caps->objectType) == 0) {
    return A2DP_NOT_SUPPORTED_OBJECT_TYPE;
  }

  // NOTE: Always assign the Object Type and Variable Bit Rate Support.
  result_config_cie.objectType = p_a2dp_aac_caps->objectType;

  // The Variable Bit Rate Support is disabled if either side disables it
  result_config_cie.variableBitRateSupport =
          p_a2dp_aac_caps->variableBitRateSupport & peer_info_cie.variableBitRateSupport;
@@ -1242,7 +1247,7 @@ tA2DP_STATUS A2dpCodecConfigAacBase::setCodecConfig(const uint8_t* p_peer_codec_
  if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) {
    log::error("cannot match channel mode: source caps = 0x{:x} peer info = 0x{:x}",
               p_a2dp_aac_caps->channelMode, peer_info_cie.channelMode);
    status = A2DP_NOT_SUPPORTED_CHANNEL_MODE;
    status = A2DP_NOT_SUPPORTED_CHANNELS;
    goto fail;
  }

+15 −0
Original line number Diff line number Diff line
@@ -1061,6 +1061,21 @@ tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info) {
  return (tA2DP_CODEC_TYPE)(p_codec_info[AVDT_CODEC_TYPE_INDEX]);
}

bool A2DP_IsCodecTypeValid(tA2DP_CODEC_TYPE codec_type) {
  switch (codec_type) {
    case A2DP_MEDIA_CT_SBC:
    case A2DP_MEDIA_CT_MPEG_AUDIO:
    case A2DP_MEDIA_CT_AAC:
    case A2DP_MEDIA_CT_MPEG_USAC:
    case A2DP_MEDIA_CT_ATRAC:
    case A2DP_MEDIA_CT_NON_A2DP:
      return true;
    default:
      break;
  }
  return false;
}

bool A2DP_IsSourceCodecValid(const uint8_t* p_codec_info) {
  tA2DP_CODEC_TYPE codec_type = A2DP_GetCodecType(p_codec_info);

+46 −36
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#define LOG_TAG "bluetooth-a2dp"

#include <bluetooth/log.h>
#include <com_android_bluetooth_flags.h>
#include <string.h>

#include "a2dp_codec_api.h"
@@ -551,12 +552,30 @@ void avdt_scb_hdl_setconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
  log::verbose("p_scb->in_use={} p_avdt_scb={} scb_index={}", p_scb->in_use, fmt::ptr(p_scb),
               p_scb->stream_config.scb_index);

  if (!p_scb->in_use) {
    log::verbose("codec: {}", A2DP_CodecInfoString(p_scb->stream_config.cfg.codec_info));
    log::verbose("codec: {}", A2DP_CodecInfoString(p_data->msg.config_cmd.p_cfg->codec_info));
  if (p_scb->in_use) {
    log::error("configuration rejected because SEP is already in use");
    avdt_scb_rej_in_use(p_scb, p_data);
    return;
  }

  AvdtpSepConfig* p_cfg = p_data->msg.config_cmd.p_cfg;
    if (A2DP_GetCodecType(p_scb->stream_config.cfg.codec_info) ==
        A2DP_GetCodecType(p_cfg->codec_info)) {
  auto local_codec_type = A2DP_GetCodecType(p_scb->stream_config.cfg.codec_info);
  auto remote_codec_type = A2DP_GetCodecType(p_cfg->codec_info);

  // Reject the configuration with error code NOT_SUPPORTED_CODEC_TYPE if
  // the codec type differs from the type of the SEP, or INVALID_CODEC_TYPE
  // if the codec type does not match the values defined by Assigned Numbers.
  if (local_codec_type != remote_codec_type) {
    p_data->msg.hdr.err_code =
            !com::android::bluetooth::flags::avdtp_error_codes() ? AVDTP_UNSUPPORTED_CONFIGURATION
            : !A2DP_IsCodecTypeValid(remote_codec_type)          ? A2DP_INVALID_CODEC_TYPE
                                                                 : A2DP_NOT_SUPPORTED_CODEC_TYPE;
    p_data->msg.hdr.err_param = 0;
    avdt_msg_send_rej(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx), p_data->msg.hdr.sig_id,
                      &p_data->msg);
    return;
  }

  /* copy info to scb */
  AvdtpCcb* p_ccb = avdt_ccb_by_idx(p_data->msg.config_cmd.hdr.ccb_idx);
  if (p_scb->p_ccb != p_ccb) {
@@ -568,27 +587,18 @@ void avdt_scb_hdl_setconfig_cmd(AvdtpScb* p_scb, tAVDT_SCB_EVT* p_data) {
    avdt_scb_rej_not_in_use(p_scb, p_data);
    return;
  }

  /* set sep as in use */
  p_scb->in_use = true;

  p_scb->peer_seid = p_data->msg.config_cmd.int_seid;
  p_scb->req_cfg = *p_cfg;

  /* call app callback */
  /* handle of scb- which is same as sep handle of bta_av_cb.p_scb*/
  (*p_scb->stream_config.p_avdt_ctrl_cback)(
          avdt_scb_to_hdl(p_scb), p_scb->p_ccb ? p_scb->p_ccb->peer_addr : RawAddress::kEmpty,
          AVDT_CONFIG_IND_EVT, (tAVDT_CTRL*)&p_data->msg.config_cmd,
          p_scb->stream_config.scb_index);
    } else {
      p_data->msg.hdr.err_code = AVDT_ERR_UNSUP_CFG;
      p_data->msg.hdr.err_param = 0;
      avdt_msg_send_rej(avdt_ccb_by_idx(p_data->msg.hdr.ccb_idx), p_data->msg.hdr.sig_id,
                        &p_data->msg);
    }
  } else {
    log::verbose("calling avdt_scb_rej_in_use()");
    avdt_scb_rej_in_use(p_scb, p_data);
  }
}

/*******************************************************************************
+3 −0
Original line number Diff line number Diff line
@@ -562,6 +562,9 @@ typedef struct {
// |p_codec_info| contains information about the codec capabilities.
tA2DP_CODEC_TYPE A2DP_GetCodecType(const uint8_t* p_codec_info);

// Check whether the codec type is valid.
bool A2DP_IsCodecTypeValid(tA2DP_CODEC_TYPE);

// Checks whether the codec capabilities contain a valid A2DP Source codec.
// NOTE: only codecs that are implemented are considered valid.
// Returns true if |p_codec_info| contains information about a valid codec,
Loading