blob: 61a23bd1beae9d42713ecc37e109733c71d43e47 [file] [log] [blame]
//
// 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/modem_simulator.h"
#include <android-base/logging.h>
#include <memory>
#include "host/commands/modem_simulator/call_service.h"
#include "host/commands/modem_simulator/data_service.h"
#include "host/commands/modem_simulator/misc_service.h"
#include "host/commands/modem_simulator/network_service.h"
#include "host/commands/modem_simulator/sim_service.h"
#include "host/commands/modem_simulator/sms_service.h"
#include "host/commands/modem_simulator/stk_service.h"
#include "host/commands/modem_simulator/sup_service.h"
namespace cuttlefish {
ModemSimulator::ModemSimulator(int32_t modem_id)
: modem_id_(modem_id), thread_looper_(new ThreadLooper()) {}
ModemSimulator::~ModemSimulator() {
// this will stop the looper so all the callbacks
// will be gone;
thread_looper_->Stop();
modem_services_.clear();
}
void ModemSimulator::LoadNvramConfig() {
auto nvram_config = NvramConfig::Get();
if (!nvram_config) {
LOG(FATAL) << "Failed to obtain nvram config singleton";
return;
}
}
void ModemSimulator::Initialize(
std::unique_ptr<ChannelMonitor>&& channel_monitor) {
channel_monitor_ = std::move(channel_monitor);
LoadNvramConfig();
RegisterModemService();
}
void ModemSimulator::RegisterModemService() {
auto networkservice = std::make_unique<NetworkService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto simservice = std::make_unique<SimService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto miscservice = std::make_unique<MiscService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto callservice = std::make_unique<CallService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto stkservice = std::make_unique<StkService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto smsservice = std::make_unique<SmsService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto dataservice = std::make_unique<DataService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
auto supservice = std::make_unique<SupService>(
modem_id_, channel_monitor_.get(), thread_looper_.get());
networkservice->SetupDependency(miscservice.get(), simservice.get(),
dataservice.get());
simservice->SetupDependency(networkservice.get());
callservice->SetupDependency(simservice.get(), networkservice.get());
stkservice->SetupDependency(simservice.get());
smsservice->SetupDependency(simservice.get());
sms_service_ = smsservice.get();
sim_service_ = simservice.get();
misc_service_ = miscservice.get();
network_service_ = networkservice.get();
modem_services_[kSimService] = std::move(simservice);
modem_services_[kNetworkService] = std::move(networkservice);
modem_services_[kCallService] = std::move(callservice);
modem_services_[kDataService] = std::move(dataservice);
modem_services_[kSmsService] = std::move(smsservice);
modem_services_[kSupService] = std::move(supservice);
modem_services_[kStkService] = std::move(stkservice);
modem_services_[kMiscService] = std::move(miscservice);
}
void ModemSimulator::DispatchCommand(const Client& client, std::string& command) {
if (sms_service_) {
if (sms_service_->IsWaitingSmsPdu()) {
sms_service_->HandleSendSMSPDU(client, command);
return;
} else if (sms_service_->IsWaitingSmsToSim()) {
sms_service_->HandleWriteSMSPduToSim(client, command);
return;
}
}
bool success = false;
for (auto& service : modem_services_) {
success = service.second->HandleModemCommand(client, command);
if (success) {
break;
}
}
if (!success && client.type != Client::REMOTE) {
LOG(DEBUG) << "Not supported AT command: " << command;
client.SendCommandResponse(ModemService::kCmeErrorOperationNotSupported);
}
}
void ModemSimulator::OnFirstClientConnected() {
if (misc_service_) {
misc_service_->TimeUpdate();
}
if (network_service_) {
network_service_->OnVoiceRegisterStateChanged();
network_service_->OnDataRegisterStateChanged();
}
}
void ModemSimulator::SaveModemState() {
if (sim_service_) {
sim_service_->SavePinStateToIccProfile();
sim_service_->SaveFacilityLockToIccProfile();
}
}
bool ModemSimulator::IsRadioOn() const {
if (network_service_) {
return !network_service_->isRadioOff();
}
return false;
}
bool ModemSimulator::IsWaitingSmsPdu() {
if (sms_service_) {
return (sms_service_->IsWaitingSmsPdu() |
sms_service_->IsWaitingSmsToSim());
}
return false;
}
void ModemSimulator::SetTimeZone(std::string timezone) {
if (misc_service_) {
misc_service_->SetTimeZone(timezone);
}
}
} // namespace cuttlefish