/******************************************************************************
 *
 *  Copyright (C) 2002-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  Utility functions to help build and parse SBC Codec Information Element
 *  and Media Payload.
 *
 ******************************************************************************/

#define LOG_TAG "a2dp_sbc"

#include "bt_target.h"

#include "a2dp_sbc.h"

#include <string.h>

#include <base/logging.h>
#include "a2dp_int.h"
#include "a2dp_sbc_encoder.h"
#include "bt_utils.h"
#include "embdrv/sbc/encoder/include/sbc_encoder.h"
#include "osi/include/log.h"
#include "osi/include/osi.h"

#define A2DP_SBC_MAX_BITPOOL 53

/* data type for the SBC Codec Information Element */
typedef struct {
  uint8_t samp_freq;    /* Sampling frequency */
  uint8_t ch_mode;      /* Channel mode */
  uint8_t block_len;    /* Block length */
  uint8_t num_subbands; /* Number of subbands */
  uint8_t alloc_method; /* Allocation method */
  uint8_t min_bitpool;  /* Minimum bitpool */
  uint8_t max_bitpool;  /* Maximum bitpool */
} tA2DP_SBC_CIE;

/* SBC SRC codec capabilities */
static const tA2DP_SBC_CIE a2dp_sbc_caps = {
    A2DP_SBC_IE_SAMP_FREQ_44, /* samp_freq */
    A2DP_SBC_IE_CH_MD_JOINT,  /* ch_mode */
    A2DP_SBC_IE_BLOCKS_16,    /* block_len */
    A2DP_SBC_IE_SUBBAND_8,    /* num_subbands */
    A2DP_SBC_IE_ALLOC_MD_L,   /* alloc_method */
    A2DP_SBC_IE_MIN_BITPOOL,  /* min_bitpool */
    A2DP_SBC_MAX_BITPOOL      /* max_bitpool */
};

/* SBC SINK codec capabilities */
static const tA2DP_SBC_CIE a2dp_sbc_sink_caps = {
    (A2DP_SBC_IE_SAMP_FREQ_48 | A2DP_SBC_IE_SAMP_FREQ_44), /* samp_freq */
    (A2DP_SBC_IE_CH_MD_MONO | A2DP_SBC_IE_CH_MD_STEREO |
     A2DP_SBC_IE_CH_MD_JOINT | A2DP_SBC_IE_CH_MD_DUAL), /* ch_mode */
    (A2DP_SBC_IE_BLOCKS_16 | A2DP_SBC_IE_BLOCKS_12 | A2DP_SBC_IE_BLOCKS_8 |
     A2DP_SBC_IE_BLOCKS_4),                            /* block_len */
    (A2DP_SBC_IE_SUBBAND_4 | A2DP_SBC_IE_SUBBAND_8),   /* num_subbands */
    (A2DP_SBC_IE_ALLOC_MD_L | A2DP_SBC_IE_ALLOC_MD_S), /* alloc_method */
    A2DP_SBC_IE_MIN_BITPOOL,                           /* min_bitpool */
    A2DP_SBC_MAX_BITPOOL                               /* max_bitpool */
};

/* Default SBC codec configuration */
const tA2DP_SBC_CIE a2dp_sbc_default_config = {
    A2DP_SBC_IE_SAMP_FREQ_44, /* samp_freq */
    A2DP_SBC_IE_CH_MD_JOINT,  /* ch_mode */
    A2DP_SBC_IE_BLOCKS_16,    /* block_len */
    A2DP_SBC_IE_SUBBAND_8,    /* num_subbands */
    A2DP_SBC_IE_ALLOC_MD_L,   /* alloc_method */
    A2DP_SBC_IE_MIN_BITPOOL,  /* min_bitpool */
    A2DP_SBC_MAX_BITPOOL      /* max_bitpool */
};

static const tA2DP_ENCODER_INTERFACE a2dp_encoder_interface_sbc = {
    a2dp_sbc_encoder_init,  a2dp_sbc_encoder_cleanup,
    a2dp_sbc_feeding_init,  a2dp_sbc_feeding_reset,
    a2dp_sbc_feeding_flush, a2dp_sbc_get_encoder_interval_ms,
    a2dp_sbc_send_frames,   a2dp_sbc_debug_codec_dump};

static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc(
    const tA2DP_SBC_CIE* p_cap, const uint8_t* p_codec_info,
    bool is_capability);
static void A2DP_ParseMplHeaderSbc(uint8_t* p_src, bool* p_frag, bool* p_start,
                                   bool* p_last, uint8_t* p_num);

// Builds the SBC Media Codec Capabilities byte sequence beginning from the
// LOSC octet. |media_type| is the media type |AVDT_MEDIA_TYPE_*|.
// |p_ie| is a pointer to the SBC Codec Information Element information.
// The result is stored in |p_result|. Returns A2DP_SUCCESS on success,
// otherwise the corresponding A2DP error status code.
static tA2DP_STATUS A2DP_BuildInfoSbc(uint8_t media_type,
                                      const tA2DP_SBC_CIE* p_ie,
                                      uint8_t* p_result) {
  tA2DP_STATUS status;

  if (p_ie == NULL || p_result == NULL ||
      (p_ie->samp_freq & ~A2DP_SBC_IE_SAMP_FREQ_MSK) ||
      (p_ie->ch_mode & ~A2DP_SBC_IE_CH_MD_MSK) ||
      (p_ie->block_len & ~A2DP_SBC_IE_BLOCKS_MSK) ||
      (p_ie->num_subbands & ~A2DP_SBC_IE_SUBBAND_MSK) ||
      (p_ie->alloc_method & ~A2DP_SBC_IE_ALLOC_MD_MSK) ||
      (p_ie->min_bitpool > p_ie->max_bitpool) ||
      (p_ie->min_bitpool < A2DP_SBC_IE_MIN_BITPOOL) ||
      (p_ie->min_bitpool > A2DP_SBC_IE_MAX_BITPOOL) ||
      (p_ie->max_bitpool < A2DP_SBC_IE_MIN_BITPOOL) ||
      (p_ie->max_bitpool > A2DP_SBC_IE_MAX_BITPOOL)) {
    /* if any unused bit is set */
    status = A2DP_INVALID_PARAMS;
  } else {
    status = A2DP_SUCCESS;
    *p_result++ = A2DP_SBC_INFO_LEN;
    *p_result++ = (media_type << 4);
    *p_result++ = A2DP_MEDIA_CT_SBC;

    /* Media Codec Specific Information Element */
    *p_result++ = p_ie->samp_freq | p_ie->ch_mode;

    *p_result++ = p_ie->block_len | p_ie->num_subbands | p_ie->alloc_method;

    *p_result++ = p_ie->min_bitpool;
    *p_result = p_ie->max_bitpool;
  }
  return status;
}

