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

#include "qmi-usb-transport.h"

#include <endian.h>
#include <lib/ddk/binding_driver.h>
#include <lib/ddk/debug.h>
#include <lib/zx/channel.h>
#include <stdio.h>
#include <zircon/status.h>
#include <zircon/syscalls/port.h>
#include <zircon/types.h>

#include <future>
#include <thread>

#include <ddktl/fidl.h>
#include <fbl/auto_lock.h>
#include <fbl/mutex.h>
#include <usb/cdc.h>
#include <usb/usb.h>

#ifndef _ALL_SOURCE
#define _ALL_SOURCE
#endif
#include <threads.h>

#define ETHERNET_MAX_TRANSMIT_DELAY 100
#define ETHERNET_MAX_RECV_DELAY 100
#define ETHERNET_TRANSMIT_DELAY 10
#define ETHERNET_RECV_DELAY 10
#define ETHERNET_INITIAL_TRANSMIT_DELAY 0
#define ETHERNET_INITIAL_RECV_DELAY 0

namespace telephony_snoop = fuchsia_telephony_snoop;

// TODO(jiamingw): investigate whether it can be replaced by eth::Operation
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);
}

namespace qmi_usb {
constexpr uint32_t kMaxTxBufSz = 32768;
constexpr uint32_t kMaxRxBufSz = 32768;

static void usb_write_complete(void* ctx, usb_request_t* request);

zx_status_t Device::SetChannelToDevice(zx_handle_t channel) {
  zxlogf(INFO, "qmi-usb-transport: getting channel from transport");
  zx_status_t result = ZX_OK;

  if (qmi_channel_ != ZX_HANDLE_INVALID) {
    zxlogf(ERROR, "qmi-usb-transport: already bound, failing");
    result = ZX_ERR_ALREADY_BOUND;
  } else if (channel == ZX_HANDLE_INVALID) {
    zxlogf(ERROR, "qmi-usb-transport: invalid channel handle");
    result = ZX_ERR_BAD_HANDLE;
  } else {
    qmi_channel_ = channel;
  }
  return result;
}

void Device::SetEthDestMacAddr(const uint8_t* mac_addr_ptr) {
  if (eth_dst_mac_addr_ == nullptr) {
    eth_dst_mac_addr_ = std::make_unique<std::array<uint8_t, kMacAddrLen>>();
  } else {
    zxlogf(INFO, "qmi-usb-transport: overwriting eth dest mac addr");
  }

  std::copy(mac_addr_ptr, &mac_addr_ptr[kMacAddrLen], eth_dst_mac_addr_.get()->begin());
}

zx_status_t Device::HandleArpReq(const ArpFrame& arp_frame) {
  if (memcmp(kArpReqHdr.data(), &arp_frame.arp_hdr, sizeof(kArpReqHdr)) != 0) {
    zxlogf(ERROR, "qmi-usb-transport: invalid arp request");
    return ZX_ERR_IO_DATA_INTEGRITY;
  }

  SetEthDestMacAddr(arp_frame.src_mac_addr);

  EthArpFrame eth_arp_resp;
  GenEthArpResp(arp_frame, &eth_arp_resp);

  // TODO(jiamingw): understand the reason to sleep here.
  zx_nanosleep(zx_deadline_after(ZX_USEC(tx_endpoint_delay_)));
  fbl::AutoLock lock(&eth_mutex_);
  if (eth_ifc_ptr_ && eth_ifc_ptr_->is_valid()) {
    // TODO(jiamingw): Log arp response.
    zxlogf(INFO, "qmi-usb-transport: Replying Arp Msg");
    eth_ifc_ptr_->Recv(reinterpret_cast<const uint8_t*>(&eth_arp_resp), kArpSize + kEthFrameHdrSize,
                       0);
  }

  return ZX_OK;
}

void Device::GenEthArpResp(const ArpFrame& req, EthArpFrame* resp) {
  // TODO(https://fxbug.dev/42115981): Generate fake mac address to support multiple
  // cellular devices.
  // Eth header
  // eth_dst_mac_addr_ is ensured to be not null when calling this method.
  std::copy(eth_dst_mac_addr_->begin(), eth_dst_mac_addr_->end(), resp->eth_hdr.dst_mac_addr);
  std::copy(kFakeMacAddr.begin(), kFakeMacAddr.end(), resp->eth_hdr.src_mac_addr);
  resp->eth_hdr.ethertype = betoh16(kEthertypeArp);
  // Eth payload.
  std::copy(kArpRespHdr.begin(), kArpRespHdr.end(), reinterpret_cast<uint8_t*>(&resp->arp.arp_hdr));
  std::copy(kFakeMacAddr.begin(), kFakeMacAddr.end(), resp->arp.src_mac_addr);
  std::copy(req.dst_ip_addr, &req.dst_ip_addr[kIpv4AddrLen], resp->arp.src_ip_addr);
  std::copy(eth_dst_mac_addr_->begin(), eth_dst_mac_addr_->end(), resp->arp.dst_mac_addr);
  std::copy(req.src_ip_addr, &req.src_ip_addr[kIpv4AddrLen], resp->arp.dst_ip_addr);
}

zx_status_t Device::QueueUsbRequestHandler(const uint8_t* ip, size_t length, usb_request_t* req) {
  auto ip_hdr = reinterpret_cast<const IpPktHdr*>(ip);
  size_t ip_length = betoh16(ip_hdr->total_length);
  zxlogf(INFO, "qmi-usb-transport: ip: x%x x%x", ip[0], ip[1]);

  if (ip_length != length) {
    zxlogf(ERROR,
           "qmi-usb-transport: length of IP packet does not match length in eth "
           "frame! %zd/%zd \n",
           ip_length, length);
    return ZX_ERR_IO;
  }

  ssize_t bytes_copied = usb_request_copy_to(req, ip, ip_length, 0);
  if (bytes_copied < 0) {
    zxlogf(ERROR, "qmi-usb-transport: failed to copy data into send txn (error %zd)", bytes_copied);
    return ZX_ERR_IO;
  }

  if (static_cast<size_t>(bytes_copied) != ip_length) {
    zxlogf(ERROR, "qmi-usb-transport: expect to copy %zu bytes but only copied %zd", ip_length,
           bytes_copied);
    return ZX_ERR_IO;
  }

  usb_request_complete_callback_t complete = {
      .callback = usb_write_complete,
      .ctx = this,
  };
  req->header.length = bytes_copied;
  // TODO(jiamingw): logging IP packet ((uintptr_t)req->virt) + req->offset) with length ip_length.
  zxlogf(INFO, "qmi-usb-transport: tx IP pkt");
  usb_request_queue(&usb_, req, &complete);
  return ZX_OK;
}

zx_status_t Device::HandleQueueUsbReq(const uint8_t* data, size_t length, usb_request_t* req) {
  zxlogf(INFO, "qmi-usb-transport: sending data to modem");
  zx_status_t res = QueueUsbRequestHandler(data, length, req);
  if (res != ZX_OK) {
    eth_tx_stats_.ipv4_tx_dropped_cnt += 1;
    return res;
  }
  eth_tx_stats_.ipv4_tx_succeed_cnt += 1;
  return ZX_OK;
}

zx_status_t inline Device::SendLocked(const uint8_t* byte_data, size_t length) {
  // Make sure that we can get all of the tx buffers we need to use
  usb_request_t* tx_req = usb_req_list_remove_head(&tx_txn_bufs_, parent_req_size_);
  if (tx_req == nullptr) {
    return ZX_ERR_SHOULD_WAIT;
  }

  zx_nanosleep(zx_deadline_after(ZX_USEC(tx_endpoint_delay_)));
  zx_status_t status;
  if ((status = HandleQueueUsbReq(byte_data, length, tx_req)) != ZX_OK) {
    // Add packet back to original place if it is not being sent.
    zx_status_t add_status = usb_req_list_add_head(&tx_txn_bufs_, tx_req, parent_req_size_);
    ZX_DEBUG_ASSERT(add_status == ZX_OK);
    return status;
  }

  return ZX_OK;
}

void Device::QmiUpdateOnlineStatus(bool is_online) {
  fbl::AutoLock lock(&eth_mutex_);
  if ((is_online && online_) || (!is_online && !online_)) {
    return;
  }

  if (is_online) {
    zxlogf(INFO, "qmi-usb-transport: connected to network");
    online_ = true;
    if (eth_ifc_ptr_ && eth_ifc_ptr_->is_valid()) {
      eth_ifc_ptr_->Status(online_ ? ETHERNET_STATUS_ONLINE : 0);
    } else {
      zxlogf(ERROR, "qmi-usb-transport: not connected to ethermac interface");
    }
  } else {
    zxlogf(INFO, "qmi-usb-transport: no connection to network");
    online_ = false;
    if (eth_ifc_ptr_ && eth_ifc_ptr_->is_valid()) {
      eth_ifc_ptr_->Status(0);
    }
  }
}

zx_status_t Device::SetAsyncWait() {
  return zx_object_wait_async(qmi_channel_, qmi_channel_port_, CHANNEL_MSG,
                              ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, 0);
}

zx_status_t Device::SetSnoopChannelToDevice(
    ::fidl::ClientEnd<fuchsia_telephony_snoop::Publisher> channel) {
  zx_port_packet_t packet;
  zx_status_t status = ZX_OK;
  // Initialize a port to watch whether the other handle of snoop channel has
  // closed
  if (!snoop_port_.is_valid()) {
    status = zx::port::create(0, &snoop_port_);
    if (status != ZX_OK) {
      zxlogf(ERROR,
             "qmi-usb-transport: failed to create a port to watch snoop channel: "
             "%s\n",
             zx_status_get_string(status));
      return status;
    }
  } else {
    status = snoop_port_.wait(zx::deadline_after(zx::sec(0)), &packet);
    if (status == ZX_ERR_TIMED_OUT) {
      zxlogf(ERROR, "qmi-usb-transport: timed out: %s", zx_status_get_string(status));
    } else if (packet.signal.observed & ZX_CHANNEL_PEER_CLOSED) {
      zxlogf(INFO, "qmi-usb-transport: snoop channel peer closed");
      snoop_client_end_.reset();
    }
  }

  status = ZX_OK;
  if (snoop_client_end_.is_valid()) {
    zxlogf(ERROR, "snoop channel already connected");
    status = ZX_ERR_ALREADY_BOUND;
  } else if (!channel.is_valid()) {
    zxlogf(ERROR, "get invalid snoop channel handle");
    status = ZX_ERR_BAD_HANDLE;
  } else {
    snoop_client_end_ = std::move(channel);
    snoop_client_end_.channel().wait_async(snoop_port_, 0, ZX_CHANNEL_PEER_CLOSED, 0);
  }
  return status;
}

zx_status_t Device::CloseQmiChannel() {
  zx_status_t ret_val = zx_handle_close(qmi_channel_);
  qmi_channel_ = ZX_HANDLE_INVALID;
  return ret_val;
}

void Device::SetChannel(SetChannelRequestView request, SetChannelCompleter::Sync& completer) {
  zx_status_t set_channel_res = SetChannelToDevice(request->transport.release());
  if (set_channel_res == ZX_OK) {
    completer.ReplySuccess();
    zx_status_t status = SetAsyncWait();
    if (status != ZX_OK) {
      CloseQmiChannel();
    }
  } else {
    completer.ReplyError(set_channel_res);
  }
}

void Device::SetNetwork(SetNetworkRequestView request, SetNetworkCompleter::Sync& completer) {
  QmiUpdateOnlineStatus(request->connected);
  completer.Reply();
}

void Device::SetSnoopChannel(SetSnoopChannelRequestView request,
                             SetSnoopChannelCompleter::Sync& completer) {
  zx_status_t set_snoop_res = SetSnoopChannelToDevice(std::move(request->interface));
  if (set_snoop_res == ZX_OK) {
    completer.ReplySuccess();
  } else {
    completer.ReplyError(static_cast<uint32_t>(set_snoop_res));
  }
}

void Device::Release() { delete this; }

void Device::DdkRelease() {
  zxlogf(INFO, "qmi-usb-transport: releasing device");
  Release();
}

uint32_t Device::GetMacAddr(uint8_t* buffer, uint32_t buffer_length) {
  if (buffer == nullptr) {
    return 0;
  }
  uint32_t copy_length = std::min((uint32_t)sizeof(kFakeMacAddr), buffer_length);
  std::copy(kFakeMacAddr.begin(), kFakeMacAddr.end(), buffer);
  return copy_length;
}

zx_status_t Device::EthernetImplQuery(uint32_t options, ethernet_info_t* info) {
  zxlogf(INFO, "qmi-usb-transport: %s called", __FUNCTION__);
  // No options are supported
  if (options) {
    zxlogf(ERROR, "qmi-usb-transport: unexpected options to ethernet_query");
    return ZX_ERR_INVALID_ARGS;
  }
  memset(info, 0, sizeof(*info));
  info->mtu = kEthMtu;
  GetMacAddr(info->mac, sizeof(info->mac));
  info->netbuf_size = sizeof(txn_info_t);
  return ZX_OK;
}

zx_status_t Device::EthernetImplStart(const ethernet_ifc_protocol_t* ifc) {
  zxlogf(INFO, "qmi-usb-transport: EthernetImplStart called");
  fbl::AutoLock lock(&eth_mutex_);
  if (eth_ifc_ptr_ && eth_ifc_ptr_->is_valid()) {
    return ZX_ERR_ALREADY_BOUND;
  }
  eth_ifc_ptr_ = std::make_unique<ddk::EthernetIfcProtocolClient>(ifc);
  return ZX_OK;
}

zx_status_t Device::EthernetImplSetParam(uint32_t param, int32_t value, const void* data,
                                         size_t data_size) {
  return ZX_ERR_NOT_SUPPORTED;
}

void Device::EthernetImplStop() {
  zxlogf(INFO, "qmi-usb-transport: %s called", __FUNCTION__);
  fbl::AutoLock lock(&eth_mutex_);
  eth_ifc_ptr_.reset();
}

void Device::EthernetImplQueueTx(uint32_t options, ethernet_netbuf_t* netbuf,
                                 ethernet_impl_queue_tx_callback completion_cb, void* cookie) {
  // TODO(jiamingw): Log netbuf->data_buffer with length netbuf->data_size.
  zxlogf(INFO, "qmi-usb-transport: transmitting outbound data plane msg:");

  size_t length = netbuf->data_size;

  if (length < kEthFrameHdrSize) {
    zxlogf(ERROR, "qmi-usb-transport: tx eth frame too short (length: %zx) ", length);
    eth_tx_stats_.eth_dropped_cnt += 1;
  }
  size_t eth_payload_len = length - kEthFrameHdrSize;

  // Check data type. Only Arp or IPv4 packet will be handled.
  const EthFrameHdr* eth_hdr = reinterpret_cast<const EthFrameHdr*>(netbuf->data_buffer);
  switch (betoh16(eth_hdr->ethertype)) {
    // Arp request. Send back Arp response.
    case kEthertypeArp: {
      eth_tx_stats_.arp_req_cnt += 1;
      if (eth_payload_len < kArpSize) {
        zxlogf(ERROR, "qmi-usb-transport: arp req too short");
        return;
      }

      auto eth_arp = reinterpret_cast<const EthArpFrame*>(netbuf->data_buffer);
      zx_status_t res = HandleArpReq(eth_arp->arp);
      if (res != ZX_OK) {
        eth_tx_stats_.arp_dropped_cnt += 1;
      }
      break;
    }
    // IPv4 packet. Send to modem.
    case kEthertypeIpv4: {
      zx_status_t status = ZX_OK;
      txn_info_t* txn = containerof(netbuf, txn_info_t, netbuf);
      txn->completion_cb = completion_cb;
      txn->cookie = cookie;

      if (length > kEthMtu || length == 0) {
        complete_txn(txn, ZX_ERR_INVALID_ARGS);
        return;
      }

      {
        fbl::AutoLock lock(&tx_mutex_);

        if (device_unbound_) {
          status = ZX_ERR_IO_NOT_PRESENT;
        } else {
          auto eth_ip = reinterpret_cast<const EthFrame*>(netbuf->data_buffer);
          status = SendLocked(eth_ip->eth_payload, eth_payload_len);
          if (status == ZX_ERR_SHOULD_WAIT) {
            // No buffers available, queue it up
            list_add_tail(&tx_pending_infos_, &txn->node);
          }
        }
      }

      if (status != ZX_ERR_SHOULD_WAIT) {
        complete_txn(txn, status);
      }
      break;
    }
    default:
      zxlogf(ERROR, "qmi-usb-transport: ethertype 0x%x not supported", eth_hdr->ethertype);
      eth_tx_stats_.eth_dropped_cnt += 1;
      break;
  }
  return;
}

static inline constexpr Device* DEV(void* ctx) { return static_cast<Device*>(ctx); }

static ethernet_impl_protocol_ops_t ethernet_impl_ops = {
    .query = [](void* ctx, uint32_t options, ethernet_info_t* info) -> zx_status_t {
      return DEV(ctx)->EthernetImplQuery(options, info);
    },
    .stop = [](void* ctx) { DEV(ctx)->EthernetImplStop(); },
    .start = [](void* ctx, const ethernet_ifc_protocol_t* ifc) -> zx_status_t {
      return DEV(ctx)->EthernetImplStart(ifc);
    },
    .queue_tx =
        [](void* ctx, uint32_t options, ethernet_netbuf_t* netbuf,
           ethernet_impl_queue_tx_callback completion_cb,
           void* cookie) { DEV(ctx)->EthernetImplQueueTx(options, netbuf, completion_cb, cookie); },
    .set_param = [](void* ctx, uint32_t param, int32_t value, const uint8_t* data, size_t data_size)
        -> zx_status_t { return DEV(ctx)->EthernetImplSetParam(param, value, data, data_size); },
};

static zx_protocol_device_t eth_qmi_ops = {
    .version = DEVICE_OPS_VERSION,
};

void Device::QmiInterruptHandler(usb_request_t* request) {
  zxlogf(INFO, "request->response.actual: %lu", request->response.actual);
  if (request->response.actual < sizeof(usb_cdc_notification_t)) {
    zxlogf(ERROR, "qmi-usb-transport: ignored interrupt (size = %ld)",
           (long)request->response.actual);
    return;
  }

  usb_cdc_notification_t usb_req = {};
  [[maybe_unused]] auto copy_length =
      usb_request_copy_from(request, &usb_req, sizeof(usb_cdc_notification_t), 0);

  // TODO(jiamingw): confirm this check is unnecessary
  uint16_t packet_size = max_packet_size_;
  if (packet_size > kUsbCtrlEpMsgSizeMax) {
    zxlogf(ERROR, "qmi-usb-transport: packet too big: %d", packet_size);
    return;
  }

  switch (usb_req.bNotification) {
    case USB_CDC_NC_RESPONSE_AVAILABLE:
      UsbCdcIntHander(packet_size);
      break;
    default:
      zxlogf(ERROR, "qmi-usb-transport: Unknown Notification Type for QMI: %d",
             usb_req.bNotification);
      break;
  }
}

void Device::UsbCdcIntHander(uint16_t packet_size) {
  zx_status_t status;
  uint8_t buffer[packet_size];

  status = usb_control_in(&usb_, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                          USB_CDC_GET_ENCAPSULATED_RESPONSE, 0, QMI_INTERFACE_NUM, ZX_TIME_INFINITE,
                          buffer, packet_size, nullptr);
  if (!qmi_channel_) {
    zxlogf(WARNING, "qmi-usb-transport: receiving USB CDC frames without a channel");
    return;
  }
  status = zx_channel_write(qmi_channel_, 0, buffer, sizeof(buffer), nullptr, 0);
  if (status < 0) {
    zxlogf(ERROR, "qmi-usb-transport: failed to write message to channel: %s",
           zx_status_get_string(status));
  }
  if (snoop_client_end_) {
    SnoopQmiMsgSend(buffer, sizeof(buffer), telephony_snoop::wire::Direction::kFromModem);
  }
  return;
}

zx_handle_t Device::GetQmiChannelPort() { return qmi_channel_port_; }

void Device::SnoopQmiMsgSend(uint8_t* msg_arr, uint32_t msg_arr_len,
                             telephony_snoop::wire::Direction direction) {
  telephony_snoop::wire::QmiMessage qmi_msg;
  uint32_t current_length = std::min(msg_arr_len, (uint32_t)sizeof(qmi_msg.opaque_bytes));
  qmi_msg.is_partial_copy = true;  // do not know the real length of QMI message for now
  qmi_msg.direction = direction;
  qmi_msg.timestamp = zx_clock_get_monotonic();
  memcpy(qmi_msg.opaque_bytes.data_, msg_arr, current_length);
  telephony_snoop::wire::Message snoop_msg = telephony_snoop::wire::Message::WithQmiMessage(
      fidl::ObjectView<telephony_snoop::wire::QmiMessage>::FromExternal(&qmi_msg));
  // TODO(https://fxbug.dev/42180237) Consider handling the error instead of ignoring it.
  (void)fidl::WireCall(snoop_client_end_)->SendMessage(std::move(snoop_msg));
}

static void qmi_interrupt_cb(void* ctx, usb_request_t* req) {
  zx_port_packet_t packet = {};
  packet.key = INTERRUPT_MSG;
  zx_port_queue(DEV(ctx)->GetQmiChannelPort(), &packet);
}

int Device::EventLoop(void) {
  usb_request_t* txn = int_txn_buf_;
  usb_request_complete_callback_t complete = {
      .callback = qmi_usb::qmi_interrupt_cb,
      .ctx = this,
  };
  usb_request_queue(&usb_, txn, &complete);
  zxlogf(INFO, "successfully queued int req");
  if (max_packet_size_ > kUsbCtrlEpMsgSizeMax) {
    zxlogf(ERROR, "qmi-usb-transport: packet too big: %d", max_packet_size_);
    return ZX_ERR_IO_REFUSED;
  }
  uint8_t buffer[max_packet_size_];
  uint32_t length = sizeof(buffer);
  zx_port_packet_t packet;
  while (true) {
    zx_status_t status = zx_port_wait(qmi_channel_port_, ZX_TIME_INFINITE, &packet);
    if (status == ZX_ERR_TIMED_OUT) {
      zxlogf(ERROR, "qmi-usb-transport: timed out: %s", zx_status_get_string(status));
      continue;
    }
    if (packet.key == CHANNEL_MSG) {
      if (packet.signal.observed & ZX_CHANNEL_PEER_CLOSED) {
        zxlogf(INFO, "qmi-usb-transport: channel closed");
        status = CloseQmiChannel();
        if (status != ZX_OK) {
          zxlogf(ERROR, "qmi-usb-transport: failed to close QMI channel: %s",
                 zx_status_get_string(status));
        }
        continue;
      }
      status =
          zx_channel_read(qmi_channel_, 0, buffer, nullptr, sizeof(buffer), 0, &length, nullptr);
      if (status != ZX_OK) {
        zxlogf(ERROR, "qmi-usb-transport: failed to read channel: %s",
               zx_status_get_string(status));
        return status;
      }
      status = usb_control_out(&usb_, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                               USB_CDC_SEND_ENCAPSULATED_COMMAND, 0, 8, ZX_TIME_INFINITE, buffer,
                               length);
      if (status != ZX_OK) {
        zxlogf(ERROR, "qmi-usb-transport: got an bad status from usb_control_out: %s",
               zx_status_get_string(status));
        return status;
      }
      status = SetAsyncWait();
      if (status != ZX_OK) {
        return status;
      }
      if (snoop_client_end_) {
        SnoopQmiMsgSend(buffer, sizeof(buffer), telephony_snoop::wire::Direction::kToModem);
      }
    } else if (packet.key == INTERRUPT_MSG) {
      if (txn->response.status == ZX_OK) {
        QmiInterruptHandler(txn);
        usb_request_complete_callback_t complete = {
            .callback = qmi_interrupt_cb,
            .ctx = this,
        };
        usb_request_queue(&usb_, txn, &complete);
      } else if (txn->response.status == ZX_ERR_PEER_CLOSED ||
                 txn->response.status == ZX_ERR_IO_NOT_PRESENT) {
        zxlogf(INFO, "qmi-usb-transport: terminating interrupt handling thread");
        return txn->response.status;
      }
    } else {
      zxlogf(ERROR, "qmi-usb-transport: invalid pkt key");
    }
  }  // while(true)
}

static int qmi_transport_thread(void* ctx) { return DEV(ctx)->EventLoop(); }

void Device::GenInboundEthFrameHdr(EthFrameHdr* eth_frame_hdr) {
  // Dest mac addr.
  std::copy(eth_dst_mac_addr_->begin(), eth_dst_mac_addr_->end(), eth_frame_hdr->dst_mac_addr);
  // Src mac addr.
  std::copy(kFakeMacAddr.begin(), kFakeMacAddr.end(), eth_frame_hdr->src_mac_addr);
  // Ethertype.
  eth_frame_hdr->ethertype = betoh16(kEthertypeIpv4);
  return;
}

// Note: the assumption made here is that no rx transmissions will be processed
// in parallel, so we do not maintain an rx mutex.
void Device::UsbRecv(usb_request_t* request) {
  size_t eth_frame_payload_len = request->response.actual;

  uint8_t* eth_frame_payload;
  zx_status_t status = usb_request_mmap(request, reinterpret_cast<void**>(&eth_frame_payload));
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: usb_request_mmap failed with status %d", status);
    return;
  }

