blob: 5aead12c0d88a9f1530ede8d33661872493b184f [file] [log] [blame]
// 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.
#include "modemfwd/modem_flasher.h"
#include <memory>
#include <utility>
#include <base/stl_util.h>
#include "modemfwd/firmware_file.h"
#include "modemfwd/modem.h"
namespace modemfwd {
ModemFlasher::ModemFlasher(
std::unique_ptr<FirmwareDirectory> firmware_directory,
std::unique_ptr<Journal> journal)
: firmware_directory_(std::move(firmware_directory)),
journal_(std::move(journal)) {}
void ModemFlasher::TryFlash(Modem* modem) {
std::string equipment_id = modem->GetEquipmentId();
if (base::ContainsKey(blacklist_, equipment_id)) {
LOG(WARNING) << "Modem with equipment ID \"" << equipment_id
<< "\" is blacklisted; not flashing";
return;
}
std::string device_id = modem->GetDeviceId();
FirmwareFileInfo file_info;
// Check if we need to update the main firmware.
if (!base::ContainsKey(main_fw_checked_, equipment_id) &&
firmware_directory_->FindMainFirmware(device_id, &file_info)) {
DLOG(INFO) << "Found main firmware blob " << file_info.version
<< ", currently installed main firmware version: "
<< modem->GetMainFirmwareVersion();
if (file_info.version != modem->GetMainFirmwareVersion()) {
FirmwareFile firmware_file;
if (!firmware_file.PrepareFrom(file_info))
return;
// We found different firmware! Flash the modem, and since it will
// reboot afterwards, we can wait to get called again to check the
// carrier firmware.
journal_->MarkStartOfFlashingMainFirmware(device_id);
if (modem->FlashMainFirmware(firmware_file.path_on_filesystem())) {
// Refer to |firmware_file.path_for_logging()| in the log and journal.
main_fw_checked_.insert(equipment_id);
DLOG(INFO) << "Flashed " << firmware_file.path_for_logging().value()
<< " to the modem";
} else {
blacklist_.insert(equipment_id);
}
journal_->MarkEndOfFlashingMainFirmware(device_id);
return;
}
}
// We don't need to check the main firmware again if there's nothing new.
main_fw_checked_.insert(equipment_id);
// If there's no SIM, we can stop here.
std::string current_carrier = modem->GetCarrierId();
if (current_carrier.empty()) {
DLOG(INFO) << "No carrier found. Is a SIM card inserted?";
return;
}
// Check if we have carrier firmware matching the SIM's carrier. If not,
// there's nothing to flash.
if (!firmware_directory_->FindCarrierFirmware(device_id, &current_carrier,
&file_info)) {
DLOG(INFO) << "No carrier firmware found for carrier " << current_carrier;
return;
}
auto it = last_carrier_fw_flashed_.find(equipment_id);
if (it != last_carrier_fw_flashed_.end() &&
it->second == file_info.firmware_path) {
DLOG(INFO) << "Already flashed carrier firmware for " << current_carrier;
return;
}
DLOG(INFO) << "Found carrier firmware blob " << file_info.version
<< " for carrier " << current_carrier;
// Carrier firmware operates a bit differently. We need to flash if
// the carrier or the version has changed, or if there wasn't any carrier
// firmware to begin with.
std::string carrier_fw_id = modem->GetCarrierFirmwareId();
std::string carrier_fw_version = modem->GetCarrierFirmwareVersion();
bool has_carrier_fw = !(carrier_fw_id.empty() || carrier_fw_version.empty());
if (has_carrier_fw) {
DLOG(INFO) << "Currently installed carrier firmware version "
<< carrier_fw_version << " for carrier " << carrier_fw_id;
} else {
DLOG(INFO) << "No carrier firmware is currently installed";
}
if (!has_carrier_fw || carrier_fw_id != current_carrier ||
carrier_fw_version != file_info.version) {
FirmwareFile firmware_file;
if (!firmware_file.PrepareFrom(file_info))
return;
journal_->MarkStartOfFlashingCarrierFirmware(device_id, current_carrier);
if (modem->FlashCarrierFirmware(firmware_file.path_on_filesystem())) {
// Refer to |firmware_file.path_for_logging()| in the log and journal.
last_carrier_fw_flashed_.insert(
std::make_pair(equipment_id, firmware_file.path_for_logging()));
DLOG(INFO) << "Flashed " << firmware_file.path_for_logging().value()
<< " to the modem";
} else {
blacklist_.insert(equipment_id);
}
journal_->MarkEndOfFlashingCarrierFirmware(device_id, current_carrier);
}
}
} // namespace modemfwd