// Copyright 2016 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 "permission_broker/usb_driver_tracker.h"

#include <fcntl.h>
#include <linux/usbdevice_fs.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include <string>

#include <base/bind.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/string_number_conversions.h>
#include <brillo/message_loops/message_loop.h>

#include "permission_broker/udev_scopers.h"

using brillo::MessageLoop;

namespace permission_broker {

UsbDriverTracker::UsbDriverTracker() {}
UsbDriverTracker::~UsbDriverTracker() {
  // Re-attach all delegated USB interfaces
  for (const std::pair<int, UsbInterfaces>  &entry : dev_fds_) {
    std::string path;
    MessageLoop::TaskId tsk_id;
    std::vector<uint8_t> ifaces;
    std::tie(path, tsk_id, ifaces) = entry.second;
    MessageLoop::current()->CancelTask(tsk_id);
    ReAttachPathToKernel(path, ifaces);
  }
}

void UsbDriverTracker::ScanClosedFd(int fd) {
  auto entry = dev_fds_.find(fd);
  if (entry != dev_fds_.end()) {
    int fd = entry->first;
    int res = fcntl(fd, F_GETFL);
    if (res < 0) {  // the browser has close the file descriptor
      std::string path;
      MessageLoop::TaskId tsk_id;
      std::vector<uint8_t> ifaces;
      std::tie(path, tsk_id, ifaces) = entry->second;
      MessageLoop::current()->CancelTask(tsk_id);
      // re-attaching the kernel driver to the USB interface.
      ReAttachPathToKernel(path, ifaces);
      // we are done with the USB interface.
      dev_fds_.erase(entry);
    }
  } else {
    LOG(WARNING) << "Untracked USB file descriptor " << fd;
  }
}

bool UsbDriverTracker::ReAttachPathToKernel(const std::string& path,
    const std::vector<uint8_t>& ifaces) {
  int fd = HANDLE_EINTR(open(path.c_str(), O_RDWR));
  if (fd < 0) {
    LOG(WARNING) << "Cannot open " << path;
    return false;
  }

  for (uint8_t iface_num : ifaces) {
    struct usbdevfs_ioctl dio;
    dio.ifno = iface_num;
    dio.ioctl_code = USBDEVFS_CONNECT;
    dio.data = NULL;

    int res = ioctl(fd, USBDEVFS_IOCTL, &dio);
    if (res < 0) {
      LOG(WARNING) << "Kernel USB driver connection for " << path
          << " on interface " << iface_num << " failed " << errno;
    } else {
      LOG(INFO) << "Kernel USB driver attached on " << path
          << " interface " << iface_num;
    }
  }
  IGNORE_EINTR(close(fd));

  return true;
}

bool UsbDriverTracker::DetachPathFromKernel(int fd, const std::string& path) {
  // Use the USB device node major/minor to find the udev entry.
  struct stat st;
  if (fstat(fd, &st) || !S_ISCHR(st.st_mode)) {
    LOG(WARNING) << "Cannot stat " << path << " device id";
    return false;
  }

  ScopedUdevPtr udev(udev_new());
  ScopedUdevDevicePtr device(
      udev_device_new_from_devnum(udev.get(), 'c', st.st_rdev));
  if (!device.get()) {
    return false;
  }

  ScopedUdevEnumeratePtr enumerate(udev_enumerate_new(udev.get()));
  udev_enumerate_add_match_parent(enumerate.get(), device.get());
  udev_enumerate_scan_devices(enumerate.get());

  // Try to find our USB interface nodes, by iterating through all devices
  // and extracting our children devices.
  bool detached = false;
  std::vector<uint8_t> ifaces;
  struct udev_list_entry *entry;
  udev_list_entry_foreach(entry,
                          udev_enumerate_get_list_entry(enumerate.get())) {
    const char *entry_path = udev_list_entry_get_name(entry);
    ScopedUdevDevicePtr child(udev_device_new_from_syspath(udev.get(),
                                                           entry_path));

    const char* child_type = udev_device_get_devtype(child.get());
    if (!child_type || strcmp(child_type, "usb_interface") != 0) {
      continue;
    }

    const char* driver = udev_device_get_driver(child.get());
    if (driver) {
      // A kernel driver is using this interface, try to detach it.
      const char *iface = udev_device_get_sysattr_value(
          child.get(), "bInterfaceNumber");
      unsigned iface_num;
      if (!iface || !base::StringToUint(iface, &iface_num)) {
        detached = false;
        continue;
      }

      struct usbdevfs_ioctl dio;
      dio.ifno = iface_num;
      dio.ioctl_code = USBDEVFS_DISCONNECT;
      dio.data = NULL;

      int res = ioctl(fd, USBDEVFS_IOCTL, &dio);
      if (res < 0) {
        LOG(WARNING) << "Kernel USB driver disconnection for " << path
            << " on interface " << iface_num << " failed " << errno;
      } else {
        detached = true;
        ifaces.push_back(iface_num);
        LOG(INFO) << "USB driver '" << driver << "' detached on " << path
            << " interface " << iface_num;
      }
    }
  }

  if (detached) {
    MessageLoop::TaskId tsk_id = MessageLoop::current()->WatchFileDescriptor(
        FROM_HERE, fd, MessageLoop::WatchMode::kWatchWrite, true,
        base::Bind(&UsbDriverTracker::ScanClosedFd,
                   base::Unretained(this), fd));
    if (!tsk_id) {
      LOG(ERROR) << "Unable to watch FD " << fd;
      return true;
    }
    UsbInterfaces fd_ifaces = std::make_tuple(path, tsk_id, ifaces);
    dev_fds_[fd] = fd_ifaces;
  }

  return detached;
}

}  // namespace permission_broker