// Parses the SBC Media Codec Capabilities byte sequence beginning from the
// LOSC octet. The result is stored in |p_ie|. The byte sequence to parse is
// |p_codec_info|. If |is_capability| is true, the byte sequence contains
// codec capability.
// Returns A2DP_SUCCESS on success, otherwise the corresponding A2DP error
// status code.
static tA2DP_STATUS A2DP_ParseInfoSbc(tA2DP_SBC_CIE* p_ie,
                                      const uint8_t* p_codec_info,
                                      bool is_capability) {
  tA2DP_STATUS status = A2DP_SUCCESS;
  uint8_t losc;
  uint8_t media_type;
  tA2DP_CODEC_TYPE codec_type;

  if (p_ie == NULL || p_codec_info == NULL) return A2DP_INVALID_PARAMS;

  // Check the codec capability length
  losc = *p_codec_info++;
  if (losc != A2DP_SBC_INFO_LEN) return A2DP_WRONG_CODEC;

  media_type = (*p_codec_info++) >> 4;
  codec_type = *p_codec_info++;
  /* Check the Media Type and Media Codec Type */
  if (media_type != AVDT_MEDIA_TYPE_AUDIO || codec_type != A2DP_MEDIA_CT_SBC) {
    return A2DP_WRONG_CODEC;
  }

  p_ie->samp_freq = *p_codec_info & A2DP_SBC_IE_SAMP_FREQ_MSK;
  p_ie->ch_mode = *p_codec_info & A2DP_SBC_IE_CH_MD_MSK;
  p_codec_info++;
  p_ie->block_len = *p_codec_info & A2DP_SBC_IE_BLOCKS_MSK;
  p_ie->num_subbands = *p_codec_info & A2DP_SBC_IE_SUBBAND_MSK;
  p_ie->alloc_method = *p_codec_info & A2DP_SBC_IE_ALLOC_MD_MSK;
  p_codec_info++;
  p_ie->min_bitpool = *p_codec_info++;
  p_ie->max_bitpool = *p_codec_info;
  if (p_ie->min_bitpool < A2DP_SBC_IE_MIN_BITPOOL ||
      p_ie->min_bitpool > A2DP_SBC_IE_MAX_BITPOOL) {
    status = A2DP_BAD_MIN_BITPOOL;
  }

  if (p_ie->max_bitpool < A2DP_SBC_IE_MIN_BITPOOL ||
      p_ie->max_bitpool > A2DP_SBC_IE_MAX_BITPOOL ||
      p_ie->max_bitpool < p_ie->min_bitpool) {
    status = A2DP_BAD_MAX_BITPOOL;
  }

  if (is_capability) return status;

  if (A2DP_BitsSet(p_ie->samp_freq) != A2DP_SET_ONE_BIT)
    status = A2DP_BAD_SAMP_FREQ;
  if (A2DP_BitsSet(p_ie->ch_mode) != A2DP_SET_ONE_BIT)
    status = A2DP_BAD_CH_MODE;
  if (A2DP_BitsSet(p_ie->block_len) != A2DP_SET_ONE_BIT)
    status = A2DP_BAD_BLOCK_LEN;
  if (A2DP_BitsSet(p_ie->num_subbands) != A2DP_SET_ONE_BIT)
    status = A2DP_BAD_SUBBANDS;
  if (A2DP_BitsSet(p_ie->alloc_method) != A2DP_SET_ONE_BIT)
    status = A2DP_BAD_ALLOC_METHOD;

  return status;
}

// Build the SBC Media Payload Header.
// |p_dst| points to the location where the header should be written to.
// If |frag| is true, the media payload frame is fragmented.
// |start| is true for the first packet of a fragmented frame.
// |last| is true for the last packet of a fragmented frame.
// If |frag| is false, |num| is the number of number of frames in the packet,
// otherwise is the number of remaining fragments (including this one).
static void A2DP_BuildMediaPayloadHeaderSbc(uint8_t* p_dst, bool frag,
                                            bool start, bool last,
                                            uint8_t num) {
  if (p_dst == NULL) return;

  *p_dst = 0;
  if (frag) *p_dst |= A2DP_SBC_HDR_F_MSK;
  if (start) *p_dst |= A2DP_SBC_HDR_S_MSK;
  if (last) *p_dst |= A2DP_SBC_HDR_L_MSK;
  *p_dst |= (A2DP_SBC_HDR_NUM_MSK & num);
}

/******************************************************************************
 *
 * Function         A2DP_ParseMplHeaderSbc
 *
 * Description      This function is called by an application to parse
 *                  the SBC Media Payload header.
 *                  Input Parameters:
 *                      p_src:  the byte sequence to parse..
 *
 *                  Output Parameters:
 *                      frag:  1, if fragmented. 0, otherwise.
 *
 *                      start:  1, if the starting packet of a fragmented frame.
 *
 *                      last:  1, if the last packet of a fragmented frame.
 *
 *                      num:  If frag is 1, this is the number of remaining
 *                            fragments
 *                            (including this fragment) of this frame.
 *                            If frag is 0, this is the number of frames in
 *                            this packet.
 *
 * Returns          void.
 *****************************************************************************/
UNUSED_ATTR static void A2DP_ParseMplHeaderSbc(uint8_t* p_src, bool* p_frag,
                                               bool* p_start, bool* p_last,
                                               uint8_t* p_num) {
  if (p_src && p_frag && p_start && p_last && p_num) {
    *p_frag = (*p_src & A2DP_SBC_HDR_F_MSK) ? true : false;
    *p_start = (*p_src & A2DP_SBC_HDR_S_MSK) ? true : false;
    *p_last = (*p_src & A2DP_SBC_HDR_L_MSK) ? true : false;
    *p_num = (*p_src & A2DP_SBC_HDR_NUM_MSK);
  }
}

const char* A2DP_CodecNameSbc(UNUSED_ATTR const uint8_t* p_codec_info) {
  return "SBC";
}

bool A2DP_IsSourceCodecValidSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE cfg_cie;

  /* Use a liberal check when parsing the codec info */
  return (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, false) == A2DP_SUCCESS) ||
         (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, true) == A2DP_SUCCESS);
}

bool A2DP_IsSinkCodecValidSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE cfg_cie;

  /* Use a liberal check when parsing the codec info */
  return (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, false) == A2DP_SUCCESS) ||
         (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, true) == A2DP_SUCCESS);
}

bool A2DP_IsPeerSourceCodecValidSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE cfg_cie;

  /* Use a liberal check when parsing the codec info */
  return (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, false) == A2DP_SUCCESS) ||
         (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, true) == A2DP_SUCCESS);
}

bool A2DP_IsPeerSinkCodecValidSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE cfg_cie;

  /* Use a liberal check when parsing the codec info */
  return (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, false) == A2DP_SUCCESS) ||
         (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, true) == A2DP_SUCCESS);
}

bool A2DP_IsSinkCodecSupportedSbc(const uint8_t* p_codec_info) {
  return (A2DP_CodecInfoMatchesCapabilitySbc(&a2dp_sbc_sink_caps, p_codec_info,
                                             false) == A2DP_SUCCESS);
}

bool A2DP_IsPeerSourceCodecSupportedSbc(const uint8_t* p_codec_info) {
  return (A2DP_CodecInfoMatchesCapabilitySbc(&a2dp_sbc_sink_caps, p_codec_info,
                                             true) == A2DP_SUCCESS);
}

void A2DP_InitDefaultCodecSbc(uint8_t* p_codec_info) {
  if (A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &a2dp_sbc_default_config,
                        p_codec_info) != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: A2DP_BuildInfoSbc failed", __func__);
  }
}