  if (eth_frame_payload_len > kUsbBulkInEpMsgSizeMax) {
    zxlogf(ERROR, "qmi-usb-transport: received usb packet is too large: %zd",
           eth_frame_payload_len);
    return;
  }

  // TODO(jiamingw): Log message eth_frame_payload.
  zxlogf(INFO, "qmi-usb-transport: getting inbound data plane msg");

  if (eth_dst_mac_addr_ == nullptr) {
    zxlogf(ERROR, "qmi-usb-transport: no eth mac addr, cannot send eth frame");
    return;
  }

  uint8_t eth_frame_arr[eth_frame_payload_len + kEthFrameHdrSize];
  auto eth_ip = reinterpret_cast<EthFrame*>(eth_frame_arr);
  GenInboundEthFrameHdr(&eth_ip->eth_hdr);

  // Copy ethernet frame payload.
  std::copy(eth_frame_payload, &eth_frame_payload[eth_frame_payload_len], eth_ip->eth_payload);
  fbl::AutoLock lock(&eth_mutex_);
  if (eth_ifc_ptr_ && eth_ifc_ptr_->is_valid()) {
    eth_ifc_ptr_->Recv(eth_frame_arr, eth_frame_payload_len + kEthFrameHdrSize, 0);
  }
}

static void usb_read_complete(void* ctx, usb_request_t* request) {
  DEV(ctx)->UsbReadCompleteHandler(request);
}

