// 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.
//
// hammerd - A daemon to update the firmware of Hammer

#include "hammerd/hammer_updater.h"

#include <unistd.h>

#include <pcrecpp.h>

#include <memory>
#include <string>
#include <utility>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <base/strings/string_number_conversions.h>
#include <base/strings/string_util.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>
#include <chromeos/dbus/service_constants.h>

#include "hammerd/uma_metric_names.h"

namespace hammerd {

const std::string HammerUpdater::TaskState::ToString() {
  return base::StringPrintf("update_ro(%d) update_rw(%d) update_tp(%d) "
                            "inject_entropy(%d) post_rw_jump(%d)",
                            update_ro, update_rw, update_tp,
                            inject_entropy, post_rw_jump);
}

HammerUpdater::UpdateCondition HammerUpdater::ToUpdateCondition(
    const std::string& s) {
  if (s == "never")
    return UpdateCondition::kNever;
  if (s == "mismatch")
    return UpdateCondition::kMismatch;
  if (s == "always")
    return UpdateCondition::kAlways;
  return UpdateCondition::kUnknown;
}

HammerUpdater::HammerUpdater(const std::string& ec_image,
                             const std::string& touchpad_image,
                             const std::string& touchpad_product_id,
                             const std::string& touchpad_fw_ver,
                             uint16_t vendor_id, uint16_t product_id,
                             int bus, const std::string& port, bool at_boot,
                             UpdateCondition update_condition)
    : HammerUpdater(
        ec_image,
        touchpad_image,
        touchpad_product_id,
        touchpad_fw_ver,
        at_boot,
        update_condition,
        std::make_unique<FirmwareUpdater>(
            std::make_unique<UsbEndpoint>(vendor_id, product_id, bus, port)),
        std::make_unique<PairManager>(),
        std::make_unique<DBusWrapper>(),
        std::make_unique<MetricsLibrary>()) {}

HammerUpdater::HammerUpdater(
    const std::string& ec_image,
    const std::string& touchpad_image,
    const std::string& touchpad_product_id,
    const std::string& touchpad_fw_ver,
    bool at_boot,
    UpdateCondition update_condition,
    std::unique_ptr<FirmwareUpdaterInterface> fw_updater,
    std::unique_ptr<PairManagerInterface> pair_manager,
    std::unique_ptr<DBusWrapperInterface> dbus_wrapper,
    std::unique_ptr<MetricsLibraryInterface> metrics)
    : ec_image_(ec_image),
      touchpad_image_(touchpad_image),
      touchpad_product_id_(touchpad_product_id),
      touchpad_fw_ver_(touchpad_fw_ver),
      at_boot_(at_boot),
      update_condition_(update_condition),
      task_(HammerUpdater::TaskState()),
      fw_updater_(std::move(fw_updater)),
      pair_manager_(std::move(pair_manager)),
      dbus_wrapper_(std::move(dbus_wrapper)),
      dbus_notified_(false),
      metrics_(std::move(metrics)) {}

HammerUpdater::RunStatus HammerUpdater::Run() {
  LOG(INFO) << "Load and validate the EC image.";
  if (!fw_updater_->LoadEcImage(ec_image_)) {
    LOG(ERROR) << "Failed to load EC image.";
    return HammerUpdater::RunStatus::kInvalidFirmware;
  }

  HammerUpdater::RunStatus status = RunLoop();
  WaitUsbReady(status);
  if (update_condition_ != UpdateCondition::kNever) {
    NotifyUpdateFinished(status == HammerUpdater::RunStatus::kNoUpdate);
  }
  return status;
}

HammerUpdater::RunStatus HammerUpdater::UpdateRW() {
  bool ret = fw_updater_->TransferImage(SectionName::RW);
  task_.update_rw = !ret;
  metrics_->SendEnumToUMA(
      kMetricRWUpdateResult,
      static_cast<int>(ret
          ? RWUpdateResult::kSucceeded
          : RWUpdateResult::kTransferFailed),
      static_cast<int>(RWUpdateResult::kCount));
  LOG(INFO) << "RW update " << (ret ? "passed." : "failed.");
  return HammerUpdater::RunStatus::kNeedReset;
}

HammerUpdater::RunStatus HammerUpdater::RunLoop() {
  constexpr unsigned int kMaximumRunCount = 20;
  // Time it takes hammer to reset or jump to RW, before being
  // available for the next USB connection.
  constexpr unsigned int kResetTimeMs = 100;
  bool criticality_checked = false;
  bool can_update = update_condition_ != UpdateCondition::kNever;
  // Set all update flags if update mode is forced.
  if (update_condition_ == UpdateCondition::kAlways) {
      task_.update_ro = true;
      task_.update_rw = true;
      task_.update_tp = true;
  }

  HammerUpdater::RunStatus status;
  for (int run_count = 0; run_count < kMaximumRunCount; ++run_count) {
    UsbConnectStatus connect_status = fw_updater_->TryConnectUsb();
    if (connect_status != UsbConnectStatus::kSuccess) {
      if (!criticality_checked && !can_update) {
        metrics_->SendEnumToUMA(
            kMetricPendingRWUpdate,
            static_cast<int>(PendingRWUpdate::kCommunicationError),
            static_cast<int>(PendingRWUpdate::kCount));
      }
      LOG(ERROR) << "Failed to connect USB.";
      fw_updater_->CloseUsb();

      if (connect_status == UsbConnectStatus::kUsbPathEmpty) {
        return HammerUpdater::RunStatus::kLostConnection;
      } else if (connect_status == UsbConnectStatus::kInvalidDevice) {
        LOG(ERROR) << "Invalid base connected.";
        dbus_wrapper_->SendSignal(kInvalidBaseConnectedSignal);
      }

      // If there is a "hammer-like" device attached, hammerd should
      // try to avoid running again when hammer jumps to RW. Use kNeedJump
      // to force this wait time before exiting.
      return HammerUpdater::RunStatus::kNeedJump;
    }

    // If this update is considered "critical", then we need to update the
    // firmware. This block is only run once at the first round of loop.
    if (!criticality_checked) {
      criticality_checked = true;

      if (!can_update) {
        PendingRWUpdate pending_metric = PendingRWUpdate::kCount;

        if (fw_updater_->IsCritical()) {
          LOG(INFO) << "Critical update available but update condition "
                    << "is set to 'never'; notify UI.";
          NotifyNeedUpdate();
          pending_metric = PendingRWUpdate::kCriticalUpdate;
        } else if (fw_updater_->VersionMismatch(SectionName::RW) ||
                   fw_updater_->CompareRollback() > 0) {
          // In theory, an increase in rollback number should imply a version
          // mismatch. Include both conditions here to simplify unittesting.
          pending_metric = PendingRWUpdate::kNonCriticalUpdate;
        } else {
          pending_metric = PendingRWUpdate::kNoUpdate;
        }

        metrics_->SendEnumToUMA(
            kMetricPendingRWUpdate,
            static_cast<int>(pending_metric),
            static_cast<int>(PendingRWUpdate::kCount));
      }
    }

    DLOG(INFO) << "Current task state: " << task_.ToString();
    status = RunOnce();
    task_.post_rw_jump = (status == HammerUpdater::RunStatus::kNeedJump);
    task_.post_rw_lock = (status == HammerUpdater::RunStatus::kNeedLock);
    switch (status) {
      case HammerUpdater::RunStatus::kNoUpdate:
        LOG(INFO) << "Hammer does not need to update.";
        fw_updater_->CloseUsb();
        return status;

      case HammerUpdater::RunStatus::kFatalError:
        LOG(ERROR) << "Hammer encountered a fatal error!";
        // Send the reset signal to hammer, and then prevent the next hammerd
        // process from being invoked.
        fw_updater_->SendSubcommand(UpdateExtraCommand::kImmediateReset);
        fw_updater_->CloseUsb();
        return HammerUpdater::RunStatus::kNeedReset;

      case HammerUpdater::RunStatus::kInvalidFirmware:
        // Send the JumpToRW to hammer, and then prevent the next hammerd
        // process from being invoked.
        fw_updater_->SendSubcommand(UpdateExtraCommand::kJumpToRW);
        fw_updater_->CloseUsb();
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        return HammerUpdater::RunStatus::kNeedJump;

      case HammerUpdater::RunStatus::kNeedReset:
        LOG(INFO) << "Reset hammer and run again. run_count=" << run_count;
        fw_updater_->SendSubcommand(UpdateExtraCommand::kImmediateReset);
        fw_updater_->CloseUsb();
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        continue;

      case HammerUpdater::RunStatus::kNeedLock:
        LOG(INFO) << "Request 'Jump to RW'. Hammer will reboot with locked RW. "
            << "Run again. run_count=" << run_count;
        fw_updater_->SendSubcommand(UpdateExtraCommand::kJumpToRW);
        fw_updater_->CloseUsb();
        // TODO(kitching): Make RW jumps more robust by polling until
        // the jump completes (or fails).
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        continue;

      case HammerUpdater::RunStatus::kNeedJump:
        LOG(INFO) << "Jump to RW and run again. run_count=" << run_count;
        fw_updater_->SendSubcommand(UpdateExtraCommand::kJumpToRW);
        fw_updater_->CloseUsb();
        // TODO(kitching): Make RW jumps more robust by polling until
        // the jump completes (or fails).
        base::PlatformThread::Sleep(
            base::TimeDelta::FromMilliseconds(kResetTimeMs));
        continue;

      case HammerUpdater::RunStatus::kTouchpadMismatched:
        LOG(ERROR) << "Touchpad firmware is mismatched!";
        fw_updater_->CloseUsb();
        return HammerUpdater::RunStatus::kTouchpadMismatched;

      default:
        LOG(ERROR) << "Unknown RunStatus: " << static_cast<int>(status);
        fw_updater_->CloseUsb();
        return HammerUpdater::RunStatus::kFatalError;
    }
  }

  LOG(ERROR) << "Maximum run count exceeded (" << kMaximumRunCount << ")! ";
  return status;
}

HammerUpdater::RunStatus HammerUpdater::RunOnce() {
  // The first time we use SendFirstPdu it is to gather information about
  // hammer's running EC. We should use SendDone right away to get the EC
  // back into a state where we can send a subcommand.
  if (!fw_updater_->SendFirstPdu()) {
    LOG(ERROR) << "Failed to send the first PDU.";
    return HammerUpdater::RunStatus::kNeedReset;
  }
  fw_updater_->SendDone();
  LOG(INFO) << "### Current Section: "
            << ToString(fw_updater_->CurrentSection()) << " ###";

  // ********************** UNKNOWN **********************
  // If the layout of the firmware has changed, we cannot handle this case.
  if (fw_updater_->CurrentSection() == SectionName::Invalid) {
    LOG(INFO) << "Hammer is in RO but the firmware layout has changed.";
    return HammerUpdater::RunStatus::kInvalidFirmware;
  }

  // After sending first PDU, we get the information of current EC.
  // Check if the firmware version is mismatched or not.
  if (update_condition_ == UpdateCondition::kMismatch) {
    // In theory, an increase in rollback number should imply a version
    // mismatch. Include both conditions here to simplify unittesting.
    if (fw_updater_->VersionMismatch(SectionName::RW) ||
        fw_updater_->CompareRollback() > 0)
      task_.update_rw = true;
    if (fw_updater_->VersionMismatch(SectionName::RO))
      task_.update_ro = true;
  }

  // ********************** RW **********************
  // If EC already entered the RW section, then check if RW needs updating.
  // If an update is needed, request a hammer reset. Let the next invocation
  // of Run handle the update.
  if (fw_updater_->CurrentSection() == SectionName::RW) {
    if (task_.update_rw) {
      if (fw_updater_->ValidKey() && fw_updater_->CompareRollback() >= 0) {
        LOG(INFO) << "RW section needs update. Rebooting to RO.";
        if (fw_updater_->IsSectionLocked(SectionName::RW)) {
          fw_updater_->UnlockRW();
        }
        return HammerUpdater::RunStatus::kNeedReset;
      } else {
        task_.update_ro = true;
        LOG(INFO) << "RW section needs update, but local image is "
                  << "incompatible. Continuing to post-RW process; maybe "
                  << "RO can be updated.";
      }
    }
    return PostRWProcess();
  }

  // ********************** RO **********************
  // Current section is now guaranteed to be RO.  Deal with
  // each of three possible ongoing tasks:
  //   (1) jump to RW (failed, attempt update if possible)
  //   (2) inject entropy
  //   (3) update RW section
  if (task_.post_rw_jump || task_.inject_entropy ||
      (task_.update_rw &&
       fw_updater_->ValidKey() &&
       fw_updater_->CompareRollback() >= 0)) {
    // If we have just finished a jump to RW, but we're still in RO, then
    // we should log the failure.
    if (task_.post_rw_jump) {
      LOG(ERROR) << "Failed to jump to RW. Need to update RW section.";
      if (update_condition_ == UpdateCondition::kNever) {
        LOG(INFO) << "RW is broken but update condition is 'never', notify UI.";
        NotifyNeedUpdate();
        return HammerUpdater::RunStatus::kFatalError;
      }
      if (!fw_updater_->ValidKey() || fw_updater_->CompareRollback() < 0) {
        LOG(ERROR) << "RW section is unusable, but local image is "
                   << "incompatible. Giving up.";
        // If both key and rollback are invalid, only the key will be
        // reported to UMA as invalid.
        metrics_->SendEnumToUMA(
            kMetricRWUpdateResult,
            static_cast<int>(fw_updater_->ValidKey()
                ? RWUpdateResult::kRollbackDisallowed
                : RWUpdateResult::kInvalidKey),
            static_cast<int>(RWUpdateResult::kCount));
        return HammerUpdater::RunStatus::kFatalError;
      }
    }

    // EC is still running in RO section. Send "Stay in RO" command before
    // continuing.
    LOG(INFO) << "Sending stay in RO command.";
    if (!fw_updater_->SendSubcommand(UpdateExtraCommand::kStayInRO)) {
      LOG(ERROR) << "Failed to stay in RO.";
      return HammerUpdater::RunStatus::kNeedReset;
    }

    if (task_.inject_entropy) {
      bool ret = fw_updater_->InjectEntropy();
      if (ret) {
        task_.inject_entropy = false;
        LOG(INFO) << "Successfully injected entropy.";
        return HammerUpdater::RunStatus::kNeedReset;
      }
      LOG(ERROR) << "Failed to inject entropy.";
      return HammerUpdater::RunStatus::kFatalError;
    }

    if (fw_updater_->IsSectionLocked(SectionName::RW)) {
      LOG(INFO) << "Unlock RW section, and reset EC.";
      fw_updater_->UnlockRW();
      return HammerUpdater::RunStatus::kNeedReset;
    }

    // Now RW section needs an update, and it is not locked. Let's update!
    return UpdateRW();
  }

  // Now we need to jump to RW section.  When requesting 'Jump to RW', hammer
  // responds differently depending on the state of RO and RW locks:
  //   (1) RO is unlocked:
  //       hammerd will jump to RW regardless of wether or not RW is locked.
  //   (2) RO is locked:
  //       (a) RW is locked: hammer will jump to RW.
  //       (b) RW is unlocked: hammer will set RW to be locked on next boot, and
  //           reset itself.
  // In the case of (2)(b), after requesting the jump, hammer will reset itself
  // and end up in RO.  Now we fall under the case of (2)(1) and may request the
  // jump again.
  // TODO(b/117909308): add unittest.
  if (fw_updater_->IsSectionLocked(SectionName::RO) &&
      !fw_updater_->IsSectionLocked(SectionName::RW)) {
    if (task_.post_rw_lock) {
      LOG(INFO) << "Failed to lock RW section... update RW section again.";
      return UpdateRW();
    }
    LOG(INFO) << "RO is locked but RW is not. "
        << "Lock RW by asking hammer to reset.";
    return HammerUpdater::RunStatus::kNeedLock;
  }
  task_.post_rw_lock = false;

  LOG(INFO) << "No need to update RW. Jump to RW section.";
  return HammerUpdater::RunStatus::kNeedJump;
}

HammerUpdater::RunStatus HammerUpdater::PostRWProcess() {
  LOG(INFO) << "Start the post-RW process.";
  HammerUpdater::RunStatus ret;

  // Update RO section.
  ret = UpdateRO();
  if (ret != HammerUpdater::RunStatus::kNoUpdate) {
    return ret;
  }

  // Trigger the retry if update fails.
  ret = RunTouchpadUpdater();
  if (ret != HammerUpdater::RunStatus::kTouchpadUpToDate) {
    LOG(INFO) << "Touchpad update failure.";
    return ret;
  }

  // Pair with hammer.
  if (!at_boot_) {
    ret = Pair();
    if (ret != HammerUpdater::RunStatus::kNoUpdate) {
      return ret;
    }
  }

  // TODO(akahuang): Rollback increment.
  // All process are done.
  return HammerUpdater::RunStatus::kNoUpdate;
}

HammerUpdater::RunStatus HammerUpdater::UpdateRO() {
  // RO section should be unlocked on dogfood devices -- no need to first run
  // UnLockSection.
  // TODO(kitching): Consider adding a UI warning to make sure a dogfood user
  // does not detach the base at the wrong time, as that could brick it.
  if (fw_updater_->IsSectionLocked(SectionName::RO)) {
    LOG(INFO) << "RO section is locked. Update infeasible.";
    return HammerUpdater::RunStatus::kNoUpdate;
  }
  if (!task_.update_ro) {
    LOG(INFO) << "RO section is unlocked, but update not needed.";
    return HammerUpdater::RunStatus::kNoUpdate;
  }
  LOG(INFO) << "RO is unlocked and update is needed. Starting update.";
  NotifyUpdateStarted();
  bool ret = fw_updater_->TransferImage(SectionName::RO);
  task_.update_ro = !ret;
  metrics_->SendEnumToUMA(
      kMetricROUpdateResult,
      static_cast<int>(ret
          ? ROUpdateResult::kSucceeded
          : ROUpdateResult::kTransferFailed),
      static_cast<int>(ROUpdateResult::kCount));
  LOG(INFO) << "RO update " << (ret ? "passed." : "failed.");
  // In the case that the update failed, a reset will either brick the device,
  // or get it back into a normal state.
  return HammerUpdater::RunStatus::kNeedReset;
}

HammerUpdater::RunStatus HammerUpdater::Pair() {
  ChallengeStatus status = pair_manager_->PairChallenge(fw_updater_.get(),
                                                        dbus_wrapper_.get());
  PairResult metric_result = PairResult::kUnknownError;
  HammerUpdater::RunStatus ret = HammerUpdater::RunStatus::kFatalError;

  switch (status) {
    case ChallengeStatus::kChallengePassed:
      metric_result = PairResult::kChallengePassed;
      // TODO(akahuang): Check if the base is swapped.
      ret = HammerUpdater::RunStatus::kNoUpdate;
      break;

    case ChallengeStatus::kNeedInjectEntropy:
      metric_result = PairResult::kNeedInjectEntropy;
      if (fw_updater_->IsRollbackLocked()) {
        if (!fw_updater_->UnlockRollback()) {
          LOG(ERROR) << "Failed to unlock rollback. Skip injecting entropy.";
          ret = HammerUpdater::RunStatus::kFatalError;
          break;
        }
      }
      task_.inject_entropy = true;
      ret = HammerUpdater::RunStatus::kNeedReset;
      break;

    case ChallengeStatus::kChallengeFailed:
      metric_result = PairResult::kChallengeFailed;
      break;

    case ChallengeStatus::kConnectionError:
      // Do not send UMA if the base is disconnected.
      metric_result = PairResult::kCount;
      ret = HammerUpdater::RunStatus::kLostConnection;
      break;

    case ChallengeStatus::kUnknownError:
      break;
  }

  if (metric_result != PairResult::kCount) {
    metrics_->SendEnumToUMA(
        kMetricPairResult,
        static_cast<int>(metric_result),
        static_cast<int>(PairResult::kCount));
  }
  return ret;
}

void HammerUpdater::WaitUsbReady(HammerUpdater::RunStatus status) {
  // The time period after which hammer automatically jumps to RW section.
  constexpr unsigned int kJumpToRWTimeMs = 1000;
  // The time period from USB device ready to udev invoking hammerd.
  constexpr unsigned int kUdevGuardTimeMs = 1500;

  // If hammerd send reset or jump to RW signal at the last run, hammer will
  // re-connect to the AP and udev will trigger hammerd again. We MUST prohibit
  // the next invocation, otherwise udev will invoke hammerd infinitely.
  //
  // The timing of invocation might be entering into RO section or RW section.
  // Therefore we might wait for USB device once when sending JumpToRW, and wait
  // twice when sending Reset signal.
  if (status == HammerUpdater::RunStatus::kNeedReset ||
      status == HammerUpdater::RunStatus::kNeedJump) {
    LOG(INFO) << "Wait for USB device ready...";
    UsbConnectStatus usb_connection = fw_updater_->TryConnectUsb();
    fw_updater_->CloseUsb();
    // If there is no device there, don't bother waiting.
    if (usb_connection == UsbConnectStatus::kUsbPathEmpty) {
      return;
    }
    if (status == HammerUpdater::RunStatus::kNeedReset) {
      LOG(INFO) << "USB device probably in RO, waiting for it to enter RW.";
      base::PlatformThread::Sleep(
          base::TimeDelta::FromMilliseconds(kJumpToRWTimeMs));

      usb_connection = fw_updater_->TryConnectUsb();
      fw_updater_->CloseUsb();
      // If there is no device there, don't bother waiting.
      if (usb_connection == UsbConnectStatus::kUsbPathEmpty) {
        return;
      }
    }

    LOG(INFO) << "Now USB device should be in RW. Wait "
              << kUdevGuardTimeMs
              << "ms to prevent udev invoking next process.";
    base::PlatformThread::Sleep(
        base::TimeDelta::FromMilliseconds(kUdevGuardTimeMs));
    LOG(INFO) << "Finish the infinite loop prevention.";
  }
}

void HammerUpdater::NotifyNeedUpdate() {
  DCHECK(update_condition_ == UpdateCondition::kNever);
  if (!dbus_notified_) {
    dbus_notified_ = true;
    dbus_wrapper_->SendSignal(kBaseFirmwareNeedUpdateSignal);
  }
}

void HammerUpdater::NotifyUpdateStarted() {
  DCHECK(update_condition_ != UpdateCondition::kNever);
  if (!dbus_notified_) {
    dbus_notified_ = true;
    dbus_wrapper_->SendSignal(kBaseFirmwareUpdateStartedSignal);
  }
}

void HammerUpdater::NotifyUpdateFinished(bool is_success) {
  DCHECK(update_condition_ != UpdateCondition::kNever);
  // If we tried to update the firmware, send a signal to notify the updating is
  // finished.
  if (dbus_notified_) {
    dbus_notified_ = false;
    dbus_wrapper_->SendSignal(is_success ? kBaseFirmwareUpdateSucceededSignal
                                         : kBaseFirmwareUpdateFailedSignal);
  }
}

std::string HammerUpdater::VersionString(TouchpadInfo info) {
  std::string base_fw_ver;
  if (info.vendor == ST_VENDOR_ID) {
    base_fw_ver = base::StringPrintf(
      kStFormatString,
      info.st.fw_version & 0x00ff,
      (info.st.fw_version & 0xff00) >> 8);
  } else {
    base_fw_ver = base::StringPrintf(
      kElanFormatString, info.elan.fw_version);
  }
  return base_fw_ver;
}

std::string HammerUpdater::VendorString(TouchpadInfo info) {
  std::string vendor;
  switch (info.vendor) {
    case ST_VENDOR_ID:
      return "ST";
      break;
    case ELAN_VENDOR_ID:
      return "ELAN";
      break;
    default:
      return "UNKNOWN";
      break;
  }
}

HammerUpdater::RunStatus HammerUpdater::RunTouchpadUpdater() {
  if (!touchpad_image_.size()) {  // We are missing the touchpad file.
    LOG(INFO) << "Touchpad will remain unmodified as binary is not provided.";
    return HammerUpdater::RunStatus::kTouchpadUpToDate;
  }

  LOG(INFO) << "Loading touchpad firmware image.";
  if (!fw_updater_->LoadTouchpadImage(touchpad_image_)) {
    LOG(ERROR) << "Failed to load touchpad image.";
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  // Make request to get infomation from hammer.
  TouchpadInfo response;
  if (!fw_updater_->SendSubcommandReceiveResponse(
          UpdateExtraCommand::kTouchpadInfo, "",
          reinterpret_cast<void*>(&response),
          sizeof(response))) {
      LOG(ERROR) << "Not able to get touchpad info from base.";
      return HammerUpdater::RunStatus::kNeedReset;
  }
  LOG(INFO) << "Current touchpad information from base:";
  LOG(INFO) << "status: 0x" << std::hex << static_cast<int>(response.status);
  LOG(INFO) << "vendor: 0x" << std::hex << response.vendor <<
    " " << VendorString(response);
  LOG(INFO) << "fw_address: 0x" << std::hex << response.fw_address;
  LOG(INFO) << "fw_size: " << response.fw_size << " bytes";
  LOG(INFO) << "allowed_fw_hash: 0x" <<
      base::HexEncode(response.allowed_fw_hash, SHA256_DIGEST_LENGTH);
  LOG(INFO) << "product_id: " << response.elan.id << ".0";

  std::string base_fw_ver = VersionString(response);
  LOG(INFO) << "fw_ver: " << base_fw_ver;

  LOG(INFO) << "fw_checksum: 0x" << std::hex << response.elan.fw_checksum;

  if (response.status != static_cast<uint8_t>(EcResponseStatus::kSuccess)) {
    // EC must be really screw up to get this.
    LOG(ERROR) << "Base can't read I2C bus normally. Abort touchpad update.";
    return HammerUpdater::RunStatus::kNeedReset;
  }

  // Check if the image size matches IC size.
  if (touchpad_image_.size() != response.fw_size) {
    LOG(ERROR) << "Local touchpad binary doesn't match remote IC size.";
    LOG(ERROR) << "Local=" << touchpad_image_.size() << " bytes."
               << "Remote=" << response.fw_size << " bytes.";
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  // Check if the SHA value of the touchpad firmware (entire file) has same
  // hash as the record in RW firmware. We check this prior to update
  // because if an individual chunk verification fail, the touchpad might
  // get into a weird state (only part of the flash is updated).
  uint8_t digest[SHA256_DIGEST_LENGTH];

  SHA256(reinterpret_cast<const uint8_t*>(touchpad_image_.data()),
         response.fw_size, reinterpret_cast<unsigned char *>(&digest));
  LOG(INFO) << "Computed local touchpad firmware hash: 0x"
            << base::HexEncode(digest, SHA256_DIGEST_LENGTH);
  if (std::memcmp(digest, response.allowed_fw_hash, SHA256_DIGEST_LENGTH)) {
    LOG(ERROR) << "Touchpad firmware mismatches hash in RW EC.";
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  // Check if the product_id is matched. Currently, Elan uses numbers for
  // product_id, but it might be different for other vendors. For example,
  // in chromeos-touch-firmware-nyan package, Cypress uses product id like
  // CYTRA-103006-00.
  if (base::StringPrintf(kElanFormatString, response.elan.id) !=
      touchpad_product_id_) {
    LOG(ERROR) << "product_id mismatch. Local: " << touchpad_product_id_;
    return HammerUpdater::RunStatus::kTouchpadMismatched;
  }

  if (!task_.update_tp) {
    // If fw_ver match, then we skip the update. Otherwise, flash it.


    LOG(INFO) << base::StringPrintf(
        "Checking touchpad firmware version: Local(%s) vs. Base(%s)",
        touchpad_fw_ver_.c_str(), base_fw_ver.c_str());

    if (base_fw_ver == touchpad_fw_ver_) {
      LOG(INFO) << "Version matched, skip update.";
      return HammerUpdater::RunStatus::kTouchpadUpToDate;
    }
    // Version mismatches. However, if update condition is "never", then
    // we should notify UI when firmware is broken, or just skip update.
    if (update_condition_ == UpdateCondition::kNever) {
      if (response.elan.fw_version == kElanBrokenFwVersion) {
        LOG(INFO) << "Touchpad firmware is broken but never update, notify UI.";
        NotifyNeedUpdate();
        return HammerUpdater::RunStatus::kTouchpadMismatched;
      }
      LOG(INFO) << "Pretend touchpad firmware is up to date.";
      return HammerUpdater::RunStatus::kTouchpadUpToDate;
    }
    // OK, we really need to update touchpad now.
    task_.update_tp = true;
  }
  LOG(INFO) << "Update touchpad firmware, notify UI";
  NotifyUpdateStarted();
  bool ret = fw_updater_->TransferTouchpadFirmware(
      response.fw_address, response.fw_size);
  task_.update_tp = !ret;
  return ret ? HammerUpdater::RunStatus::kTouchpadUpToDate
             : HammerUpdater::RunStatus::kNeedReset;
}

bool HammerUpdater::ParseTouchpadInfoFromFilename(
      const std::string& filename,
      std::string* touchpad_product_id,
      std::string* touchpad_fw_ver) {
  base::FilePath real_path;
  bool ret = base::NormalizeFilePath(base::FilePath(filename), &real_path);
  std::string basename = real_path.BaseName().value();

  LOG(INFO) << "Canonical path for touchpad firmware : " << real_path.value();
  // Filename should be in format of <product_id>_<fw_ver>.bin
  pcrecpp::RE re("(.+)_([\\.\\d]+?)\\.bin");
  ret &= re.FullMatch(basename, touchpad_product_id, touchpad_fw_ver);
  LOG(INFO) << "Parsed product_id : " << *touchpad_product_id;
  LOG(INFO) << "Parsed fw_ver : " << *touchpad_fw_ver;

  return ret;
}

void HammerUpdater::SetInjectEntropyFlag(bool inject_entropy) {
  LOG(INFO) << "inject_entropy is set to " << inject_entropy;
  task_.inject_entropy = inject_entropy;
}

}  // namespace hammerd
