/*
 * Copyright 2020 The Chromium OS 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 "arc/adbd/arcvm_sock_to_usb.h"

#include <fcntl.h>
#include <unistd.h>

#include <vector>

#include <base/bind.h>
#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>

#define EXIT_IF(f, msg)                        \
  do {                                         \
    if ((f)) {                                 \
      PLOG(ERROR) << (msg);                    \
      /* Don't use CHECK() or fatal logging */ \
      _exit(EXIT_FAILURE);                     \
    }                                          \
  } while (false)

namespace adbd {

ArcVmSockToUsb::ArcVmSockToUsb(const int sock_fd, const int usb_fd)
    : sock_fd_(sock_fd), usb_fd_(usb_fd), thread_("sock->usb") {
  DCHECK_GE(sock_fd_, 0);
  DCHECK_GE(usb_fd_, 0);
}

ArcVmSockToUsb::~ArcVmSockToUsb() = default;

bool ArcVmSockToUsb::Start() {
  if (!thread_.StartWithOptions(
          base::Thread::Options(base::MessagePumpType::IO, 0))) {
    LOG(ERROR) << "Failed to start thread";
    return false;
  }
  if (!thread_.task_runner()->PostTask(
          FROM_HERE,
          base::BindOnce(&ArcVmSockToUsb::Run, base::Unretained(this)))) {
    LOG(ERROR) << "Failed to dispatch task to thread";
    return false;
  }
  LOG(INFO) << "ArcVmSockToUsb started";
  return true;
}

void ArcVmSockToUsb::Run() {
  std::vector<char> buf(kUsbWriteBufSize);
  while (true) {
    char* data = buf.data();
    EXIT_IF(!base::ReadFromFD(sock_fd_, data, kAmessageSize),
            "failed to read adb message from socket");

    EXIT_IF(!base::WriteFileDescriptor(usb_fd_,
                                       base::StringPiece(data, kAmessageSize)),
            "failed to write adb message to usb");

    // The ADB design of USB transport splits the header and the optional
    // data payload of a message into two USB transfers. The peer expects
    // the exact package length of each transfer to USB layers. But such
    // behavior seems not for socket transport. As a result, we have to
    // step into the traffic from the socket to split the data properly
    // before relaying the data to USB endpoint.
    // We achieve this by using the depth control of buffer. Data won't be
    // sent until we have the expected amount.
    int payload_len = 0;
    for (int i = 0; i < 4; i++) {
      payload_len +=
          static_cast<unsigned char>(data[kAmessageDataLenOffset + i]) << 8 * i;
    }
    if (payload_len > kAdbPayloadMaxSize) {
      LOG(ERROR) << "payload length is too big";
      _exit(EXIT_FAILURE);
    }
    if (payload_len > 0) {
      EXIT_IF(!base::ReadFromFD(sock_fd_, data, payload_len),
              "failed to read adb payload from socket");
      EXIT_IF(!base::WriteFileDescriptor(usb_fd_,
                                         base::StringPiece(data, payload_len)),
              "failed to write adb payload to usb");
    }
  }
}

}  // namespace adbd
