// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <audio-proto-utils/format-utils.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>

#include "debug-logging.h"
#include "usb-audio-device.h"
#include "usb-audio-path.h"
#include "usb-audio-stream-interface.h"

namespace audio {
namespace usb {

// We use our parent's log prefix
const char* UsbAudioStreamInterface::log_prefix() const {
    return parent_.log_prefix();
}

fbl::unique_ptr<UsbAudioStreamInterface> UsbAudioStreamInterface::Create(
        UsbAudioDevice* parent,
        DescriptorListMemory::Iterator* iter) {
    ZX_DEBUG_ASSERT(parent != nullptr);
    ZX_DEBUG_ASSERT(iter != nullptr);

    auto ihdr = iter->hdr_as<usb_interface_descriptor_t>();
    ZX_DEBUG_ASSERT(ihdr);  // The caller should have already verified this.
    uint8_t iid = ihdr->bInterfaceNumber;

    fbl::AllocChecker ac;
    fbl::unique_ptr<UsbAudioStreamInterface> ret(
            new (&ac) UsbAudioStreamInterface(parent, iter->desc_list(), iid));
    if (ac.check()) {
        zx_status_t res = ret->AddInterface(iter);
        if (res == ZX_OK) {
            return ret;
        }
        LOG_EX(ERROR, *parent,
              "Failed to add initial interface (id %u) to UsbAudioStreamInterface (res %d)\n",
              iid, res);
    } else {
        iter->Next(); // Success or failure, we are expected to consume this header.
        LOG_EX(ERROR, *parent,
               "Out of memory attempting to allocate UsbAudioStreamInterface (id %u)\n", iid);
    }

    return nullptr;
}

zx_status_t UsbAudioStreamInterface::AddInterface(DescriptorListMemory::Iterator* iter) {
    // All of these checks should have been made by the caller already.
    ZX_DEBUG_ASSERT(iter != nullptr);
    ZX_DEBUG_ASSERT(iter->desc_list() == desc_list_);

    auto ihdr = iter->hdr_as<usb_interface_descriptor_t>();
    ZX_DEBUG_ASSERT(ihdr != nullptr);
    ZX_DEBUG_ASSERT(ihdr->bInterfaceNumber == iid());

    // No matter what, we need to consume the current descriptor header.
    iter->Next();

    // Make sure that this header represents a unique alternate setting.
    auto alt_id = ihdr->bAlternateSetting;
    auto fmt_iter = formats_.find_if([alt_id](const Format& fmt) -> bool {
                                        return alt_id == fmt.alt_id();
                                    });
    if (fmt_iter.IsValid() || ((idle_hdr_ && (idle_hdr_->bAlternateSetting == alt_id)))) {
        LOG(WARN,
            "Skipping duplicate alternate setting ID in streaming interface descriptor.  "
            "(iid %u, alt_id %u)\n",
            ihdr->bInterfaceNumber, alt_id);
        // Don't return an error if we encounter a malformed header.  Just skip
        // it and do the best we can with what we have.
        return ZX_OK;
    }

    // Examine the next descriptor.  If it is an audio streaming class specific
    // interface descriptor, then this top level descriptor is part of a
    // described format.  Otherwise, this is an empty alternate interface which
    // is probably meant to be selected when this streaming interface is idle
    // and should not be using any bus resources.
    auto next_hdr = iter->hdr_as<usb_audio_desc_header>();
    if ((next_hdr != nullptr) &&
        (next_hdr->bDescriptorType == USB_AUDIO_CS_INTERFACE) &&
        (next_hdr->bDescriptorSubtype == USB_AUDIO_AS_GENERAL)) {
        auto aud_hdr = iter->hdr_as<usb_audio_as_header_desc>();
        iter->Next();

        if (aud_hdr == nullptr) {
            LOG(WARN,
                "Skipping badly formed alternate setting ID in streaming interface descriptor "
                "(iid %u, alt_id %u).\n",
                ihdr->bInterfaceNumber, alt_id);
            return ZX_OK;
        }

        fbl::AllocChecker ac;
        auto format = fbl::make_unique_checked<Format>(&ac, this, iter->desc_list(), ihdr, aud_hdr);
        if (!ac.check()) {
            LOG(ERROR, "Out of memory attempt to add Format to StreamInterface\n");
            return ZX_ERR_NO_MEMORY;
        }

        zx_status_t status = format->Init(iter);
        if (status != ZX_OK) {
            LOG(WARN,
                "Skipping bad format streaming interface descriptor.  (iid %u, alt_id %u)\n",
                ihdr->bInterfaceNumber, alt_id);
            return ZX_OK;
        }

        // Make sure that the endpoint address and terminal link ID of this
        // format matches all previously encountered formats.
        //
        // TODO(johngro) : It is unclear whether or not it makes any sense to
        // have formats which link to different audio paths or have different
        // endpoint addresses (implying potentially different directions).  For
        // now we simply skip these formats if we encounter them.
        //
        // If we ever encounter a device which has a mix of these parameters, we
        // need come back and determine if there is a good generic approach for
        // dealing with the situation.
        if (!formats_.is_empty()) {
            if (format->term_link() != term_link_) {
                LOG(WARN,
                    "Skipping format (iid %u, alt_id %u) with non-uniform terminal ID "
                    "(expected %u, got %u)\n",
                    ihdr->bInterfaceNumber, alt_id, term_link_, format->term_link());
                return ZX_OK;
            }

            if ((format->ep_addr() != ep_addr_) || (format->ep_attr() != ep_attr_)) {
                LOG(ERROR,
                    "Skipping format (iid %u, alt_id %u) with non-uniform endpoint "
                    "address/attributes (expected 0x%02x/0x%02x, got 0x%02x/0x%02x)\n",
                    ihdr->bInterfaceNumber, alt_id,
                    ep_addr_, ep_attr_,
                    format->ep_addr(), format->ep_attr());
                return ZX_OK;
            }
        } else {
            term_link_ = format->term_link();
            ep_addr_   = format->ep_addr();
            ep_attr_   = format->ep_attr();
        }

        max_req_size_ = fbl::max(max_req_size_, format->max_req_size());
        formats_.push_back(fbl::move(format));
    } else {
        if (idle_hdr_ == nullptr) {
            idle_hdr_ = ihdr;
        } else {
            LOG(WARN,
                "Skipping duplicate \"idle\" interface descriptor in streaming interface "
                "descriptor.  (iid %u, alt_id %u)\n",
                ihdr->bInterfaceNumber, ihdr->bAlternateSetting);
        }
    }

    return ZX_OK;
}

zx_status_t UsbAudioStreamInterface::BuildFormatMap() {
    if (format_map_.size()) {
        LOG(WARN, "Attempted to re-build format map for streaming interface (iid %u)\n", iid());
        return ZX_ERR_BAD_STATE;
    }

    // Make a pass over our list of formats and figure out how big our format
    // map vector may need to be.
    //
    // Note: this is a rough worst case bound on how big the vector needs to be.
    // Someday, we could come back here and compute a much tighter bound if we
    // wanted to.
    size_t worst_case_map_entries = 0;
    for (const auto& fmt : formats_) {
        // A frame rate count of 0 indicates a continuous format range which
        // requires only one format range entry.
        worst_case_map_entries += fmt.frame_rate_cnt() ? fmt.frame_rate_cnt() : 1;
    }

    // Now reserve our memory.
    fbl::AllocChecker ac;
    format_map_.reserve(worst_case_map_entries, &ac);
    if (!ac.check()) {
        LOG(ERROR, "Out of memory attempting to reserve %zu format ranges\n",
            worst_case_map_entries);
        return ZX_ERR_NO_MEMORY;
    }

    // Now iterate over our set and build the map.
    for (const auto& fmt : formats_) {
        // Record the min/max number of channels.
        audio_stream_format_range_t range;
        range.min_channels = fmt.ch_count();
        range.max_channels = fmt.ch_count();

        // Encode the sample container type from the type I format descriptor
        // as an audio device driver audio_sample_format_t.  If we encounter
        // anything that we don't know how to encode, log a warning and skip the
        // format.
        //
        auto tag = fmt.format_tag();
        if (tag == USB_AUDIO_AS_FT_PCM8) {
            if ((fmt.bit_resolution() != 8) || (fmt.subframe_bytes() != 1)) {
                LOG(WARN, "Skipping PCM8 format with invalid bit res/subframe size (%u/%u)\n",
                    fmt.bit_resolution(), fmt.subframe_bytes());
                continue;
            }
            range.sample_formats = static_cast<audio_sample_format_t>(
                    AUDIO_SAMPLE_FORMAT_8BIT | AUDIO_SAMPLE_FORMAT_FLAG_UNSIGNED);
        } else
        if (tag == USB_AUDIO_AS_FT_IEEE_FLOAT) {
            if ((fmt.bit_resolution() != 32) || (fmt.subframe_bytes() != 4)) {
                LOG(WARN, "Skipping IEEE_FLOAT format with invalid bit res/subframe size (%u/%u)\n",
                    fmt.bit_resolution(), fmt.subframe_bytes());
                continue;
            }
            range.sample_formats = AUDIO_SAMPLE_FORMAT_32BIT_FLOAT;
        } else
        if (tag == USB_AUDIO_AS_FT_PCM) {
            switch (fmt.bit_resolution()) {
            case 8:
            case 16:
            case 32: {
                if (fmt.subframe_bytes() != (fmt.bit_resolution() >> 3)) {
                    LOG(WARN,
                        "Skipping PCM format.  Subframe size (%u bytes) does not "
                        "match Bit Res (%u bits)\n",
                        fmt.bit_resolution(),
                        fmt.subframe_bytes());
                    continue;
                }
                switch (fmt.bit_resolution()) {
                case 8:  range.sample_formats = AUDIO_SAMPLE_FORMAT_8BIT; break;
                case 16: range.sample_formats = AUDIO_SAMPLE_FORMAT_16BIT; break;
                case 32: range.sample_formats = AUDIO_SAMPLE_FORMAT_32BIT; break;
                }
            } break;

            case 20:
            case 24: {
                if ((fmt.subframe_bytes() != 3) && (fmt.subframe_bytes() != 4)) {
                    LOG(WARN,
                        "Skipping PCM format.  %u-bit audio must be packed into a 3 "
                        "or 4 byte subframe (Subframe size %u)\n",
                        fmt.bit_resolution(),
                        fmt.subframe_bytes());
                    continue;
                }
                switch (fmt.bit_resolution()) {
                case 20:
                    range.sample_formats = ((fmt.subframe_bytes() == 3)
                                            ? AUDIO_SAMPLE_FORMAT_20BIT_PACKED
                                            : AUDIO_SAMPLE_FORMAT_20BIT_IN32);
                    break;
                case 24:
                    range.sample_formats = ((fmt.subframe_bytes() == 3)
                                            ? AUDIO_SAMPLE_FORMAT_24BIT_PACKED
                                            : AUDIO_SAMPLE_FORMAT_24BIT_IN32);
                    break;
                }
            } break;

            default:
                LOG(WARN, "Skipping PCM format with unsupported bit res (%u bits)\n",
                    fmt.bit_resolution());
                continue;
            }
        } else {
            LOG(WARN, "Skipping unsupported format tag (%u)\n", tag);
            continue;
        }

        // Now pack the supported frame rates.  A format with a frame rate count of
        // 0 is a continuous range of frame rates.  Otherwise, we pack each discrete
        // frame rate as an individual entry.
        //
        // TODO(johngro) : Discrete frame rates could be encoded more compactly
        // if wanted to do so by extracting all of the 48k and 44.1k rates into
        // a bitmask, and then putting together ranges which represented
        // continuous runs of frame rates in each of the families.
        if (fmt.frame_rate_cnt()) {
            for (uint8_t i = 0; i < fmt.frame_rate_cnt(); ++i) {
                uint32_t rate = fmt.frame_rate(i);
                range.min_frames_per_second = rate;
                range.max_frames_per_second = rate;

                if (audio::utils::FrameRateIn48kFamily(rate)) {
                    range.flags = ASF_RANGE_FLAG_FPS_48000_FAMILY;
                } else
                if (audio::utils::FrameRateIn441kFamily(rate)) {
                    range.flags = ASF_RANGE_FLAG_FPS_44100_FAMILY;
                } else {
                    range.flags = ASF_RANGE_FLAG_FPS_CONTINUOUS;
                }

                format_map_.push_back({ range, fmt.alt_id(), fmt.ep_addr(), fmt.max_req_size() });
            }
        } else {
            range.min_frames_per_second = fmt.min_cont_frame_rate();
            range.max_frames_per_second = fmt.max_cont_frame_rate();
            range.flags = ASF_RANGE_FLAG_FPS_CONTINUOUS;
            format_map_.push_back({ range, fmt.alt_id(), fmt.ep_addr(), fmt.max_req_size() });
        }
    }

    // If we failed to encode *any* valid format ranges, log a warning and
    // return an error.  This stream interface is not going to be useful to us.
    if (format_map_.is_empty()) {
        LOG(WARN, "Failed to find any usable formats for streaming interface (iid %u)\n", iid());
        return ZX_ERR_NOT_SUPPORTED;
    }

    return ZX_OK;
}

zx_status_t UsbAudioStreamInterface::LookupFormat(uint32_t frames_per_second,
                                                  uint16_t channels,
                                                  audio_sample_format_t sample_format,
                                                  size_t* out_format_ndx) {
    if (out_format_ndx == nullptr) {
        return ZX_ERR_INVALID_ARGS;
    }

    *out_format_ndx = format_map_.size();

    // Search our format map to find the alternate interface setting which
    // supports the requested format.
    for (size_t i = 0; i < format_map_.size(); ++i) {
        if (audio::utils::FormatIsCompatible(frames_per_second,
                                             channels,
                                             sample_format,
                                             format_map_[i].range_)) {
            *out_format_ndx = i;
            return ZX_OK;
        }
    }

    return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t UsbAudioStreamInterface::ActivateFormat(size_t ndx, uint32_t frames_per_second) {
    if (ndx >= format_map_.size()) {
        return ZX_ERR_INVALID_ARGS;
    }

    // Select the interface used for this format, then configure the endpoint
    // for the requested frame rate.  user know what the maximum request size is
    // for this interface.
    zx_status_t status;
    const auto& f = format_map_[ndx];
    status = usb_set_interface(&parent_.usb_proto(), iid(), f.alt_id_);
    if (status != ZX_OK) {
        LOG(ERROR,
            "Failed to select interface (id %u, alt %u, ep %u) "
            "when configuring format ndx %zu (status %d)\n",
            iid(), f.alt_id_, f.ep_addr_, ndx, status);
        return status;
    }

    // Do not attempt to set the sample rate if the endpoint supports
    // only one.  In theory, devices should ignore this request, but in
    // practice, some devices will refuse the command entirely, and we
    // will get ZX_ERR_IO_REFUSED back from the bus driver.
    //
    // Note: This method of determining whether or not an endpoint
    // supports only a single rate only works here because we currently
    // demand that all of our formats share a single endpoint address.
    // If this changes in the future, this heuristic will need to be
    // revisited.
    bool single_rate = (format_map_.size() == 1) &&
                      !(format_map_[0].range_.flags & ASF_RANGE_FLAG_FPS_CONTINUOUS);
    if (!single_rate) {
        // See section 5.2.3.2.3.1 of the USB Audio 1.0 spec.
        uint8_t buffer[3];
        buffer[0] = static_cast<uint8_t>(frames_per_second);
        buffer[1] = static_cast<uint8_t>(frames_per_second >> 8);
        buffer[2] = static_cast<uint8_t>(frames_per_second >> 16);
        status = usb_control(&parent_.usb_proto(),
                             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
                             USB_AUDIO_SET_CUR,
                             USB_AUDIO_SAMPLING_FREQ_CONTROL << 8,
                             f.ep_addr_,
                             &buffer, sizeof(buffer), ZX_TIME_INFINITE, NULL);
        if (status != ZX_OK) {
            if (status == ZX_ERR_IO_REFUSED || status == ZX_ERR_IO_INVALID) {
                // clear the stall/error
                usb_reset_endpoint(&parent_.usb_proto(), f.ep_addr_);
            }

            LOG(ERROR, "Failed to set frame rate %u for ep address %u (status %d)\n",
                frames_per_second, f.ep_addr_, status);

            return status;
        }
    }

    return ZX_OK;
}

zx_status_t UsbAudioStreamInterface::ActivateIdleFormat() {
    if (idle_hdr_ == nullptr) {
        return ZX_ERR_NOT_SUPPORTED;
    }

    ZX_DEBUG_ASSERT(idle_hdr_->bInterfaceNumber == iid());
    return usb_set_interface(&parent_.usb_proto(), iid(), idle_hdr_->bAlternateSetting);
}

void UsbAudioStreamInterface::LinkPath(fbl::unique_ptr<AudioPath> path) {
    ZX_DEBUG_ASSERT(path != nullptr);
    ZX_DEBUG_ASSERT(path_ == nullptr);
    ZX_DEBUG_ASSERT(direction() == path->direction());
    ZX_DEBUG_ASSERT(term_link() == path->stream_terminal().id());
    path_ = fbl::move(path);
}

zx_status_t UsbAudioStreamInterface::Format::Init(DescriptorListMemory::Iterator* iter) {
    ZX_DEBUG_ASSERT(iter != nullptr);
    ZX_DEBUG_ASSERT(iter->desc_list() == desc_list_);

    // Skip formats tags that we currently do not support or know how to deal
    // with.  Right now, we only deal with the linear PCM forms of Type I audio
    // formats.
    switch (class_hdr_->wFormatTag) {
    case USB_AUDIO_AS_FT_PCM:
    case USB_AUDIO_AS_FT_PCM8:
    case USB_AUDIO_AS_FT_IEEE_FLOAT:
        break;

    default:
        LOG(ERROR,
            "Unsupported format tag (0x%04hx) in class specific audio stream interface "
            "(iid %u, alt_id %u)\n",
            class_hdr_->wFormatTag, interface_hdr_->bInterfaceNumber, alt_id());
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Next go looking for the other headers we will need in order to operate.
    // In specific, we need to find an audio format descriptor (specifically a
    // Type I descriptor), a general USB Endpoint descriptor, and a audio class
    // specific endpoint descriptor.
    //
    // If we encounter something which is not one of these things, then we have
    // run out of headers to parse.
    //
    // If we encounter duplicates of these descriptors, or we encounter
    // something clearly incompatible (such as a type II or type III format
    // descriptor), then we are confused and this interface should be ignored.
    // Be sure to skip headers like this if we return from the middle of the
    // do/while loop below.
    auto cleanup = fbl::MakeAutoCall([iter]() { iter->Next(); });
    do {
        auto hdr = iter->hdr();
        if (hdr == nullptr) {
            break;
        }

        if (hdr->bDescriptorType == USB_AUDIO_CS_INTERFACE) {
            // Stop parsing if this is not an audio format type descriptor
            auto ihdr = iter->hdr_as<usb_audio_desc_header>();
            if ((ihdr == nullptr) || (ihdr->bDescriptorSubtype != USB_AUDIO_AS_FORMAT_TYPE)) {
                break;
            }

            auto fmt_hdr = iter->hdr_as<usb_audio_as_format_type_hdr>();
            if (fmt_hdr == nullptr) {
                break;
            }

            if (fmt_hdr->bFormatType != USB_AUDIO_FORMAT_TYPE_I) {
                LOG(ERROR,
                    "Unsupported format type (%u) in class specific audio stream format type "
                    "interface (iid %u, alt_id %u)\n",
                    fmt_hdr->bFormatType, interface_hdr_->bInterfaceNumber, alt_id());
                return ZX_ERR_NOT_SUPPORTED;
            }

            auto fmt_desc = iter->hdr_as<usb_audio_as_format_type_i_desc>();
            if ((fmt_desc_ != nullptr) || (fmt_desc == nullptr)) {
                LOG(ERROR,
                    "Malformed or duplicate type 1 format type descriptor in class specific audio "
                    "interface (iid %u, alt_id %u)\n",
                    interface_hdr_->bInterfaceNumber, alt_id());
                return ZX_ERR_NOT_SUPPORTED;
            }

            // Stash the pointer, we'll sanity check a bit more once we are finished finding
            // headers.
            fmt_desc_ = fmt_desc;
        } else
        if (hdr->bDescriptorType == USB_DT_ENDPOINT) {
            auto ep_desc = iter->hdr_as<usb_endpoint_descriptor_t>();
            if (ep_desc == nullptr) {
                LOG(ERROR,
                    "Malformed standard endpoint descriptor in class specific audio interface "
                    "(iid %u, alt_id %u)\n",
                    interface_hdr_->bInterfaceNumber, alt_id());
                return ZX_ERR_NOT_SUPPORTED;
            }

            // TODO(johngro): Come back and fix this.  There are devices with
            // multiple isochronous endpoints per format interface.  Device
            // which use an isochronous output endpoint with an Asynchronous
            // sync type seem to have an isochronous input endpoint as well
            // which is probably used for clock recovery.  Instead of
            // skipping/ignoring this endpoint, we really should be using it to
            // recover the device clock.
            if (ep_desc_ != nullptr) {
                LOG(WARN,
                    "Skipping duplicate standard endpoint descriptor in class specific audio "
                    "interface (iid %u, alt_id %u, ep_addr %u)\n",
                    interface_hdr_->bInterfaceNumber, alt_id(), ep_desc->bEndpointAddress);
            } else {
                if ((usb_ep_type(ep_desc) != USB_ENDPOINT_ISOCHRONOUS) ||
                    (usb_ep_sync_type(ep_desc) == USB_ENDPOINT_NO_SYNCHRONIZATION)) {
                    LOG(WARN,
                        "Skipping endpoint descriptor with unsupported attributes "
                        "interface (iid %u, alt_id %u, ep_attr 0x%02x)\n",
                        interface_hdr_->bInterfaceNumber, alt_id(), ep_desc->bmAttributes);
                } else {
                    ep_desc_ = ep_desc;
                }
            }
        } else
        if (hdr->bDescriptorType == USB_AUDIO_CS_ENDPOINT) {
            // Stop parsing if this is not a class specific AS isochronous endpoint descriptor
            auto ihdr = iter->hdr_as<usb_audio_desc_header>();
            if ((ihdr == nullptr) || (ihdr->bDescriptorSubtype != USB_AUDIO_EP_GENERAL)) {
                break;
            }

            auto class_ep_desc = iter->hdr_as<usb_audio_as_isoch_ep_desc>();
            if (class_ep_desc == nullptr) {
                LOG(ERROR,
                    "Malformed or class specific endpoint descriptor in class specific audio "
                    "interface (iid %u, alt_id %u)\n",
                    interface_hdr_->bInterfaceNumber, alt_id());
                return ZX_ERR_NOT_SUPPORTED;
            }

            if (class_ep_desc_ != nullptr) {
                LOG(WARN,
                    "Skipping duplicate class specific endpoint descriptor in class specific "
                    "audio interface (iid %u, alt_id %u\n",
                    interface_hdr_->bInterfaceNumber, alt_id());
            } else {
                class_ep_desc_ = class_ep_desc;
            }
        } else {
            // We don't recognize this descriptor, so we have run out of
            // descriptors that we beleive belong to this format.  Move on to
            // sanity checks.
            break;
        }
    } while (iter->Next());
    cleanup.cancel();

    // Sanity check what we have found so far.  Right now, we need to have found...
    //
    // 1) A Type I audio format type descriptor (PCM)
    // 2) A standard Isochronous USB endpoint descriptor.
    // 3) An audio class specific endpoint descriptor.
    //
    // In addition, we need to make sure that the range of frame rates present
    // in the Type I descriptor makes sense.  If the range is continuous, the
    // array must contain *exactly* 2 entries.  If the range is discrete, then
    // the array must contain an integer number of entries, and must contain at
    // least one entry.
    if ((fmt_desc_ == nullptr) || (ep_desc_ == nullptr) || (class_ep_desc_ == nullptr)) {
        LOG(ERROR,
            "Missing one or more required descriptors in audio interface (iid %u, alt_id %u); "
            "Missing%s%s%s\n",
            interface_hdr_->bInterfaceNumber, alt_id(),
            (fmt_desc_ == nullptr) ? " [Type I Format Type Descriptor]" : "",
            (ep_desc_ == nullptr) ? " [Standard Endpoint Descriptor]" : "",
            (class_ep_desc_  == nullptr) ? " [Class Endpoint Descriptor]" : "");
        return ZX_ERR_NOT_SUPPORTED;
    }

    // hdr_as<> should have already verified this for us.
    ZX_DEBUG_ASSERT(fmt_desc_->bLength >= sizeof(*fmt_desc_));

    // Sanity check the size of the frame rate table.
    size_t expected_bytes = (frame_rate_cnt() ? frame_rate_cnt() : 2)
                          * sizeof(usb_audio_as_samp_freq);
    size_t extra_bytes = fmt_desc_->bLength - sizeof(*fmt_desc_);
    if (expected_bytes != extra_bytes) {
        LOG(ERROR,
            "Bad frame rate table size in type 1 audio format type descriptor in audio interface "
            "(iid %u, alt_id %u).  Expected %zu, Got %zu\n",
            interface_hdr_->bInterfaceNumber, alt_id(), expected_bytes, extra_bytes);
        return ZX_ERR_INTERNAL;
    }

    // If this is a continuous range of frame rates, then the min/max order needs to be correct.
    if ((frame_rate_cnt() == 0) && (min_cont_frame_rate() > max_cont_frame_rate())) {
        LOG(ERROR,
            "Invalid continuous frame rate range [%u, %u] type 1 audio format type descriptor in "
            "audio interface (iid %u, alt_id %u).\n",
            min_cont_frame_rate(), max_cont_frame_rate(),
            interface_hdr_->bInterfaceNumber, alt_id());
        return ZX_ERR_INTERNAL;
    }

    return ZX_OK;
}

}  // namespace usb
}  // namespace audio