// Checks whether A2DP SBC codec configuration matches with a device's codec
// capabilities. |p_cap| is the SBC codec configuration. |p_codec_info| is
// the device's codec capabilities. |is_capability| is true if
// |p_codec_info| contains A2DP codec capability.
// Returns A2DP_SUCCESS if the codec configuration matches with capabilities,
// otherwise the corresponding A2DP error status code.
static tA2DP_STATUS A2DP_CodecInfoMatchesCapabilitySbc(
    const tA2DP_SBC_CIE* p_cap, const uint8_t* p_codec_info,
    bool is_capability) {
  tA2DP_STATUS status;
  tA2DP_SBC_CIE cfg_cie;

  /* parse configuration */
  status = A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, is_capability);
  if (status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: parsing failed %d", __func__, status);
    return status;
  }

  /* verify that each parameter is in range */

  LOG_DEBUG(LOG_TAG, "FREQ peer: 0x%x, capability 0x%x", cfg_cie.samp_freq,
            p_cap->samp_freq);
  LOG_DEBUG(LOG_TAG, "CH_MODE peer: 0x%x, capability 0x%x", cfg_cie.ch_mode,
            p_cap->ch_mode);
  LOG_DEBUG(LOG_TAG, "BLOCK_LEN peer: 0x%x, capability 0x%x", cfg_cie.block_len,
            p_cap->block_len);
  LOG_DEBUG(LOG_TAG, "SUB_BAND peer: 0x%x, capability 0x%x",
            cfg_cie.num_subbands, p_cap->num_subbands);
  LOG_DEBUG(LOG_TAG, "ALLOC_METHOD peer: 0x%x, capability 0x%x",
            cfg_cie.alloc_method, p_cap->alloc_method);
  LOG_DEBUG(LOG_TAG, "MIN_BitPool peer: 0x%x, capability 0x%x",
            cfg_cie.min_bitpool, p_cap->min_bitpool);
  LOG_DEBUG(LOG_TAG, "MAX_BitPool peer: 0x%x, capability 0x%x",
            cfg_cie.max_bitpool, p_cap->max_bitpool);

  /* sampling frequency */
  if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) return A2DP_NS_SAMP_FREQ;

  /* channel mode */
  if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) return A2DP_NS_CH_MODE;

  /* block length */
  if ((cfg_cie.block_len & p_cap->block_len) == 0) return A2DP_BAD_BLOCK_LEN;

  /* subbands */
  if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0)
    return A2DP_NS_SUBBANDS;

  /* allocation method */
  if ((cfg_cie.alloc_method & p_cap->alloc_method) == 0)
    return A2DP_NS_ALLOC_METHOD;

  /* min bitpool */
  if (cfg_cie.min_bitpool > p_cap->max_bitpool) return A2DP_NS_MIN_BITPOOL;

  /* max bitpool */
  if (cfg_cie.max_bitpool < p_cap->min_bitpool) return A2DP_NS_MAX_BITPOOL;

  return A2DP_SUCCESS;
}

tA2DP_STATUS A2DP_BuildSrc2SinkConfigSbc(const uint8_t* p_src_cap,
                                         uint8_t* p_pref_cfg) {
  tA2DP_SBC_CIE src_cap;
  tA2DP_SBC_CIE pref_cap;

  /* initialize it to default SBC configuration */
  A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &a2dp_sbc_default_config,
                    p_pref_cfg);

  /* now try to build a preferred one */
  /* parse configuration */
  tA2DP_STATUS status = A2DP_ParseInfoSbc(&src_cap, p_src_cap, true);
  if (status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: can't parse src cap ret = %d", __func__, status);
    return A2DP_FAIL;
  }

  if (src_cap.samp_freq & A2DP_SBC_IE_SAMP_FREQ_48)
    pref_cap.samp_freq = A2DP_SBC_IE_SAMP_FREQ_48;
  else if (src_cap.samp_freq & A2DP_SBC_IE_SAMP_FREQ_44)
    pref_cap.samp_freq = A2DP_SBC_IE_SAMP_FREQ_44;

  if (src_cap.ch_mode & A2DP_SBC_IE_CH_MD_JOINT)
    pref_cap.ch_mode = A2DP_SBC_IE_CH_MD_JOINT;
  else if (src_cap.ch_mode & A2DP_SBC_IE_CH_MD_STEREO)
    pref_cap.ch_mode = A2DP_SBC_IE_CH_MD_STEREO;
  else if (src_cap.ch_mode & A2DP_SBC_IE_CH_MD_DUAL)
    pref_cap.ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
  else if (src_cap.ch_mode & A2DP_SBC_IE_CH_MD_MONO)
    pref_cap.ch_mode = A2DP_SBC_IE_CH_MD_MONO;

  if (src_cap.block_len & A2DP_SBC_IE_BLOCKS_16)
    pref_cap.block_len = A2DP_SBC_IE_BLOCKS_16;
  else if (src_cap.block_len & A2DP_SBC_IE_BLOCKS_12)
    pref_cap.block_len = A2DP_SBC_IE_BLOCKS_12;
  else if (src_cap.block_len & A2DP_SBC_IE_BLOCKS_8)
    pref_cap.block_len = A2DP_SBC_IE_BLOCKS_8;
  else if (src_cap.block_len & A2DP_SBC_IE_BLOCKS_4)
    pref_cap.block_len = A2DP_SBC_IE_BLOCKS_4;

  if (src_cap.num_subbands & A2DP_SBC_IE_SUBBAND_8)
    pref_cap.num_subbands = A2DP_SBC_IE_SUBBAND_8;
  else if (src_cap.num_subbands & A2DP_SBC_IE_SUBBAND_4)
    pref_cap.num_subbands = A2DP_SBC_IE_SUBBAND_4;

  if (src_cap.alloc_method & A2DP_SBC_IE_ALLOC_MD_L)
    pref_cap.alloc_method = A2DP_SBC_IE_ALLOC_MD_L;
  else if (src_cap.alloc_method & A2DP_SBC_IE_ALLOC_MD_S)
    pref_cap.alloc_method = A2DP_SBC_IE_ALLOC_MD_S;

  pref_cap.min_bitpool = src_cap.min_bitpool;
  pref_cap.max_bitpool = src_cap.max_bitpool;

  A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &pref_cap, p_pref_cfg);

  return A2DP_SUCCESS;
}

bool A2DP_CodecTypeEqualsSbc(const uint8_t* p_codec_info_a,
                             const uint8_t* p_codec_info_b) {
  tA2DP_SBC_CIE sbc_cie_a;
  tA2DP_SBC_CIE sbc_cie_b;

  // Check whether the codec info contains valid data
  tA2DP_STATUS a2dp_status =
      A2DP_ParseInfoSbc(&sbc_cie_a, p_codec_info_a, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return false;
  }
  a2dp_status = A2DP_ParseInfoSbc(&sbc_cie_b, p_codec_info_b, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return false;
  }

  tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
  tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);

  return (codec_type_a == codec_type_b) && (codec_type_a == A2DP_MEDIA_CT_SBC);
}

