blob: 21430f81520a4aa589e0f9ed133131cb9ba0540e [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/modem.h"
#include "modemfwd/modem_helper.h"
namespace modemfwd {
ModemFlasher::ModemFlasher(
std::unique_ptr<ModemHelperDirectory> helper_directory,
std::unique_ptr<FirmwareDirectory> firmware_directory)
: helper_directory_(std::move(helper_directory)),
firmware_directory_(std::move(firmware_directory)) {
}
void ModemFlasher::TryFlash(Modem* modem) {
std::string equipment_id = modem->GetEquipmentId();
if (ContainsValue(blacklist_, equipment_id)) {
LOG(WARNING) << "Modem with equipment ID " << equipment_id
<< " is blacklisted; not flashing";
return;
}
std::string device_id = modem->GetDeviceId();
ModemHelper* helper = helper_directory_->GetHelperForDeviceId(device_id);
if (!helper) {
LOG(WARNING) << "No helper found to update modems with ID ["
<< device_id << "]";
return;
}
FirmwareFileInfo file_info;
// Check if we need to update the main firmware.
if (!ContainsValue(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()) {
// 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.
if (helper->FlashMainFirmware(file_info.firmware_path)) {
main_fw_checked_.insert(equipment_id);
DLOG(INFO) << "Flashed " << file_info.firmware_path.value()
<< " to the modem";
} else {
blacklist_.insert(equipment_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.
CarrierFirmwareInfo carrier_fw_info;
bool has_carrier_fw = helper->GetCarrierFirmwareInfo(&carrier_fw_info);
if (has_carrier_fw) {
DLOG(INFO) << "Currently installed carrier firmware version "
<< carrier_fw_info.version << " for carrier "
<< carrier_fw_info.carrier_name;
} else {
DLOG(INFO) << "No carrier firmware is currently installed";
}
if (!has_carrier_fw ||
carrier_fw_info.carrier_name != current_carrier ||
carrier_fw_info.version != file_info.version) {
if (helper->FlashCarrierFirmware(file_info.firmware_path)) {
last_carrier_fw_flashed_.insert(
std::make_pair(equipment_id, file_info.firmware_path));
DLOG(INFO) << "Flashed " << file_info.firmware_path.value()
<< " to the modem";
} else {
blacklist_.insert(equipment_id);
}
}
}
} // namespace modemfwd