//
// Copyright 2017 Mimo monitors. All rights reserved.
//
// SPDX-License-Identifier: BSD-3-Clause
//
#include <libusb-1.0/libusb.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <base/logging.h>
#include <brillo/syslog_logging.h>

#include <memory>
#include <cstring>
#include <iostream>
#include <sstream>
#include <fstream>

////////////////////////////////////////////////////////////////////////////////
// File Description:
// The codes are used to read a binary file, the firmware used by
// the Displaylink ASIC (inside the MIMO touch screen), and write into the
// EEPROM inside the ASIC.
// The following things will be checked:
// 1. The updater will check if the firmware file exists and if the firmware
//    file name and size are valid.
// 2. The firmware version in the device and the version from the CrOS release.
//    If the 2 numbers are inconsistent, the updater will perform the firmware
//    update. Note that the firmware version is not provided in the firmware
//    file itself. The version is coded in the firmware file name.
// Note
//    The actual firmware contents are opaque to the updater, and it is only
//    known to the vendor, Displaylink. In addition to that, the sequence of
//    updating the firmware is also provided by Displaylink and MIMO monitors.
////////////////////////////////////////////////////////////////////////////////

namespace std {

// This class is used for auto file close.
template<>
struct default_delete<FILE> {
  void operator()(FILE* file_ptr) const {
    fclose(file_ptr);
  }
};
}  // namespace std