void Device::UsbReadCompleteHandler(usb_request_t* request) {
  if (request->response.status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: usb_read_complete called with status %d",
           (int)request->response.status);
  }

  if (request->response.status == ZX_ERR_IO_NOT_PRESENT) {
    usb_request_release(request);
    return;
  }

  if (request->response.status == ZX_ERR_IO_REFUSED) {
    zxlogf(ERROR, "qmi-usb-transport: resetting receive endpoint");
    usb_reset_endpoint(&usb_, rx_endpoint_addr_);
  } else if (request->response.status == ZX_ERR_IO_INVALID) {
    if (rx_endpoint_delay_ < ETHERNET_MAX_RECV_DELAY) {
      rx_endpoint_delay_ += ETHERNET_RECV_DELAY;
    }
    zxlogf(ERROR,
           "qmi-usb-transport: slowing down the requests by %d usec."
           "Resetting the recv endpoint\n",
           ETHERNET_RECV_DELAY);
    usb_reset_endpoint(&usb_, rx_endpoint_addr_);
  } else if (request->response.status == ZX_OK) {
    UsbRecv(request);
  }

  zx_nanosleep(zx_deadline_after(ZX_USEC(rx_endpoint_delay_)));

  usb_request_complete_callback_t complete = {
      .callback = qmi_usb::usb_read_complete,
      .ctx = this,
  };
  usb_request_queue(&usb_, request, &complete);
}

