// 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 <fbl/algorithm.h>
#include <limits>
#include <math.h>
#include <utility>

#include "debug-logging.h"
#include "usb-audio-units.h"

namespace audio {
namespace usb {

// a small internal helper methods which handles a bunch of ugly casting for us.
template <typename T, typename U>
static inline const T* offset_ptr(const U* p, size_t offset) {
    return ((offset + sizeof(T)) <= p->bLength)
        ? reinterpret_cast<const T*>(reinterpret_cast<uintptr_t>(p) + offset)
        : nullptr;
}

const char* AudioUnit::type_name() const {
    switch (type()) {
        case Type::InputTerminal:  return "InputTerminal";
        case Type::OutputTerminal: return "OutputTerminal";
        case Type::MixerUnit:      return "MixerUnit";
        case Type::SelectorUnit:   return "SelectorUnit";
        case Type::FeatureUnit:    return "FeatureUnit";
        case Type::ProcessingUnit: return "ProcessingUnit";
        case Type::ExtensionUnit:  return "ExtensionUnit";
        default:                   return "<Unknown>";
    }
}

fbl::RefPtr<AudioUnit> AudioUnit::Create(const DescriptorListMemory::Iterator& iter, uint8_t iid) {
    auto hdr = iter.hdr_as<usb_audio_desc_header>();

    // This should already have been verified by the code calling us.
    ZX_DEBUG_ASSERT(hdr != nullptr);

    switch (hdr->bDescriptorSubtype) {
        case USB_AUDIO_AC_INPUT_TERMINAL:   return InputTerminal::Create(iter, iid);
        case USB_AUDIO_AC_OUTPUT_TERMINAL:  return OutputTerminal::Create(iter, iid);
        case USB_AUDIO_AC_MIXER_UNIT:       return MixerUnit::Create(iter, iid);
        case USB_AUDIO_AC_SELECTOR_UNIT:    return SelectorUnit::Create(iter, iid);
        case USB_AUDIO_AC_FEATURE_UNIT:     return FeatureUnit::Create(iter, iid);
        case USB_AUDIO_AC_PROCESSING_UNIT:  return ProcessingUnit::Create(iter, iid);
        case USB_AUDIO_AC_EXTENSION_UNIT:   return ExtensionUnit::Create(iter, iid);
        default:
            GLOBAL_LOG(WARN, "Unrecognized audio control descriptor (type %u) @ offset %zu\n",
                       hdr->bDescriptorSubtype, iter.offset());
            return nullptr;
    }
}

zx_status_t AudioUnit::CtrlReq(const usb_protocol_t& proto,
                               uint8_t code, uint16_t val, uint16_t len, void* data) {
    if (!len || (data == nullptr)) {
        return ZX_ERR_INVALID_ARGS;
    }

    // For audio class specific control codes, get control codes all have their MSB set.
    uint8_t req_type = (code & 0x80)
                     ? USB_DIR_IN  | USB_TYPE_CLASS | USB_RECIP_INTERFACE
                     : USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;

    // TODO(johngro) : See about fixing the use of const in the C API for the
    // USB bus protocol.  There is no good reason why a usb_protocol structure
    // should need to be mutable when performing operations such as usb_control.
    auto proto_ptr = const_cast<usb_protocol_t*>(&proto);

    // TODO(johngro) : Do better than this if we can.
    //
    // None of these control transactions should every take any
    // significant amount of time, and if the turn out to do so, then we really
    // need to find a way to use the USB bus driver in an asynchronous fashion.
    // Even 500 mSec is just *way* too long to ever block a driver thread, for
    // pretty much any reason.  Right now, this timeout is here only for safety
    // reasons; it would be better to timeout after a half of a second then to
    // block the entire USB device forever.
    //
    // It is tempting to simply kill the driver/process if we ever timeout on
    // one of these operations, but at time this code was written, that would
    // kill the entire USB bus driver.  So, for now, we eat the timeout and rely
    // on the code above us taking some action to shut this device down.
    constexpr uint64_t kRelativeTimeout = ZX_MSEC(500);
    size_t done = 0;
    zx_status_t status = usb_control(proto_ptr, req_type, code, val, index(), data, len,
                                     zx_deadline_after(kRelativeTimeout), &done);
    if ((status == ZX_OK) && (done != len)) {
        status = ZX_ERR_BUFFER_TOO_SMALL;
    }

    if (status != ZX_OK) {
        GLOBAL_LOG(WARN,
                   "WARNING: Audio control request failed! Unit (%s:id %u), "
                   "code 0x%02x val 0x%04hx, ndx 0x%04x [bytes expected %u, got %zu] (status %d)\n",
                   type_name(), id(), code, val, index(), len, done, status);
    }

    return status;
}

fbl::RefPtr<InputTerminal> InputTerminal::Create(const DescriptorListMemory::Iterator& iter,
                                                 uint8_t iid) {
    auto hdr = iter.hdr_as<usb_audio_ac_input_terminal_desc>();

    if (hdr == nullptr) {
        GLOBAL_LOG(WARN, "InputTerminal header appears invalid @ offset %zu\n", iter.offset());
        return nullptr;
    }

    // TODO(johngro): additional sanity checking and pre-processing goes here.

    fbl::AllocChecker ac;
    auto ret = fbl::AdoptRef(new (&ac) InputTerminal(iter.desc_list(), hdr, iid));
    return ac.check() ? ret : nullptr;
}

fbl::RefPtr<OutputTerminal> OutputTerminal::Create(const DescriptorListMemory::Iterator& iter,
                                                   uint8_t iid) {
    auto hdr = iter.hdr_as<usb_audio_ac_output_terminal_desc>();

    if (hdr == nullptr) {
        GLOBAL_LOG(WARN, "OutputTerminal header appears invalid @ offset %zu\n", iter.offset());
        return nullptr;
    }

    // TODO(johngro): additional sanity checking and pre-processing goes here.

    fbl::AllocChecker ac;
    auto ret = fbl::AdoptRef(new (&ac) OutputTerminal(iter.desc_list(), hdr, iid));
    return ac.check() ? ret : nullptr;
}

fbl::RefPtr<MixerUnit> MixerUnit::Create(const DescriptorListMemory::Iterator& iter, uint8_t iid) {
    // Find the size of each of the inlined variable length arrays in this
    // structure, finding the locations of the constant headers in the process.
    // If anything does not look right, complain and move on.
    auto hdr0 = iter.hdr_as<usb_audio_ac_mixer_unit_desc_0>();
    if (hdr0 != nullptr) {
        size_t off = sizeof(*hdr0) + hdr0->bNrInPins;
        auto hdr1 = offset_ptr<usb_audio_ac_mixer_unit_desc_1>(hdr0, off);
        if (hdr1 != nullptr) {
            // Determining the size of bmControls is a bit of a pain.  To do so,
            // we need to know 'n', which is the sum the number of channels
            // across all of the input pins, and 'm' (which should be
            // hdr1->bNrChannels).  At this stage of parsing our unit/terminal
            // graph, we may not have access to all of the sources which might
            // feed into the calculation of 'n'.  Because of this, for now, just
            // assume that the size of bmControls (in bytes) is equal to the
            // space remaining in the descriptor, demanding that this be at
            // least equal to a single byte (if it was zero, it means that we
            // either have no input or no output channels, neither of which
            // makes sense).
            if (sizeof(usb_audio_ac_mixer_unit_desc_2) < hdr0->bLength) {
                size_t off2 = hdr0->bLength - sizeof(usb_audio_ac_mixer_unit_desc_2);
                if (off2 > off) {
                    auto hdr2 = offset_ptr<usb_audio_ac_mixer_unit_desc_2>(hdr0, off2);
                    ZX_DEBUG_ASSERT(hdr2 != nullptr);

                    // TODO(johngro): additional sanity checking and pre-processing goes here.
                    fbl::AllocChecker ac;
                    auto ret = fbl::AdoptRef(
                            new (&ac) MixerUnit(iter.desc_list(), hdr0, hdr1, hdr2, iid));
                    return ac.check() ? ret : nullptr;
                }
            }
        }
    }

    GLOBAL_LOG(WARN, "MixerUnit header appears invalid @ offset %zu\n", iter.offset());
    return nullptr;
}

fbl::RefPtr<SelectorUnit> SelectorUnit::Create(const DescriptorListMemory::Iterator& iter,
                                               uint8_t iid) {
    // Find the size of each of the inlined variable length arrays in this
    // structure, finding the locations of the constant headers in the process.
    // If anything does not look right, complain and move on.
    auto hdr0 = iter.hdr_as<usb_audio_ac_selector_unit_desc_0>();
    if (hdr0 != nullptr) {
        size_t off = sizeof(*hdr0) + hdr0->bNrInPins;
        auto hdr1 = offset_ptr<usb_audio_ac_selector_unit_desc_1>(hdr0, off);
        if (hdr1 != nullptr) {
            // TODO(johngro): additional sanity checking and pre-processing goes here.
            fbl::AllocChecker ac;
            auto ret = fbl::AdoptRef(new (&ac) SelectorUnit(iter.desc_list(), hdr0, hdr1, iid));
            return ac.check() ? ret : nullptr;
        }
    }

    GLOBAL_LOG(WARN, "SelectorUnit header appears invalid @ offset %zu\n", iter.offset());
    return nullptr;
}

zx_status_t SelectorUnit::Select(const usb_protocol_t& proto, uint8_t upstream_id) {
    // Section 5.2.2.3.3. defines the selector index as being 1s indexed, so
    // zero is an easy to use "invalid" value.
    uint8_t ndx = 0;

    // Find the appropriate index or return an error trying.
    uint32_t cnt = source_count();
    for (uint32_t i = 0; i < cnt; ++i) {
        if (upstream_id == source_id(i)) {
            ndx = static_cast<uint8_t>(i + 1);
            break;
        }
    }

    if (!ndx) {
        return ZX_ERR_INVALID_ARGS;
    }

    // Now go ahead and set the value;
    return CtrlReq(proto, USB_AUDIO_SET_CUR, 0, &ndx);
}

fbl::RefPtr<FeatureUnit> FeatureUnit::Create(const DescriptorListMemory::Iterator& iter,
                                             uint8_t iid) {
    // Find the size of each of the inlined variable length arrays in this
    // structure, finding the locations of the constant headers in the process.
    // If anything does not look right, complain and move on.
    auto hdr0 = iter.hdr_as<usb_audio_ac_feature_unit_desc_0>();
    if (hdr0 != nullptr) {
        // The exact expected size of the Controls bitmap depends on the number
        // of channels feeding this feature unit.  This information is not
        // contained in the feature unit itself, but instead exists upstream of
        // the unit in first unit/terminal which contains a channel cluster
        // element.  At this point in parsing, we have not discovered all of the
        // units present in the audio control interface yet, so we cannot trace
        // upstream to sanity check the size of this field.
        //
        // For now, we perform the most basic check we can by assuming that the
        // size of the Controls bitmap must be...
        //
        // 1) Non-zero, and...
        // 2) Divisible by bControlSize, which must also be non-zero.
        //
        // In the future, more stringent checks can be applied during Probe.
        constexpr size_t kHdrOverhead = sizeof(*hdr0) + sizeof(usb_audio_ac_feature_unit_desc_1);
        size_t ctrl_array_bytes = hdr0->bLength - kHdrOverhead;
        if ((kHdrOverhead < hdr0->bLength) &&
            (hdr0->bControlSize > 0) &&
            (!(ctrl_array_bytes % hdr0->bControlSize))) {
            // Allocate memory for our Features capability array.
            fbl::AllocChecker ac;
            size_t feat_len = ctrl_array_bytes / hdr0->bControlSize;
            auto feat_mem = fbl::unique_ptr<Features[]>(new (&ac) Features[feat_len]);

            if (ac.check()) {
                // We just made sure that this fits, there should be no way for us
                // to have run out of data.
                size_t off = hdr0->bLength - sizeof(usb_audio_ac_feature_unit_desc_1);
                auto hdr1 = offset_ptr<usb_audio_ac_feature_unit_desc_1>(hdr0, off);
                ZX_DEBUG_ASSERT(hdr1 != nullptr);

                auto ret = fbl::AdoptRef(new (&ac) FeatureUnit(iter.desc_list(),
                                                               hdr0, hdr1,
                                                               std::move(feat_mem), feat_len,
                                                               iid));
                if (ac.check()) {
                    return ret;
                }
            }

            GLOBAL_LOG(WARN, "Out of memory attempting to allocate FeatureUnit @ offset %zu\n",
                       iter.offset());
            return nullptr;
        }
    }

    GLOBAL_LOG(WARN, "FeatureUnit header appears invalid @ offset %zu\n", iter.offset());
    return nullptr;
}

zx_status_t FeatureUnit::Probe(const usb_protocol_t& proto) {
    zx_status_t res;

    // Start by going over our channel feature bitmap and extracting the actual
    // feature bits for each channel.  Right now, we demand that the size of
    // each entry be (at most) a 32 bit integer.  The USB Audio 1.0 Spec only
    // defines bits up to bit 9, so we really only understand how to handle up
    // to there.  If we cannot fit each of the bitmap entries in a 32-bit
    // integer, then the USB audio spec has come a long way and someone should
    // come back here and update this driver.
    ZX_DEBUG_ASSERT(feature_desc()->bControlSize != 0); // Create should have checked this already
    if (feature_desc()->bControlSize > sizeof(uint32_t)) {
        GLOBAL_LOG(WARN, "FeatureUnit id %u has unsupported bControlSize > %zu (%u)\n",
                   id(), sizeof(uint32_t), feature_desc()->bControlSize);
        return ZX_ERR_NOT_SUPPORTED;
    }

    for (size_t i = 0; i < features_.size(); ++i) {
        auto& f = features_[i];
        f.supported_ = 0;
        for (uint8_t j = 0; j <feature_desc()->bControlSize; ++j) {
            uint32_t bits = feature_desc()->bmaControls[(i * feature_desc()->bControlSize) + j];
            f.supported_ |= bits << (8 * j);
        }
    }

    // Now, go over our array of features and compute both the union and the
    // intersection of the features for all of the individual channels.
    uint32_t ch_feat_union = 0;
    uint32_t ch_feat_intersection = 0;
    if (features_.size() > 1) {
        ch_feat_union = features_[1].supported_;
        ch_feat_intersection = features_[1].supported_;
        for (size_t i = 2; i < features_.size(); ++i) {
            ch_feat_union |= features_[i].supported_;
            ch_feat_intersection &= features_[i].supported_;

        }
    }

    // Next check for a set of uniformity requirements.  In particular, there
    // are three types of controls (mute, AGC, and volume/gain) that we want to
    // enforce these guarantees for.  Specifically,
    //
    // 1) We can handle these controls at the master level, or the individual
    //    channel level, but we don't really know what to do if the controls
    //    exist at both levels.
    // 2) If we are controlling these things at the individual control level, we
    //    are doing so in a way which mimics a master control knob only.  So, if
    //    we have these controls at the per-channel level, it is important that
    //    they be they be identical for each of the individual channels.
    constexpr uint32_t kUniformControls = USB_AUDIO_FU_BMA_MUTE
                                        | USB_AUDIO_FU_BMA_VOLUME
                                        | USB_AUDIO_FU_BMA_AUTOMATIC_GAIN;
    ZX_DEBUG_ASSERT(features_.size() > 0); // Create should have checked this already
    if (((features_[0].supported_ & ch_feat_union & kUniformControls) != 0) ||  // Check #1
        ((ch_feat_union ^ ch_feat_intersection) & kUniformControls)) {          // Check #2
        GLOBAL_LOG(WARN,
                   "FeatureUnit id %u has unsupported non-uniform gain controls.  "
                   "Master 0x%08x, Channel Union 0x%08x, Channel Intersection 0x%08x.\n",
                   id(), features_[0].supported_, ch_feat_union, ch_feat_intersection);
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Stash bitmaps of controls we care about for later.
    master_feat_ = features_[0].supported_ & kUniformControls;
    ch_feat_ = ch_feat_intersection & kUniformControls;

    // If this feature unit has volume control, fetch and sanity check the
    // min/max/res of all of the channels.
    if (has_vol()) {
        // Go over each of the volume controls and cache the min/max/res values.
        for (size_t i = 0; i < features_.size(); ++i) {
            auto& f = features_[i];

            if (!f.has_vol()) {
                continue;
            }

            uint8_t ch = static_cast<uint8_t>(i);

            res = FeatCtrlReq(proto, USB_AUDIO_GET_MIN, USB_AUDIO_VOLUME_CONTROL, ch, &f.vol_min_);
            if (res != ZX_OK) {
                return res;
            }

            res = FeatCtrlReq(proto, USB_AUDIO_GET_MAX, USB_AUDIO_VOLUME_CONTROL, ch, &f.vol_max_);
            if (res != ZX_OK) {
                return res;
            }

            res = FeatCtrlReq(proto, USB_AUDIO_GET_RES, USB_AUDIO_VOLUME_CONTROL, ch, &f.vol_res_);
            if (res != ZX_OK) {
                return res;
            }
        }

        // If volume control is done at the per-channel level, make sure that all of
        // the channels support the same range.  Otherwise, our volume control range
        // is equal to the master channel's range.
        if (features_[0].has_vol()) {
            vol_min_ = features_[0].vol_min_;
            vol_max_ = features_[0].vol_max_;
            vol_res_ = features_[0].vol_res_;
        } else {
            vol_min_ = features_[1].vol_min_;
            vol_max_ = features_[1].vol_max_;
            vol_res_ = features_[1].vol_res_;
            for (size_t i = 2; i < features_.size(); ++i) {
                if ((vol_min_ != features_[i].vol_min_) ||
                    (vol_max_ != features_[i].vol_max_) ||
                    (vol_res_ != features_[i].vol_res_)) {
                    GLOBAL_LOG(WARN,
                            "FeatureUnit id %u has unsupported non-uniform gain controls.  "
                            "Channel %zu's gain range [%hd, %hd, %hd] does not match Channel 1's "
                            "range [%hd, %hd, %hd]\n",
                            id(), i,
                            vol_min_, vol_max_, vol_res_,
                            features_[i].vol_min_, features_[i].vol_max_, features_[i].vol_res_);
                    return ZX_ERR_NOT_SUPPORTED;
                }
            }
        }

        if (vol_min_ > vol_max_) {
            GLOBAL_LOG(WARN, "FeatureUnit id %u has invalid volume range [%hd, %hd]\n",
                       id(), vol_min_, vol_max_);
            return ZX_ERR_NOT_SUPPORTED;
        }

        if (!vol_res_) {
            GLOBAL_LOG(WARN, "FeatureUnit id %u has invalid volume res %hd\n", id(), vol_res_);
            return ZX_ERR_NOT_SUPPORTED;
        }

        // Fetch the current volume setting from the appropriate source, then
        // make certain that all channels are set to the same if there is no
        // master control knob.
        bool master_control = (master_feat_ & USB_AUDIO_FU_BMA_VOLUME);
        uint8_t ch = master_control ? 0 : 1;
        res = FeatCtrlReq(proto, USB_AUDIO_GET_CUR, USB_AUDIO_VOLUME_CONTROL, ch, &vol_cur_);
        if (res != ZX_OK) {
            return res;
        }

        if (!master_control) {
            SetFeature(proto, USB_AUDIO_VOLUME_CONTROL, vol_cur_);
        }
    }

    // If we have mute controls, figure out the current setting.
    if (has_mute()) {
        res = FeatCtrlReq(proto, USB_AUDIO_GET_CUR, USB_AUDIO_MUTE_CONTROL, 0, &mute_cur_);
        if (res != ZX_OK) {
            return res;
        }
    }

    // If we have agc controls, figure out the current setting.
    if (has_agc()) {
        res = FeatCtrlReq(proto, USB_AUDIO_GET_CUR, USB_AUDIO_AUTOMATIC_GAIN_CONTROL, 0, &agc_cur_);
        if (res != ZX_OK) {
            return res;
        }
    }

    // Dump some diags info if TRACE level logging is enabled.
    if (has_vol()) {
        GLOBAL_LOG(TRACE,
                   "FeatureUnit id %u: can%s mute, can%s AGC, gain [%.3f, %.3f: step %.3f] dB\n",
                   id(),
                   has_mute() ? "" : "not",
                   has_agc() ? "" : "not",
                   vol_min_db(), vol_max_db(), vol_res_db());
    } else {
        GLOBAL_LOG(TRACE, "FeatureUnit id %u: can%s mute, can%s AGC, and has fixed gain\n",
                   id(), has_mute() ? "" : "not", has_agc() ? "" : "not");
    }

    // All done!  Declare success and get out.
    return ZX_OK;
};

float FeatureUnit::SetVol(const usb_protocol_t& proto, float db) {
    // If we have no volume control, then our gain is fixed at 0.0 dB no matter
    // what the user asks for.
    if (!has_vol()) {
        return 0.0;
    }

    // Convert to our target value.  Start by converting to ticks.
    float ticks_float = db / kDbPerTick;

    // Now snap to the closest allowed tick based on our resolution.
    ticks_float = roundf(ticks_float / vol_res_) * vol_res_;

    // Now clamp to the acceptable min/max range and convert to integer ticks.
    vol_cur_ = static_cast<int16_t>(fbl::clamp<float>(ticks_float, vol_min_, vol_max_));

    // Finally apply the setting.  If we have no explicit mute control, and we
    // are currently supposed to be muted, skip this step.  We are using the
    // volume control to simulate mute to the best of our abilities; we will
    // restore vol_cur_ when the unit finally becomes un-muted.
    if (!(mute_cur_ && !has_mute())) {
        SetFeature(proto, USB_AUDIO_VOLUME_CONTROL, vol_cur_);
    }

    return vol_cur_ * kDbPerTick;
}

bool FeatureUnit::SetMute(const usb_protocol_t& proto, bool mute) {
    mute_cur_ = mute;

    // If we have an explicit mute control, use that.  Otherwise, do the best we
    // can using the volume control (if present).
    if (has_mute()) {
        SetFeature(proto, USB_AUDIO_MUTE_CONTROL, mute_cur_);
    } else {
        // Section 5.2.2.4.3.2 of the USB Audio 1.0 spec defines int16::min as
        // -inf dB for the purpose of setting gain.
        int16_t tgt = mute ? std::numeric_limits<int16_t>::min() : vol_cur_;
        SetFeature(proto, USB_AUDIO_VOLUME_CONTROL, tgt);
    }

    return !!mute_cur_;
}

bool FeatureUnit::SetAgc(const usb_protocol_t& proto, bool agc) {
    if (has_agc()) {
        agc_cur_ = agc;
        SetFeature(proto, USB_AUDIO_AUTOMATIC_GAIN_CONTROL, static_cast<uint8_t>(agc));
    }
    return !!agc_cur_;
}

fbl::RefPtr<ProcessingUnit> ProcessingUnit::Create(const DescriptorListMemory::Iterator& iter,
                                                   uint8_t iid) {
    // Find the size of each of the inlined variable length arrays in this
    // structure, finding the locations of the constant headers in the process.
    // If anything does not look right, complain and move on.
    auto hdr0 = iter.hdr_as<usb_audio_ac_processing_unit_desc_0>();
    if (hdr0 != nullptr) {
        size_t off = sizeof(*hdr0) + hdr0->bNrInPins;
        auto hdr1 = offset_ptr<usb_audio_ac_processing_unit_desc_1>(hdr0, off);
        if (hdr1 != nullptr) {
            off += sizeof(*hdr1) + hdr1->bControlSize;
            auto hdr2 = offset_ptr<usb_audio_ac_processing_unit_desc_2>(hdr0, off);

            // TODO(johngro): additional sanity checking and pre-processing goes here.
            //
            // Note: Processing units actually come in their own pre-defined
            // sub-flavors (determined by hdr0->wProcessType).  Instead of
            // lumping them all together into one ProcessingUnit class, we
            // should probably take the time to break them down into the various
            // sub-flavors, at which point in time, the big validation switch
            // statement would go somewhere in here.
            //
            // For now, however, we do not expect to have any need to control
            // processing units.  If we ever encounter one, we really only want
            // to understand the size of the baSourceID array so that we can
            // successfully walk the graph when attempting to build input/output
            // stream paths.
            fbl::AllocChecker ac;
            auto ret = fbl::AdoptRef(
                    new (&ac) ProcessingUnit(iter.desc_list(), hdr0, hdr1, hdr2, iid));
            return ac.check() ? ret : nullptr;
        }
    }

    GLOBAL_LOG(WARN, "ProcessingUnit header appears invalid @ offset %zu\n", iter.offset());
    return nullptr;
}

fbl::RefPtr<ExtensionUnit> ExtensionUnit::Create(const DescriptorListMemory::Iterator& iter,
                                                 uint8_t iid) {
    // Find the size of each of the inlined variable length arrays in this
    // structure, finding the locations of the constant headers in the process.
    // If anything does not look right, complain and move on.
    auto hdr0 = iter.hdr_as<usb_audio_ac_extension_unit_desc_0>();
    if (hdr0 != nullptr) {
        size_t off = sizeof(*hdr0) + hdr0->bNrInPins;
        auto hdr1 = offset_ptr<usb_audio_ac_extension_unit_desc_1>(hdr0, off);
        if (hdr1 != nullptr) {
            off += sizeof(*hdr1) + hdr1->bControlSize;
            auto hdr2 = offset_ptr<usb_audio_ac_extension_unit_desc_2>(hdr0, off);

            // TODO(johngro): additional sanity checking and pre-processing goes here.
            fbl::AllocChecker ac;
            auto ret = fbl::AdoptRef(
                    new (&ac) ExtensionUnit(iter.desc_list(), hdr0, hdr1, hdr2, iid));
            return ac.check() ? ret : nullptr;
        }
    }

    GLOBAL_LOG(WARN, "ExtensionUnit header appears invalid @ offset %zu\n", iter.offset());
    return nullptr;
}

}  // namespace usb
}  // namespace audio
