// 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 <fcntl.h>
#include <fuchsia/hardware/audio/llcpp/fidl.h>
#include <inttypes.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/handle.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <stdio.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/device/audio.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/time.h>
#include <zircon/types.h>

#include <limits>

#include <audio-utils/audio-device-stream.h>
#include <audio-utils/audio-input.h>
#include <audio-utils/audio-output.h>
#include <fbl/algorithm.h>
#include <fbl/auto_call.h>
#include <fbl/unique_fd.h>

namespace audio {
namespace utils {

template <typename ReqType, typename RespType>
zx_status_t DoCallImpl(const zx::channel& channel, const ReqType& req, RespType* resp,
                       zx::handle* resp_handle_out, uint32_t* resp_len_out = nullptr) {
  zx_channel_call_args_t args;

  ZX_DEBUG_ASSERT((resp_handle_out == nullptr) || !resp_handle_out->is_valid());

  args.wr_bytes = const_cast<ReqType*>(&req);
  args.wr_num_bytes = sizeof(ReqType);
  args.wr_handles = nullptr;
  args.wr_num_handles = 0;
  args.rd_bytes = resp;
  args.rd_num_bytes = sizeof(RespType);
  args.rd_handles = resp_handle_out ? resp_handle_out->reset_and_get_address() : nullptr;
  args.rd_num_handles = resp_handle_out ? 1 : 0;

  uint32_t bytes, handles;

  zx_status_t status = channel.call(0, zx::time(ZX_TIME_INFINITE), &args, &bytes, &handles);
  if (status != ZX_OK) {
    printf("Cmd failure (cmd %04x, res %d)\n", req.hdr.cmd, status);
    return status;
  }

  // If the caller wants to know the size of the response length, let them
  // check to make sure it is consistent with what they expect.  Otherwise,
  // make sure that the number of bytes we got back matches the size of the
  // response structure.
  if (resp_len_out != nullptr) {
    *resp_len_out = bytes;
  } else if (bytes != sizeof(RespType)) {
    printf("Unexpected response size (got %u, expected %zu)\n", bytes, sizeof(RespType));
    return ZX_ERR_INTERNAL;
  }

  return ZX_OK;
}

template <typename ReqType, typename RespType>
zx_status_t DoCall(const zx::channel& channel, const ReqType& req, RespType* resp,
                   zx::handle* resp_handle_out = nullptr) {
  zx_status_t res = DoCallImpl(channel, req, resp, resp_handle_out);
  return (res != ZX_OK) ? res : resp->result;
}

template <typename ReqType, typename RespType>
zx_status_t DoNoFailCall(const zx::channel& channel, const ReqType& req, RespType* resp,
                         zx::handle* resp_handle_out = nullptr) {
  return DoCallImpl(channel, req, resp, resp_handle_out);
}

AudioDeviceStream::AudioDeviceStream(StreamDirection direction, uint32_t dev_id)
    : direction_(direction) {
  snprintf(name_, sizeof(name_), "/dev/class/audio-%s/%03u",
           direction == StreamDirection::kInput ? "input" : "output", dev_id);
}

AudioDeviceStream::AudioDeviceStream(StreamDirection direction, const char* dev_path)
    : direction_(direction) {
  strncpy(name_, dev_path, sizeof(name_) - 1);
  name_[sizeof(name_) - 1] = 0;
}

AudioDeviceStream::~AudioDeviceStream() { Close(); }

zx_status_t AudioDeviceStream::Open() {
  if (stream_ch_ != ZX_HANDLE_INVALID)
    return ZX_ERR_BAD_STATE;

  zx::channel local, remote;
  auto res = zx::channel::create(0, &local, &remote);
  if (res != ZX_OK) {
    printf("Failed to create channel (res %d)\n", res);
  }
  res = fdio_service_connect(name(), remote.release());
  using Device = ::llcpp::fuchsia::hardware::audio::Device;
  Device::SyncClient client_wrap(std::move(local));
  Device::ResultOf::GetChannel channel_wrap = client_wrap.GetChannel();
  stream_ch_ = std::move(channel_wrap->channel);

  return res;
}

zx_status_t AudioDeviceStream::GetSupportedFormats(
    fbl::Vector<audio_stream_format_range_t>* out_formats) const {
  constexpr uint32_t MIN_RESP_SIZE = offsetof(audio_stream_cmd_get_formats_resp_t, format_ranges);
  audio_stream_cmd_get_formats_req req;
  audio_stream_cmd_get_formats_resp resp;
  uint32_t rxed;
  zx_status_t res;

  if (out_formats == nullptr) {
    return ZX_ERR_INVALID_ARGS;
  }

  req.hdr.cmd = AUDIO_STREAM_CMD_GET_FORMATS;
  req.hdr.transaction_id = 1;
  res = DoCallImpl(stream_ch_, req, &resp, nullptr, &rxed);
  if ((res != ZX_OK) || (rxed < MIN_RESP_SIZE)) {
    printf("Failed to fetch initial suppored format list chunk (res %d, rxed %u)\n", res, rxed);
    return res;
  }

  uint32_t expected_formats = resp.format_range_count;
  if (!expected_formats)
    return ZX_OK;

  out_formats->reset();
  fbl::AllocChecker ac;
  out_formats->reserve(expected_formats, &ac);
  if (!ac.check()) {
    printf("Failed to allocated %u entries for format ranges\n", expected_formats);
    return ZX_ERR_NO_MEMORY;
  }

  zx_txid_t txid = resp.hdr.transaction_id;
  uint32_t processed_formats = 0;
  while (true) {
    if (resp.hdr.cmd != AUDIO_STREAM_CMD_GET_FORMATS) {
      printf(
          "Unexpected response command while fetching formats "
          "(expected 0x%08x, got 0x%08x)\n",
          AUDIO_STREAM_CMD_GET_FORMATS, resp.hdr.cmd);
      return ZX_ERR_INTERNAL;
    }

    if (resp.hdr.transaction_id != txid) {
      printf(
          "Unexpected response transaction id while fetching formats "
          "(expected 0x%08x, got 0x%08x)\n",
          txid, resp.hdr.transaction_id);
      return ZX_ERR_INTERNAL;
    }

    if (resp.first_format_range_ndx != processed_formats) {
      printf("Bad format index while fetching formats (expected %u, got %hu)\n", processed_formats,
             resp.first_format_range_ndx);
      return ZX_ERR_INTERNAL;
    }

    uint32_t todo = fbl::min(static_cast<uint32_t>(expected_formats - processed_formats),
                             AUDIO_STREAM_CMD_GET_FORMATS_MAX_RANGES_PER_RESPONSE);
    size_t min_size = MIN_RESP_SIZE + (todo * sizeof(audio_stream_format_range_t));
    if (rxed < min_size) {
      printf("Short response while fetching formats (%u < %zu)\n", rxed, min_size);
      return ZX_ERR_INTERNAL;
    }

    for (uint16_t i = 0; i < todo; ++i) {
      out_formats->push_back(resp.format_ranges[i]);
    }

    processed_formats += todo;
    if (processed_formats == expected_formats)
      break;

    zx_signals_t pending_sig;
    res = stream_ch_.wait_one(ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED,
                              zx::time(ZX_TIME_INFINITE), &pending_sig);
    if (res != ZX_OK) {
      printf("Failed to wait for next response after processing %u/%u formats (res %d)\n",
             processed_formats, expected_formats, res);
      return res;
    }

    res = stream_ch_.read(0u, &resp, nullptr, sizeof(resp), 0, &rxed, nullptr);
    if (res != ZX_OK) {
      printf("Failed to read next response after processing %u/%u formats (res %d)\n",
             processed_formats, expected_formats, res);
      return res;
    }
  }

  return ZX_OK;
}

zx_status_t AudioDeviceStream::GetPlugState(audio_stream_cmd_plug_detect_resp_t* out_state,
                                            bool enable_notify) const {
  ZX_DEBUG_ASSERT(out_state != nullptr);
  audio_stream_cmd_plug_detect_req req;

  req.hdr.cmd = AUDIO_STREAM_CMD_PLUG_DETECT;
  req.hdr.transaction_id = 1;
  req.flags = enable_notify ? AUDIO_PDF_ENABLE_NOTIFICATIONS : AUDIO_PDF_NONE;

  zx_status_t res = DoNoFailCall(stream_ch_, req, out_state);
  if (res != ZX_OK)
    printf("Failed to fetch plug detect information! (res %d)\n", res);

  return res;
}

void AudioDeviceStream::DisablePlugNotifications() {
  audio_stream_cmd_plug_detect_req req;

  req.hdr.cmd = static_cast<audio_cmd_t>(AUDIO_STREAM_CMD_PLUG_DETECT | AUDIO_FLAG_NO_ACK);
  req.hdr.transaction_id = 1;
  req.flags = AUDIO_PDF_DISABLE_NOTIFICATIONS;

  stream_ch_.write(0, &req, sizeof(req), nullptr, 0);
}

zx_status_t AudioDeviceStream::SetMute(bool mute) {
  audio_stream_cmd_set_gain_req req;
  audio_stream_cmd_set_gain_resp resp;

  req.hdr.cmd = AUDIO_STREAM_CMD_SET_GAIN;
  req.hdr.transaction_id = 1;
  req.flags = mute ? static_cast<audio_set_gain_flags_t>(AUDIO_SGF_MUTE_VALID | AUDIO_SGF_MUTE)
                   : AUDIO_SGF_MUTE_VALID;

  zx_status_t res = DoCall(stream_ch_, req, &resp);
  if (res != ZX_OK)
    printf("Failed to %smute stream! (res %d)\n", mute ? "" : "un", res);
  else
    printf("Stream is now %smuted\n", mute ? "" : "un");

  return res;
}

zx_status_t AudioDeviceStream::SetAgc(bool enabled) {
  audio_stream_cmd_set_gain_req req;
  audio_stream_cmd_set_gain_resp resp;

  req.hdr.cmd = AUDIO_STREAM_CMD_SET_GAIN;
  req.hdr.transaction_id = 1;
  req.flags = enabled ? static_cast<audio_set_gain_flags_t>(AUDIO_SGF_AGC_VALID | AUDIO_SGF_AGC)
                      : AUDIO_SGF_AGC_VALID;

  zx_status_t res = DoCall(stream_ch_, req, &resp);
  if (res != ZX_OK)
    printf("Failed to %sable AGC for stream! (res %d)\n", enabled ? "en" : "dis", res);
  else
    printf("Stream AGC is now %sabled\n", enabled ? "en" : "dis");

  return res;
}

zx_status_t AudioDeviceStream::SetGain(float gain) {
  audio_stream_cmd_set_gain_req req;
  audio_stream_cmd_set_gain_resp resp;

  req.hdr.cmd = AUDIO_STREAM_CMD_SET_GAIN;
  req.hdr.transaction_id = 1;
  req.flags = AUDIO_SGF_GAIN_VALID;
  req.gain = gain;

  zx_status_t res = DoCall(stream_ch_, req, &resp);
  if (res != ZX_OK) {
    printf("Failed to set gain to %.2f dB! (res %d)\n", gain, res);
  } else {
    printf("Gain is now %.2f dB.  Stream is %smuted.\n", resp.cur_gain, resp.cur_mute ? "" : "un");
  }

  return res;
}

zx_status_t AudioDeviceStream::GetGain(audio_stream_cmd_get_gain_resp_t* out_gain) const {
  if (out_gain == nullptr)
    return ZX_ERR_INVALID_ARGS;

  audio_stream_cmd_get_gain_req req;
  req.hdr.cmd = AUDIO_STREAM_CMD_GET_GAIN;
  req.hdr.transaction_id = 1;

  return DoNoFailCall(stream_ch_, req, out_gain);
}

zx_status_t AudioDeviceStream::GetUniqueId(audio_stream_cmd_get_unique_id_resp_t* out_id) const {
  if (out_id == nullptr)
    return ZX_ERR_INVALID_ARGS;

  audio_stream_cmd_get_unique_id_req req;
  req.hdr.cmd = AUDIO_STREAM_CMD_GET_UNIQUE_ID;
  req.hdr.transaction_id = 1;

  return DoNoFailCall(stream_ch_, req, out_id);
}

zx_status_t AudioDeviceStream::GetString(audio_stream_string_id_t id,
                                         audio_stream_cmd_get_string_resp_t* out_str) const {
  if (out_str == nullptr)
    return ZX_ERR_INVALID_ARGS;

  audio_stream_cmd_get_string_req req;
  req.hdr.cmd = AUDIO_STREAM_CMD_GET_STRING;
  req.hdr.transaction_id = 1;
  req.id = id;

  return DoNoFailCall(stream_ch_, req, out_str);
}

zx_status_t AudioDeviceStream::GetClockDomain(
    audio_stream_cmd_get_clock_domain_resp_t* out_domain) const {
  if (out_domain == nullptr)
    return ZX_ERR_INVALID_ARGS;

  audio_stream_cmd_get_clock_domain_req req;
  req.hdr.cmd = AUDIO_STREAM_CMD_GET_CLOCK_DOMAIN;
  req.hdr.transaction_id = 1;

  return DoNoFailCall(stream_ch_, req, out_domain);
}

zx_status_t AudioDeviceStream::PlugMonitor(float duration, PlugMonitorCallback* monitor) {
  const double duration_ns = static_cast<double>(duration) * ZX_SEC(1);
  const zx_time_t deadline = zx_deadline_after(static_cast<zx_duration_t>(duration_ns));
  audio_stream_cmd_plug_detect_resp resp;
  zx_status_t res = GetPlugState(&resp, true);
  if (res != ZX_OK)
    return res;

  zx_time_t last_plug_time = resp.plug_state_time;
  bool last_plug_state = (resp.flags & AUDIO_PDNF_PLUGGED);
  printf("Initial plug state is : %s.\n", last_plug_state ? "plugged" : "unplugged");

  if (resp.flags & AUDIO_PDNF_HARDWIRED) {
    printf("Stream reports that it is hardwired, Monitoring is not possible.\n");
    return ZX_OK;
  }

  auto ReportPlugState = [&last_plug_time, &last_plug_state, &monitor](
                             bool plug_state, zx_time_t plug_time) -> bool {
    printf("Plug State now : %s (%.3lf sec since last change).\n",
           plug_state ? "plugged" : "unplugged",
           static_cast<double>(zx_time_sub_time(plug_time, last_plug_time)) /
               static_cast<double>(ZX_SEC(1)));

    last_plug_state = plug_state;
    last_plug_time = plug_time;
    if (monitor) {
      return (*monitor)(plug_state, plug_time);
    }
    return true;  // Continue monitoring.
  };

  if (resp.flags & AUDIO_PDNF_CAN_NOTIFY) {
    printf("Stream is capable of async notification.  Monitoring for %.2f seconds\n", duration);

    auto cleanup = fbl::MakeAutoCall([this]() { DisablePlugNotifications(); });
    while (true) {
      zx_signals_t pending;
      res = stream_ch_.wait_one(ZX_CHANNEL_PEER_CLOSED | ZX_CHANNEL_READABLE, zx::time(deadline),
                                &pending);

      if ((res != ZX_OK) || (pending & ZX_CHANNEL_PEER_CLOSED)) {
        if (res != ZX_ERR_TIMED_OUT)
          printf("Error while waiting for plug notification (res %d)\n", res);

        if (pending & ZX_CHANNEL_PEER_CLOSED)
          printf("Peer closed while waiting for plug notification\n");

        break;
      }

      ZX_DEBUG_ASSERT(pending & ZX_CHANNEL_READABLE);

      audio_stream_plug_detect_notify_t state;
      uint32_t bytes_read;
      res = stream_ch_.read(0, &state, nullptr, sizeof(state), 0, &bytes_read, nullptr);
      if (res != ZX_OK) {
        printf("Read failure while waiting for plug notification (res %d)\n", res);
        break;
      }

      if ((bytes_read != sizeof(state)) || (state.hdr.cmd != AUDIO_STREAM_PLUG_DETECT_NOTIFY)) {
        printf(
            "Size/type mismatch while waiting for plug notification.  "
            "Got (%u/%u) Expected (%zu/%u)\n",
            bytes_read, state.hdr.cmd, sizeof(state), AUDIO_STREAM_PLUG_DETECT_NOTIFY);
        break;
      }

      bool plug_state = (state.flags & AUDIO_PDNF_PLUGGED);
      if (!ReportPlugState(plug_state, state.plug_state_time)) {
        printf("Monitoring finished after callback reported.\n");
        return ZX_OK;
      }
    }
  } else {
    printf("Stream is not capable of async notification.  Polling for %.2f seconds\n", duration);

    while (true) {
      zx_time_t now = zx_clock_get_monotonic();
      if (now >= deadline)
        break;

      zx_time_t next_wake = fbl::min(deadline, zx_time_add_duration(now, ZX_MSEC(100u)));

      zx_signals_t sigs;
      zx_status_t res = stream_ch_.wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time(next_wake), &sigs);

      if ((res != ZX_OK) && (res != ZX_ERR_TIMED_OUT)) {
        printf("Error waiting on stream channel (res %d)\n", res);
        break;
      }

      if (sigs & ZX_CHANNEL_PEER_CLOSED) {
        printf("Peer closed connection while polling plug state\n");
        break;
      }

      res = GetPlugState(&resp, true);
      if (res != ZX_OK) {
        printf("Failed to poll plug state (res %d)\n", res);
        break;
      }

      bool plug_state = (resp.flags & AUDIO_PDNF_PLUGGED);
      if (plug_state != last_plug_state) {
        if (!ReportPlugState(resp.flags, resp.plug_state_time)) {
          printf("Monitoring finished after callback reported.\n");
          return ZX_OK;
        }
      }
    }
  }

