1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 #include "host/commands/modem_simulator/modem_simulator.h"
17
18 #include <android-base/logging.h>
19
20 #include <memory>
21
22 #include "host/commands/modem_simulator/call_service.h"
23 #include "host/commands/modem_simulator/data_service.h"
24 #include "host/commands/modem_simulator/misc_service.h"
25 #include "host/commands/modem_simulator/network_service.h"
26 #include "host/commands/modem_simulator/sim_service.h"
27 #include "host/commands/modem_simulator/sms_service.h"
28 #include "host/commands/modem_simulator/stk_service.h"
29 #include "host/commands/modem_simulator/sup_service.h"
30
31 namespace cuttlefish {
32
ModemSimulator(int32_t modem_id)33 ModemSimulator::ModemSimulator(int32_t modem_id)
34 : modem_id_(modem_id), thread_looper_(new ThreadLooper()) {}
35
~ModemSimulator()36 ModemSimulator::~ModemSimulator() {
37 // this will stop the looper so all the callbacks
38 // will be gone;
39 thread_looper_->Stop();
40 modem_services_.clear();
41 }
42
LoadNvramConfig()43 void ModemSimulator::LoadNvramConfig() {
44 auto nvram_config = NvramConfig::Get();
45 if (!nvram_config) {
46 LOG(FATAL) << "Failed to obtain nvram config singleton";
47 return;
48 }
49 }
50
Initialize(std::unique_ptr<ChannelMonitor> && channel_monitor)51 void ModemSimulator::Initialize(
52 std::unique_ptr<ChannelMonitor>&& channel_monitor) {
53 channel_monitor_ = std::move(channel_monitor);
54 LoadNvramConfig();
55 RegisterModemService();
56 }
57
RegisterModemService()58 void ModemSimulator::RegisterModemService() {
59 auto networkservice = std::make_unique<NetworkService>(
60 modem_id_, channel_monitor_.get(), thread_looper_.get());
61 auto simservice = std::make_unique<SimService>(
62 modem_id_, channel_monitor_.get(), thread_looper_.get());
63 auto miscservice = std::make_unique<MiscService>(
64 modem_id_, channel_monitor_.get(), thread_looper_.get());
65 auto callservice = std::make_unique<CallService>(
66 modem_id_, channel_monitor_.get(), thread_looper_.get());
67 auto stkservice = std::make_unique<StkService>(
68 modem_id_, channel_monitor_.get(), thread_looper_.get());
69 auto smsservice = std::make_unique<SmsService>(
70 modem_id_, channel_monitor_.get(), thread_looper_.get());
71 auto dataservice = std::make_unique<DataService>(
72 modem_id_, channel_monitor_.get(), thread_looper_.get());
73 auto supservice = std::make_unique<SupService>(
74 modem_id_, channel_monitor_.get(), thread_looper_.get());
75
76 networkservice->SetupDependency(miscservice.get(), simservice.get(),
77 dataservice.get());
78 simservice->SetupDependency(networkservice.get());
79 callservice->SetupDependency(simservice.get(), networkservice.get());
80 stkservice->SetupDependency(simservice.get());
81 smsservice->SetupDependency(simservice.get());
82
83 sms_service_ = smsservice.get();
84 sim_service_ = simservice.get();
85 misc_service_ = miscservice.get();
86 network_service_ = networkservice.get();
87 modem_services_[kSimService] = std::move(simservice);
88 modem_services_[kNetworkService] = std::move(networkservice);
89 modem_services_[kCallService] = std::move(callservice);
90 modem_services_[kDataService] = std::move(dataservice);
91 modem_services_[kSmsService] = std::move(smsservice);
92 modem_services_[kSupService] = std::move(supservice);
93 modem_services_[kStkService] = std::move(stkservice);
94 modem_services_[kMiscService] = std::move(miscservice);
95 }
96
DispatchCommand(const Client & client,std::string & command)97 void ModemSimulator::DispatchCommand(const Client& client, std::string& command) {
98 if (sms_service_) {
99 if (sms_service_->IsWaitingSmsPdu()) {
100 sms_service_->HandleSendSMSPDU(client, command);
101 return;
102 } else if (sms_service_->IsWaitingSmsToSim()) {
103 sms_service_->HandleWriteSMSPduToSim(client, command);
104 return;
105 }
106 }
107
108 bool success = false;
109 for (auto& service : modem_services_) {
110 success = service.second->HandleModemCommand(client, command);
111 if (success) {
112 break;
113 }
114 }
115
116 if (!success && client.Type() != Client::REMOTE) {
117 LOG(DEBUG) << "Not supported AT command: " << command;
118 client.SendCommandResponse(ModemService::kCmeErrorOperationNotSupported);
119 }
120 }
121
OnFirstClientConnected()122 void ModemSimulator::OnFirstClientConnected() {
123 if (misc_service_) {
124 misc_service_->TimeUpdate();
125 }
126
127 if (network_service_) {
128 network_service_->OnVoiceRegisterStateChanged();
129 network_service_->OnDataRegisterStateChanged();
130 }
131 }
132
SaveModemState()133 void ModemSimulator::SaveModemState() {
134 if (sim_service_) {
135 sim_service_->SavePinStateToIccProfile();
136 sim_service_->SaveFacilityLockToIccProfile();
137 }
138 }
139
IsRadioOn() const140 bool ModemSimulator::IsRadioOn() const {
141 if (network_service_) {
142 return !network_service_->isRadioOff();
143 }
144 return false;
145 }
146
IsWaitingSmsPdu()147 bool ModemSimulator::IsWaitingSmsPdu() {
148 if (sms_service_) {
149 return (sms_service_->IsWaitingSmsPdu() ||
150 sms_service_->IsWaitingSmsToSim());
151 }
152 return false;
153 }
154
SetTimeZone(std::string timezone)155 void ModemSimulator::SetTimeZone(std::string timezone) {
156 if (misc_service_) {
157 misc_service_->SetTimeZone(timezone);
158 }
159 }
160
SetPhoneNumber(std::string_view number)161 bool ModemSimulator::SetPhoneNumber(std::string_view number) {
162 if (sim_service_) {
163 return sim_service_->SetPhoneNumber(number);
164 }
165 return false;
166 }
167
168 } // namespace cuttlefish
169