// Copyright 2017 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 <ddk/device.h>
#include <digest/digest.h>
#include <dispatcher-pool/dispatcher-thread-pool.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <lib/zx/vmar.h>
#include <limits>
#include <string.h>
#include <usb/usb-request.h>
#include <utility>
#include <zircon/hw/usb/audio.h>
#include <zircon/process.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include "usb-audio.h"
#include "usb-audio-device.h"
#include "usb-audio-stream.h"
#include "usb-audio-stream-interface.h"

namespace audio {
namespace usb {

// Device FIDL thunks
fuchsia_hardware_audio_Device_ops_t UsbAudioStream::AUDIO_FIDL_THUNKS {
    .GetChannel = [](void* ctx, fidl_txn_t* txn) -> zx_status_t {
                        return reinterpret_cast<UsbAudioStream*>(ctx)->GetChannel(txn);
                   },
};

static constexpr uint32_t MAX_OUTSTANDING_REQ = 8;

static constexpr uint32_t ExtractSampleRate(const usb_audio_as_samp_freq& sr) {
    return static_cast<uint32_t>(sr.freq[0])
        | (static_cast<uint32_t>(sr.freq[1]) << 8)
        | (static_cast<uint32_t>(sr.freq[2]) << 16);
}

UsbAudioStream::UsbAudioStream(UsbAudioDevice* parent,
                               fbl::unique_ptr<UsbAudioStreamInterface> ifc,
                               fbl::RefPtr<dispatcher::ExecutionDomain> default_domain)
    : UsbAudioStreamBase(parent->zxdev()),
      AudioStreamProtocol(ifc->direction() == Direction::Input),
      parent_(*parent),
      ifc_(std::move(ifc)),
      default_domain_(std::move(default_domain)),
      create_time_(zx_clock_get_monotonic()) {
    snprintf(log_prefix_, sizeof(log_prefix_),
             "UsbAud %04hx:%04hx %s-%03d",
             parent_.vid(),
             parent_.pid(),
             is_input() ? "input" : "output",
             ifc_->term_link());
}

UsbAudioStream::~UsbAudioStream() {
    // We destructing.  All of our requests should be sitting in the free list.
    ZX_DEBUG_ASSERT(allocated_req_cnt_ == free_req_cnt_);

    while (!list_is_empty(&free_req_)) {
        usb_request_release(usb_req_list_remove_head(&free_req_, parent_.parent_req_size()));
    }
}

fbl::RefPtr<UsbAudioStream> UsbAudioStream::Create(UsbAudioDevice* parent,
                                                   fbl::unique_ptr<UsbAudioStreamInterface> ifc) {
    ZX_DEBUG_ASSERT(parent != nullptr);
    ZX_DEBUG_ASSERT(ifc != nullptr);

    auto domain = dispatcher::ExecutionDomain::Create();
    if (domain == nullptr) {
        LOG_EX(ERROR, *parent,
               "Failed to create execution domain while trying to create UsbAudioStream\n");
        return nullptr;
    }

    fbl::AllocChecker ac;
    auto stream = fbl::AdoptRef(
            new (&ac) UsbAudioStream(parent, std::move(ifc), std::move(domain)));
    if (!ac.check()) {
        LOG_EX(ERROR, *parent,
               "Out of memory while attempting to allocate UsbAudioStream\n");
        return nullptr;
    }

    stream->ComputePersistentUniqueId();

    return stream;
}

zx_status_t UsbAudioStream::Bind() {
    // TODO(johngro): Do this differently when we have the ability to queue io
    // transactions to a USB isochronous endpoint and can have the bus driver
    // DMA directly from the ring buffer we have set up with our user.
    {
        fbl::AutoLock req_lock(&req_lock_);

        list_initialize(&free_req_);
        free_req_cnt_ = 0;
        allocated_req_cnt_ = 0;

        uint64_t req_size = parent_.parent_req_size() + sizeof(usb_req_internal_t);
        for (uint32_t i = 0; i < MAX_OUTSTANDING_REQ; ++i) {
            usb_request_t* req;
            zx_status_t status = usb_request_alloc(&req, ifc_->max_req_size(),
                                                   ifc_->ep_addr(), req_size);
            if (status != ZX_OK) {
                LOG(ERROR, "Failed to allocate usb request %u/%u (size %u): %d\n",
                    i + 1, MAX_OUTSTANDING_REQ, ifc_->max_req_size(), status);
                return status;
            }

            status = usb_req_list_add_head(&free_req_, req, parent_.parent_req_size());
            ZX_DEBUG_ASSERT(status == ZX_OK);
            ++free_req_cnt_;
            ++allocated_req_cnt_;
        }
    }

    char name[64];
    snprintf(name, sizeof(name), "usb-audio-%s-%03d",
             is_input() ? "input" : "output", ifc_->term_link());

    zx_status_t status = UsbAudioStreamBase::DdkAdd(name);
    if (status == ZX_OK) {
        // If bind/setup has succeeded, then the devmgr now holds a reference to us.
        // Manually increase our reference count to account for this.
        this->AddRef();
    } else {
        LOG(ERROR, "Failed to publish UsbAudioStream device node (name \"%s\", status %d)\n",
            name, status);
    }

    status = device_get_profile(zxdev_, 24 /* HIGH_PRIORITY in LK */,
                                "zircon/system/dev/audio/usb-audio/usb-audio-stream",
                                profile_handle_.reset_and_get_address());
    if (status != ZX_OK) {
        LOG(ERROR, "Failed to retrieve profile, status %d\n", status);
        return status;
    }

    return status;
}

void UsbAudioStream::RequestCompleteCallback(void* ctx, usb_request_t* request) {
    ZX_DEBUG_ASSERT(ctx != nullptr);
    reinterpret_cast<UsbAudioStream*>(ctx)->RequestComplete(request);
}

void UsbAudioStream::ComputePersistentUniqueId() {
    // Do the best that we can to generate a persistent ID unique to this audio
    // stream by blending information from a number of sources.  In particular,
    // consume...
    //
    // 1) This USB device's top level device descriptor (this contains the
    //    VID/PID of the device, among other things)
    // 2) The contents of the descriptor list used to describe the control and
    //    streaming interfaces present in the device.
    // 3) The manufacturer, product, and serial number string descriptors (if
    //    present)
    // 4) The stream interface ID.
    //
    // The goal here is to produce something like a UUID which is as unique to a
    // specific instance of a specific device as we can make it, but which
    // should persist across boots even in the presence of driver updates an
    // such.  Even so, upper levels of code will still need to deal with the sad
    // reality that some types of devices may end up looking the same between
    // two different instances.  If/when this becomes an issue, we may need to
    // pursue other options.  One choice might be to change the way devices are
    // enumerated in the USB section of the device tree so that their path has
    // only to do with physical topology, and has no runtime enumeration order
    // dependencies.  At that point in time, adding the topology into the hash
    // should do the job, but would imply that the same device plugged into two
    // different ports will have a different unique ID for the purposes of
    // saving and restoring driver settings (as it does in some operating
    // systems today).
    //
    uint16_t vid = parent_.desc().idVendor;
    uint16_t pid = parent_.desc().idProduct;
    audio_stream_unique_id_t fallback_id { .data = {
        'U', 'S', 'B', ' ',
        static_cast<uint8_t>(vid >> 8),
        static_cast<uint8_t>(vid),
        static_cast<uint8_t>(pid >> 8),
        static_cast<uint8_t>(pid),
        ifc_->iid()
    }};
    persistent_unique_id_ = fallback_id;

    digest::Digest sha;
    zx_status_t res = sha.Init();
    if (res != ZX_OK) {
        LOG(WARN, "Failed to initialize digest while computing unique ID.  "
                  "Falling back on defaults (res %d)\n", res);
        return;
    }

    // #1: Top level descriptor.
    sha.Update(&parent_.desc(), sizeof(parent_.desc()));

    // #2: The descriptor list
    const auto& desc_list = parent_.desc_list();
    ZX_DEBUG_ASSERT((desc_list != nullptr) && (desc_list->size() > 0));
    sha.Update(desc_list->data(), desc_list->size());

    // #3: The various descriptor strings which may exist.
    const fbl::Array<uint8_t>* desc_strings[] = {
        &parent_.mfr_name(),
        &parent_.prod_name(),
        &parent_.serial_num()
    };
    for (const auto str : desc_strings) {
        if (str->size()) {
            sha.Update(str->get(), str->size());
        }
    }

    // #4: The stream interface's ID.
    auto iid = ifc_->iid();
    sha.Update(&iid, sizeof(iid));

    // Finish the SHA and attempt to copy as much of the results to our internal
    // cached representation as we can.
    uint8_t digest_out[digest::Digest::kLength];
    sha.Final();
    res = sha.CopyTo(digest_out, sizeof(digest_out));
    if (res != ZX_OK) {
        LOG(WARN, "Failed to copy digest while computing unique ID.  "
                  "Falling back on defaults (res %d)\n", res);
        return;
    }

    constexpr size_t todo = fbl::min(sizeof(digest_out), sizeof(persistent_unique_id_.data));
    if (todo < sizeof(persistent_unique_id_.data)) {
        ::memset(&persistent_unique_id_.data, 0, sizeof(persistent_unique_id_.data));
    }
    ::memcpy(persistent_unique_id_.data, digest_out, todo);
}

void UsbAudioStream::ReleaseRingBufferLocked() {
    if (ring_buffer_virt_ != nullptr) {
        ZX_DEBUG_ASSERT(ring_buffer_size_ != 0);
        zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(ring_buffer_virt_),
                                     ring_buffer_size_);
        ring_buffer_virt_ = nullptr;
        ring_buffer_size_ = 0;
    }
    ring_buffer_vmo_.reset();
}

zx_status_t UsbAudioStream::GetChannel(fidl_txn_t* txn) {
    fbl::AutoLock lock(&lock_);

    // Attempt to allocate a new driver channel and bind it to us.  If we don't
    // already have an stream_channel_, flag this channel is the privileged
    // connection (The connection which is allowed to do things like change
    // formats).
    bool privileged = (stream_channel_ == nullptr);
    auto channel = dispatcher::Channel::Create();
    if (channel == nullptr)
        return ZX_ERR_NO_MEMORY;

    dispatcher::Channel::ProcessHandler phandler(
    [stream = fbl::WrapRefPtr(this), privileged](dispatcher::Channel* channel) -> zx_status_t {
        OBTAIN_EXECUTION_DOMAIN_TOKEN(t, stream->default_domain_);
        return stream->ProcessStreamChannel(channel, privileged);
    });

    dispatcher::Channel::ChannelClosedHandler chandler;
    if (privileged) {
        chandler = dispatcher::Channel::ChannelClosedHandler(
        [stream = fbl::WrapRefPtr(this)](const dispatcher::Channel* channel) -> void {
            OBTAIN_EXECUTION_DOMAIN_TOKEN(t, stream->default_domain_);
            stream->DeactivateStreamChannel(channel);
        });
    }

    zx::channel client_endpoint;
    zx_status_t res = channel->Activate(&client_endpoint,
                                        default_domain_,
                                        std::move(phandler),
                                        std::move(chandler));
    if (res == ZX_OK) {
        if (privileged) {
            ZX_DEBUG_ASSERT(stream_channel_ == nullptr);
            stream_channel_ = channel;
        }

        return fuchsia_hardware_audio_DeviceGetChannel_reply(txn, client_endpoint.release());
    }

    return res;
}

void UsbAudioStream::DdkUnbind() {
    // Close all of our client event sources if we have not already.
    default_domain_->Deactivate();

    // Unpublish our device node.
    DdkRemove();
}

void UsbAudioStream::DdkRelease() {
    // Reclaim our reference from the driver framework and let it go out of
    // scope.  If this is our last reference (it should be), we will destruct
    // immediately afterwards.
    auto stream = fbl::internal::MakeRefPtrNoAdopt(this);

    // Make sure that our parent is no longer holding a reference to us.
    parent_.RemoveAudioStream(stream);
}

#define HREQ(_cmd, _payload, _handler, _allow_noack, ...)         \
case _cmd:                                                        \
    if (req_size != sizeof(req._payload)) {                       \
        LOG(TRACE, "Bad " #_cmd " response length (%u != %zu)\n", \
            req_size, sizeof(req._payload));                      \
        return ZX_ERR_INVALID_ARGS;                               \
    }                                                             \
    if (!_allow_noack && (req.hdr.cmd & AUDIO_FLAG_NO_ACK)) {     \
        LOG(TRACE, "NO_ACK flag not allowed for " #_cmd "\n");    \
        return ZX_ERR_INVALID_ARGS;                               \
    }                                                             \
    return _handler(channel, req._payload, ##__VA_ARGS__);
zx_status_t UsbAudioStream::ProcessStreamChannel(dispatcher::Channel* channel, bool priv) {
    ZX_DEBUG_ASSERT(channel != nullptr);
    fbl::AutoLock lock(&lock_);

    // TODO(johngro) : Factor all of this behavior around accepting channels and
    // dispatching audio driver requests into some form of utility class so it
    // can be shared with the IntelHDA codec implementations as well.
    union {
        audio_proto::CmdHdr           hdr;
        audio_proto::StreamGetFmtsReq get_formats;
        audio_proto::StreamSetFmtReq  set_format;
        audio_proto::GetGainReq       get_gain;
        audio_proto::SetGainReq       set_gain;
        audio_proto::PlugDetectReq    plug_detect;
        audio_proto::GetUniqueIdReq   get_unique_id;
        audio_proto::GetStringReq     get_string;
        // TODO(johngro) : add more commands here
    } req;

    static_assert(sizeof(req) <= 256,
                  "Request buffer is getting to be too large to hold on the stack!");

    uint32_t req_size;
    zx_status_t res = channel->Read(&req, sizeof(req), &req_size);
    if (res != ZX_OK)
        return res;

    if ((req_size < sizeof(req.hdr) ||
        (req.hdr.transaction_id == AUDIO_INVALID_TRANSACTION_ID)))
        return ZX_ERR_INVALID_ARGS;

    // Strip the NO_ACK flag from the request before selecting the dispatch target.
    auto cmd = static_cast<audio_proto::Cmd>(req.hdr.cmd & ~AUDIO_FLAG_NO_ACK);
    switch (cmd) {
    HREQ(AUDIO_STREAM_CMD_GET_FORMATS,   get_formats,   OnGetStreamFormatsLocked, false);
    HREQ(AUDIO_STREAM_CMD_SET_FORMAT,    set_format,    OnSetStreamFormatLocked,  false, priv);
    HREQ(AUDIO_STREAM_CMD_GET_GAIN,      get_gain,      OnGetGainLocked,          false);
    HREQ(AUDIO_STREAM_CMD_SET_GAIN,      set_gain,      OnSetGainLocked,          true);
    HREQ(AUDIO_STREAM_CMD_PLUG_DETECT,   plug_detect,   OnPlugDetectLocked,       true);
    HREQ(AUDIO_STREAM_CMD_GET_UNIQUE_ID, get_unique_id, OnGetUniqueIdLocked,      false);
    HREQ(AUDIO_STREAM_CMD_GET_STRING,    get_string,    OnGetStringLocked,        false);
    default:
        LOG(TRACE, "Unrecognized stream command 0x%04x\n", req.hdr.cmd);
        return ZX_ERR_NOT_SUPPORTED;
    }
}

zx_status_t UsbAudioStream::ProcessRingBufferChannel(dispatcher::Channel* channel) {
    ZX_DEBUG_ASSERT(channel != nullptr);
    fbl::AutoLock lock(&lock_);

    union {
        audio_proto::CmdHdr                 hdr;
        audio_proto::RingBufGetFifoDepthReq get_fifo_depth;
        audio_proto::RingBufGetBufferReq    get_buffer;
        audio_proto::RingBufStartReq        rb_start;
        audio_proto::RingBufStopReq         rb_stop;
        // TODO(johngro) : add more commands here
    } req;

    static_assert(sizeof(req) <= 256,
                  "Request buffer is getting to be too large to hold on the stack!");

    uint32_t req_size;
    zx_status_t res = channel->Read(&req, sizeof(req), &req_size);
    if (res != ZX_OK)
        return res;

    if ((req_size < sizeof(req.hdr) ||
        (req.hdr.transaction_id == AUDIO_INVALID_TRANSACTION_ID)))
        return ZX_ERR_INVALID_ARGS;

    // Strip the NO_ACK flag from the request before selecting the dispatch target.
    auto cmd = static_cast<audio_proto::Cmd>(req.hdr.cmd & ~AUDIO_FLAG_NO_ACK);
    switch (cmd) {
    HREQ(AUDIO_RB_CMD_GET_FIFO_DEPTH, get_fifo_depth, OnGetFifoDepthLocked, false);
    HREQ(AUDIO_RB_CMD_GET_BUFFER,     get_buffer,     OnGetBufferLocked,    false);
    HREQ(AUDIO_RB_CMD_START,          rb_start,       OnStartLocked,        false);
    HREQ(AUDIO_RB_CMD_STOP,           rb_stop,        OnStopLocked,         false);
    default:
        LOG(TRACE, "Unrecognized ring buffer command 0x%04x\n", req.hdr.cmd);
        return ZX_ERR_NOT_SUPPORTED;
    }

    return ZX_ERR_NOT_SUPPORTED;
}
#undef HREQ

zx_status_t UsbAudioStream::OnGetStreamFormatsLocked(dispatcher::Channel* channel,
                                                     const audio_proto::StreamGetFmtsReq& req) {
    ZX_DEBUG_ASSERT(channel != nullptr);
    audio_proto::StreamGetFmtsResp resp = { };

    const auto& formats = ifc_->formats();
    if (formats.size() > std::numeric_limits<uint16_t>::max()) {
        LOG(ERROR, "Too many formats (%zu) to send during AUDIO_STREAM_CMD_GET_FORMATS request!\n",
            formats.size());
        return ZX_ERR_INTERNAL;
    }

    size_t formats_sent = 0;
    resp.hdr = req.hdr;
    resp.format_range_count = static_cast<uint16_t>(formats.size());

    do {
        size_t todo, payload_sz, __UNUSED to_send;
        zx_status_t res;

        todo = fbl::min<size_t>(formats.size() - formats_sent,
                                AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE);
        payload_sz = sizeof(resp.format_ranges[0]) * todo;
        to_send = offsetof(audio_proto::StreamGetFmtsResp, format_ranges) + payload_sz;

        resp.first_format_range_ndx = static_cast<uint16_t>(formats_sent);
        for (uint32_t i = 0; i < todo; ++i) {
            resp.format_ranges[i] = formats[formats_sent + i].range_;
        }

        res = channel->Write(&resp, sizeof(resp));
        if (res != ZX_OK) {
            LOG(TRACE, "Failed to send get stream formats response (res %d)\n", res);
            return res;
        }

        formats_sent += todo;
    } while (formats_sent < formats.size());

    return ZX_OK;
}

zx_status_t UsbAudioStream::OnSetStreamFormatLocked(dispatcher::Channel* channel,
                                                    const audio_proto::StreamSetFmtReq& req,
                                                    bool privileged) {
    ZX_DEBUG_ASSERT(channel != nullptr);

    zx::channel client_rb_channel;
    audio_proto::StreamSetFmtResp resp = { };
    resp.hdr = req.hdr;

    // Only the privileged stream channel is allowed to change the format.
    if (!privileged) {
        ZX_DEBUG_ASSERT(channel != stream_channel_.get());
        resp.result = ZX_ERR_ACCESS_DENIED;
        goto finished;
    }

    // Look up the details about the interface and the endpoint which will be
    // used for the requested format.
    size_t format_ndx;
    resp.result = ifc_->LookupFormat(req.frames_per_second,
                                     req.channels,
                                     req.sample_format,
                                     &format_ndx);
    if (resp.result != ZX_OK) {
        goto finished;
    }

    // Determine the frame size needed for this requested format, then compute
    // the size of our short packets, and the constants used to generate the
    // short/long packet cadence.  For now, assume that we will be operating at
    // a 1mSec isochronous rate.
    //
    // Make sure that we can fit our longest payload length into one of our
    // usb requests.
    //
    // Store the results of all of these calculations in local variables.  Do
    // not commit them to member variables until we are certain that we are
    // going to go ahead with this format change.
    //
    // TODO(johngro) : Unless/until we can find some way to set the USB bus
    // driver to perform direct DMA to/from the Ring Buffer VMO without the need
    // for software intervention, we may want to expose ways to either increase
    // the isochronous interval (to minimize load) or to use USB 2.0 125uSec
    // sub-frame timing (to decrease latency) if possible.
    uint32_t frame_size;
    frame_size = audio::utils::ComputeFrameSize(req.channels, req.sample_format);
    if (!frame_size) {
        LOG(ERROR, "Failed to compute frame size (ch %hu fmt 0x%08x)\n",
            req.channels, req.sample_format);
        resp.result = ZX_ERR_INTERNAL;
        goto finished;
    }

    static constexpr uint32_t iso_packet_rate = 1000;
    uint32_t bytes_per_packet, fractional_bpp_inc, long_payload_len;
    bytes_per_packet   = (req.frames_per_second / iso_packet_rate) * frame_size;
    fractional_bpp_inc = (req.frames_per_second % iso_packet_rate);
    long_payload_len   = bytes_per_packet + (fractional_bpp_inc ? frame_size : 0);

    ZX_DEBUG_ASSERT(format_ndx < ifc_->formats().size());
    if (long_payload_len > ifc_->formats()[format_ndx].max_req_size_) {
        resp.result = ZX_ERR_INVALID_ARGS;
        goto finished;
    }

    // Deny the format change request if the ring buffer is not currently stopped.
    {
        // TODO(johngro) : If the ring buffer is running, should we automatically
        // stop it instead of returning bad state?
        fbl::AutoLock req_lock(&req_lock_);
        if (ring_buffer_state_ != RingBufferState::STOPPED) {
            resp.result = ZX_ERR_BAD_STATE;
            goto finished;
        }
    }

    // Looks like we are going ahead with this format change.  Tear down any
    // exiting ring buffer interface before proceeding.
    if (rb_channel_ != nullptr) {
        rb_channel_->Deactivate();
        rb_channel_.reset();
    }

    // Record the details of our cadence and format selection
    selected_format_ndx_ = format_ndx;
    selected_frame_rate_ = req.frames_per_second;
    frame_size_          = frame_size;
    iso_packet_rate_     = iso_packet_rate;
    bytes_per_packet_    = bytes_per_packet;
    fractional_bpp_inc_  = fractional_bpp_inc;

    // Compute the effective fifo depth for this stream.  Right now, we assume
    // that the controller will never get farther ahead than two isochronous usb
    // requests, so we report this as the worst case fifo_depth.
    //
    // Based on our cadence generation parameters, adjust this number based on
    // whether or not it is possible to have 0, 1 or 2 long packets back to back
    // at any point in time during the sequence.
    //
    // TODO(johngro): This is not the proper way to report the FIFO depth.  How
    // far ahead the USB controller will read ahead into its FIFO is going to be
    // a property of the controller and the properties of the endpoint.  It is
    // possible that this is negotiable to some extent as well.  I need to work
    // with voydanof@ to determine what we can expose from the USB bus driver in
    // order to report this accurately.
    fifo_bytes_ = bytes_per_packet_ << 1;

    // If we have no fractional portion to accumulate, we always send
    // short packets.  If our fractional portion is <= 1/2 of our
    // isochronous rate, then we will never send two long packets back
    // to back.
    if (fractional_bpp_inc_) {
        fifo_bytes_ += frame_size_;
        if (fractional_bpp_inc_ > (iso_packet_rate_ >> 1)) {
            fifo_bytes_ += frame_size_;
        }
    }

    // Create a new ring buffer channel which can be used to move bulk data and
    // bind it to us.
    rb_channel_ = dispatcher::Channel::Create();
    if (rb_channel_ == nullptr) {
        resp.result = ZX_ERR_NO_MEMORY;
    } else {
        dispatcher::Channel::ProcessHandler phandler(
        [stream = fbl::WrapRefPtr(this)](dispatcher::Channel* channel) -> zx_status_t {
            OBTAIN_EXECUTION_DOMAIN_TOKEN(t, stream->default_domain_);
            return stream->ProcessRingBufferChannel(channel);
        });

        dispatcher::Channel::ChannelClosedHandler chandler(
        [stream = fbl::WrapRefPtr(this)](const dispatcher::Channel* channel) -> void {
            OBTAIN_EXECUTION_DOMAIN_TOKEN(t, stream->default_domain_);
            stream->DeactivateRingBufferChannel(channel);
        });

        resp.result = rb_channel_->Activate(&client_rb_channel,
                                            default_domain_,
                                            std::move(phandler),
                                            std::move(chandler));
        if (resp.result != ZX_OK) {
            rb_channel_.reset();
        }
    }

finished:
    if (resp.result == ZX_OK) {
        // TODO(johngro): Report the actual external delay.
        resp.external_delay_nsec = 0;
        return channel->Write(&resp, sizeof(resp), std::move(client_rb_channel));
    } else {
        return channel->Write(&resp, sizeof(resp));
    }
}

zx_status_t UsbAudioStream::OnGetGainLocked(dispatcher::Channel* channel,
                                            const audio_proto::GetGainReq& req) {
    ZX_DEBUG_ASSERT(channel != nullptr);
    audio_proto::GetGainResp resp = { };
    resp.hdr = req.hdr;

    ZX_DEBUG_ASSERT(ifc_->path() != nullptr);
    const auto& path = *(ifc_->path());

    resp.can_mute  = path.has_mute();
    resp.cur_mute  = path.cur_mute();
    resp.can_agc   = path.has_agc();
    resp.cur_agc   = path.cur_agc();
    resp.cur_gain  = path.cur_gain();
    resp.min_gain  = path.min_gain();
    resp.max_gain  = path.max_gain();
    resp.gain_step = path.gain_res();

    return channel->Write(&resp, sizeof(resp));
}

zx_status_t UsbAudioStream::OnSetGainLocked(dispatcher::Channel* channel,
                                            const audio_proto::SetGainReq& req) {
    // TODO(johngro): Actually perform the set operation on our audio path.
    ZX_DEBUG_ASSERT(channel != nullptr);

    audio_proto::SetGainResp resp = { };
    resp.hdr = req.hdr;

    ZX_DEBUG_ASSERT(ifc_->path() != nullptr);
    auto& path = *(ifc_->path());
    bool req_mute = req.flags & AUDIO_SGF_MUTE;
    bool req_agc  = req.flags & AUDIO_SGF_AGC;
    bool illegal_mute = (req.flags & AUDIO_SGF_MUTE_VALID) && req_mute && !path.has_mute();
    bool illegal_agc  = (req.flags & AUDIO_SGF_AGC_VALID)  && req_agc  && !path.has_agc();
    bool illegal_gain = (req.flags & AUDIO_SGF_GAIN_VALID) && (req.gain != 0) && !path.has_gain();

    if (illegal_mute || illegal_agc || illegal_gain) {
        // If this request is illegal, make no changes but attempt to report the
        // current state of the world.
        resp.cur_mute = path.cur_mute();
        resp.cur_agc  = path.cur_agc();
        resp.cur_gain = path.cur_gain();
        resp.result = ZX_ERR_INVALID_ARGS;
    } else {
        if (req.flags & AUDIO_SGF_MUTE_VALID) {
            resp.cur_mute = path.SetMute(parent_.usb_proto(), req_mute);
        }

        if (req.flags & AUDIO_SGF_AGC_VALID) {
            resp.cur_agc = path.SetAgc(parent_.usb_proto(), req_agc);
        }

        if (req.flags & AUDIO_SGF_GAIN_VALID) {
            resp.cur_gain = path.SetGain(parent_.usb_proto(), req.gain);
        }

        resp.result = ZX_OK;
    }

    return (req.hdr.cmd & AUDIO_FLAG_NO_ACK) ? ZX_OK : channel->Write(&resp, sizeof(resp));
}

zx_status_t UsbAudioStream::OnPlugDetectLocked(dispatcher::Channel* channel,
                                               const audio_proto::PlugDetectReq& req) {
    if (req.hdr.cmd & AUDIO_FLAG_NO_ACK)
        return ZX_OK;

    audio_proto::PlugDetectResp resp = { };
    resp.hdr   = req.hdr;
    resp.flags = static_cast<audio_pd_notify_flags_t>(AUDIO_PDNF_HARDWIRED | AUDIO_PDNF_PLUGGED);
    resp.plug_state_time = create_time_;

    return channel->Write(&resp, sizeof(resp));
}

zx_status_t UsbAudioStream::OnGetUniqueIdLocked(dispatcher::Channel* channel,
                                                const audio_proto::GetUniqueIdReq& req) {
    audio_proto::GetUniqueIdResp resp;

    static_assert(sizeof(resp.unique_id) == sizeof(persistent_unique_id_),
                  "Unique ID sizes much match!");
    resp.hdr = req.hdr;
    resp.unique_id = persistent_unique_id_;

    return channel->Write(&resp, sizeof(resp));
}

zx_status_t UsbAudioStream::OnGetStringLocked(dispatcher::Channel* channel,
                                              const audio_proto::GetStringReq& req) {
    audio_proto::GetStringResp resp;
    const fbl::Array<uint8_t>* str;

    resp.hdr = req.hdr;
    resp.id = req.id;

    switch (req.id) {
        case AUDIO_STREAM_STR_ID_MANUFACTURER: str = &parent_.mfr_name(); break;
        case AUDIO_STREAM_STR_ID_PRODUCT:      str = &parent_.prod_name(); break;
        default:                               str = nullptr; break;
    }

    if (str == nullptr) {
        resp.result = ZX_ERR_NOT_FOUND;
        resp.strlen = 0;
    } else {
        size_t todo = fbl::min<size_t>(sizeof(resp.str), str->size());
        ZX_DEBUG_ASSERT(todo <= std::numeric_limits<uint32_t>::max());

        ::memset(resp.str, 0, sizeof(resp.str));
        if (todo) {
            ::memcpy(resp.str, str->get(), todo);
        }

        resp.result = ZX_OK;
        resp.strlen = static_cast<uint32_t>(todo);
    }

    return channel->Write(&resp, sizeof(resp));
}

zx_status_t UsbAudioStream::OnGetFifoDepthLocked(dispatcher::Channel* channel,
                                                 const audio_proto::RingBufGetFifoDepthReq& req) {
    audio_proto::RingBufGetFifoDepthResp resp = { };

    resp.hdr = req.hdr;
    resp.result = ZX_OK;
    resp.fifo_depth = fifo_bytes_;

    return channel->Write(&resp, sizeof(resp));
}

zx_status_t UsbAudioStream::OnGetBufferLocked(dispatcher::Channel* channel,
                                              const audio_proto::RingBufGetBufferReq& req) {
    audio_proto::RingBufGetBufferResp resp = { };
    zx::vmo client_rb_handle;
    uint32_t map_flags, client_rights;

    resp.hdr    = req.hdr;
    resp.result = ZX_ERR_INTERNAL;

    {
        // We cannot create a new ring buffer if we are not currently stopped.
        fbl::AutoLock req_lock(&req_lock_);
        if (ring_buffer_state_ != RingBufferState::STOPPED) {
            resp.result = ZX_ERR_BAD_STATE;
            goto finished;
        }
    }

    // Unmap and release any previous ring buffer.
    ReleaseRingBufferLocked();

    // Compute the ring buffer size.  It needs to be at least as big
    // as the virtual fifo depth.
    ZX_DEBUG_ASSERT(frame_size_ && ((fifo_bytes_ % frame_size_) == 0));
    ZX_DEBUG_ASSERT(fifo_bytes_ && ((fifo_bytes_ % fifo_bytes_) == 0));
    ring_buffer_size_  = req.min_ring_buffer_frames;
    ring_buffer_size_ *= frame_size_;
    if (ring_buffer_size_ < fifo_bytes_)
        ring_buffer_size_ = fbl::round_up(fifo_bytes_, frame_size_);

    // Set up our state for generating notifications.
    if (req.notifications_per_ring) {
        bytes_per_notification_ = ring_buffer_size_ / req.notifications_per_ring;
    } else {
        bytes_per_notification_ = 0;
    }

    // Create the ring buffer vmo we will use to share memory with the client.
    resp.result = zx::vmo::create(ring_buffer_size_, 0, &ring_buffer_vmo_);
    if (resp.result != ZX_OK) {
        LOG(ERROR, "Failed to create ring buffer (size %u, res %d)\n",
            ring_buffer_size_, resp.result);
        goto finished;
    }

    // Map the VMO into our address space.
    //
    // TODO(johngro): skip this step when APIs in the USB bus driver exist to
    // DMA directly from the VMO.
    map_flags = ZX_VM_PERM_READ;
    if (is_input())
        map_flags |= ZX_VM_PERM_WRITE;

    resp.result = zx::vmar::root_self()->map(0, ring_buffer_vmo_,
                                             0, ring_buffer_size_,
                                             map_flags,
                                             reinterpret_cast<uintptr_t*>(&ring_buffer_virt_));
    if (resp.result != ZX_OK) {
        LOG(ERROR, "Failed to map ring buffer (size %u, res %d)\n",
            ring_buffer_size_, resp.result);
        goto finished;
    }

    // Create the client's handle to the ring buffer vmo and set it back to them.
    client_rights = ZX_RIGHT_TRANSFER | ZX_RIGHT_MAP | ZX_RIGHT_READ;
    if (!is_input())
        client_rights |= ZX_RIGHT_WRITE;

    resp.result = ring_buffer_vmo_.duplicate(client_rights, &client_rb_handle);
    if (resp.result != ZX_OK) {
        LOG(ERROR, "Failed to duplicate ring buffer handle (res %d)\n", resp.result);
        goto finished;
    }
    resp.num_ring_buffer_frames = ring_buffer_size_ / frame_size_;

finished:
    zx_status_t res;
    if (resp.result == ZX_OK) {
        ZX_DEBUG_ASSERT(client_rb_handle.is_valid());
        res = channel->Write(&resp, sizeof(resp), std::move(client_rb_handle));
    } else {
        res = channel->Write(&resp, sizeof(resp));
    }

    if (res != ZX_OK)
        ReleaseRingBufferLocked();

    return res;
}

zx_status_t UsbAudioStream::OnStartLocked(dispatcher::Channel* channel,
                                          const audio_proto::RingBufStartReq& req) {
    audio_proto::RingBufStartResp resp = { };
    resp.hdr = req.hdr;

    fbl::AutoLock req_lock(&req_lock_);

    if (ring_buffer_state_ != RingBufferState::STOPPED) {
        // The ring buffer is running, do not linger in the lock while we send
        // the error code back to the user.
        req_lock.release();
        resp.result = ZX_ERR_BAD_STATE;
        return channel->Write(&resp, sizeof(resp));
    }

    // We are idle, all of our usb requests should be sitting in the free list.
    ZX_DEBUG_ASSERT(allocated_req_cnt_ == free_req_cnt_);

    // Activate the format.
    resp.result = ifc_->ActivateFormat(selected_format_ndx_, selected_frame_rate_);
    if (resp.result != ZX_OK) {
        return channel->Write(&resp, sizeof(resp));
    }

    // Initialize the counters used to...
    // 1) generate the short/long packet cadence.
    // 2) generate notifications.
    // 3) track the position in the ring buffer.
    fractional_bpp_acc_ = 0;
    notification_acc_   = 0;
    ring_buffer_offset_ = 0;
    ring_buffer_pos_    = 0;

    // Schedule the frame number which the first transaction will go out on.
    //
    // TODO(johngro): This cannot be the current frame number, that train
    // has already left the station.  It probably should not be the next frame
    // number either as that train might be just about to leave the station.
    //
    // For now, set this to be the current frame number +2 and use the first
    // transaction complete callback to estimate the DMA start time.  Moving
    // forward, when the USB bus driver can tell us which frame a transaction
    // went out on, schedule the transaction using the special "on the next USB
    // isochronous frame" sentinel value and figure out which frame that was
    // during the callback.
    usb_frame_num_ = usb_get_current_frame(&parent_.usb_proto()) + 2;

    // Flag ourselves as being in the starting state, then queue up all of our
    // transactions.
    ring_buffer_state_ = RingBufferState::STARTING;
    while (!list_is_empty(&free_req_))
        QueueRequestLocked();

    // Record the transaction ID we will send back to our client when we have
    // successfully started, then get out.
    pending_job_resp_.start = resp;
    return ZX_OK;
}

zx_status_t UsbAudioStream::OnStopLocked(dispatcher::Channel* channel,
                                         const audio_proto::RingBufStopReq& req) {
    fbl::AutoLock req_lock(&req_lock_);

    // TODO(johngro): Fix this to use the cancel transaction capabilities added
    // to the USB bus driver.
    //
    // Also, investigate whether or not the cancel interface is synchronous or
    // whether we will need to maintain an intermediate stopping state.
    if (ring_buffer_state_ != RingBufferState::STARTED) {
        audio_proto::RingBufStopResp resp = { };

        req_lock.release();
        resp.hdr = req.hdr;
        resp.result = ZX_ERR_BAD_STATE;

        return channel->Write(&resp, sizeof(resp));
    }

    ring_buffer_state_ = RingBufferState::STOPPING;
    pending_job_resp_.stop.hdr = req.hdr;

    return ZX_OK;
}

void UsbAudioStream::RequestComplete(usb_request_t* req) {
    enum class Action {
        NONE,
        SIGNAL_STARTED,
        SIGNAL_STOPPED,
        NOTIFY_POSITION,
        HANDLE_UNPLUG,
    };

    union {
        audio_proto::RingBufStopResp  stop;
        audio_proto::RingBufStartResp start;
        audio_proto::RingBufPositionNotify notify_pos;
    } resp;

    uint64_t complete_time = zx_clock_get_monotonic();
    Action when_finished = Action::NONE;

    // TODO(johngro) : See ZX-940.  Eliminate this as soon as we have a more
    // official way of meeting real-time latency requirements.  Also, the fact
    // that this boosting gets done after the first transaction completes
    // degrades the quality of the startup time estimate (if the system is under
    // high load when the system starts up).  As a general issue, there are
    // better ways of refining this estimate than bumping the thread prio before
    // the first transaction gets queued.  Therefor, we just have a poor
    // estimate for now and will need to live with the consequences.
    if (!req_complete_prio_bumped_) {
        zx_object_set_profile(zx_thread_self(), profile_handle_.get(), 0);
        req_complete_prio_bumped_ = true;
    }

    {
        fbl::AutoLock req_lock(&req_lock_);

        // Cache the status and length of this usb request.
        zx_status_t req_status = req->response.status;
        uint32_t req_length = static_cast<uint32_t>(req->header.length);

        // Complete the usb request.  This will return the transaction to the free
        // list and (in the case of an input stream) copy the payload to the
        // ring buffer, and update the ring buffer position.
        //
        // TODO(johngro): copying the payload out of the ring buffer is an
        // operation which goes away when we get to the zero copy world.
        CompleteRequestLocked(req);

        // Did the transaction fail because the device was unplugged?  If so,
        // enter the stopping state and close the connections to our clients.
        if (req_status == ZX_ERR_IO_NOT_PRESENT) {
            ring_buffer_state_ = RingBufferState::STOPPING_AFTER_UNPLUG;
        } else {
            // If we are supposed to be delivering notifications, check to see
            // if it is time to do so.
            if (bytes_per_notification_) {
                notification_acc_ += req_length;

                if ((ring_buffer_state_ == RingBufferState::STARTED) &&
                    (notification_acc_ >= bytes_per_notification_)) {
                    when_finished = Action::NOTIFY_POSITION;
                    notification_acc_ = (notification_acc_ % bytes_per_notification_);
                    resp.notify_pos.ring_buffer_pos = ring_buffer_pos_;
                }
            }
        }

        switch (ring_buffer_state_) {
        case RingBufferState::STOPPING:
            if (free_req_cnt_ == allocated_req_cnt_) {
                resp.stop = pending_job_resp_.stop;
                when_finished = Action::SIGNAL_STOPPED;
            }
            break;

        case RingBufferState::STOPPING_AFTER_UNPLUG:
            if (free_req_cnt_ == allocated_req_cnt_) {
                resp.stop = pending_job_resp_.stop;
                when_finished = Action::HANDLE_UNPLUG;
            }
            break;

        case RingBufferState::STARTING:
            resp.start = pending_job_resp_.start;
            when_finished = Action::SIGNAL_STARTED;
            break;

        case RingBufferState::STARTED:
            QueueRequestLocked();
            break;

        case RingBufferState::STOPPED:
        default:
            LOG(ERROR, "Invalid state (%u) in %s\n",
                static_cast<uint32_t>(ring_buffer_state_), __PRETTY_FUNCTION__);
            ZX_DEBUG_ASSERT(false);
            break;
        }
    }

    if (when_finished != Action::NONE) {
        fbl::AutoLock lock(&lock_);
        switch (when_finished) {
        case Action::SIGNAL_STARTED:
            if (rb_channel_ != nullptr) {
                // TODO(johngro) : this start time estimate is not as good as it
                // could be.  We really need to have the USB bus driver report
                // the relationship between the USB frame counter and the system
                // tick counter (and track the relationship in the case that the
                // USB oscillator is not derived from the system oscillator).
                // Then we can accurately report the start time as the time of
                // the tick on which we scheduled the first transaction.
                resp.start.result = ZX_OK;
                resp.start.start_time = zx_time_sub_duration(complete_time, ZX_MSEC(1));
                rb_channel_->Write(&resp.start, sizeof(resp.start));
            }
            {
                fbl::AutoLock req_lock(&req_lock_);
                ring_buffer_state_ = RingBufferState::STARTED;
            }
            break;

        case Action::HANDLE_UNPLUG:
            if (rb_channel_ != nullptr) {
                rb_channel_->Deactivate();
                rb_channel_.reset();
            }

            if (stream_channel_ != nullptr) {
                stream_channel_->Deactivate();
                stream_channel_.reset();
            }

            {
                fbl::AutoLock req_lock(&req_lock_);
                ring_buffer_state_ = RingBufferState::STOPPED;
            }
            break;

        case Action::SIGNAL_STOPPED:
            if (rb_channel_ != nullptr) {
                resp.stop.result = ZX_OK;
                rb_channel_->Write(&resp.stop, sizeof(resp.stop));
            }
            {
                fbl::AutoLock req_lock(&req_lock_);
                ring_buffer_state_ = RingBufferState::STOPPED;
                ifc_->ActivateIdleFormat();
            }
            break;

        case Action::NOTIFY_POSITION:
            resp.notify_pos.hdr.cmd = AUDIO_RB_POSITION_NOTIFY;
            resp.notify_pos.hdr.transaction_id = AUDIO_INVALID_TRANSACTION_ID;
            rb_channel_->Write(&resp.notify_pos, sizeof(resp.notify_pos));
            break;

        default:
            ZX_DEBUG_ASSERT(false);
            break;
        }
    }
}

void UsbAudioStream::QueueRequestLocked() {
    ZX_DEBUG_ASSERT((ring_buffer_state_ == RingBufferState::STARTING) ||
                    (ring_buffer_state_ == RingBufferState::STARTED));
    ZX_DEBUG_ASSERT(!list_is_empty(&free_req_));

    // Figure out how much we want to send or receive this time (short or long
    // packet)
    uint32_t todo = bytes_per_packet_;
    fractional_bpp_acc_ += fractional_bpp_inc_;
    if (fractional_bpp_acc_ >= iso_packet_rate_) {
        fractional_bpp_acc_ -= iso_packet_rate_;
        todo += frame_size_;
        ZX_DEBUG_ASSERT(fractional_bpp_acc_ < iso_packet_rate_);
    }

    // Grab a free usb request.
    auto req = usb_req_list_remove_head(&free_req_, parent_.parent_req_size());
    ZX_DEBUG_ASSERT(req != nullptr);
    ZX_DEBUG_ASSERT(free_req_cnt_ > 0);
    --free_req_cnt_;

    // If this is an output stream, copy our data into the usb request.
    // TODO(johngro): eliminate this when we can get to a zero-copy world.
    if (!is_input()) {
        uint32_t avail = ring_buffer_size_ - ring_buffer_offset_;
        ZX_DEBUG_ASSERT(ring_buffer_offset_ < ring_buffer_size_);
        ZX_DEBUG_ASSERT((avail % frame_size_) == 0);
        uint32_t amt = fbl::min(avail, todo);

        const uint8_t* src = reinterpret_cast<uint8_t*>(ring_buffer_virt_) + ring_buffer_offset_;
        usb_request_copy_to(req, src, amt, 0);
        if (amt == avail) {
            ring_buffer_offset_ = todo - amt;
            if (ring_buffer_offset_ > 0) {
                usb_request_copy_to(req, ring_buffer_virt_, ring_buffer_offset_, amt);
            }
        } else {
            ring_buffer_offset_ += amt;
        }
    }

    req->header.frame = usb_frame_num_++;
    req->header.length = todo;
    usb_request_complete_t complete = {
        .callback = UsbAudioStream::RequestCompleteCallback,
        .ctx = this,
    };
    usb_request_queue(&parent_.usb_proto(), req, &complete);
}

void UsbAudioStream::CompleteRequestLocked(usb_request_t* req) {
    ZX_DEBUG_ASSERT(req);

    // If we are an input stream, copy the payload into the ring buffer.
    if (is_input()) {
        uint32_t todo = static_cast<uint32_t>(req->header.length);

        uint32_t avail = ring_buffer_size_ - ring_buffer_offset_;
        ZX_DEBUG_ASSERT(ring_buffer_offset_ < ring_buffer_size_);
        ZX_DEBUG_ASSERT((avail % frame_size_) == 0);

        uint32_t amt = fbl::min(avail, todo);
        uint8_t* dst = reinterpret_cast<uint8_t*>(ring_buffer_virt_) + ring_buffer_offset_;

        if (req->response.status == ZX_OK) {
            usb_request_copy_from(req, dst, amt, 0);
            if (amt < todo) {
                usb_request_copy_from(req, ring_buffer_virt_, todo - amt, amt);
            }
        } else {
            // TODO(johngro): filling with zeros is only the proper thing to do
            // for signed formats.  USB does support unsigned 8-bit audio; if
            // that is our format, we should fill with 0x80 instead in order to
            // fill with silence.
            memset(dst, 0, amt);
            if (amt < todo) {
                memset(ring_buffer_virt_, 0, todo - amt);
            }
        }
    }

    // Update the ring buffer position.
    ring_buffer_pos_ += static_cast<uint32_t>(req->header.length);
    if (ring_buffer_pos_ >= ring_buffer_size_) {
        ring_buffer_pos_ -= ring_buffer_size_;
        ZX_DEBUG_ASSERT(ring_buffer_pos_ < ring_buffer_size_);
    }

    // If this is an input stream, the ring buffer offset should always be equal
    // to the stream position.
    if (is_input()) {
        ring_buffer_offset_ = ring_buffer_pos_;
    }

    // Return the transaction to the free list.
    zx_status_t status = usb_req_list_add_head(&free_req_, req, parent_.parent_req_size());
    ZX_DEBUG_ASSERT(status == ZX_OK);
    ++free_req_cnt_;
    ZX_DEBUG_ASSERT(free_req_cnt_ <= allocated_req_cnt_);
}

void UsbAudioStream::DeactivateStreamChannel(const dispatcher::Channel* channel) {
    fbl::AutoLock lock(&lock_);

    ZX_DEBUG_ASSERT(stream_channel_.get() == channel);
    ZX_DEBUG_ASSERT(rb_channel_.get() != channel);
    stream_channel_.reset();
}

void UsbAudioStream::DeactivateRingBufferChannel(const dispatcher::Channel* channel) {
    fbl::AutoLock lock(&lock_);

    ZX_DEBUG_ASSERT(stream_channel_.get() != channel);
    ZX_DEBUG_ASSERT(rb_channel_.get() == channel);

    {
        fbl::AutoLock req_lock(&req_lock_);
        if (ring_buffer_state_ != RingBufferState::STOPPED) {
            ring_buffer_state_ = RingBufferState::STOPPING;
        }
    }

    rb_channel_.reset();
}

}  // namespace usb
}  // namespace audio
