blob: 2b3bf86562ab21533443f3b11753e87e9693b379 [file] [log] [blame]
// Copyright 2020 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 "biod/updater/update_utils.h"
#include <optional>
#include <string>
#include <string_view>
#include <base/files/file_enumerator.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/notreached.h>
#include <base/optional.h>
#include <brillo/vcsid.h>
#include <cros_config/cros_config_interface.h>
#include "biod/biod_config.h"
namespace {
constexpr char kFirmwareGlobSuffix[] = "_*.bin";
constexpr char kFirmwareLegacyBoardPattern[] = "*_fp";
constexpr char kUpdateDisableFile[] = "/opt/google/biod/fw/.disable_fp_updater";
} // namespace
namespace biod {
namespace updater {
constexpr char kFirmwareDir[] = "/opt/google/biod/fw";
std::string UpdaterVersion() {
CHECK(brillo::kVCSID) << "The updater requires VCSID to function properly.";
return std::string(*brillo::kVCSID);
}
bool UpdateDisallowed() {
return base::PathExists(base::FilePath(kUpdateDisableFile));
}
// FindFirmwareFile searches |directory| for a single firmware file
// that matches the |board_name|+|kFirmwareGlobSuffix| file pattern.
// If a single matching firmware file is found is found,
// its path is written to |file|. Otherwise, |file| will be untouched.
static FindFirmwareFileStatus FindFirmwareFile(const base::FilePath& directory,
const std::string& board_name,
base::FilePath* file) {
if (!base::DirectoryExists(directory)) {
return FindFirmwareFileStatus::kNoDirectory;
}
std::string glob(board_name + std::string(kFirmwareGlobSuffix));
base::FileEnumerator fw_bin_list(directory, false,
base::FileEnumerator::FileType::FILES, glob);
// Find provided firmware file
base::FilePath fw_bin = fw_bin_list.Next();
if (fw_bin.empty()) {
return FindFirmwareFileStatus::kFileNotFound;
}
LOG(INFO) << "Found firmware file '" << fw_bin.value() << "'.";
// Ensure that there are no other firmware files
bool extra_fw_files = false;
for (base::FilePath fw_extra = fw_bin_list.Next(); !fw_extra.empty();
fw_extra = fw_bin_list.Next()) {
extra_fw_files = true;
LOG(ERROR) << "Found firmware file '" << fw_extra.value() << "'.";
}
if (extra_fw_files) {
return FindFirmwareFileStatus::kMultipleFiles;
}
*file = fw_bin;
return FindFirmwareFileStatus::kFoundFile;
}
FindFirmwareFileStatus FindFirmwareFile(
const base::FilePath& directory,
brillo::CrosConfigInterface* cros_config,
base::FilePath* file) {
base::Optional<std::string> board_name = biod::FingerprintBoard(cros_config);
if (board_name) {
LOG(INFO) << "Identified fingerprint board name as '" << *board_name
<< "'.";
} else {
LOG(WARNING) << "Fingerprint board name is unavailable, continuing with "
"legacy update.";
board_name = kFirmwareLegacyBoardPattern;
}
return FindFirmwareFile(directory, *board_name, file);
}
std::string FindFirmwareFileStatusToString(FindFirmwareFileStatus status) {
switch (status) {
case FindFirmwareFileStatus::kFoundFile:
return "Firmware file found.";
case FindFirmwareFileStatus::kNoDirectory:
return "Firmware directory does not exist.";
case FindFirmwareFileStatus::kFileNotFound:
return "Firmware file not found.";
case FindFirmwareFileStatus::kMultipleFiles:
return "More than one firmware file was found.";
}
NOTREACHED();
return "Unknown find firmware file status encountered.";
}
} // namespace updater
} // namespace biod