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

Commit c6803a06 authored by Henri Chataing's avatar Henri Chataing
Browse files

system/stack/avdt: Return correct error code in avdt_scb_hdl_setconfig_cmd

Required to pass pts tests A2DP/SRC/AVP/BI-20-C and A2DP/SRC/AVP/BI-30-C

Bug: 336232163
Test: atest pts-bot
Flag: EXEMPT, minor refactor
Change-Id: I4ad12b13cc98e8b645900beeaba561c72bda727d
parent 091f4627
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",
+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,
+3 −0
Original line number Diff line number Diff line
@@ -36,7 +36,10 @@
// cf. Assigned Numbers § 6.5.1 Audio Codec ID
enum tA2DP_CODEC_TYPE : uint8_t {
  A2DP_MEDIA_CT_SBC = 0x00,
  A2DP_MEDIA_CT_MPEG_AUDIO = 0x01,
  A2DP_MEDIA_CT_AAC = 0x02,
  A2DP_MEDIA_CT_MPEG_USAC = 0x03,
  A2DP_MEDIA_CT_ATRAC = 0x04,
  A2DP_MEDIA_CT_NON_A2DP = 0xff,
};

Loading