namespace {

// Mode config
const int kNrParamPollMode = 1;
const int kNrParamUpdateMode = 2;

// device control commands and addresses
const int kDlAddr = 0xa2;
const int kSizeOfRebootPayload = 4;
const int kVersionNumberAddr = 0xaa;
const int kNrI2cFlag16bitAddr = 0x01;
const int kNrI2cFlagInhabit9Clock = 0x04;
const int kNrI2cFlagWaitForWrite = 0x02;
const int kNrUsbReqExec = 0x15;
const int kNrUsbReqStatusDw = 0x06;
const int kRebootAddr = 0x0381;
const int kWriteCmdAddr = 2;
const int kWriteCmdSeqA = 0xc212;
const int kWriteCmdSeqB = 0xc213;
const int kNrUsbReqTimeoutSec = 10000;
const int kI2cFlag =
    (kDlAddr |
        ((kNrI2cFlag16bitAddr |
          kNrI2cFlagInhabit9Clock |
          kNrI2cFlagWaitForWrite) << 8));

// version numbers
const int kFwMajorVerLen = 4;
const int kFwMinorVerLen = 4;
const int kFwVersionLen = kFwMajorVerLen + kFwMinorVerLen;
const int kFwVersionLenByte = kFwVersionLen/2;
const uint8_t kFwInvalidVersion[kFwVersionLenByte] = {0xff, 0xff, 0xff, 0xff};
const int kFwNameLen = 28;
const int kFwNameVersionOffset = 12;
const int kFwSizeLimit = 16 * 1024;

// USB ids and target dependent consts
const uint16_t kMimoVendorId = 0x17e9;
const uint16_t kMimoProductIdA = 0x416d;
const uint16_t kMimoProductIdB = 0x016b;
const uint16_t kMimoProductIdRecovery = 0x8060;
const uint8_t kMimoFwHeader = 0xa2;
const int kReservedChunkNumber = 2;
const int kSizeIOChunk = 64;
const int kUsbTimeOutMs = 1000;

// vendor-specific IDs
const int kVendorReqPoke = 0x03;
const int kVendorI2cRead = 0x19;
const int kVendorI2cWrite = 0x18;

const int kReqTypeVendorIn =
    (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN);
const int kReqTypeVendorOut =
    (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT);

enum TestPointLocation {
  E_TP_INVALID,
  E_TP_BEFORE_INIT_FW_VERSION,
  E_TP_WRITE_FW
};

enum StatusCode {
  E_OK = 0,
  E_OK_NO_UPDATE,
  E_FAILED_USB_OPERATIONS,
  E_INVALID_FW_FILE_NAME,
  E_FAILED_FW_FILE_NOT_ACCESSIBLE,
  E_FAILED_INCORRECT_PARAM_LIST,
  E_FAILED_TO_RESET_FW_VERSION,
  E_FAILED_TO_GET_DEVICE_LIST,
  E_FAILED_TO_SEND_USB_CONTROL,
  E_FAILED_TO_FSEEK,
  E_FAILED_TO_GET_FILE_SIZE,
  E_FAILED_TO_OPEN_FW_FILE,
  E_FAILED_TO_READ_FW_FILE,
  E_INVALID_FW_FILE_SIZE
};

enum OperationMode {
  E_POLL_VERSION_MODE,
  E_FW_UPDATE_MODE
};

TestPointLocation test_point_position = E_TP_INVALID;
uint32_t test_point_wait_time = 0;

// This is a testing function
// This function can do 2 things.
// 1. mimic the power cut.
//    When you put the function in a certain place and setup
//    the test_point_position as the test_point_number parameter is,
//    the program will die if the 'cond' is true. By using this
//    method, you can test if the power-cut mechanism works.
// 2. delay the processing
//    When you want to test the complicated USB behaviors, you can
//    set the test_point_wait_time to a non-zero value. The program
//    will stop and wait for you. Then, you can do other USB commands.
static void TestPoint(const TestPointLocation test_point, bool cond = true) {
  if (test_point_position == test_point && cond) {
    if (test_point_wait_time == 0)
      abort();
    else
      sleep(10);
  }
}

// Description
//    Compare 2 version arrays
// Param:
//    v1 and v2 are uint8_t array, length of kFwVersionLenByte
// Return
//    true:   if they are identical
//    fasle:  if they are not identical.
static bool CompareVersionNumber(const uint8_t* v1, const uint8_t* v2) {
  return (memcmp(v1, v2, kFwVersionLenByte) == 0);
}

// Description
//    The function check the return code of the libusb func.
//    if it's not a good expected value, log the error.
// Param
//    usb_ret_code: actual return code
//    expected_ret: what we're expecting, generally 0
// Return
//    StatusCode.
static StatusCode LibUsbHelperError(
    const int usb_ret_code,
    const int expected_ret = 0) {
  if (usb_ret_code == expected_ret)
    return E_OK;

  LOG(ERROR)
      << "Usb error: "
      << libusb_error_name(usb_ret_code)
      << "(" << usb_ret_code << "," << expected_ret << ")";

  return E_FAILED_USB_OPERATIONS;
}

// Description
//    The function check the return code of the libusb func.
//    if it's not a good expected value, log the warning.
// Param
//    usb_ret_code: actual return code
//    expected_ret: what we're expecting, generally 0
// Return
//    StatusCode.
static StatusCode LibUsbHelperWarning(
    const int usb_ret_code,
    const int expected_ret = 0) {
  if (usb_ret_code == expected_ret)
    return E_OK;

  LOG(WARNING)
      << "Possible usb error: "
      << libusb_error_name(usb_ret_code)
      << "(" << usb_ret_code << "," << expected_ret << ")";

  return E_FAILED_USB_OPERATIONS;
}

// Description
//    The function sends a 'POKE' command to the ASIC.
//    Upon receiving this vendor command,
//    the ASIC will update the internal status according to the
//    addr and value. The payload of the control transfer is
//    the data provided.
// Param
//    dev_handle: the usb device we want to write to
//    value/addr: used by the control transfer
//    data/data_len: payload and its size
// return
//    Status code
static StatusCode Poke(
    libusb_device_handle *dev_handle,
    int value,
    int addr,
    uint8_t *data,
    int data_len) {
  int written_length = libusb_control_transfer(
      dev_handle,
      kReqTypeVendorOut,
      kVendorReqPoke,
      value,
      addr,
      data,
      data_len,
      kUsbTimeOutMs);

  if (LibUsbHelperError(written_length, data_len))
    return E_FAILED_TO_SEND_USB_CONTROL;

  return E_OK;
}

// Description
//    Request the device to do a I2C read access.
// return
//    Status code
static StatusCode I2cRead(
    libusb_device_handle *dev_handle,
    int value,
    int addr,
    uint8_t *data,
    int data_len) {
  int written_len = libusb_control_transfer(
      dev_handle,
      kReqTypeVendorIn,
      kVendorI2cRead,
      value,
      addr,
      data,
      data_len,
      kUsbTimeOutMs);

  if (LibUsbHelperError(written_len, data_len))
    return E_FAILED_TO_SEND_USB_CONTROL;

  return E_OK;
}

// Description
//    Request the device to do a I2C write access.
// return
//    Status code
static StatusCode I2cWrite(
    libusb_device_handle *dev_handle,
    int value,
    int addr,
    uint8_t *data,
    int data_len) {
  int written_len = libusb_control_transfer(
      dev_handle,
      kReqTypeVendorOut,
      kVendorI2cWrite,
      value,
      addr,
      data,
      data_len,
      kUsbTimeOutMs);

  if (LibUsbHelperError(written_len, data_len))
    return E_FAILED_TO_SEND_USB_CONTROL;

  return E_OK;
}

// Description
//    Reboot the device.
// return
//    Status code
static StatusCode RebootMimo(libusb_device_handle *dev_handle) {
  uint32_t len = 4;
  uint8_t payload[kSizeOfRebootPayload] = {0, 0, 0, 0};

  int ret = libusb_control_transfer(
      dev_handle,
      kReqTypeVendorOut,
      kNrUsbReqExec,
      0,
      kRebootAddr,
      payload,
      kSizeOfRebootPayload,
      kNrUsbReqTimeoutSec);
  LibUsbHelperWarning(ret, 4);

  ret = libusb_control_transfer(
      dev_handle,
      kReqTypeVendorOut,
      kNrUsbReqStatusDw,
      0,
      0,
      reinterpret_cast<uint8_t*>(&len),
      sizeof(len),
      kUsbTimeOutMs);

  LibUsbHelperWarning(ret, sizeof(len));
  return E_OK;
}

static StatusCode WriteFwVersion(
    libusb_device *dev,
    libusb_device_handle *dev_handle,
    int prog_if,
    const uint8_t* version) {
  StatusCode return_code;
  uint8_t payload;
  uint8_t version_payload[kFwVersionLenByte];

  TestPoint(E_TP_BEFORE_INIT_FW_VERSION);

  payload = 9;
  const int payload_size = sizeof(payload);
  if (Poke(dev_handle, kWriteCmdAddr, kWriteCmdSeqA, &payload, payload_size) ||
      Poke(dev_handle, kWriteCmdAddr, kWriteCmdSeqB, &payload, payload_size)) {
    return E_FAILED_USB_OPERATIONS;
  }

  // copy the version number(const type conversion for libusb)
  memcpy(version_payload, version, kFwVersionLenByte);

  return_code = I2cWrite(
      dev_handle,
      kVersionNumberAddr,
      kI2cFlag,
      version_payload,
      kFwVersionLenByte);

  if (return_code)
    return return_code;

  return E_OK;
}

static StatusCode CalcFileSize(
    const std::string& file_name,
    size_t *fw_file_size) {
  struct stat fw_file_info;

  if (stat(file_name.c_str(), &fw_file_info))
    return E_FAILED_TO_GET_FILE_SIZE;

  *fw_file_size = fw_file_info.st_size;
  return E_OK;
}

static StatusCode WriteFw(
    libusb_device *dev,
    libusb_device_handle *dev_handle,
    int prog_if,
    bool reset,
    const std::string& file_name) {
  uint8_t payload[kSizeIOChunk];
  StatusCode status;
  size_t fw_file_size;
  int n_chunks;
  int c_pos;
  int current_chunk;
  size_t rc;

  // check filesize
  status = CalcFileSize(file_name, &fw_file_size);
  if (status) {
    return status;
  } else {
    if (fw_file_size <= 0 || fw_file_size > kFwSizeLimit) {
      return E_INVALID_FW_FILE_SIZE;
    }
  }

  // Note: we use 'e' flag here. glibc extension
  std::unique_ptr<FILE> fw_file(fopen(file_name.c_str(), "rbe"));

  if (fw_file.get() == nullptr)
    return E_FAILED_TO_OPEN_FW_FILE;

  // magic codes needed by the device
  payload[0] = 9;

  if (Poke(dev_handle, kWriteCmdAddr, kWriteCmdSeqA, payload, 1) ||
      Poke(dev_handle, kWriteCmdAddr, kWriteCmdSeqB, payload, 1)) {
    return E_FAILED_USB_OPERATIONS;
  }

  n_chunks = (fw_file_size + (kSizeIOChunk - 1)) / kSizeIOChunk;
  c_pos = 0;

  for (current_chunk = 0; current_chunk < n_chunks; current_chunk++) {
    // Test function: Simulate power-cut
    TestPoint(E_TP_WRITE_FW, (current_chunk == 5));

    rc = fread(payload, sizeof(uint8_t), kSizeIOChunk, fw_file.get());

    if (ferror(fw_file.get()) != 0 || rc == 0) {
      return E_FAILED_TO_READ_FW_FILE;
    }

    payload[0] *= static_cast<uint8_t>(current_chunk != 0);

    // avoid overwrite serial number
    if (current_chunk == kReservedChunkNumber) {
      // skipping the reserved parts.
      status = I2cWrite(dev_handle, 0xa0, kI2cFlag, &payload[16], 10);
      if (status)
        return status;

      // skipping the reserved parts again.
      status = I2cWrite(dev_handle, 0xc0, kI2cFlag, &payload[32], 16);
      if (status)
        return status;

    } else {
      // for normal blocks
      status = I2cWrite(dev_handle, c_pos, kI2cFlag, payload, rc);
    }

    if (status)
      return status;

    // increment the current position
    c_pos += kSizeIOChunk;
  }

  // make sure to write back the altered byte
  payload[0] = kMimoFwHeader;
  status = I2cWrite(dev_handle, 0, kI2cFlag, payload, sizeof(kMimoFwHeader));
  return status;
}

// read the firmware version from the device.
// The firmware version is located in the very last position of the firmware
static StatusCode ReadDeviceFwVersion(
    libusb_device *device,
    libusb_device_handle *dev_handle,
    const int prog_if,
    uint8_t *version) {
  StatusCode status;
  uint8_t data = 9;

  // Step 2. check if the USB kernel driver is active.
  // if active, we need to detach the driver first
  if (libusb_kernel_driver_active(dev_handle, prog_if) == 1) {
    if (LibUsbHelperError(libusb_detach_kernel_driver(dev_handle, prog_if))) {
      return E_FAILED_USB_OPERATIONS;
    }
  }

  // Step 3. set USB configurations
  LibUsbHelperWarning(libusb_set_configuration(dev_handle, 1));

  // Step 4. claim USB interface
  if (LibUsbHelperError(libusb_claim_interface(dev_handle, prog_if)))
    return E_FAILED_USB_OPERATIONS;

  // secret source: write 9 to 0xc212 and 0xc213.(using req type 2)
  if (Poke(dev_handle, kWriteCmdAddr, kWriteCmdSeqA, &data, 1) ||
      Poke(dev_handle, kWriteCmdAddr, kWriteCmdSeqB, &data, 1))
    return E_FAILED_USB_OPERATIONS;

  status = I2cRead(
      dev_handle,
      kVersionNumberAddr,
      kI2cFlag,
      version,
      kFwVersionLenByte);

  if (status)
    return status;

  return E_OK;
}

static void PrintFwVersion(uint8_t* version) {
  uint32_t version_number = 0;

  for (int i = 0; i < 4; ++i) {
    uint32_t current_digit = version[i];
    version_number = version_number + (current_digit << (8 * i));
  }

  LOG(INFO)
      << "Firmware version: "
      << "0x" << std::hex << version_number
      << std::dec;
}

// Actually update the firmware.
static StatusCode UpdateFw(
    libusb_device *dev,
    libusb_device_handle *device_handle,
    libusb_device_descriptor *desc,
    const int prog_if,
    const std::string& fw_file_name,
    const uint8_t* version) {
  // store the firmware version in the device.
  uint8_t curr_version[kFwVersionLenByte];
  StatusCode status;

  // Step 0. read the current version number
  status = ReadDeviceFwVersion(dev, device_handle, prog_if, curr_version);
  if (status != E_OK)
    return status;

  PrintFwVersion(curr_version);

  // the version is the same, no need to update
  if (CompareVersionNumber(version, curr_version))
    return E_OK_NO_UPDATE;

  // Step 1. reset the version number in firmware
  status = WriteFwVersion(dev, device_handle, prog_if, kFwInvalidVersion);
  if (status)
    return E_FAILED_TO_RESET_FW_VERSION;

  // Step 2. flash the firmware
  status = WriteFw(dev, device_handle, prog_if, false, fw_file_name);
  if (status)
    return status;

  // Step 3. update the correct firmware version
  status = WriteFwVersion(dev, device_handle, prog_if, version);
  if (status)
    return status;

  return E_OK;
}

static void Usage() {
  std::cout << "[Usage]" << std::endl;
  std::cout << "  mimo_fw_updater [fw binary file]: update the firmware";
  std::cout << std::endl;
  std::cout << "  mimo_fw_updater: to poll the version information";
  std::cout << std::endl;
}

static StatusCode ReadFwVersionFromFwFileName(
    const std::string& fw_file_name,
    uint8_t *version) {

  // reset the version
  memcpy(version, kFwInvalidVersion, kFwVersionLenByte);

  // firmware name format: mimofw_0x016B_0x00000001.bin
  if (fw_file_name.length() < kFwNameLen)
    return E_INVALID_FW_FILE_NAME;

  const int starting_position = fw_file_name.length() - kFwNameVersionOffset;
  std::string version_string(
      fw_file_name.substr(starting_position, kFwVersionLen));

  // validate the version string.
  for (char& c : version_string) {
    if (isxdigit(c) == 0)
      return E_INVALID_FW_FILE_NAME;
  }

  // construct the value
  uint32_t version_from_file;
  std::stringstream ss;
  ss << std::hex << version_string;
  ss >> version_from_file;

  // the endianness here would be correct
  // since stringstream should handle that
  memcpy(version, &version_from_file, kFwVersionLenByte);
  return E_OK;
}

static StatusCode CheckFwFileValidityAndGetVersion(
    const std::string& fw_file_name,
    uint8_t* fw_version) {
  std::ifstream fw_file_stream(
      fw_file_name.c_str(),
      std::ios_base::in | std::ios_base::binary);

  // verify the file existence and access priviledge
  if (!fw_file_stream.good())
    return E_FAILED_FW_FILE_NOT_ACCESSIBLE;

  // Retrieve the version number in the file name
  if (ReadFwVersionFromFwFileName(fw_file_name, fw_version))
    return E_INVALID_FW_FILE_NAME;

  return E_OK;
}

static StatusCode FwUpdateMainOrPollVersion(
    const std::string& file_name,
    const OperationMode operation_mode) {
  libusb_device **devs;
  libusb_context *ctx;
  libusb_device_descriptor device_descriptor;
  StatusCode status;
  uint8_t version[kFwVersionLenByte];

  // check the validity of the FW file name
  if (operation_mode == E_FW_UPDATE_MODE) {
    status = CheckFwFileValidityAndGetVersion(file_name, version);

    if (status)
      return status;
  }

  // Step 1. init USB lib
  if (LibUsbHelperError(libusb_init(&ctx)))
    return E_FAILED_USB_OPERATIONS;

#if defined(LIBUSB_API_VERSION) && (LIBUSB_API_VERSION >= 0x01000106)
  libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
#else
  libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_INFO);
#endif