bool A2DP_CodecEqualsSbc(const uint8_t* p_codec_info_a,
                         const uint8_t* p_codec_info_b) {
  tA2DP_SBC_CIE sbc_cie_a;
  tA2DP_SBC_CIE sbc_cie_b;

  // Check whether the codec info contains valid data
  tA2DP_STATUS a2dp_status =
      A2DP_ParseInfoSbc(&sbc_cie_a, p_codec_info_a, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return false;
  }
  a2dp_status = A2DP_ParseInfoSbc(&sbc_cie_b, p_codec_info_b, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return false;
  }

  tA2DP_CODEC_TYPE codec_type_a = A2DP_GetCodecType(p_codec_info_a);
  tA2DP_CODEC_TYPE codec_type_b = A2DP_GetCodecType(p_codec_info_b);

  if ((codec_type_a != codec_type_b) || (codec_type_a != A2DP_MEDIA_CT_SBC))
    return false;

  return (sbc_cie_a.samp_freq == sbc_cie_b.samp_freq) &&
         (sbc_cie_a.ch_mode == sbc_cie_b.ch_mode) &&
         (sbc_cie_a.block_len == sbc_cie_b.block_len) &&
         (sbc_cie_a.num_subbands == sbc_cie_b.num_subbands) &&
         (sbc_cie_a.alloc_method == sbc_cie_b.alloc_method) &&
         (sbc_cie_a.min_bitpool == sbc_cie_b.min_bitpool) &&
         (sbc_cie_a.max_bitpool == sbc_cie_b.max_bitpool);
}

int A2DP_GetTrackSampleRateSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.samp_freq) {
    case A2DP_SBC_IE_SAMP_FREQ_16:
      return 16000;
    case A2DP_SBC_IE_SAMP_FREQ_32:
      return 32000;
    case A2DP_SBC_IE_SAMP_FREQ_44:
      return 44100;
    case A2DP_SBC_IE_SAMP_FREQ_48:
      return 48000;
    default:
      break;
  }

  return -1;
}

int A2DP_GetTrackBitsPerSampleSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  return 16;  // For SBC we always use 16 bits per audio sample
}

int A2DP_GetTrackChannelCountSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.ch_mode) {
    case A2DP_SBC_IE_CH_MD_MONO:
      return 1;
    case A2DP_SBC_IE_CH_MD_DUAL:
    case A2DP_SBC_IE_CH_MD_STEREO:
    case A2DP_SBC_IE_CH_MD_JOINT:
      return 2;
    default:
      break;
  }

  return -1;
}

int A2DP_GetNumberOfSubbandsSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.num_subbands) {
    case A2DP_SBC_IE_SUBBAND_4:
      return 4;
    case A2DP_SBC_IE_SUBBAND_8:
      return 8;
    default:
      break;
  }

  return -1;
}

int A2DP_GetNumberOfBlocksSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.block_len) {
    case A2DP_SBC_IE_BLOCKS_4:
      return 4;
    case A2DP_SBC_IE_BLOCKS_8:
      return 8;
    case A2DP_SBC_IE_BLOCKS_12:
      return 12;
    case A2DP_SBC_IE_BLOCKS_16:
      return 16;
    default:
      break;
  }

  return -1;
}

int A2DP_GetAllocationMethodCodeSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.alloc_method) {
    case A2DP_SBC_IE_ALLOC_MD_S:
      return SBC_SNR;
    case A2DP_SBC_IE_ALLOC_MD_L:
      return SBC_LOUDNESS;
    default:
      break;
  }

  return -1;
}

int A2DP_GetChannelModeCodeSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.ch_mode) {
    case A2DP_SBC_IE_CH_MD_MONO:
      return SBC_MONO;
    case A2DP_SBC_IE_CH_MD_DUAL:
      return SBC_DUAL;
    case A2DP_SBC_IE_CH_MD_STEREO:
      return SBC_STEREO;
    case A2DP_SBC_IE_CH_MD_JOINT:
      return SBC_JOINT_STEREO;
    default:
      break;
  }

  return -1;
}

int A2DP_GetSamplingFrequencyCodeSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.samp_freq) {
    case A2DP_SBC_IE_SAMP_FREQ_16:
      return SBC_sf16000;
    case A2DP_SBC_IE_SAMP_FREQ_32:
      return SBC_sf32000;
    case A2DP_SBC_IE_SAMP_FREQ_44:
      return SBC_sf44100;
    case A2DP_SBC_IE_SAMP_FREQ_48:
      return SBC_sf48000;
    default:
      break;
  }

  return -1;
}

int A2DP_GetMinBitpoolSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  return sbc_cie.min_bitpool;
}

int A2DP_GetMaxBitpoolSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  return sbc_cie.max_bitpool;
}

int A2DP_GetSinkTrackChannelTypeSbc(const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  switch (sbc_cie.ch_mode) {
    case A2DP_SBC_IE_CH_MD_MONO:
      return 1;
    case A2DP_SBC_IE_CH_MD_DUAL:
    case A2DP_SBC_IE_CH_MD_STEREO:
    case A2DP_SBC_IE_CH_MD_JOINT:
      return 3;
    default:
      break;
  }

  return -1;
}

int A2DP_GetSinkFramesCountToProcessSbc(uint64_t time_interval_ms,
                                        const uint8_t* p_codec_info) {
  tA2DP_SBC_CIE sbc_cie;
  uint32_t freq_multiple;
  uint32_t num_blocks;
  uint32_t num_subbands;
  int frames_to_process;

  tA2DP_STATUS a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, false);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: cannot decode codec information: %d", __func__,
              a2dp_status);
    return -1;
  }

  // Check the sample frequency
  switch (sbc_cie.samp_freq) {
    case A2DP_SBC_IE_SAMP_FREQ_16:
      LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (16000)", __func__,
                  sbc_cie.samp_freq);
      freq_multiple = 16 * time_interval_ms;
      break;
    case A2DP_SBC_IE_SAMP_FREQ_32:
      LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (32000)", __func__,
                  sbc_cie.samp_freq);
      freq_multiple = 32 * time_interval_ms;
      break;
    case A2DP_SBC_IE_SAMP_FREQ_44:
      LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (44100)", __func__,
                  sbc_cie.samp_freq);
      freq_multiple = (441 * time_interval_ms) / 10;
      break;
    case A2DP_SBC_IE_SAMP_FREQ_48:
      LOG_VERBOSE(LOG_TAG, "%s: samp_freq:%d (48000)", __func__,
                  sbc_cie.samp_freq);
      freq_multiple = 48 * time_interval_ms;
      break;
    default:
      LOG_ERROR(LOG_TAG, "%s: unknown frequency: %d", __func__,
                sbc_cie.samp_freq);
      return -1;
  }

  // Check the channel mode
  switch (sbc_cie.ch_mode) {
    case A2DP_SBC_IE_CH_MD_MONO:
      LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (Mono)", __func__, sbc_cie.ch_mode);
      break;
    case A2DP_SBC_IE_CH_MD_DUAL:
      LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (DUAL)", __func__, sbc_cie.ch_mode);
      break;
    case A2DP_SBC_IE_CH_MD_STEREO:
      LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (STEREO)", __func__,
                  sbc_cie.ch_mode);
      break;
    case A2DP_SBC_IE_CH_MD_JOINT:
      LOG_VERBOSE(LOG_TAG, "%s: ch_mode:%d (JOINT)", __func__, sbc_cie.ch_mode);
      break;
    default:
      LOG_ERROR(LOG_TAG, "%s: unknown channel mode: %d", __func__,
                sbc_cie.ch_mode);
      return -1;
  }

  // Check the block length
  switch (sbc_cie.block_len) {
    case A2DP_SBC_IE_BLOCKS_4:
      LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (4)", __func__, sbc_cie.block_len);
      num_blocks = 4;
      break;
    case A2DP_SBC_IE_BLOCKS_8:
      LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (8)", __func__, sbc_cie.block_len);
      num_blocks = 8;
      break;
    case A2DP_SBC_IE_BLOCKS_12:
      LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (12)", __func__,
                  sbc_cie.block_len);
      num_blocks = 12;
      break;
    case A2DP_SBC_IE_BLOCKS_16:
      LOG_VERBOSE(LOG_TAG, "%s: block_len:%d (16)", __func__,
                  sbc_cie.block_len);
      num_blocks = 16;
      break;
    default:
      LOG_ERROR(LOG_TAG, "%s: unknown block length: %d", __func__,
                sbc_cie.block_len);
      return -1;
  }

  // Check the number of sub-bands
  switch (sbc_cie.num_subbands) {
    case A2DP_SBC_IE_SUBBAND_4:
      LOG_VERBOSE(LOG_TAG, "%s: num_subbands:%d (4)", __func__,
                  sbc_cie.num_subbands);
      num_subbands = 4;
      break;
    case A2DP_SBC_IE_SUBBAND_8:
      LOG_VERBOSE(LOG_TAG, "%s: num_subbands:%d (8)", __func__,
                  sbc_cie.num_subbands);
      num_subbands = 8;
      break;
    default:
      LOG_ERROR(LOG_TAG, "%s: unknown number of subbands: %d", __func__,
                sbc_cie.num_subbands);
      return -1;
  }

  // Check the allocation method
  switch (sbc_cie.alloc_method) {
    case A2DP_SBC_IE_ALLOC_MD_S:
      LOG_VERBOSE(LOG_TAG, "%s: alloc_method:%d (SNR)", __func__,
                  sbc_cie.alloc_method);
      break;
    case A2DP_SBC_IE_ALLOC_MD_L:
      LOG_VERBOSE(LOG_TAG, "%s: alloc_method:%d (Loudness)", __func__,
                  sbc_cie.alloc_method);
      break;
    default:
      LOG_ERROR(LOG_TAG, "%s: unknown allocation method: %d", __func__,
                sbc_cie.alloc_method);
      return -1;
  }

  LOG_VERBOSE(LOG_TAG, "%s: Bit pool Min:%d Max:%d", __func__,
              sbc_cie.min_bitpool, sbc_cie.max_bitpool);

  frames_to_process = ((freq_multiple) / (num_blocks * num_subbands)) + 1;

  return frames_to_process;
}

