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