  printf("Monitoring finished.\n");

  return ZX_OK;
}

zx_status_t AudioDeviceStream::SetFormat(uint32_t frames_per_second, uint16_t channels,
                                         audio_sample_format_t sample_format) {
  if ((stream_ch_ == ZX_HANDLE_INVALID) || (rb_ch_ != ZX_HANDLE_INVALID))
    return ZX_ERR_BAD_STATE;

  auto noflag_format =
      static_cast<audio_sample_format_t>((sample_format & ~AUDIO_SAMPLE_FORMAT_FLAG_MASK));

  switch (noflag_format) {
    case AUDIO_SAMPLE_FORMAT_8BIT:
      sample_size_ = 1;
      break;
    case AUDIO_SAMPLE_FORMAT_16BIT:
      sample_size_ = 2;
      break;
    case AUDIO_SAMPLE_FORMAT_24BIT_PACKED:
      sample_size_ = 3;
      break;
    case AUDIO_SAMPLE_FORMAT_20BIT_IN32:
    case AUDIO_SAMPLE_FORMAT_24BIT_IN32:
    case AUDIO_SAMPLE_FORMAT_32BIT:
    case AUDIO_SAMPLE_FORMAT_32BIT_FLOAT:
      sample_size_ = 4;
      break;
    default:
      return ZX_ERR_NOT_SUPPORTED;
  }

  channel_cnt_ = channels;
  frame_sz_ = channels * sample_size_;
  frame_rate_ = frames_per_second;
  sample_format_ = sample_format;

  audio_stream_cmd_set_format_req_t req;
  audio_stream_cmd_set_format_resp_t resp;
  req.hdr.cmd = AUDIO_STREAM_CMD_SET_FORMAT;
  req.hdr.transaction_id = 1;
  req.frames_per_second = frames_per_second;
  req.channels = channels;
  req.sample_format = sample_format;

  zx::handle tmp;
  zx_status_t res = DoCall(stream_ch_, req, &resp, &tmp);
  if (res != ZX_OK) {
    printf("Failed to set format %uHz %hu-Ch fmt 0x%x (res %d)\n", frames_per_second, channels,
           sample_format, res);
  }

  external_delay_nsec_ = resp.external_delay_nsec;

  // TODO(johngro) : Verify the type of this handle before transferring it to
  // our ring buffer channel handle.
  rb_ch_.reset(tmp.release());

  return res;
}

zx_status_t AudioDeviceStream::GetBuffer(uint32_t frames, uint32_t irqs_per_ring) {
  zx_status_t res;

  if (!frames)
    return ZX_ERR_INVALID_ARGS;

  if (!rb_ch_.is_valid() || rb_vmo_.is_valid() || !frame_sz_)
    return ZX_ERR_BAD_STATE;

  // Stash the FIFO depth, in case users need to know it.
  {
    audio_rb_cmd_get_fifo_depth_req_t req;
    audio_rb_cmd_get_fifo_depth_resp_t resp;

    req.hdr.cmd = AUDIO_RB_CMD_GET_FIFO_DEPTH;
    req.hdr.transaction_id = 1;
    res = DoCall(rb_ch_, req, &resp);
    if (res != ZX_OK) {
      printf("Failed to fetch fifo depth (res %d)\n", res);
      return res;
    }

    fifo_depth_ = resp.fifo_depth;
  }

  uint64_t rb_sz;
  {
    // Get a VMO representing the ring buffer we will share with the audio driver.
    audio_rb_cmd_get_buffer_req_t req;
    audio_rb_cmd_get_buffer_resp_t resp;

    req.hdr.cmd = AUDIO_RB_CMD_GET_BUFFER;
    req.hdr.transaction_id = 1;
    req.min_ring_buffer_frames = frames;
    req.notifications_per_ring = irqs_per_ring;

    zx::handle tmp;
    res = DoCall(rb_ch_, req, &resp, &tmp);

    if ((res == ZX_OK) && (resp.result != ZX_OK))
      res = resp.result;

    if (res != ZX_OK) {
      printf("Failed to get driver ring buffer VMO (res %d)\n", res);
      return res;
    }

    rb_sz = static_cast<uint64_t>(resp.num_ring_buffer_frames) * frame_sz_;

    // TODO(johngro) : Verify the type of this handle before transferring it to our VMO handle.
    rb_vmo_.reset(tmp.release());
  }

  // We have the buffer, fetch the underlying size of the VMO (a rounded up
  // multiple of pages) and sanity check it against the effective size the
  // driver reported.
  uint64_t rb_page_sz;
  res = rb_vmo_.get_size(&rb_page_sz);
  if (res != ZX_OK) {
    printf("Failed to fetch ring buffer VMO size (res %d)\n", res);
    return res;
  }

  if ((rb_sz > std::numeric_limits<decltype(rb_sz_)>::max()) || (rb_sz > rb_page_sz)) {
    printf(
        "Bad ring buffer size returned by audio driver! "
        "(kernel size = %lu driver size = %lu)\n",
        rb_page_sz, rb_sz);
    return ZX_ERR_INVALID_ARGS;
  }

  rb_sz_ = static_cast<decltype(rb_sz_)>(rb_sz);

  // Map the VMO into our address space
  // TODO(johngro) : How do I specify the cache policy for this mapping?
  uint32_t flags = input() ? ZX_VM_PERM_READ : ZX_VM_PERM_READ | ZX_VM_PERM_WRITE;
  res = zx::vmar::root_self()->map(0u, rb_vmo_, 0u, rb_sz_, flags,
                                   reinterpret_cast<uintptr_t*>(&rb_virt_));

  if (res != ZX_OK) {
    printf("Failed to map ring buffer VMO (res %d)\n", res);
    return res;
  }

  // Success!  If this is an output device, zero out the buffer and we are done.
  if (!input()) {
    memset(rb_virt_, 0, rb_sz_);
  }

  return ZX_OK;
}

zx_status_t AudioDeviceStream::StartRingBuffer() {
  if (rb_ch_ == ZX_HANDLE_INVALID)
    return ZX_ERR_BAD_STATE;

  audio_rb_cmd_start_req_t req;
  audio_rb_cmd_start_resp_t resp;

  req.hdr.cmd = AUDIO_RB_CMD_START;
  req.hdr.transaction_id = 1;

  zx_status_t res = DoCall(rb_ch_, req, &resp);

  if (res == ZX_OK) {
    start_time_ = resp.start_time;
  }

  return res;
}

zx_status_t AudioDeviceStream::StopRingBuffer() {
  if (rb_ch_ == ZX_HANDLE_INVALID)
    return ZX_ERR_BAD_STATE;

  start_time_ = 0;

  audio_rb_cmd_stop_req_t req;
  audio_rb_cmd_stop_resp_t resp;

  req.hdr.cmd = AUDIO_RB_CMD_STOP;
  req.hdr.transaction_id = 1;

  return DoCall(rb_ch_, req, &resp);
}

void AudioDeviceStream::ResetRingBuffer() {
  if (rb_virt_ != nullptr) {
    ZX_DEBUG_ASSERT(rb_sz_ != 0);
    zx::vmar::root_self()->unmap(reinterpret_cast<uintptr_t>(rb_virt_), rb_sz_);
  }
  rb_ch_.reset();
  rb_vmo_.reset();
  rb_sz_ = 0;
  rb_virt_ = nullptr;
}

void AudioDeviceStream::Close() {
  ResetRingBuffer();
  stream_ch_.reset();
}

bool AudioDeviceStream::IsChannelConnected(const zx::channel& ch) {
  if (!ch.is_valid())
    return false;

  zx_signals_t junk;
  return ch.wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time(), &junk) != ZX_ERR_TIMED_OUT;
}

}  // namespace utils
}  // namespace audio
