// 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 "src/connectivity/ethernet/drivers/usb-cdc-function/usb-cdc-function.h"

#include <endian.h>
#include <fidl/fuchsia.boot.metadata/cpp/fidl.h>
#include <fidl/fuchsia.hardware.usb.endpoint/cpp/fidl.h>
#include <fidl/fuchsia.hardware.usb.function/cpp/fidl.h>
#include <lib/driver/compat/cpp/banjo_client.h>
#include <lib/driver/component/cpp/driver_export.h>
#include <lib/driver/metadata/cpp/metadata_server.h>
#include <lib/fdf/cpp/dispatcher.h>
#include <lib/trace/event.h>

#include <mutex>
#include <vector>

#include <usb-endpoint/usb-endpoint-client.h>
#include <usb/request-fidl.h>
#include <usb/usb-request.h>

namespace {

// TODO(https://fxbug.dev/436378683): Remove once usb-cdc-function no longer hangs while
// initializing.
enum class InitState {
  kWaitingForAllocInterface1 = 0,
  kWaitingForAllocInterface2 = 1,
  kWaitingForAllocEp1 = 2,
  kWaitingForAllocEp2 = 3,
  kWaitingForAllocEp3 = 4,
  kWaitingForMacAddress = 5,
  kWaitingForInit1 = 6,
  kWaitingForAddRequests1 = 7,
  kWaitingForInit2 = 8,
  kWaitingForAddRequests2 = 9,
  kWaitingForInit3 = 10,
  kWaitingForAddRequests3 = 11,
  kWaitingForSetInterface = 12
};

}  // namespace