void Device::UsbWriteCompleteHandler(usb_request_t* request) {
  if (request->response.status == ZX_ERR_IO_NOT_PRESENT) {
    usb_request_release(request);
    return;
  }

  // Return transmission buffer to pool
  fbl::AutoLock tx_lock(&tx_mutex_);

  zx_status_t status = usb_req_list_add_tail(&tx_txn_bufs_, request, parent_req_size_);
  ZX_DEBUG_ASSERT(status == ZX_OK);

  if (request->response.status == ZX_ERR_IO_REFUSED) {
    zxlogf(ERROR, "qmi-usb-transport: resetting transmit endpoint");
    usb_reset_endpoint(&usb_, tx_endpoint_addr_);
  }

  if (request->response.status == ZX_ERR_IO_INVALID) {
    zxlogf(ERROR,
           "qmi-usb-transport: slowing down the requests by %d usec."
           "Resetting the transmit endpoint\n",
           ETHERNET_TRANSMIT_DELAY);
    if (tx_endpoint_delay_ < ETHERNET_MAX_TRANSMIT_DELAY) {
      tx_endpoint_delay_ += ETHERNET_TRANSMIT_DELAY;
    }
    usb_reset_endpoint(&usb_, tx_endpoint_addr_);
  }

  bool additional_tx_queued = false;
  txn_info_t* txn;
  zx_status_t send_status = ZX_OK;
  if (!list_is_empty(&tx_pending_infos_)) {
    txn = list_peek_head_type(&tx_pending_infos_, txn_info_t, node);
    send_status =
        SendLocked(&static_cast<const uint8_t*>(txn->netbuf.data_buffer)[kEthFrameHdrSize],
                   (txn->netbuf.data_size - kEthFrameHdrSize));
    if (send_status != ZX_ERR_SHOULD_WAIT) {
      list_remove_head(&tx_pending_infos_);
      additional_tx_queued = true;
    }
  }

  tx_lock.release();

  fbl::AutoLock eth_lock(&eth_mutex_);
  if (additional_tx_queued) {
    complete_txn(txn, send_status);
  }
  // When the interface is offline, the transaction will complete with status
  // set to ZX_ERR_IO_NOT_PRESENT. There's not much we can do except ignore it.
}