bool A2DP_GetPacketTimestampSbc(UNUSED_ATTR const uint8_t* p_codec_info,
                                const uint8_t* p_data, uint32_t* p_timestamp) {
  *p_timestamp = *(const uint32_t*)p_data;
  return true;
}

bool A2DP_BuildCodecHeaderSbc(UNUSED_ATTR const uint8_t* p_codec_info,
                              BT_HDR* p_buf, uint16_t frames_per_packet) {
  uint8_t* p;

  p_buf->offset -= A2DP_SBC_MPL_HDR_LEN;
  p = (uint8_t*)(p_buf + 1) + p_buf->offset;
  p_buf->len += A2DP_SBC_MPL_HDR_LEN;
  A2DP_BuildMediaPayloadHeaderSbc(p, false, false, false,
                                  (uint8_t)frames_per_packet);

  return true;
}

void A2DP_DumpCodecInfoSbc(const uint8_t* p_codec_info) {
  tA2DP_STATUS a2dp_status;
  tA2DP_SBC_CIE sbc_cie;

  LOG_DEBUG(LOG_TAG, "%s", __func__);

  a2dp_status = A2DP_ParseInfoSbc(&sbc_cie, p_codec_info, true);
  if (a2dp_status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: A2DP_ParseInfoSbc fail:%d", __func__, a2dp_status);
    return;
  }

  LOG_DEBUG(LOG_TAG, "\tsamp_freq: 0x%x", sbc_cie.samp_freq);
  if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_16) {
    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (16000)");
  }
  if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_32) {
    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (32000)");
  }
  if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_44) {
    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (44100)");
  }
  if (sbc_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_48) {
    LOG_DEBUG(LOG_TAG, "\tsamp_freq: (48000)");
  }

  LOG_DEBUG(LOG_TAG, "\tch_mode: 0x%x", sbc_cie.ch_mode);
  if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
    LOG_DEBUG(LOG_TAG, "\tch_mode: (Mono)");
  }
  if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
    LOG_DEBUG(LOG_TAG, "\tch_mode: (Dual)");
  }
  if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_STEREO) {
    LOG_DEBUG(LOG_TAG, "\tch_mode: (Stereo)");
  }
  if (sbc_cie.ch_mode & A2DP_SBC_IE_CH_MD_JOINT) {
    LOG_DEBUG(LOG_TAG, "\tch_mode: (Joint)");
  }

  LOG_DEBUG(LOG_TAG, "\tblock_len: 0x%x", sbc_cie.block_len);
  if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_4) {
    LOG_DEBUG(LOG_TAG, "\tblock_len: (4)");
  }
  if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_8) {
    LOG_DEBUG(LOG_TAG, "\tblock_len: (8)");
  }
  if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_12) {
    LOG_DEBUG(LOG_TAG, "\tblock_len: (12)");
  }
  if (sbc_cie.block_len & A2DP_SBC_IE_BLOCKS_16) {
    LOG_DEBUG(LOG_TAG, "\tblock_len: (16)");
  }

  LOG_DEBUG(LOG_TAG, "\tnum_subbands: 0x%x", sbc_cie.num_subbands);
  if (sbc_cie.num_subbands & A2DP_SBC_IE_SUBBAND_4) {
    LOG_DEBUG(LOG_TAG, "\tnum_subbands: (4)");
  }
  if (sbc_cie.num_subbands & A2DP_SBC_IE_SUBBAND_8) {
    LOG_DEBUG(LOG_TAG, "\tnum_subbands: (8)");
  }

  LOG_DEBUG(LOG_TAG, "\talloc_method: 0x%x)", sbc_cie.alloc_method);
  if (sbc_cie.alloc_method & A2DP_SBC_IE_ALLOC_MD_S) {
    LOG_DEBUG(LOG_TAG, "\talloc_method: (SNR)");
  }
  if (sbc_cie.alloc_method & A2DP_SBC_IE_ALLOC_MD_L) {
    LOG_DEBUG(LOG_TAG, "\talloc_method: (Loundess)");
  }

  LOG_DEBUG(LOG_TAG, "\tBit pool Min:%d Max:%d", sbc_cie.min_bitpool,
            sbc_cie.max_bitpool);
}

const tA2DP_ENCODER_INTERFACE* A2DP_GetEncoderInterfaceSbc(
    const uint8_t* p_codec_info) {
  if (!A2DP_IsSourceCodecValidSbc(p_codec_info)) return NULL;

  return &a2dp_encoder_interface_sbc;
}

bool A2DP_AdjustCodecSbc(uint8_t* p_codec_info) {
  tA2DP_SBC_CIE cfg_cie;

  if (A2DP_ParseInfoSbc(&cfg_cie, p_codec_info, true) != A2DP_SUCCESS)
    return false;

  // Updated the max bitpool
  if (cfg_cie.max_bitpool > A2DP_SBC_MAX_BITPOOL) {
    LOG_WARN(LOG_TAG, "Updated the SBC codec max bitpool from %d to %d",
             cfg_cie.max_bitpool, A2DP_SBC_MAX_BITPOOL);
    cfg_cie.max_bitpool = A2DP_SBC_MAX_BITPOOL;
  }

  return (A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &cfg_cie, p_codec_info) ==
          A2DP_SUCCESS);
}

