// 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);
  UsbEndpoint(const UsbEndpoint&) = delete;
  UsbEndpoint& operator=(const UsbEndpoint&) = delete;

  // 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_;
};

}  // namespace hammerd
#endif  // HAMMERD_USB_UTILS_H_