static void usb_write_complete(void* ctx, usb_request_t* request) {
  DEV(ctx)->UsbWriteCompleteHandler(request);
}

Device::Device(zx_device_t* parent) : DeviceType(parent) { usb_device_ = parent; }

void Device::QmiBindFailedNoErr(usb_request_t* int_buf) {
  if (int_buf) {
    usb_request_release(int_buf);
  }
}

void Device::QmiBindFailedErr(zx_status_t status, usb_request_t* int_buf) {
  zxlogf(ERROR, "qmi-usb-transport: bind failed: %s", zx_status_get_string(status));
  QmiBindFailedNoErr(int_buf);
}

void Device::EthClientInit(const ethernet_ifc_protocol_t* ifc) {
  eth_ifc_ptr_.reset(new ddk::EthernetIfcProtocolClient(ifc));
}

void Device::EthTxListNodeInit() {
  list_initialize(&tx_txn_bufs_);
  list_initialize(&tx_pending_infos_);
}

zx_status_t Device::Bind() __TA_NO_THREAD_SAFETY_ANALYSIS {
  zx_status_t status;
  usb_request_t* int_buf = nullptr;

  // Set up USB stuff
  usb_protocol_t usb;
  status = device_get_protocol(usb_device_, ZX_PROTOCOL_USB, &usb);
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: get protocol failed: %s", zx_status_get_string(status));
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  // Initialize context
  memcpy(&usb_, &usb, sizeof(usb_));
  EthTxListNodeInit();

  parent_req_size_ = usb_get_request_size(&usb_);
  uint64_t req_size = parent_req_size_ + sizeof(usb_req_internal_t);
  ZX_DEBUG_ASSERT(parent_req_size_ != 0);

  // find our endpoints
  usb_desc_iter_t iter;
  zx_status_t result = usb_desc_iter_init(&usb, &iter);
  if (result < 0) {
    status = result;
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  // QMI needs to bind to interface QMI_INTERFACE_NUM on current hardware.
  // Ignore the others for now.
  // TODO generic way of describing usb interfaces
  usb_interface_descriptor_t* intf = usb_desc_iter_next_interface(&iter, true);
  if (!intf || intf->b_interface_number != QMI_INTERFACE_NUM) {
    usb_desc_iter_release(&iter);
    status = ZX_ERR_NOT_SUPPORTED;
    QmiBindFailedNoErr(int_buf);
    return status;
  }

  if (intf->b_num_endpoints != 3) {
    zxlogf(ERROR,
           "qmi-usb-transport: interface does not have the required 3 "
           "endpoints\n");
    usb_desc_iter_release(&iter);
    status = ZX_ERR_NOT_SUPPORTED;
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  uint8_t bulk_in_addr = 0;
  uint8_t bulk_out_addr = 0;
  uint8_t intr_addr = 0;
  uint16_t intr_max_packet = 0;
  uint16_t bulk_max_packet = 0;

  usb_descriptor_header_t* desc;
  while ((desc = usb_desc_iter_peek(&iter)) != NULL) {
    if (desc->b_descriptor_type == USB_DT_ENDPOINT) {
      usb_endpoint_descriptor_t* endp = reinterpret_cast<usb_endpoint_descriptor_t*>(
          usb_desc_iter_get_structure(&iter, sizeof(usb_endpoint_descriptor_t)));
      if (endp == NULL) {
        break;
      }
      if (usb_ep_direction(endp) == USB_ENDPOINT_OUT) {
        if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
          bulk_out_addr = endp->b_endpoint_address;
          bulk_max_packet = usb_ep_max_packet(endp);
        }
      } else {
        if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
          bulk_in_addr = endp->b_endpoint_address;
        } else if (usb_ep_type(endp) == USB_ENDPOINT_INTERRUPT) {
          intr_addr = endp->b_endpoint_address;
          intr_max_packet = usb_ep_max_packet(endp);
        }
      }
    }
    usb_desc_iter_advance(&iter);
  }
  usb_desc_iter_release(&iter);

  if (bulk_in_addr == 0 || bulk_out_addr == 0 || intr_addr == 0) {
    zxlogf(ERROR, "qmi-usb-transport: failed to find one of the usb endpoints");
    zxlogf(ERROR, "qmi-usb-transport: bulkIn:%u, bulkOut:%u, intr:%u", bulk_in_addr, bulk_out_addr,
           intr_addr);
    status = ZX_ERR_INTERNAL;
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  if (intr_max_packet < 1 || bulk_max_packet < 1) {
    zxlogf(ERROR, "qmi-usb-transport: failed to find reasonable max packet sizes");
    zxlogf(ERROR, "qmi-usb-transport: intr_max_packet:%u, bulk_max_packet:%u", intr_max_packet,
           bulk_max_packet);
    status = ZX_ERR_INTERNAL;
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  rx_endpoint_delay_ = ETHERNET_INITIAL_RECV_DELAY;
  tx_endpoint_delay_ = ETHERNET_INITIAL_TRANSMIT_DELAY;

  // Reset by selecting default interface followed by data interface. We can't
  // start queueing transactions until this is complete.
  usb_set_interface(&usb, 8, 0);

  // set up interrupt
  status = usb_request_alloc(&int_buf, intr_max_packet, intr_addr, req_size);
  max_packet_size_ = bulk_max_packet;
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: failed to allocate for usb request: %s",
           zx_status_get_string(status));
    QmiBindFailedErr(status, int_buf);
    return status;
  }
  int_txn_buf_ = int_buf;

  // create port to watch for interrupts and channel messages
  status = zx_port_create(0, &qmi_channel_port_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: failed to create a port: %s", zx_status_get_string(status));
    QmiBindFailedErr(status, int_buf);
    return status;
  }
  rx_endpoint_addr_ = bulk_in_addr;
  tx_endpoint_addr_ = bulk_out_addr;

  // Allocate tx transaction buffers
  // TODO uint16_t tx_buf_sz = qmi_ctx->mtu;
  uint16_t tx_buf_sz = kEthMtu;
  size_t tx_buf_remain = kMaxTxBufSz;
  while (tx_buf_remain >= tx_buf_sz) {
    usb_request_t* tx_buf;
    zx_status_t alloc_result = usb_request_alloc(&tx_buf, tx_buf_sz, tx_endpoint_addr_, req_size);
    if (alloc_result != ZX_OK) {
      result = alloc_result;
      QmiBindFailedErr(status, int_buf);
      return status;
    }

    // As per the CDC-ECM spec, we need to send a zero-length packet to signify
    // the end of transmission when the endpoint max packet size is a factor of
    // the total transmission size
    tx_buf->header.send_zlp = true;

    zx_status_t status = usb_req_list_add_head(&tx_txn_bufs_, tx_buf, parent_req_size_);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    tx_buf_remain -= tx_buf_sz;
  }

  // Allocate rx transaction buffers
  // TODO(bwb) get correct buffer sizes from usb
  uint16_t rx_buf_sz = kEthMtu;
  size_t rx_buf_remain = kMaxRxBufSz;
  while (rx_buf_remain >= rx_buf_sz) {
    usb_request_t* rx_buf;
    zx_status_t alloc_result = usb_request_alloc(&rx_buf, rx_buf_sz, rx_endpoint_addr_, req_size);
    if (alloc_result != ZX_OK) {
      result = alloc_result;
      QmiBindFailedErr(status, int_buf);
      return status;
    }

    usb_request_complete_callback_t complete = {
        .callback = usb_read_complete,
        .ctx = this,
    };
    usb_request_queue(&usb_, rx_buf, &complete);
    rx_buf_remain -= rx_buf_sz;
  }

  // Kick off the handler thread
  int thread_result =
      thrd_create((thrd_t*)&int_thread_, (thrd_start_t)qmi_transport_thread, (void*)this);

  if (thread_result != thrd_success) {
    zxlogf(ERROR, "qmi-usb-transport: failed to create transport thread (%d)", thread_result);
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  status = DdkAdd(ddk::DeviceAddArgs("qmi-usb-transport").set_proto_id(ZX_PROTOCOL_QMI_TRANSPORT));
  if (status < 0) {
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  device_add_args_t eth_args = {
      .version = DEVICE_ADD_ARGS_VERSION,
      .name = "qmi-cdc-ethernet",
      .ctx = this,
      // sibling of qmi transport. Cleanup happens when qmi device unbinds
      .ops = &eth_qmi_ops,
      .proto_id = ZX_PROTOCOL_ETHERNET_IMPL,
      .proto_ops = &ethernet_impl_ops,
  };
  result = device_add(usb_device_, &eth_args, &eth_zxdev_);
  if (result < 0) {
    zxlogf(ERROR, "qmi-usb-transport: failed to add ethernet device: %d", (int)result);
    QmiBindFailedErr(status, int_buf);
    return status;
  }

  return ZX_OK;
}
}  // namespace qmi_usb

static zx_status_t qmi_bind(void* ctx, zx_device_t* device) {
  zx_status_t status = ZX_OK;
  auto dev = std::make_unique<qmi_usb::Device>(device);
  status = dev->Bind();
  std::printf("%s\n", __func__);
  if (status != ZX_OK) {
    std::printf("qmi-usb-transport: could not bind: %d\n", status);
  } else {
    dev.release();
  }
  return status;
}

static zx_driver_ops_t qmi_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = qmi_bind,
};

ZIRCON_DRIVER(qmi_usb, qmi_driver_ops, "zircon", "0.1");