btav_a2dp_codec_index_t A2DP_SourceCodecIndexSbc(
    UNUSED_ATTR const uint8_t* p_codec_info) {
  return BTAV_A2DP_CODEC_INDEX_SOURCE_SBC;
}

const char* A2DP_CodecIndexStrSbc(void) { return "SBC"; }

const char* A2DP_CodecIndexStrSbcSink(void) { return "SBC SINK"; }

bool A2DP_InitCodecConfigSbc(tAVDT_CFG* p_cfg) {
  if (A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &a2dp_sbc_caps,
                        p_cfg->codec_info) != A2DP_SUCCESS) {
    return false;
  }

#if (BTA_AV_CO_CP_SCMS_T == TRUE)
  /* Content protection info - support SCMS-T */
  uint8_t* p = p_cfg->protect_info;
  *p++ = AVDT_CP_LOSC;
  UINT16_TO_STREAM(p, AVDT_CP_SCMS_T_ID);
  p_cfg->num_protect = 1;
#endif

  return true;
}

bool A2DP_InitCodecConfigSbcSink(tAVDT_CFG* p_cfg) {
  if (A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &a2dp_sbc_sink_caps,
                        p_cfg->codec_info) != A2DP_SUCCESS) {
    return false;
  }

  return true;
}

UNUSED_ATTR static void build_codec_config(const tA2DP_SBC_CIE& config_cie,
                                           btav_a2dp_codec_config_t* result) {
  if (config_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_44)
    result->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
  if (config_cie.samp_freq & A2DP_SBC_IE_SAMP_FREQ_48)
    result->sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_48000;

  result->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;

  if (config_cie.ch_mode & A2DP_SBC_IE_CH_MD_MONO)
    result->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;

  if (config_cie.ch_mode & (A2DP_SBC_IE_CH_MD_STEREO | A2DP_SBC_IE_CH_MD_JOINT |
                            A2DP_SBC_IE_CH_MD_DUAL)) {
    result->channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
  }
}

A2dpCodecConfigSbc::A2dpCodecConfigSbc()
    : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SOURCE_SBC, "SBC") {}

A2dpCodecConfigSbc::~A2dpCodecConfigSbc() {}

bool A2dpCodecConfigSbc::init() {
  if (!isValid()) return false;

  // Load the encoder
  if (!A2DP_LoadEncoderSbc()) {
    LOG_ERROR(LOG_TAG, "%s: cannot load the encoder", __func__);
    return false;
  }

  return true;
}

//
// Selects the best sample rate from |samp_freq|.
// The result is stored in |p_result| and |p_codec_config|.
// Returns true if a selection was made, otherwise false.
//
static bool select_best_sample_rate(uint8_t samp_freq, tA2DP_SBC_CIE* p_result,
                                    btav_a2dp_codec_config_t* p_codec_config) {
  if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_48) {
    p_result->samp_freq = A2DP_SBC_IE_SAMP_FREQ_48;
    p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
    return true;
  }
  if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_44) {
    p_result->samp_freq = A2DP_SBC_IE_SAMP_FREQ_44;
    p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
    return true;
  }
  return false;
}

//
// Selects the audio sample rate from |p_codec_audio_config|.
// |samp_freq| contains the capability.
// The result is stored in |p_result| and |p_codec_config|.
// Returns true if a selection was made, otherwise false.
//
static bool select_audio_sample_rate(
    const btav_a2dp_codec_config_t* p_codec_audio_config, uint8_t samp_freq,
    tA2DP_SBC_CIE* p_result, btav_a2dp_codec_config_t* p_codec_config) {
  switch (p_codec_audio_config->sample_rate) {
    case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
      if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_44) {
        p_result->samp_freq = A2DP_SBC_IE_SAMP_FREQ_44;
        p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
        return true;
      }
      break;
    case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
      if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_48) {
        p_result->samp_freq = A2DP_SBC_IE_SAMP_FREQ_48;
        p_codec_config->sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_48000;
        return true;
      }
      break;
    case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
      break;
  }

  return false;
}

//
// Selects the best bits per sample.
// The result is stored in |p_codec_config|.
// Returns true if a selection was made, otherwise false.
//
static bool select_best_bits_per_sample(
    btav_a2dp_codec_config_t* p_codec_config) {
  p_codec_config->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
  return true;
}

//
// Selects the audio bits per sample from |p_codec_audio_config|.
// The result is stored in |p_codec_config|.
// Returns true if a selection was made, otherwise false.
//
static bool select_audio_bits_per_sample(
    const btav_a2dp_codec_config_t* p_codec_audio_config,
    btav_a2dp_codec_config_t* p_codec_config) {
  switch (p_codec_audio_config->bits_per_sample) {
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
      p_codec_config->bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;
      return true;
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
      break;
  }
  return false;
}

//
// Selects the best channel mode from |ch_mode|.
// The result is stored in |p_result| and |p_codec_config|.
// Returns true if a selection was made, otherwise false.
//
static bool select_best_channel_mode(uint8_t ch_mode, tA2DP_SBC_CIE* p_result,
                                     btav_a2dp_codec_config_t* p_codec_config) {
  if (ch_mode & A2DP_SBC_IE_CH_MD_JOINT) {
    p_result->ch_mode = A2DP_SBC_IE_CH_MD_JOINT;
    p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
    return true;
  }
  if (ch_mode & A2DP_SBC_IE_CH_MD_STEREO) {
    p_result->ch_mode = A2DP_SBC_IE_CH_MD_STEREO;
    p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
    return true;
  }
  if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
    p_result->ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
    p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
    return true;
  }
  if (ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
    p_result->ch_mode = A2DP_SBC_IE_CH_MD_MONO;
    p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
    return true;
  }
  return false;
}

//
// Selects the audio channel mode from |p_codec_audio_config|.
// |ch_mode| contains the capability.
// The result is stored in |p_result| and |p_codec_config|.
// Returns true if a selection was made, otherwise false.
//
static bool select_audio_channel_mode(
    const btav_a2dp_codec_config_t* p_codec_audio_config, uint8_t ch_mode,
    tA2DP_SBC_CIE* p_result, btav_a2dp_codec_config_t* p_codec_config) {
  switch (p_codec_audio_config->channel_mode) {
    case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
      if (ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
        p_result->ch_mode = A2DP_SBC_IE_CH_MD_MONO;
        p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
        return true;
      }
      break;
    case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
      if (ch_mode & A2DP_SBC_IE_CH_MD_JOINT) {
        p_result->ch_mode = A2DP_SBC_IE_CH_MD_JOINT;
        p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
        return true;
      }
      if (ch_mode & A2DP_SBC_IE_CH_MD_STEREO) {
        p_result->ch_mode = A2DP_SBC_IE_CH_MD_STEREO;
        p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
        return true;
      }
      if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
        p_result->ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
        p_codec_config->channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
        return true;
      }
      break;
    case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
      break;
  }

  return false;
}