namespace usb_cdc_function {

namespace fendpoint = fuchsia_hardware_usb_endpoint;
namespace ffunction = fuchsia_hardware_usb_function;
namespace frequest = fuchsia_hardware_usb_request;

typedef struct txn_info {
  ethernet_netbuf_t netbuf;
  ethernet_impl_queue_tx_callback completion_cb;
  void* cookie;
  list_node_t node;
} txn_info_t;

static void complete_txn(txn_info_t* txn, zx_status_t status) {
  txn->completion_cb(txn->cookie, status, &txn->netbuf);
}

zx_status_t UsbCdcFunction::insert_usb_request(usb::FidlRequest&& req,
                                               usb::EndpointClient<UsbCdcFunction>& ep) {
  if (unbound_) {
    return ZX_OK;
  }
  ep.PutRequest(std::move(req));
  return ZX_OK;
}

void UsbCdcFunction::usb_request_queue(usb::FidlRequest&& req,
                                       usb::EndpointClient<UsbCdcFunction>& ep) {
  if (unbound_) {
    return;
  }

  std::vector<frequest::Request> reqs;
  reqs.emplace_back(req.take_request());
  auto result = ep->QueueRequests({std::move(reqs)});
  ZX_ASSERT(result.is_ok());
}

zx_status_t UsbCdcFunction::cdc_generate_mac_address() {
  zx::result result =
      fdf_metadata::GetMetadataIfExists<fuchsia_boot_metadata::MacAddressMetadata>(incoming());
  if (result.is_error()) {
    fdf::error("Failed to get MAC address metadata: {}", result);
    return result.status_value();
  }
  if (result.value().has_value()) {
    const auto& metadata = result.value().value();
    if (!metadata.mac_address().has_value()) {
      fdf::error("MAC address metadata missing mac_address field");
      return ZX_ERR_INTERNAL;
    }
    mac_addr_ = metadata.mac_address().value().octets();
  } else {
    fdf::info("ethernet MAC metadata not found. Generating random address");

    zx_cprng_draw(mac_addr_.data(), mac_addr_.size());
    mac_addr_[0] = 0x02;
  }

  char buffer[sizeof(mac_addr_) * 3];
  snprintf(buffer, sizeof(buffer), "%02X%02X%02X%02X%02X%02X", mac_addr_[0], mac_addr_[1],
           mac_addr_[2], mac_addr_[3], mac_addr_[4], mac_addr_[5]);

  // Make the host and device addresses different so packets are routed correctly.
  mac_addr_[5] ^= 1;

  return function_.AllocStringDesc(buffer, &descriptors_.cdc_eth.iMACAddress);
}

zx_status_t UsbCdcFunction::EthernetImplQuery(uint32_t options, ethernet_info_t* out_info) {
  // No options are supported
  if (options) {
    fdf::error("unexpected options (0x{:x}) to ethernet_impl_query", options);
    return ZX_ERR_INVALID_ARGS;
  }

  memset(out_info, 0, sizeof(*out_info));
  out_info->mtu = ETH_MTU;
  memcpy(out_info->mac, mac_addr_.data(), mac_addr_.size());
  out_info->netbuf_size = sizeof(txn_info_t);

  return ZX_OK;
}

void UsbCdcFunction::EthernetImplStop() {
  std::lock_guard<std::mutex> tx(tx_mutex_);
  std::lock_guard<std::mutex> ethernet(ethernet_mutex_);
  ethernet_ifc_.clear();
}

zx_status_t UsbCdcFunction::EthernetImplStart(const ethernet_ifc_protocol_t* ifc) {
  if (unbound_) {
    return ZX_ERR_BAD_STATE;
  }
  std::lock_guard<std::mutex> ethernet(ethernet_mutex_);
  if (ethernet_ifc_.is_valid()) {
    return ZX_ERR_ALREADY_BOUND;
  }
  ethernet_ifc_ = ddk::EthernetIfcProtocolClient(ifc);
  ethernet_ifc_.Status(online_ ? ETHERNET_STATUS_ONLINE : 0);
  return ZX_OK;
}

zx_status_t UsbCdcFunction::cdc_send_locked(ethernet_netbuf_t* netbuf) {
  {
    std::lock_guard<std::mutex> _(ethernet_mutex_);
    if (!ethernet_ifc_.is_valid()) {
      return ZX_ERR_BAD_STATE;
    }
  }

  const auto* byte_data = netbuf->data_buffer;
  size_t length = netbuf->data_size;

  // Make sure that we can get all of the tx buffers we need to use
  std::optional<usb::FidlRequest> tx_req = bulk_in_ep_.GetRequest();
  if (!tx_req.has_value()) {
    return ZX_ERR_SHOULD_WAIT;
  }

  // Send data
  tx_req->clear_buffers();
  std::vector<size_t> actual = tx_req->CopyTo(0, byte_data, length, bulk_in_ep_.GetMappedLocked());

  size_t actual_total = 0;
  for (size_t i = 0; i < actual.size(); i++) {
    // Fill in size of data.
    (*tx_req)->data()->at(i).size(actual[i]);
    actual_total += actual[i];
  }

  if (actual_total != length) {
    insert_usb_request(std::move(tx_req.value()), bulk_in_ep_);
    return ZX_ERR_INTERNAL;
  }

  zx_status_t status = tx_req->CacheFlush(bulk_in_ep_.GetMappedLocked());
  if (status != ZX_OK) {
    fdf::error("[bug] tx_req->CacheFlush(): {}", zx_status_get_string(status));
    return status;
  }
  usb_request_queue(std::move(tx_req.value()), bulk_in_ep_);

  return ZX_OK;
}

void UsbCdcFunction::EthernetImplQueueTx(uint32_t options, ethernet_netbuf_t* netbuf,
                                         ethernet_impl_queue_tx_callback callback, void* cookie) {
  size_t length = netbuf->data_size;
  zx_status_t status;

  txn_info_t* txn = containerof(netbuf, txn_info_t, netbuf);
  txn->completion_cb = callback;
  txn->cookie = cookie;

  {
    std::lock_guard<std::mutex> _(ethernet_mutex_);
    if (!online_ || length > ETH_MTU || length == 0 || unbound_) {
      complete_txn(txn, ZX_ERR_INVALID_ARGS);
      return;
    }
  }

  {
    std::lock_guard<std::mutex> tx(tx_mutex_);
    if (unbound_) {
      status = ZX_ERR_IO_NOT_PRESENT;
    } else {
      status = cdc_send_locked(netbuf);
      if (status == ZX_ERR_SHOULD_WAIT) {
        // No buffers available, queue it up
        txn_info_t* txn = containerof(netbuf, txn_info_t, netbuf);
        list_add_tail(tx_pending_infos(), &txn->node);
      }
    }
  }

  if (status != ZX_ERR_SHOULD_WAIT) {
    complete_txn(txn, status);
  }
}

zx_status_t UsbCdcFunction::EthernetImplSetParam(uint32_t param, int32_t value,
                                                 const uint8_t* data_buffer, size_t data_size) {
  return ZX_ERR_NOT_SUPPORTED;
}

void UsbCdcFunction::cdc_intr_complete(fendpoint::Completion completion) {
  usb::FidlRequest req{std::move(completion.request().value())};

  std::lock_guard<std::mutex> intr(intr_mutex_);
  if (!unbound_) {
    zx_status_t status = insert_usb_request(std::move(req), intr_ep_);
    ZX_DEBUG_ASSERT(status == ZX_OK);
  }
}

void UsbCdcFunction::cdc_send_notifications() {
  std::lock_guard<std::mutex> _(ethernet_mutex_);

  usb_cdc_notification_t network_notification = {
      .bmRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
      .bNotification = USB_CDC_NC_NETWORK_CONNECTION,
      .wValue = online_,
      .wIndex = descriptors_.cdc_intf_0.b_interface_number,
      .wLength = 0,
  };

  usb_cdc_speed_change_notification_t speed_notification = {
      .notification =
          {
              .bmRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
              .bNotification = USB_CDC_NC_CONNECTION_SPEED_CHANGE,
              .wValue = 0,
              .wIndex = descriptors_.cdc_intf_0.b_interface_number,
              .wLength = 2 * sizeof(uint32_t),
          },
      .downlink_br = 0,
      .uplink_br = 0,
  };

  if (online_) {
    if (speed_ == USB_SPEED_SUPER) {
      // Claim to be gigabit speed.
      speed_notification.downlink_br = speed_notification.uplink_br = 1000 * 1000 * 1000;
    } else {
      // Claim to be 100 megabit speed.
      speed_notification.downlink_br = speed_notification.uplink_br = 100 * 1000 * 1000;
    }
  } else {
    speed_notification.downlink_br = speed_notification.uplink_br = 0;
  }
  std::optional<usb::FidlRequest> req = intr_ep_.GetRequest();
  if (!req.has_value()) {
    fdf::error("[bug] intr_ep_.GetRequest(): no request available");
    return;
  }

  req->clear_buffers();
  std::vector<size_t> actual =
      req->CopyTo(0, &network_notification, sizeof(network_notification), intr_ep_.GetMapped());

  size_t actual_total = 0;
  for (size_t i = 0; i < actual.size(); i++) {
    // Fill in size of data.
    (*req)->data()->at(i).size(actual[i]);
    actual_total += actual[i];
  }

  ZX_ASSERT(actual_total == sizeof(network_notification));

  req->CacheFlush(intr_ep_.GetMapped());
  usb_request_queue(std::move(req.value()), intr_ep_);
  std::optional<usb::FidlRequest> req2 = intr_ep_.GetRequest();
  if (!req2.has_value()) {
    fdf::error("[bug] intr_ep_.GetRequest(): no request available");
    return;
  }

  req2->clear_buffers();
  actual = req2->CopyTo(0, &speed_notification, sizeof(speed_notification), intr_ep_.GetMapped());

  actual_total = 0;
  for (size_t i = 0; i < actual.size(); i++) {
    // Fill in size of data.
    (*req2)->data()->at(i).size(actual[i]);
    actual_total += actual[i];
  }

  ZX_ASSERT(actual_total == sizeof(speed_notification));

  req2->CacheFlush(intr_ep_.GetMapped());
  usb_request_queue(std::move(req2.value()), intr_ep_);
}

void UsbCdcFunction::cdc_rx_complete(fendpoint::Completion completion) {
  usb::FidlRequest req{std::move(completion.request().value())};
  zx_status_t status = *completion.status();

  if (status == ZX_ERR_IO_NOT_PRESENT) {
    std::lock_guard<std::mutex> rx(rx_mutex_);
    zx_status_t status = insert_usb_request(std::move(req), bulk_out_ep_);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    return;
  }
  if (status != ZX_OK) {
    fdf::error("[bug] rx_completion: {}", zx_status_get_string(status));
  }

  if (status == ZX_OK) {
    std::lock_guard<std::mutex> ethernet(ethernet_mutex_);
    if (ethernet_ifc_.is_valid()) {
      std::optional<zx_vaddr_t> addr = bulk_out_ep_.GetMappedAddr(req.request(), 0);
      if (addr.has_value()) {
        ethernet_ifc_.Recv(reinterpret_cast<uint8_t*>(*addr), *completion.transfer_size(), 0);
      }
    }
  }

  req.reset_buffers(bulk_out_ep_.GetMapped());
  status = req.CacheFlushInvalidate(bulk_out_ep_.GetMapped());
  if (status != ZX_OK) {
    fdf::error("[bug] CacheFlushInvalidate(): {}", zx_status_get_string(status));
  }

  usb_request_queue(std::move(req), bulk_out_ep_);
}

void UsbCdcFunction::cdc_tx_complete(fendpoint::Completion completion) {
  usb::FidlRequest req{std::move(completion.request().value())};

  if (unbound_) {
    return;
  }

  std::optional additional_tx_queued =
      [&]() -> std::optional<std::tuple<txn_info_t*, zx_status_t>> {
    std::lock_guard<std::mutex> tx(tx_mutex_);
    {
      if (unbound_) {
        return std::nullopt;
      }
      zx_status_t status = insert_usb_request(std::move(req), bulk_in_ep_);
      ZX_DEBUG_ASSERT(status == ZX_OK);
    }

    // Do not queue requests if status is ZX_ERR_IO_NOT_PRESENT, as the underlying connection could
    // be disconnected or USB_RESET is being processed. Calling cdc_send_locked in such scenario
    // will deadlock and crash the driver (see https://fxbug.dev/42174506).
    if (*completion.status() != ZX_ERR_IO_NOT_PRESENT) {
      if (txn_info_t* txn = list_peek_head_type(tx_pending_infos(), txn_info_t, node);
          txn != nullptr) {
        if (zx_status_t send_status = cdc_send_locked(&txn->netbuf);
            send_status != ZX_ERR_SHOULD_WAIT) {
          list_remove_head(tx_pending_infos());
          return std::make_tuple(txn, send_status);
        }
      }
    }
    return std::nullopt;
  }();

  if (additional_tx_queued.has_value()) {
    std::lock_guard<std::mutex> ethernet(ethernet_mutex_);
    auto [txn, send_status] = *additional_tx_queued;
    complete_txn(txn, send_status);
  }
}

size_t UsbCdcFunction::UsbFunctionInterfaceGetDescriptorsSize() { return sizeof(descriptors_); }

void UsbCdcFunction::UsbFunctionInterfaceGetDescriptors(uint8_t* out_descriptors_buffer,
                                                        size_t descriptors_size,
                                                        size_t* out_descriptors_actual) {
  const size_t length = std::min(sizeof(descriptors_), descriptors_size);
  memcpy(out_descriptors_buffer, &descriptors_, length);
  *out_descriptors_actual = length;
}

zx_status_t UsbCdcFunction::UsbFunctionInterfaceControl(const usb_setup_t* setup,
                                                        const uint8_t* write_buffer,
                                                        size_t write_size, uint8_t* out_read_buffer,
                                                        size_t read_size, size_t* out_read_actual) {
  uint16_t w_value{le16toh(setup->w_value)};
  uint16_t w_index{le16toh(setup->w_index)};
  uint16_t w_length{le16toh(setup->w_length)};

  fdf::debug(
      "bmRequestType={:02x} bRequest={:02x} wValue={:04x} ({}) wIndex={:04x} ({}) wLength={:04x} ({})",
      setup->bm_request_type, setup->b_request, w_value, w_value, w_index, w_index, w_length,
      w_length);

  TRACE_DURATION("cdc_eth", __func__, "write_size", write_size, "read_size", read_size);
  if (out_read_actual != NULL) {
    *out_read_actual = 0;
  }

  // The following control requests are currently unsupported, though non-criticial. To avoid
  // hanging up bus-enumeration, reply with success.

  if (setup->bm_request_type == (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) &&
      setup->b_request == USB_CDC_SET_ETHERNET_PACKET_FILTER) {
    fdf::debug("setting packet filter not supported");
    // TODO(voydanoff) implement the requested packet filtering
    return ZX_OK;
  }

  if (setup->bm_request_type == (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT) &&
      setup->b_request == USB_REQ_CLEAR_FEATURE && setup->w_value == USB_ENDPOINT_HALT) {
    fdf::debug("clearing endpoint-halt not supported");
    return ZX_OK;
  }

  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t UsbCdcFunction::UsbFunctionInterfaceSetConfigured(bool configured, usb_speed_t speed) {
  TRACE_DURATION("cdc_eth", __func__, "configured", configured, "speed", speed);

  if (configured_ == configured) {
    return ZX_OK;
  }

  {
    std::lock_guard<std::mutex> ethernet(ethernet_mutex_);
    online_ = false;
    if (ethernet_ifc_.is_valid()) {
      ethernet_ifc_.Status(0);
    }
  }

  fdf::info("configured = {}", configured);
  if (configured) {
    if (zx_status_t status = function_.ConfigEp(&descriptors_.intr_ep, NULL); status != ZX_OK) {
      fdf::error("[bug] ConfigEp(): {}", zx_status_get_string(status));
      return status;
    }
    speed_ = speed;
    configured_ = configured;
    cdc_send_notifications();
  } else {
    function_.DisableEp(bulk_out_addr_);
    function_.DisableEp(bulk_in_addr_);
    function_.DisableEp(intr_addr_);

    // Everything is disabled, cancel pending transactions if we have any.
    DiscardPendingTxInfos(ZX_ERR_CANCELED);

    speed_ = USB_SPEED_UNDEFINED;
    configured_ = configured;
  }

  return ZX_OK;
}

zx_status_t UsbCdcFunction::UsbFunctionInterfaceSetInterface(uint8_t interface,
                                                             uint8_t alt_setting) {
  TRACE_DURATION("cdc_eth", __func__, "interface", interface, "alt_setting", alt_setting);

  if (interface != descriptors_.cdc_intf_0.b_interface_number || alt_setting > 1) {
    return ZX_ERR_INVALID_ARGS;
  }

  // TODO(voydanoff) fullspeed and superspeed support
  if (alt_setting) {
    for (const auto* ep : {&descriptors_.bulk_out_ep, &descriptors_.bulk_in_ep}) {
      if (zx_status_t status = function_.ConfigEp(ep, nullptr); status != ZX_OK) {
        fdf::error("[bug] ConfigEp(): {}", zx_status_get_string(status));
        return status;
      }
    }
  } else {
    for (const uint8_t ep : {bulk_out_addr_, bulk_in_addr_}) {
      if (zx_status_t status = function_.DisableEp(ep); status != ZX_OK) {
        fdf::error("[bug] DisableEp(): {}", zx_status_get_string(status));
        return status;
      }
    }
  }

  bool online;
  if (alt_setting) {
    online = true;

    // queue our OUT reqs
    std::lock_guard<std::mutex> rx(rx_mutex_);
    while (!bulk_out_ep_.RequestsEmpty()) {
      std::optional<usb::FidlRequest> req = bulk_out_ep_.GetRequest();
      ZX_ASSERT(req.has_value());  // A given from the loop.
      req->reset_buffers(bulk_out_ep_.GetMappedLocked());

      if (zx_status_t status = req->CacheFlushInvalidate(bulk_out_ep_.GetMappedLocked());
          status != ZX_OK) {
        fdf::error("[bug] CacheFlushInvalidate(): {}", zx_status_get_string(status));
        return status;
      }
      usb_request_queue(std::move(req.value()), bulk_out_ep_);
    }
  } else {
    online = false;

    // Everything is disabled, cancel pending transactions if we have any.
    DiscardPendingTxInfos(ZX_ERR_CANCELED);
  }

  {
    std::lock_guard<std::mutex> ethernet(ethernet_mutex_);
    online_ = online;
    if (ethernet_ifc_.is_valid()) {
      ethernet_ifc_.Status(online ? ETHERNET_STATUS_ONLINE : 0);
    }
  }

  // send status notifications on interrupt endpoint
  cdc_send_notifications();

  return ZX_OK;
}

void UsbCdcFunction::DiscardPendingTxInfos(zx_status_t status) {
  std::lock_guard<std::mutex> l(tx_mutex_);
  txn_info_t* txn;
  while ((txn = list_remove_head_type(tx_pending_infos(), txn_info_t, node)) != NULL) {
    complete_txn(txn, status);
  }
}

zx::result<> UsbCdcFunction::Start() {
  zx::result function = compat::ConnectBanjo<ddk::UsbFunctionProtocolClient>(incoming());
  if (function.is_error()) {
    fdf::error("Failed to connect function: {}", function);
    return function.take_error();
  }
  function_ = *function;

  list_initialize(&tx_pending_infos_);

  // TODO(https://fxbug.dev/436378683): Remove once usb-cdc-function no longer hangs while
  // initializing.
  std::atomic<InitState> state(InitState::kWaitingForAllocInterface1);

  // TODO(https://fxbug.dev/436378683): Remove once usb-cdc-function no longer hangs while
  // initializing.
  sync_completion_t state_dispatcher_shutdown;

  // TODO(https://fxbug.dev/436378683): Remove once usb-cdc-function no longer hangs while
  // initializing.
  auto state_dispatcher = fdf::SynchronizedDispatcher::Create(
      {}, "init-state-checker",
      [&](fdf_dispatcher_t*) { sync_completion_signal(&state_dispatcher_shutdown); });
  if (state_dispatcher.is_error()) {
    fdf::error("Failed to create synchronized dispatcher: {}", state_dispatcher);
    return state_dispatcher.take_error();
  }

  async::PostDelayedTask(
      state_dispatcher.value().async_dispatcher(),
      [start = zx::clock::get_monotonic(), &state]() {
        auto now = zx::clock::get_monotonic();
        const char* reason = "Unknown";
        switch (state) {
          case InitState::kWaitingForAllocInterface1:
            reason = "Waiting for AllocInterface(1)";
            break;
          case InitState::kWaitingForAllocInterface2:
            reason = "Waiting for AllocInterface(2)";
            break;
          case InitState::kWaitingForAllocEp1:
            reason = "Waiting for AllocEp1(1)";
            break;
          case InitState::kWaitingForAllocEp2:
            reason = "Waiting for AllocEp1(2)";
            break;
          case InitState::kWaitingForAllocEp3:
            reason = "Waiting for AllocEp1(3)";
            break;
          case InitState::kWaitingForMacAddress:
            reason = "Waiting for mac address";
            break;
          case InitState::kWaitingForInit1:
            reason = "Waiting for Init(1)";
            break;
          case InitState::kWaitingForAddRequests1:
            reason = "Waiting for AddRequests(1)";
            break;
          case InitState::kWaitingForInit2:
            reason = "Waiting for Init(2)";
            break;
          case InitState::kWaitingForAddRequests2:
            reason = "Waiting for AddRequests(2)";
            break;
          case InitState::kWaitingForInit3:
            reason = "Waiting for Init(3)";
            break;
          case InitState::kWaitingForAddRequests3:
            reason = "Waiting for AddRequests(3)";
            break;
          case InitState::kWaitingForSetInterface:
            reason = "Waiting for SetInterface()";
            break;
        }
        fdf::warn("Initialization still has not completed after {} seconds: {}",
                  (now - start).to_secs(), reason);
      },
      zx::sec(20));

  auto status = function_.AllocInterface(&descriptors_.comm_intf.b_interface_number);
  if (status != ZX_OK) {
    fdf::error("[bug] AllocInterface(comm_intf): {}", zx_status_get_string(status));
    return zx::error(status);
  }
  state = InitState::kWaitingForAllocInterface2;
  status = function_.AllocInterface(&descriptors_.cdc_intf_0.b_interface_number);
  if (status != ZX_OK) {
    fdf::error("[bug] AllocInterface(data_intf): {}", zx_status_get_string(status));
    return zx::error(status);
  }
  descriptors_.cdc_intf_1.b_interface_number = descriptors_.cdc_intf_0.b_interface_number;
  descriptors_.cdc_union.bControlInterface = descriptors_.comm_intf.b_interface_number;
  descriptors_.cdc_union.bSubordinateInterface = descriptors_.cdc_intf_0.b_interface_number;

  state = InitState::kWaitingForAllocEp1;
  status = function_.AllocEp(USB_DIR_OUT, &bulk_out_addr_);
  if (status != ZX_OK) {
    fdf::error("[bug] AllocEp(bulk_out): {}", zx_status_get_string(status));
    return zx::error(status);
  }
  state = InitState::kWaitingForAllocEp2;
  status = function_.AllocEp(USB_DIR_IN, &bulk_in_addr_);
  if (status != ZX_OK) {
    fdf::error("[bug] AllocEp(bulk_in): {}", zx_status_get_string(status));
    return zx::error(status);
  }
  state = InitState::kWaitingForAllocEp3;
  status = function_.AllocEp(USB_DIR_IN, &intr_addr_);
  if (status != ZX_OK) {
    fdf::error("[bug] AllocEp(intr): {}", zx_status_get_string(status));
    return zx::error(status);
  }

  descriptors_.bulk_out_ep.b_endpoint_address = bulk_out_addr_;
  descriptors_.bulk_in_ep.b_endpoint_address = bulk_in_addr_;
  descriptors_.intr_ep.b_endpoint_address = intr_addr_;

  state = InitState::kWaitingForMacAddress;
  status = cdc_generate_mac_address();
  if (status != ZX_OK) {
    return zx::error(status);
  }

  auto dispatcher =
      fdf::SynchronizedDispatcher::Create({}, "cdc-ep-dispatcher", [](fdf_dispatcher_t*) {});
  if (dispatcher.is_error()) {
    fdf::error("[bug] fdf::SynchronizedDispatcher::Create(): {}", dispatcher);
    return zx::error(status);
  }
  dispatcher_ = std::move(dispatcher.value());

  auto result = incoming()->Connect<ffunction::UsbFunctionService::Device>();
  if (result.is_error()) {
    fdf::error("could not connect to UsbFunctionService: {}", result);
    return zx::error(status);
  }

  state = InitState::kWaitingForInit1;
  // allocate bulk out usb requests
  status = bulk_out_ep_.Init(bulk_out_addr_, result.value(), dispatcher_.async_dispatcher());
  if (status != ZX_OK) {
    fdf::error("[bug] bulk_out_ep_.Init(): {}", zx_status_get_string(status));
    return zx::error(status);
  }

  state = InitState::kWaitingForAddRequests1;
  size_t actual =
      bulk_out_ep_.AddRequests(BULK_RX_COUNT, BULK_REQ_SIZE, frequest::Buffer::Tag::kVmoId);
  if (actual != BULK_RX_COUNT) {
    fdf::error("[bug] bulk_out_ep_.AddRequests(): want {}, got {}", BULK_RX_COUNT, actual);
    return zx::error(status);
  }

  state = InitState::kWaitingForInit2;
  // allocate bulk in usb requests
  status = bulk_in_ep_.Init(bulk_in_addr_, result.value(), dispatcher_.async_dispatcher());
  if (status != ZX_OK) {
    fdf::error("[bug] bulk_in_ep_.Init(): {}", zx_status_get_string(status));
    return zx::error(status);
  }

  state = InitState::kWaitingForAddRequests2;
  actual = bulk_in_ep_.AddRequests(BULK_TX_COUNT, BULK_REQ_SIZE, frequest::Buffer::Tag::kVmoId);
  if (actual != BULK_TX_COUNT) {
    fdf::error("[bug] bulk_in_ep_.AddRequests(): want {}, got {}", BULK_TX_COUNT, actual);
    return zx::error(status);
  }

  state = InitState::kWaitingForInit3;
  // allocate interrupt requests
  status = intr_ep_.Init(intr_addr_, result.value(), dispatcher_.async_dispatcher());
  if (status != ZX_OK) {
    fdf::error("[bug] intr_ep_.Init(): {}", zx_status_get_string(status));
    return zx::error(status);
  }

  state = InitState::kWaitingForAddRequests3;
  actual = intr_ep_.AddRequests(INTR_COUNT, BULK_REQ_SIZE, frequest::Buffer::Tag::kVmoId);
  if (actual != INTR_COUNT) {
    fdf::error("[bug] intr_ep_.AddRequests(): want {}, got {}", INTR_COUNT, actual);
    return zx::error(status);
  }

  state = InitState::kWaitingForSetInterface;
  status = function_.SetInterface(this, &usb_function_interface_protocol_ops_);
  if (status != ZX_OK) {
    fdf::error("[bug] function_.SetInterface(): {}", zx_status_get_string(status));
    return zx::error(status);
  }

  state_dispatcher.value().ShutdownAsync();
  sync_completion_wait(&state_dispatcher_shutdown, ZX_TIME_INFINITE);

  constexpr char kChildName[] = "cdc-eth-function";
  {
    zx::result<> result = child_.Initialize(incoming(), outgoing(), node_name(), kChildName,
                                            compat::ForwardMetadata::None(), get_banjo_config());
    if (result.is_error()) {
      return result.take_error();
    }
  }

  zx::result controller =
      AddChild(kChildName, {{banjo_server_.property()}}, child_.CreateOffers2());
  if (controller.is_error()) {
    fdf::error("Failed to add child with error: {}", controller);
    return controller.take_error();
  }
  child_controller_ = std::move(controller.value());

  return zx::ok();
}

void UsbCdcFunction::PrepareStop(fdf::PrepareStopCompleter completer) {
  // Start the suspend process by setting unbound to true.
  // When the pipeline tries to submit requests, they will be immediately free'd.
  unbound_ = true;

  // Disable endpoints to prevent new requests present in our
  // pipeline from getting queued.
  function_.DisableEp(bulk_out_addr_);
  function_.DisableEp(bulk_in_addr_);
  function_.DisableEp(intr_addr_);

  // Cancel all requests in the pipeline -- the completion handler
  // will free these requests as they come in.
  function_.CancelAll(intr_addr_);
  function_.CancelAll(bulk_out_addr_);
  function_.CancelAll(bulk_in_addr_);

  list_node_t list;
  {
    std::lock_guard<std::mutex> l(tx_mutex_);
    list_move(tx_pending_infos(), &list);
  }
  txn_info_t* tx_txn;
  while ((tx_txn = list_remove_head_type(&list, txn_info_t, node)) != NULL) {
    complete_txn(tx_txn, ZX_ERR_PEER_CLOSED);
  }

  dispatcher_.ShutdownAsync();
  dispatcher_.release();
  completer(zx::ok());
}

}  // namespace usb_cdc_function

FUCHSIA_DRIVER_EXPORT(usb_cdc_function::UsbCdcFunction);
