// Copyright 2017 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.
//
// Implement the USB-related functions using sysfs and usbfs.
// The structure of sysfs:
// /sys/bus/usb/devices/
// |-- <bus>-<port>/
//     |-- idVendor
//     |-- idProduct
//     |-- configuration
//     |-- uevent
//     |-- <bus>-<port>:<config>.<interface>/
//         |-- bInterfaceNumber
//         |-- bInterfaceClass
//         |-- bInterfaceSubClass
//         |-- bInterfaceProtocol
//         |-- ep_<ep_num>/
//             |-- wMaxPacketSize

#ifndef HAMMERD_USB_UTILS_H_
#define HAMMERD_USB_UTILS_H_

#include <stdint.h>

#include <string>

#include <base/files/file_path.h>
#include <base/macros.h>

namespace hammerd {

constexpr int kUsbEndpointIn = 0x80;
constexpr int kUsbEndpointOut = 0x00;

constexpr uint8_t kUsbClassGoogleUpdate = 0xff;
constexpr uint8_t kUsbSubclassGoogleUpdate = 0x53;
constexpr uint8_t kUsbProtocolGoogleUpdate = 0xff;

// Get the path of the USB device root sysfs.
const base::FilePath GetUsbSysfsPath(const std::string& path);

enum class UsbConnectStatus {
  kSuccess,  // USB device is connected successfully.
  kUsbPathEmpty,  // Sysfs path of USB device is not found.
  kInvalidDevice,  // USB device has wrong VID/PID.
  kUnknownError,  // Other failure.
};

class UsbEndpointInterface {
 public:
  virtual ~UsbEndpointInterface() = default;

  // Check whether the USB sysfs file exist or not.
  virtual bool UsbSysfsExists() = 0;
  // Initializes the USB endpoint.
  virtual UsbConnectStatus Connect() = 0;
  // Releases USB endpoint.
  virtual void Close() = 0;
  // Returns whether the USB endpoint is initialized.
  virtual bool IsConnected() const = 0;

  // Sends the data to USB endpoint and then reads the result back.
  // Returns the byte number of the received data. -1 if the process fails, or
  // if `allow_less` is false and the received data does not match outlen.
  virtual int Transfer(const void* outbuf,
                       int outlen,
                       void* inbuf,
                       int inlen,
                       bool allow_less = false,
                       unsigned int timeout_ms = 0) = 0;
  // Sends the data to USB endpoint.
  // Returns the byte number of the received data. -1 if the process fails, or
  // if `allow_less` is false and the received data does not match outlen.
  virtual int Send(const void* outbuf,
                   int outlen,
                   bool allow_less = false,
                   unsigned int timeout_ms = 0) = 0;
  // Receives the data from USB endpoint.
  // Returns the byte number of the received data. -1 if the process fails, or
  // if `allow_less` is false and the received data does not match outlen.
  virtual int Receive(void* inbuf,
                      int inlen,
                      bool allow_less = false,
                      unsigned int timeout_ms = 0) = 0;

  // Gets the chunk length of the USB endpoint.
  virtual int GetChunkLength() const = 0;

  // Gets the configuration string of the USB endpoint.
  virtual std::string GetConfigurationString() const = 0;
};

class UsbEndpoint : public UsbEndpointInterface {
 public:
  UsbEndpoint(uint16_t vendor_id, uint16_t product_id,
              std::string path);

  // UsbEndpointInterface:
  ~UsbEndpoint() override;
  bool UsbSysfsExists() override;
  UsbConnectStatus Connect() override;
  void Close() override;
  bool IsConnected() const override;
  int Transfer(const void* outbuf,
               int outlen,
               void* inbuf,
               int inlen,
               bool allow_less = false,
               unsigned int timeout_ms = 0) override;
  int Send(const void* outbuf,
           int outlen,
           bool allow_less = false,
           unsigned int timeout_ms = 0) override;
  int Receive(void* inbuf,
              int inlen,
              bool allow_less = false,
              unsigned int timeout_ms = 0) override;
  int GetChunkLength() const override { return chunk_len_; }
  std::string GetConfigurationString() const override {
    return configuration_string_;
  }

 private:
  // Returns the actual transfered data size.
  // If the timeout is not assigned, then use default timeout value.
  // |direction_mask| should be one of kUsbEndpointIn or kUsbEndpointOut.
  int BulkTransfer(void* buf,
                   int direction_mask,
                   int len,
                   unsigned int timeout_ms = 0);

  uint16_t vendor_id_;
  uint16_t product_id_;
  std::string path_;
  int fd_;
  std::string configuration_string_;
  int iface_num_;
  int ep_num_;
  int chunk_len_;
  DISALLOW_COPY_AND_ASSIGN(UsbEndpoint);
};

}  // namespace hammerd
#endif  // HAMMERD_USB_UTILS_H_