bool A2dpCodecConfigSbc::setCodecConfig(const uint8_t* p_peer_codec_info,
                                        bool is_capability,
                                        uint8_t* p_result_codec_config) {
  std::lock_guard<std::recursive_mutex> lock(codec_mutex_);
  tA2DP_SBC_CIE sink_info_cie;
  tA2DP_SBC_CIE result_config_cie;
  uint8_t samp_freq;
  uint8_t ch_mode;
  uint8_t block_len;
  uint8_t num_subbands;
  uint8_t alloc_method;

  // Save the internal state
  btav_a2dp_codec_config_t saved_codec_config = codec_config_;
  btav_a2dp_codec_config_t saved_codec_capability = codec_capability_;
  btav_a2dp_codec_config_t saved_codec_user_config = codec_user_config_;
  btav_a2dp_codec_config_t saved_codec_audio_config = codec_audio_config_;
  uint8_t saved_ota_codec_config[AVDT_CODEC_SIZE];
  uint8_t saved_ota_codec_peer_capability[AVDT_CODEC_SIZE];
  uint8_t saved_ota_codec_peer_config[AVDT_CODEC_SIZE];
  memcpy(saved_ota_codec_config, ota_codec_config_, sizeof(ota_codec_config_));
  memcpy(saved_ota_codec_peer_capability, ota_codec_peer_capability_,
         sizeof(ota_codec_peer_capability_));
  memcpy(saved_ota_codec_peer_config, ota_codec_peer_config_,
         sizeof(ota_codec_peer_config_));

  tA2DP_STATUS status =
      A2DP_ParseInfoSbc(&sink_info_cie, p_peer_codec_info, is_capability);
  if (status != A2DP_SUCCESS) {
    LOG_ERROR(LOG_TAG, "%s: can't parse peer's Sink capabilities: error = %d",
              __func__, status);
    goto fail;
  }

  //
  // Build the preferred configuration
  //
  memset(&result_config_cie, 0, sizeof(result_config_cie));

  //
  // Select the sample frequency
  //
  samp_freq = a2dp_sbc_caps.samp_freq & sink_info_cie.samp_freq;
  codec_config_.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
  switch (codec_user_config_.sample_rate) {
    case BTAV_A2DP_CODEC_SAMPLE_RATE_44100:
      if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_44) {
        result_config_cie.samp_freq = A2DP_SBC_IE_SAMP_FREQ_44;
        codec_capability_.sample_rate = codec_user_config_.sample_rate;
        codec_config_.sample_rate = codec_user_config_.sample_rate;
      }
      break;
    case BTAV_A2DP_CODEC_SAMPLE_RATE_48000:
      if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_48) {
        result_config_cie.samp_freq = A2DP_SBC_IE_SAMP_FREQ_48;
        codec_capability_.sample_rate = codec_user_config_.sample_rate;
        codec_config_.sample_rate = codec_user_config_.sample_rate;
      }
      break;
    case BTAV_A2DP_CODEC_SAMPLE_RATE_88200:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_96000:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_176400:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_192000:
    case BTAV_A2DP_CODEC_SAMPLE_RATE_NONE:
      codec_capability_.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
      codec_config_.sample_rate = BTAV_A2DP_CODEC_SAMPLE_RATE_NONE;
      break;
  }

  // Select the sample frequency if there is no user preference
  do {
    if (codec_config_.sample_rate != BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) break;

    // Compute the common capability
    if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_44)
      codec_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_44100;
    if (samp_freq & A2DP_SBC_IE_SAMP_FREQ_48)
      codec_capability_.sample_rate |= BTAV_A2DP_CODEC_SAMPLE_RATE_48000;

    // No user preference - try the codec audio config
    if (select_audio_sample_rate(&codec_audio_config_, samp_freq,
                                 &result_config_cie, &codec_config_)) {
      break;
    }

    // No user preference - try the default config
    if (select_best_sample_rate(
            a2dp_sbc_default_config.samp_freq & sink_info_cie.samp_freq,
            &result_config_cie, &codec_config_)) {
      break;
    }

    // No user preference - use the best match
    if (select_best_sample_rate(samp_freq, &result_config_cie,
                                &codec_config_)) {
      break;
    }
  } while (false);
  if (codec_config_.sample_rate == BTAV_A2DP_CODEC_SAMPLE_RATE_NONE) {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match sample frequency: source caps = 0x%x "
              "sink info = 0x%x",
              __func__, a2dp_sbc_caps.samp_freq, sink_info_cie.samp_freq);
    goto fail;
  }

  //
  // Select the bits per sample
  //
  // NOTE: this information is NOT included in the SBC A2DP codec description
  // that is sent OTA.
  codec_config_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
  switch (codec_user_config_.bits_per_sample) {
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16:
      codec_capability_.bits_per_sample = codec_user_config_.bits_per_sample;
      codec_config_.bits_per_sample = codec_user_config_.bits_per_sample;
      break;
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24:
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32:
    case BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE:
      codec_capability_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
      codec_config_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE;
      break;
  }

  // Select the bits per sample if there is no user preference
  do {
    if (codec_config_.bits_per_sample != BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE)
      break;

    // Compute the common capability
    codec_capability_.bits_per_sample = BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16;

    // No user preference - try the codec audio config
    if (select_audio_bits_per_sample(&codec_audio_config_, &codec_config_)) {
      break;
    }

    // No user preference - try the default config
    if (select_best_bits_per_sample(&codec_config_)) {
      break;
    }

    // No user preference - use the best match
    // TODO: no-op - temporary kept here for consistency
    if (select_best_bits_per_sample(&codec_config_)) {
      break;
    }
  } while (false);
  if (codec_config_.bits_per_sample == BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE) {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match bits per sample: user preference = 0x%x",
              __func__, codec_user_config_.bits_per_sample);
    goto fail;
  }

  //
  // Select the channel mode
  //
  ch_mode = a2dp_sbc_caps.ch_mode & sink_info_cie.ch_mode;
  codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
  switch (codec_user_config_.channel_mode) {
    case BTAV_A2DP_CODEC_CHANNEL_MODE_MONO:
      if (ch_mode & A2DP_SBC_IE_CH_MD_MONO) {
        result_config_cie.ch_mode = A2DP_SBC_IE_CH_MD_MONO;
        codec_capability_.channel_mode = codec_user_config_.channel_mode;
        codec_config_.channel_mode = codec_user_config_.channel_mode;
      }
      break;
    case BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO:
      if (ch_mode & A2DP_SBC_IE_CH_MD_JOINT) {
        result_config_cie.ch_mode = A2DP_SBC_IE_CH_MD_JOINT;
        codec_capability_.channel_mode = codec_user_config_.channel_mode;
        codec_config_.channel_mode = codec_user_config_.channel_mode;
        break;
      }
      if (ch_mode & A2DP_SBC_IE_CH_MD_STEREO) {
        result_config_cie.ch_mode = A2DP_SBC_IE_CH_MD_STEREO;
        codec_capability_.channel_mode = codec_user_config_.channel_mode;
        codec_config_.channel_mode = codec_user_config_.channel_mode;
        break;
      }
      if (ch_mode & A2DP_SBC_IE_CH_MD_DUAL) {
        result_config_cie.ch_mode = A2DP_SBC_IE_CH_MD_DUAL;
        codec_capability_.channel_mode = codec_user_config_.channel_mode;
        codec_config_.channel_mode = codec_user_config_.channel_mode;
        break;
      }
      break;
    case BTAV_A2DP_CODEC_CHANNEL_MODE_NONE:
      codec_capability_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
      codec_config_.channel_mode = BTAV_A2DP_CODEC_CHANNEL_MODE_NONE;
      break;
  }

  // Select the channel mode if there is no user preference
  do {
    if (codec_config_.channel_mode != BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) break;

    // Compute the common capability
    if (ch_mode & A2DP_SBC_IE_CH_MD_MONO)
      codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_MONO;
    if (ch_mode & (A2DP_SBC_IE_CH_MD_JOINT | A2DP_SBC_IE_CH_MD_STEREO |
                   A2DP_SBC_IE_CH_MD_DUAL)) {
      codec_capability_.channel_mode |= BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO;
    }

    // No user preference - use the codec audio config
    if (select_audio_channel_mode(&codec_audio_config_, ch_mode,
                                  &result_config_cie, &codec_config_)) {
      break;
    }

    // No user preference - try the default config
    if (select_best_channel_mode(
            a2dp_sbc_default_config.ch_mode & sink_info_cie.ch_mode,
            &result_config_cie, &codec_config_)) {
      break;
    }

    // No user preference - use the best match
    if (select_best_channel_mode(ch_mode, &result_config_cie, &codec_config_)) {
      break;
    }
  } while (false);
  if (codec_config_.channel_mode == BTAV_A2DP_CODEC_CHANNEL_MODE_NONE) {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match channel mode: source caps = 0x%x "
              "sink info = 0x%x",
              __func__, a2dp_sbc_caps.ch_mode, sink_info_cie.ch_mode);
    goto fail;
  }

  //
  // Select the block length
  //
  block_len = a2dp_sbc_caps.block_len & sink_info_cie.block_len;
  if (block_len & A2DP_SBC_IE_BLOCKS_16) {
    result_config_cie.block_len = A2DP_SBC_IE_BLOCKS_16;
  } else if (block_len & A2DP_SBC_IE_BLOCKS_12) {
    result_config_cie.block_len = A2DP_SBC_IE_BLOCKS_12;
  } else if (block_len & A2DP_SBC_IE_BLOCKS_8) {
    result_config_cie.block_len = A2DP_SBC_IE_BLOCKS_8;
  } else if (block_len & A2DP_SBC_IE_BLOCKS_4) {
    result_config_cie.block_len = A2DP_SBC_IE_BLOCKS_4;
  } else {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match block length: source caps = 0x%x "
              "sink info = 0x%x",
              __func__, a2dp_sbc_caps.block_len, sink_info_cie.block_len);
    goto fail;
  }

  //
  // Select the number of sub-bands
  //
  num_subbands = a2dp_sbc_caps.num_subbands & sink_info_cie.num_subbands;
  if (num_subbands & A2DP_SBC_IE_SUBBAND_8) {
    result_config_cie.num_subbands = A2DP_SBC_IE_SUBBAND_8;
  } else if (num_subbands & A2DP_SBC_IE_SUBBAND_4) {
    result_config_cie.num_subbands = A2DP_SBC_IE_SUBBAND_4;
  } else {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match number of sub-bands: source caps = 0x%x "
              "sink info = 0x%x",
              __func__, a2dp_sbc_caps.num_subbands, sink_info_cie.num_subbands);
    goto fail;
  }

  //
  // Select the allocation method
  //
  alloc_method = a2dp_sbc_caps.alloc_method & sink_info_cie.alloc_method;
  if (alloc_method & A2DP_SBC_IE_ALLOC_MD_L) {
    result_config_cie.alloc_method = A2DP_SBC_IE_ALLOC_MD_L;
  } else if (alloc_method & A2DP_SBC_IE_ALLOC_MD_S) {
    result_config_cie.alloc_method = A2DP_SBC_IE_ALLOC_MD_S;
  } else {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match allocation method: source caps = 0x%x "
              "sink info = 0x%x",
              __func__, a2dp_sbc_caps.alloc_method, sink_info_cie.alloc_method);
    goto fail;
  }

  //
  // Select the min/max bitpool
  //
  result_config_cie.min_bitpool = a2dp_sbc_caps.min_bitpool;
  if (result_config_cie.min_bitpool < sink_info_cie.min_bitpool)
    result_config_cie.min_bitpool = sink_info_cie.min_bitpool;
  result_config_cie.max_bitpool = a2dp_sbc_caps.max_bitpool;
  if (result_config_cie.max_bitpool > sink_info_cie.max_bitpool)
    result_config_cie.max_bitpool = sink_info_cie.max_bitpool;
  if (result_config_cie.min_bitpool > result_config_cie.max_bitpool) {
    LOG_ERROR(LOG_TAG,
              "%s: cannot match min/max bitpool: "
              "source caps min/max = 0x%x/0x%x sink info min/max = 0x%x/0x%x",
              __func__, a2dp_sbc_caps.min_bitpool, a2dp_sbc_caps.max_bitpool,
              sink_info_cie.min_bitpool, sink_info_cie.max_bitpool);
    goto fail;
  }

  if (A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie,
                        p_result_codec_config) != A2DP_SUCCESS) {
    goto fail;
  }

  //
  // Copy the codec-specific fields if they are not zero
  //
  if (codec_user_config_.codec_specific_1 != 0)
    codec_config_.codec_specific_1 = codec_user_config_.codec_specific_1;
  if (codec_user_config_.codec_specific_2 != 0)
    codec_config_.codec_specific_2 = codec_user_config_.codec_specific_2;
  if (codec_user_config_.codec_specific_3 != 0)
    codec_config_.codec_specific_3 = codec_user_config_.codec_specific_3;
  if (codec_user_config_.codec_specific_4 != 0)
    codec_config_.codec_specific_4 = codec_user_config_.codec_specific_4;

  // Create a local copy of the peer codec capability/config, and the
  // result codec config.
  if (is_capability) {
    status = A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &sink_info_cie,
                               ota_codec_peer_capability_);
  } else {
    status = A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &sink_info_cie,
                               ota_codec_peer_config_);
  }
  CHECK(status == A2DP_SUCCESS);
  status = A2DP_BuildInfoSbc(AVDT_MEDIA_TYPE_AUDIO, &result_config_cie,
                             ota_codec_config_);
  CHECK(status == A2DP_SUCCESS);
  return true;

