// Copyright (c) 2012 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 "gpio_handler.h"

#include <base/memory/scoped_ptr.h>
#include <base/string_util.h>
#include <base/stringprintf.h>

#include "update_engine/file_descriptor.h"

using base::Time;
using base::TimeDelta;
using std::string;

using namespace chromeos_update_engine;

namespace chromeos_update_engine {

const char* StandardGpioHandler::gpio_dirs_[kGpioDirMax] = {
  "in",   // kGpioDirIn
  "out",  // kGpioDirOut
};

const char* StandardGpioHandler::gpio_vals_[kGpioValMax] = {
  "1",  // kGpioValUp
  "0",  // kGpioValDown
};

const StandardGpioHandler::GpioDef
StandardGpioHandler::gpio_defs_[kGpioIdMax] = {
  { "dutflaga", "ID_GPIO_DUTFLAGA" },  // kGpioIdDutflaga
  { "dutflagb", "ID_GPIO_DUTFLAGB" },  // kGpioIdDutflagb
};

unsigned StandardGpioHandler::num_instances_ = 0;


StandardGpioHandler::StandardGpioHandler(UdevInterface* udev_iface,
                                         FileDescriptor* fd,
                                         bool is_defer_discovery,
                                         bool is_cache_test_mode)
    : udev_iface_(udev_iface),
      fd_(fd),
      is_cache_test_mode_(is_cache_test_mode),
      is_discovery_attempted_(false) {
  CHECK(udev_iface && fd);

  // Ensure there's only one instance of this class.
  CHECK_EQ(num_instances_, static_cast<unsigned>(0));
  num_instances_++;

  // Reset test signal flags.
  ResetTestModeSignalingFlags();

  // If GPIO discovery not deferred, do it.
  if (!(is_defer_discovery || DiscoverGpios())) {
    LOG(WARNING) << "GPIO discovery failed";
  }
}

StandardGpioHandler::~StandardGpioHandler() {
  num_instances_--;
}

bool StandardGpioHandler::IsTestModeSignaled() {
  // Attempt GPIO discovery.
  if (!DiscoverGpios()) {
    LOG(WARNING) << "GPIO discovery failed";
  }

  // Force a check if so requested.
  if (!is_cache_test_mode_)
    ResetTestModeSignalingFlags();

  bool is_returning_cached = !is_first_check_;  // for logging purposes
  if (is_first_check_) {
    is_first_check_ = false;
    DoTestModeSignalingProtocol();
  }

  LOG(INFO) << "result: " << (is_test_mode_ ? "test" : "normal") << " mode"
            << (is_returning_cached ? " (cached)" : "")
            << (is_handshake_completed_ ? "" : " (default)");
  return is_test_mode_;
}


bool StandardGpioHandler::GpioChipUdevEnumHelper::SetupEnumFilters(
    udev_enumerate* udev_enum) {
  CHECK(udev_enum);

  return !(gpio_handler_->udev_iface_->EnumerateAddMatchSubsystem(
               udev_enum, "gpio") ||
           gpio_handler_->udev_iface_->EnumerateAddMatchSysname(
               udev_enum, "gpiochip*"));
}

bool StandardGpioHandler::GpioChipUdevEnumHelper::ProcessDev(udev_device* dev) {
  CHECK(dev);

  // Ensure we did not encounter more than one chip.
  if (num_gpio_chips_++) {
    LOG(ERROR) << "enumerated multiple GPIO chips";
    return false;
  }

  // Obtain GPIO descriptors.
  for (int id = 0; id < kGpioIdMax; id++) {
    const GpioDef* gpio_def = &gpio_defs_[id];
    const char* descriptor =
        gpio_handler_->udev_iface_->DeviceGetPropertyValue(
            dev, gpio_def->udev_property);
    if (!descriptor) {
      LOG(ERROR) << "could not obtain " << gpio_def->name
                 << " descriptor using property " << gpio_def->udev_property;
      return false;
    }
    gpio_handler_->gpios_[id].descriptor = descriptor;
  }

  return true;
}

bool StandardGpioHandler::GpioChipUdevEnumHelper::Finalize() {
  if (num_gpio_chips_ != 1) {
    LOG(ERROR) << "could not enumerate a GPIO chip";
    return false;
  }
  return true;
}

bool StandardGpioHandler::GpioUdevEnumHelper::SetupEnumFilters(
    udev_enumerate* udev_enum) {
  CHECK(udev_enum);
  const string gpio_pattern =
      string("*").append(gpio_handler_->gpios_[id_].descriptor);
  return !(
      gpio_handler_->udev_iface_->EnumerateAddMatchSubsystem(
          udev_enum, "gpio") ||
      gpio_handler_->udev_iface_->EnumerateAddMatchSysname(
          udev_enum, gpio_pattern.c_str()));
}

bool StandardGpioHandler::GpioUdevEnumHelper::ProcessDev(udev_device* dev) {
  CHECK(dev);

  // Ensure we did not encounter more than one GPIO device.
  if (num_gpios_++) {
    LOG(ERROR) << "enumerated multiple GPIO devices for a given descriptor";
    return false;
  }

  // Obtain GPIO device sysfs path.
  const char* dev_path = gpio_handler_->udev_iface_->DeviceGetSyspath(dev);
  if (!dev_path) {
    LOG(ERROR) << "failed to obtain device syspath for GPIO "
               << gpio_defs_[id_].name;
    return false;
  }
  gpio_handler_->gpios_[id_].dev_path = dev_path;

  LOG(INFO) << "obtained device syspath: " << gpio_defs_[id_].name << " -> "
            << gpio_handler_->gpios_[id_].dev_path;
  return true;
}

bool StandardGpioHandler::GpioUdevEnumHelper::Finalize() {
  if (num_gpios_ != 1) {
    LOG(ERROR) << "could not enumerate GPIO device " << gpio_defs_[id_].name;
    return false;
  }
  return true;
}

StandardGpioHandler::GpioDirResetter::GpioDirResetter(
    StandardGpioHandler* handler, GpioId id, GpioDir dir) :
    do_reset_(false), handler_(handler), id_(id), dir_(dir) {
  CHECK(handler);
  CHECK_GE(id, 0);
  CHECK_LT(id, kGpioIdMax);
  CHECK_GE(dir, 0);
  CHECK_LT(dir, kGpioDirMax);
}

StandardGpioHandler::GpioDirResetter::~GpioDirResetter() {
  if (do_reset_ && !handler_->SetGpioDirection(id_, dir_)) {
    LOG(WARNING) << "failed to reset direction of " << gpio_defs_[id_].name
                 << " to " << gpio_dirs_[dir_];
  }
}


bool StandardGpioHandler::InitUdevEnum(struct udev* udev,
                                       UdevEnumHelper* enum_helper) {
  // Obtain a udev enumerate object.
  struct udev_enumerate* udev_enum;
  if (!(udev_enum = udev_iface_->EnumerateNew(udev))) {
    LOG(ERROR) << "failed to obtain udev enumerate context";
    return false;
  }

  // Assign enumerate object to closer.
  scoped_ptr<UdevInterface::UdevEnumerateCloser>
      udev_enum_closer(udev_iface_->NewUdevEnumerateCloser(&udev_enum));

  // Setup enumeration filters.
  if (!enum_helper->SetupEnumFilters(udev_enum)) {
    LOG(ERROR) << "failed to setup udev enumerate filters";
    return false;
  }

  // Scan for matching devices.
  if (udev_iface_->EnumerateScanDevices(udev_enum)) {
    LOG(ERROR) << "udev enumerate scan failed";
    return false;
  }

  // Iterate over matching devices.
  struct udev_list_entry* list_entry;
  for (list_entry = udev_iface_->EnumerateGetListEntry(udev_enum);
       list_entry; list_entry = udev_iface_->ListEntryGetNext(list_entry)) {
    // Obtain device name.
    const char* dev_path = udev_iface_->ListEntryGetName(list_entry);
    if (!dev_path) {
      LOG(ERROR) << "enumerated device has a null name string";
      return false;
    }

    // Obtain device object.
    struct udev_device* dev = udev_iface_->DeviceNewFromSyspath(udev, dev_path);
    if (!dev) {
      LOG(ERROR) << "obtained a null device object for enumerated device";
      return false;
    }
    scoped_ptr<UdevInterface::UdevDeviceCloser>
        dev_closer(udev_iface_->NewUdevDeviceCloser(&dev));

    if (!enum_helper->ProcessDev(dev))
      return false;
  }

  // Make sure postconditions were met.
  return enum_helper->Finalize();
}

void StandardGpioHandler::ResetTestModeSignalingFlags() {
  is_first_check_ = true;
  is_handshake_completed_ = false;
  is_test_mode_ = false;
}

bool StandardGpioHandler::DiscoverGpios() {
  if (is_discovery_attempted_)
    return true;

  is_discovery_attempted_ = true;

  // Obtain libudev instance and attach to a dedicated closer.
  struct udev* udev;
  if (!(udev = udev_iface_->New())) {
    LOG(ERROR) << "failed to obtain libudev instance";
    return false;
  }
  scoped_ptr<UdevInterface::UdevCloser>
      udev_closer(udev_iface_->NewUdevCloser(&udev));

  // Enumerate GPIO chips, scanning for GPIO descriptors.
  GpioChipUdevEnumHelper chip_enum_helper(this);
  if (!InitUdevEnum(udev, &chip_enum_helper)) {
    LOG(ERROR) << "enumeration error, aborting GPIO discovery";
    return false;
  }

  // Obtain device names for all discovered GPIOs, reusing the udev instance.
  for (int id = 0; id < kGpioIdMax; id++) {
    GpioUdevEnumHelper gpio_enum_helper(this, static_cast<GpioId>(id));
    if (!InitUdevEnum(udev, &gpio_enum_helper)) {
      LOG(ERROR) << "enumeration error, aborting GPIO discovery";
      return false;
    }
  }

  return true;
}

bool StandardGpioHandler::GetGpioDevName(StandardGpioHandler::GpioId id,
                                         string* dev_path_p) {
  CHECK(id >= 0 && id < kGpioIdMax && dev_path_p);

  *dev_path_p = gpios_[id].dev_path;
  return true;
}

bool StandardGpioHandler::OpenGpioFd(StandardGpioHandler::GpioId id,
                                     const char* dev_name,
                                     bool is_write) {
  CHECK(id >= 0 && id < kGpioIdMax && dev_name);
  string file_name = StringPrintf("%s/%s", gpios_[id].dev_path.c_str(),
                                  dev_name);
  if (!fd_->Open(file_name.c_str(), (is_write ? O_WRONLY : O_RDONLY))) {
    const string err_str = StringPrintf("failed to open %s (%s) for %s",
                                        file_name.c_str(), gpio_defs_[id].name,
                                        (is_write ? "writing" : "reading"));
    if (fd_->IsSettingErrno()) {
      PLOG(ERROR) << err_str;
    } else {
      LOG(ERROR) << err_str;
    }
    return false;
  }
  return true;
}

bool StandardGpioHandler::SetGpio(StandardGpioHandler::GpioId id,
                                  const char* dev_name, const char* entries[],
                                  const int num_entries, int index) {
  CHECK_GE(id, 0);
  CHECK_LT(id, kGpioIdMax);
  CHECK(dev_name);
  CHECK(entries);
  CHECK_GT(num_entries, 0);
  CHECK_GE(index, 0);
  CHECK_LT(index, num_entries);

  // Open device for writing.
  if (!OpenGpioFd(id, dev_name, true))
    return false;
  ScopedFileDescriptorCloser dev_fd_closer(fd_);

  // Write a string corresponding to the requested output index to the GPIO
  // device, appending a newline.
  string output_str = entries[index];
  output_str += '\n';
  ssize_t write_len = fd_->Write(output_str.c_str(), output_str.length());
  if (write_len != static_cast<ssize_t>(output_str.length())) {
    if (write_len < 0) {
      const string err_str = "failed to write to GPIO";
      if (fd_->IsSettingErrno()) {
        PLOG(ERROR) << err_str;
      } else {
        LOG(ERROR) << err_str;
      }
    } else {
      LOG(ERROR) << "wrong number of bytes written (" << write_len
                 << " instead of " << output_str.length() << ")";
    }
    return false;
  }

  // Close the device explicitly, returning the close result.
  return fd_->Close();
}

bool StandardGpioHandler::GetGpio(StandardGpioHandler::GpioId id,
                                  const char* dev_name, const char* entries[],
                                  const int num_entries, int* index_p) {
  CHECK_GE(id, 0);
  CHECK_LT(id, kGpioIdMax);
  CHECK(dev_name);
  CHECK(entries);
  CHECK_GT(num_entries, 0);
  CHECK(index_p);

  // Open device for reading.
  if (!OpenGpioFd(id, dev_name, false))
    return false;
  ScopedFileDescriptorCloser dev_fd_closer(fd_);

  // Read the GPIO device. We attempt to read more than the max number of
  // characters expected followed by a newline, to ensure that we've indeed read
  // all the data available on the device.
  size_t max_entry_len = 0;
  for (int i = 0; i < num_entries; i++) {
    size_t entry_len = strlen(entries[i]);
    if (entry_len > max_entry_len)
      max_entry_len = entry_len;
  }
  max_entry_len++;  // account for trailing newline
  size_t buf_len = max_entry_len + 1;  // room for excess char / null terminator
  char buf[buf_len];
  memset(buf, 0, buf_len);
  ssize_t read_len = fd_->Read(buf, buf_len);
  if (read_len < 0 || read_len > static_cast<ssize_t>(max_entry_len)) {
    if (read_len < 0) {
      const string err_str = "failed to read GPIO";
      if (fd_->IsSettingErrno()) {
        PLOG(ERROR) << err_str;
      } else {
        LOG(ERROR) << err_str;
      }
    } else {
      LOG(ERROR) << "read too many bytes (" << read_len << ")";
    }
    return false;
  }

  // Remove trailing newline.
  read_len--;
  if (buf[read_len] != '\n') {
    LOG(ERROR) << "read value missing trailing newline";
    return false;
  }
  buf[read_len] = '\0';

  // Identify and write GPIO status.
  for (int i = 0; i < num_entries; i++)
    if (!strcmp(entries[i], buf)) {
      *index_p = i;
      // Close the device explicitly, returning the close result.
      return fd_->Close();
    }

  // Oops, unidentified reading...
  LOG(ERROR) << "read unexpected value from GPIO (`" << buf << "')";
  return false;
}

bool StandardGpioHandler::SetGpioDirection(StandardGpioHandler::GpioId id,
                                           StandardGpioHandler::GpioDir dir) {
  return SetGpio(id, "direction", gpio_dirs_, kGpioDirMax, dir);
}

bool StandardGpioHandler::GetGpioDirection(
    StandardGpioHandler::GpioId id,
    StandardGpioHandler::GpioDir* direction_p) {
  return GetGpio(id, "direction", gpio_dirs_, kGpioDirMax,
                 reinterpret_cast<int*>(direction_p));
}

bool StandardGpioHandler::SetGpioValue(StandardGpioHandler::GpioId id,
                                       StandardGpioHandler::GpioVal value,
                                       bool is_check_direction) {
  // If so instructed, ensure that the GPIO is indeed in the output direction
  // before attempting to write to it.
  if (is_check_direction) {
    GpioDir dir;
    if (!(GetGpioDirection(id, &dir) && dir == kGpioDirOut)) {
      LOG(ERROR) << "couldn't verify that GPIO is in the output direction "
                    "prior to reading from it";
      return false;
    }
  }

  return SetGpio(id, "value", gpio_vals_, kGpioValMax, value);
}

bool StandardGpioHandler::GetGpioValue(StandardGpioHandler::GpioId id,
                                       StandardGpioHandler::GpioVal* value_p,
                                       bool is_check_direction) {
  // If so instructed, ensure that the GPIO is indeed in the input direction
  // before attempting to read from it.
  if (is_check_direction) {
    GpioDir dir;
    if (!(GetGpioDirection(id, &dir) && dir == kGpioDirIn)) {
      LOG(ERROR) << "couldn't verify that GPIO is in the input direction "
                    "prior to reading from it";
      return false;
    }
  }

  return GetGpio(id, "value", gpio_vals_, kGpioValMax,
                 reinterpret_cast<int*>(value_p));
}

bool StandardGpioHandler::DoTestModeSignalingProtocol() {
  // The test mode signaling protocol is designed to provide a robust indication
  // that a Chrome OS device is physically connected to a servo board in a lab
  // setting. It is making very few assumptions about the soundness of the
  // hardware, firmware and kernel driver implementation of the GPIO mechanism.
  // In general, it is performing a three-way handshake between servo and the
  // Chrome OS client, based on changes in the GPIO value readings. The
  // client-side implementation does the following:
  //
  //  1. Check for an initial signal (0) on the input GPIO (dut_flaga).
  //
  //  2. Flip the signal (1 -> 0) on the output GPIO (dut_flagb).
  //
  //  3. Check for a flipped signal (1) on the input GPIO.
  //
  // TODO(garnold) the current implementation is based on sysfs access to GPIOs.
  // We will likely change this to using a specialized in-kernel driver
  // implementation, which would give us better performance and security
  // guarantees.

  LOG(INFO) << "attempting GPIO handshake";

  const char* dutflaga_name = gpio_defs_[kGpioIdDutflaga].name;
  const char* dutflagb_name = gpio_defs_[kGpioIdDutflagb].name;

  // Flip GPIO direction, set it to "in".
  // TODO(garnold) changing the GPIO direction back and forth is necessary for
  // overcoming a firmware/kernel issue which causes the device to be in the
  // "out" state whereas the kernel thinks it is in the "in" state.  This should
  // be abandoned once the firmware and/or kernel driver have been fixed.
  // Details here: http://code.google.com/p/chromium-os/issues/detail?id=27680
  if (!(SetGpioDirection(kGpioIdDutflaga, kGpioDirOut) &&
        SetGpioDirection(kGpioIdDutflaga, kGpioDirIn))) {
    LOG(ERROR) << "failed to flip direction of input GPIO " << dutflaga_name;
    return false;
  }

  // Peek input GPIO state.
  GpioVal dutflaga_gpio_value;
  if (!GetGpioValue(kGpioIdDutflaga, &dutflaga_gpio_value, true)) {
    LOG(ERROR) << "failed to read input GPIO " << dutflaga_name;
    return false;
  }

  // If initial handshake signal not received, abort.
  if (dutflaga_gpio_value != kGpioValDown) {
    LOG(INFO) << "input GPIO " << dutflaga_name
              << " unset, terminating handshake";
    is_handshake_completed_ = true;
    return true;
  }

  // Initialize output GPIO to a default state.
  // TODO(garnold) a similar workaround for possible driver/firmware glitches,
  // we insist on flipping the direction of the GPIO prior to assuming it is in
  // the "out" direction.
  GpioDirResetter dutflagb_dir_resetter(this, kGpioIdDutflagb, kGpioDirIn);
  if (!(SetGpioDirection(kGpioIdDutflagb, kGpioDirIn) &&
        dutflagb_dir_resetter.set_do_reset(
            SetGpioDirection(kGpioIdDutflagb, kGpioDirOut)) &&
        SetGpioValue(kGpioIdDutflagb, kGpioValUp, false))) {
    LOG(ERROR) << "failed to initialize output GPIO " << dutflagb_name;
    return false;
  }

  // Wait, giving the receiving end enough time to sense the fall.
  sleep(kServoOutputResponseWaitInSecs);

  // Flip the output signal.
  if (!SetGpioValue(kGpioIdDutflagb, kGpioValDown, false)) {
    LOG(ERROR) << "failed to flip output GPIO " << dutflagb_name;
    return false;
  }

  // Look for flipped input GPIO value, up to a preset timeout.
  Time expires =
      Time::Now() + TimeDelta::FromSeconds(kServoInputResponseTimeoutInSecs);
  TimeDelta delay =
      TimeDelta::FromMicroseconds(1000000 / kServoInputNumChecksPerSec);
  bool is_first_response_check = true;
  bool is_error = false;
  while (Time::Now() < expires) {
    if (is_first_response_check)
      is_first_response_check = false;
    else
      usleep(delay.InMicroseconds());

    // Read input GPIO.
    if (!GetGpioValue(kGpioIdDutflaga, &dutflaga_gpio_value, true)) {
      LOG(ERROR) << "failed to read input GPIO " << dutflaga_name;
      is_error = true;
      break;
    }

    // If dutflaga is now up (flipped), we got our signal!
    if (dutflaga_gpio_value == kGpioValUp) {
      is_test_mode_ = true;
      break;
    }
  }

  if (!is_error) {
    if (is_test_mode_) {
      is_handshake_completed_ = true;
      LOG(INFO) << "GPIO handshake completed, test mode signaled";
    } else {
      LOG(INFO) << "timed out waiting for input GPIO " << dutflaga_name
                << " to flip, terminating handshake";
    }
  }

  return is_handshake_completed_;
}

}  // namespace chromeos_update_engine