  // Step 2. get all USB devices
  const ssize_t dev_cnt = libusb_get_device_list(ctx, &devs);

  if (dev_cnt < 0) {
    libusb_exit(ctx);
    return E_FAILED_TO_GET_DEVICE_LIST;
  }

  // Step 3. Iterator through the device list
  for (ssize_t i = 0; i < dev_cnt; i++) {
    // current device pointer
    libusb_device *current_device = devs[i];

    // get the device descriptor, if failed, we just keep going.
    if (libusb_get_device_descriptor(current_device, &device_descriptor))
      continue;

    // check ID
    if (device_descriptor.idVendor != kMimoVendorId)
      continue;

    const int pid = device_descriptor.idProduct;

    if ((pid == kMimoProductIdA) ||
        (pid == kMimoProductIdB) ||
        (pid == kMimoProductIdRecovery)) {
      const int prog_if = (pid == kMimoProductIdA) ? 1 : 0;
      libusb_device_handle *device_handle;

      if (LibUsbHelperError(libusb_open(current_device, &device_handle)))
        return E_FAILED_USB_OPERATIONS;

      switch (operation_mode) {
        case E_POLL_VERSION_MODE: {
          uint8_t fw_version[kFwVersionLenByte];
          status = ReadDeviceFwVersion(
              current_device,
              device_handle,
              prog_if,
              fw_version);

          if (status == E_OK) {
            PrintFwVersion(fw_version);
          } else {
            LOG(ERROR)
                << "Failed to poll firmware: " << status
                << ", device: " << i;
          }
          break;
        }
        case E_FW_UPDATE_MODE: {
          StatusCode status;
          status = UpdateFw(
              current_device,
              device_handle,
              &device_descriptor,
              prog_if,
              file_name,
              version);

          if (status != E_OK && status != E_OK_NO_UPDATE) {
            LOG(ERROR)
                << "Failed to update firmware: " << status
                << ", device: " << i;
          }

          // The reason that it is rebooted even if the update fails is that
          // the device will be in the recovery mode after reboot. the device
          // to let the device go into the recovery mode.
          // If it's in the recovery mode, the system will have a chance to
          // redo it again to fix the problem.
          if (status != E_OK_NO_UPDATE)
            RebootMimo(device_handle);

          break;
        }
        default: {
          LOG(ERROR)
              << "Unknown operation mode("
              << operation_mode << ")";
          break;
        }
      }

      LibUsbHelperWarning(libusb_release_interface(device_handle, prog_if));
      LibUsbHelperWarning(libusb_attach_kernel_driver(device_handle, prog_if));
      libusb_close(device_handle);
    }
  }

  // clean up libusb devices
  libusb_free_device_list(devs, 1);
  libusb_exit(ctx);
  return E_OK;
}
}  // namespace

int main(int argc, char **argv) {
  // Initialize the logging system.
  brillo::InitLog(brillo::InitFlags::kLogToSyslog);

  OperationMode operation_mode;
  std::string fw_file_name;

  // check the input
  if (argc == kNrParamPollMode) {
    LOG(INFO) << "Querying device firmware version info:";
    operation_mode = E_POLL_VERSION_MODE;
  } else if (argc == kNrParamUpdateMode) {
    operation_mode = E_FW_UPDATE_MODE;
    fw_file_name = argv[1];
  } else {
    Usage();
    return E_FAILED_INCORRECT_PARAM_LIST;
  }

  StatusCode status;

  // executing the update procedure
  status = FwUpdateMainOrPollVersion(fw_file_name, operation_mode);

  if (status != E_OK) {
    LOG(ERROR)
        << "Failed to update firmware: "
        << "status: " << status;
    return status;
  }

  return E_OK;
}