fail:
  // Restore the internal state
  codec_config_ = saved_codec_config;
  codec_capability_ = saved_codec_capability;
  codec_user_config_ = saved_codec_user_config;
  codec_audio_config_ = saved_codec_audio_config;
  memcpy(ota_codec_config_, saved_ota_codec_config, sizeof(ota_codec_config_));
  memcpy(ota_codec_peer_capability_, saved_ota_codec_peer_capability,
         sizeof(ota_codec_peer_capability_));
  memcpy(ota_codec_peer_config_, saved_ota_codec_peer_config,
         sizeof(ota_codec_peer_config_));
  return false;
}

A2dpCodecConfigSbcSink::A2dpCodecConfigSbcSink()
    : A2dpCodecConfig(BTAV_A2DP_CODEC_INDEX_SINK_SBC, "SBC(Sink)") {}

A2dpCodecConfigSbcSink::~A2dpCodecConfigSbcSink() {}

bool A2dpCodecConfigSbcSink::init() {
  if (!isValid()) return false;

  return true;
}

bool A2dpCodecConfigSbcSink::setCodecConfig(
    UNUSED_ATTR const uint8_t* p_peer_codec_info,
    UNUSED_ATTR bool is_capability,
    UNUSED_ATTR uint8_t* p_result_codec_config) {
  // TODO: This method applies only to Source codecs
  return false;
}

bool A2dpCodecConfigSbcSink::updateEncoderUserConfig(
    UNUSED_ATTR const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params,
    UNUSED_ATTR bool* p_restart_input, UNUSED_ATTR bool* p_restart_output,
    UNUSED_ATTR bool* p_config_updated) {
  // TODO: This method applies only to Source codecs
  return false;
}
