blob: 1b0e7f539ae8882d6cf38ce2f3361ce960e2e694 [file] [log] [blame]
// Copyright 2018 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.
#ifndef BIOD_CROS_FP_DEVICE_H_
#define BIOD_CROS_FP_DEVICE_H_
#include <bitset>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_util.h>
#include "biod/biod_metrics.h"
#include "biod/cros_fp_device_interface.h"
#include "biod/ec_command_factory.h"
#include "biod/fp_info_command.h"
#include "biod/fp_mode.h"
#include "biod/uinput_device.h"
namespace biod {
class CrosFpDevice : public CrosFpDeviceInterface {
public:
static std::unique_ptr<CrosFpDevice> Create(
BiodMetricsInterface* biod_metrics,
std::unique_ptr<EcCommandFactoryInterface> ec_command_factory) {
// Using new to access non-public constructor.
// See https://abseil.io/tips/134.
auto dev = base::WrapUnique(
new CrosFpDevice(biod_metrics, std::move(ec_command_factory)));
if (!dev->Init()) {
return nullptr;
}
return dev;
}
void SetMkbpEventCallback(MkbpCallback callback) override;
// Run a simple command to get the version information from FP MCU and check
// whether the image type returned is the same as |expected_image|.
static bool WaitOnEcBoot(const base::ScopedFD& cros_fp_fd,
ec_current_image expected_image);
// Run a simple command to get the version information from FP MCU.
// The retrieved version is written to |ver|.
// Returns true if successfully retrieved the version.
static bool GetVersion(const base::ScopedFD& cros_fp_fd, EcVersion* ver);
// CrosFpDeviceInterface overrides:
~CrosFpDevice() override;
bool SetFpMode(const FpMode& mode) override;
bool GetFpMode(FpMode* mode) override;
bool GetFpStats(int* capture_ms, int* matcher_ms, int* overall_ms) override;
bool GetDirtyMap(std::bitset<32>* bitmap) override;
bool SupportsPositiveMatchSecret() override;
bool GetPositiveMatchSecret(int index, brillo::SecureBlob* secret) override;
bool GetTemplate(int index, VendorTemplate* out) override;
bool UploadTemplate(const VendorTemplate& tmpl) override;
bool SetContext(std::string user_id) override;
bool ResetContext() override;
// Initialise the entropy in the SBP. If |reset| is true, the old entropy
// will be deleted. If |reset| is false, we will only add entropy, and only
// if no entropy had been added before.
bool InitEntropy(bool reset) override;
bool UpdateFpInfo() override;
int MaxTemplateCount() override;
int TemplateVersion() override;
int DeadPixelCount() override;
EcCmdVersionSupportStatus EcCmdVersionSupported(uint16_t cmd,
uint32_t ver) override;
// Kernel device exposing the MCU command interface.
static constexpr char kCrosFpPath[] = "/dev/cros_fp";
// Although very rare, we have seen device commands fail due
// to ETIMEDOUT. For this reason, we attempt certain critical
// device IO operation twice.
static constexpr int kMaxIoAttempts = 2;
static constexpr int kLastTemplate = -1;
protected:
CrosFpDevice(BiodMetricsInterface* biod_metrics,
std::unique_ptr<EcCommandFactoryInterface> ec_command_factory)
: ec_command_factory_(std::move(ec_command_factory)),
biod_metrics_(biod_metrics) {}
bool Init();
private:
bool EcDevInit();
ssize_t ReadVersion(char* buffer, size_t size);
bool EcProtoInfo(ssize_t* max_read, ssize_t* max_write);
bool EcReboot(ec_current_image to_image);
// Run the EC command to generate new entropy in the underlying MCU.
// |reset| specifies whether we want to merely add entropy (false), or
// perform a reset, which erases old entropy(true).
bool AddEntropy(bool reset);
// Get block id from rollback info.
bool GetRollBackInfoId(int32_t* block_id);
bool FpFrame(int index, std::vector<uint8_t>* frame);
bool FpReadMatchSecret(uint16_t index, brillo::SecureBlob* secret);
bool GetIndexOfLastTemplate(int* index);
// Run a sequence of EC commands to update the entropy in the
// MCU. If |reset| is set to true, it will additionally erase the existing
// entropy too.
bool UpdateEntropy(bool reset);
std::unique_ptr<struct ec_response_flash_protect> GetFlashProtect();
void OnEventReadable();
base::ScopedFD cros_fd_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;
ssize_t max_read_size_ = 0;
ssize_t max_write_size_ = 0;
std::unique_ptr<FpInfoCommand> info_;
std::unique_ptr<EcCommandFactoryInterface> ec_command_factory_;
MkbpCallback mkbp_event_;
UinputDevice input_device_;
BiodMetricsInterface* biod_metrics_ = nullptr; // Not owned.
};
} // namespace biod
#endif // BIOD_CROS_FP_DEVICE_H_