201 lines
6.5 KiB
C++
201 lines
6.5 KiB
C++
//
|
|
// Copyright (C) 2020 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "host/commands/modem_simulator/nvram_config.h"
|
|
|
|
#include <android-base/logging.h>
|
|
#include <json/json.h>
|
|
|
|
#include <fstream>
|
|
#include <mutex>
|
|
#include <sstream>
|
|
|
|
#include "common/libs/utils/files.h"
|
|
#include "host/commands/modem_simulator/device_config.h"
|
|
|
|
namespace cuttlefish {
|
|
|
|
const char* kInstances = "instances";
|
|
const char* kNetworkSelectionMode = "network_selection_mode";
|
|
const char* kOperatorNumeric = "operator_numeric";
|
|
const char* kModemTechnoloy = "modem_technoloy";
|
|
const char* kPreferredNetworkMode = "preferred_network_mode";
|
|
const char* kEmergencyMode = "emergency_mode";
|
|
const char* kSimType = "sim_type";
|
|
|
|
const int kDefaultNetworkSelectionMode = 0; // AUTOMATIC
|
|
const std::string kDefaultOperatorNumeric = "";
|
|
const int kDefaultModemTechnoloy = 0x10; // LTE
|
|
const int kDefaultPreferredNetworkMode = 0x13; // LTE | WCDMA | GSM
|
|
const bool kDefaultEmergencyMode = false;
|
|
|
|
/**
|
|
* Creates the (initially empty) config object and populates it with values from
|
|
* the config file "modem_nvram.json" located in the cuttlefish instance path,
|
|
* or uses the default value if the config file not exists,
|
|
* Returns nullptr if there was an error loading from file
|
|
*/
|
|
NvramConfig* NvramConfig::BuildConfigImpl(size_t num_instances, int sim_type) {
|
|
auto nvram_config_path =
|
|
cuttlefish::modem::DeviceConfig::PerInstancePath("modem_nvram.json");
|
|
|
|
auto ret = new NvramConfig(num_instances, sim_type);
|
|
if (ret) {
|
|
if (!cuttlefish::FileExists(nvram_config_path) ||
|
|
!cuttlefish::FileHasContent(nvram_config_path.c_str())) {
|
|
ret->InitDefaultNvramConfig();
|
|
} else {
|
|
auto loaded = ret->LoadFromFile(nvram_config_path.c_str());
|
|
if (!loaded) {
|
|
delete ret;
|
|
return nullptr;
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
std::unique_ptr<NvramConfig> NvramConfig::s_nvram_config;
|
|
|
|
void NvramConfig::InitNvramConfigService(size_t num_instances, int sim_type) {
|
|
static std::once_flag once_flag;
|
|
|
|
std::call_once(once_flag, [num_instances, sim_type]() {
|
|
NvramConfig::s_nvram_config.reset(BuildConfigImpl(num_instances, sim_type));
|
|
});
|
|
}
|
|
|
|
/* static */ const NvramConfig* NvramConfig::Get() {
|
|
return s_nvram_config.get();
|
|
}
|
|
|
|
void NvramConfig::SaveToFile() {
|
|
auto nvram_config = Get();
|
|
auto nvram_config_file = nvram_config->ConfigFileLocation();
|
|
nvram_config->SaveToFile(nvram_config_file);
|
|
}
|
|
|
|
NvramConfig::NvramConfig(size_t num_instances, int sim_type)
|
|
: total_instances_(num_instances),
|
|
sim_type_(sim_type),
|
|
dictionary_(new Json::Value()) {}
|
|
// Can't use '= default' on the header because the compiler complains of
|
|
// Json::Value being an incomplete type
|
|
NvramConfig::~NvramConfig() = default;
|
|
|
|
NvramConfig::NvramConfig(NvramConfig&&) = default;
|
|
NvramConfig& NvramConfig::operator=(NvramConfig&&) = default;
|
|
|
|
NvramConfig::InstanceSpecific NvramConfig::ForInstance(int num) const {
|
|
return InstanceSpecific(this, std::to_string(num));
|
|
}
|
|
|
|
std::string NvramConfig::ConfigFileLocation() const {
|
|
return cuttlefish::AbsolutePath(
|
|
cuttlefish::modem::DeviceConfig::PerInstancePath("modem_nvram.json"));
|
|
}
|
|
|
|
bool NvramConfig::LoadFromFile(const char* file) {
|
|
auto real_file_path = cuttlefish::AbsolutePath(file);
|
|
if (real_file_path.empty()) {
|
|
LOG(ERROR) << "Could not get real path for file " << file;
|
|
return false;
|
|
}
|
|
|
|
Json::CharReaderBuilder builder;
|
|
std::ifstream ifs = modem::DeviceConfig::open_ifstream_crossplat(real_file_path.c_str());
|
|
std::string errorMessage;
|
|
if (!Json::parseFromStream(builder, ifs, dictionary_.get(), &errorMessage)) {
|
|
LOG(ERROR) << "Could not read config file " << file << ": "
|
|
<< errorMessage;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool NvramConfig::SaveToFile(const std::string& file) const {
|
|
std::ofstream ofs = modem::DeviceConfig::open_ofstream_crossplat(file.c_str());
|
|
if (!ofs.is_open()) {
|
|
LOG(ERROR) << "Unable to write to file " << file;
|
|
return false;
|
|
}
|
|
ofs << *dictionary_;
|
|
return !ofs.fail();
|
|
}
|
|
|
|
void NvramConfig::InitDefaultNvramConfig() {
|
|
for (size_t num = 0; num < total_instances_; num++) {
|
|
auto instance = ForInstance(num);
|
|
instance.set_modem_technoloy(kDefaultModemTechnoloy);
|
|
instance.set_network_selection_mode(kDefaultNetworkSelectionMode);
|
|
instance.set_preferred_network_mode(kDefaultPreferredNetworkMode);
|
|
instance.set_emergency_mode(kDefaultEmergencyMode);
|
|
}
|
|
}
|
|
|
|
const Json::Value* NvramConfig::InstanceSpecific::Dictionary() const {
|
|
return &(*config_->dictionary_)[kInstances][id_];
|
|
}
|
|
|
|
Json::Value* NvramConfig::InstanceSpecific::Dictionary() {
|
|
return &(*config_->dictionary_)[kInstances][id_];
|
|
}
|
|
|
|
int NvramConfig::InstanceSpecific::network_selection_mode() const {
|
|
return (*Dictionary())[kNetworkSelectionMode].asInt();
|
|
}
|
|
|
|
void NvramConfig::InstanceSpecific::set_network_selection_mode(int mode) {
|
|
(*Dictionary())[kNetworkSelectionMode] = mode;
|
|
}
|
|
|
|
std::string NvramConfig::InstanceSpecific::operator_numeric() const {
|
|
return (*Dictionary())[kOperatorNumeric].asString();
|
|
}
|
|
|
|
void NvramConfig::InstanceSpecific::set_operator_numeric(std::string& operator_numeric) {
|
|
(*Dictionary())[kOperatorNumeric] = operator_numeric;
|
|
}
|
|
|
|
int NvramConfig::InstanceSpecific::modem_technoloy() const {
|
|
return (*Dictionary())[kModemTechnoloy].asInt();
|
|
}
|
|
|
|
void NvramConfig::InstanceSpecific::set_modem_technoloy(int technoloy) {
|
|
(*Dictionary())[kModemTechnoloy] = technoloy;
|
|
}
|
|
|
|
int NvramConfig::InstanceSpecific::preferred_network_mode() const {
|
|
return (*Dictionary())[kPreferredNetworkMode].asInt();
|
|
}
|
|
|
|
void NvramConfig::InstanceSpecific::set_preferred_network_mode(int mode) {
|
|
(*Dictionary())[kPreferredNetworkMode] = mode;
|
|
}
|
|
|
|
bool NvramConfig::InstanceSpecific::emergency_mode() const {
|
|
return (*Dictionary())[kEmergencyMode].asBool();
|
|
}
|
|
|
|
void NvramConfig::InstanceSpecific::set_emergency_mode(bool mode) {
|
|
(*Dictionary())[kEmergencyMode] = mode;
|
|
}
|
|
|
|
int NvramConfig::sim_type() const {
|
|
return sim_type_;
|
|
}
|
|
|
|
} // namespace cuttlefish
|