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 <memory>
19
20 #include "host/commands/modem_simulator/call_service.h"
21 #include "host/commands/modem_simulator/data_service.h"
22 #include "host/commands/modem_simulator/misc_service.h"
23 #include "host/commands/modem_simulator/network_service.h"
24 #include "host/commands/modem_simulator/sim_service.h"
25 #include "host/commands/modem_simulator/sms_service.h"
26 #include "host/commands/modem_simulator/stk_service.h"
27 #include "host/commands/modem_simulator/sup_service.h"
28
29 namespace cuttlefish {
30
ModemSimulator(int32_t modem_id)31 ModemSimulator::ModemSimulator(int32_t modem_id)
32 : modem_id_(modem_id), thread_looper_(new ThreadLooper()) {}
33
~ModemSimulator()34 ModemSimulator::~ModemSimulator() {
35 // this will stop the looper so all the callbacks
36 // will be gone;
37 thread_looper_->Stop();
38 modem_services_.clear();
39 }
40
LoadNvramConfig()41 void ModemSimulator::LoadNvramConfig() {
42 auto nvram_config = NvramConfig::Get();
43 if (!nvram_config) {
44 LOG(FATAL) << "Failed to obtain nvram config singleton";
45 return;
46 }
47 }
48
Initialize(std::unique_ptr<ChannelMonitor> && channel_monitor)49 void ModemSimulator::Initialize(
50 std::unique_ptr<ChannelMonitor>&& channel_monitor) {
51 channel_monitor_ = std::move(channel_monitor);
52 LoadNvramConfig();
53 RegisterModemService();
54 }
55
RegisterModemService()56 void ModemSimulator::RegisterModemService() {
57 auto netservice = std::make_unique<NetworkService>(
58 modem_id_, channel_monitor_.get(), thread_looper_.get());
59 auto simservice = std::make_unique<SimService>(
60 modem_id_, channel_monitor_.get(), thread_looper_.get());
61 auto miscservice = std::make_unique<MiscService>(
62 modem_id_, channel_monitor_.get(), thread_looper_.get());
63 auto callservice = std::make_unique<CallService>(
64 modem_id_, channel_monitor_.get(), thread_looper_.get());
65 auto stkservice = std::make_unique<StkService>(
66 modem_id_, channel_monitor_.get(), thread_looper_.get());
67 auto smsservice = std::make_unique<SmsService>(
68 modem_id_, channel_monitor_.get(), thread_looper_.get());
69 auto dataservice = std::make_unique<DataService>(
70 modem_id_, channel_monitor_.get(), thread_looper_.get());
71 auto supservice = std::make_unique<SupService>(
72 modem_id_, channel_monitor_.get(), thread_looper_.get());
73
74 netservice->SetupDependency(miscservice.get(), simservice.get(),
75 dataservice.get());
76 simservice->SetupDependency(netservice.get());
77 callservice->SetupDependency(simservice.get(), netservice.get());
78 stkservice->SetupDependency(simservice.get());
79 smsservice->SetupDependency(simservice.get());
80
81 modem_services_[kSimService] = std::move(simservice);
82 modem_services_[kNetworkService] = std::move(netservice);
83 modem_services_[kCallService] = std::move(callservice);
84 modem_services_[kDataService] = std::move(dataservice);
85 modem_services_[kSmsService] = std::move(smsservice);
86 modem_services_[kSupService] = std::move(supservice);
87 modem_services_[kStkService] = std::move(stkservice);
88 modem_services_[kMiscService] = std::move(miscservice);
89 }
90
DispatchCommand(const Client & client,std::string & command)91 void ModemSimulator::DispatchCommand(const Client& client, std::string& command) {
92 auto iter = modem_services_.find(kSmsService);
93 if (iter != modem_services_.end()) {
94 auto sms_service =
95 dynamic_cast<SmsService*>(modem_services_[kSmsService].get());
96 if (sms_service->IsWaitingSmsPdu()) {
97 sms_service->HandleSendSMSPDU(client, command);
98 return;
99 } else if (sms_service->IsWaitingSmsToSim()) {
100 sms_service->HandleWriteSMSPduToSim(client, command);
101 return;
102 }
103 }
104
105 bool success = false;
106 for (auto& service : modem_services_) {
107 success = service.second->HandleModemCommand(client, command);
108 if (success) {
109 break;
110 }
111 }
112
113 if (!success && client.type != Client::REMOTE) {
114 LOG(DEBUG) << "Not supported AT command: " << command;
115 client.SendCommandResponse(ModemService::kCmeErrorOperationNotSupported);
116 }
117 }
118
OnFirstClientConnected()119 void ModemSimulator::OnFirstClientConnected() {
120 auto iter = modem_services_.find(kMiscService);
121 if (iter != modem_services_.end()) {
122 auto misc_service =
123 dynamic_cast<MiscService*>(modem_services_[kMiscService].get());
124 misc_service->TimeUpdate();
125 }
126
127 iter = modem_services_.find(kNetworkService);
128 if (iter != modem_services_.end()) {
129 auto network_service =
130 dynamic_cast<NetworkService*>(modem_services_[kNetworkService].get());
131 network_service->OnVoiceRegisterStateChanged();
132 network_service->OnDataRegisterStateChanged();
133 }
134 }
135
SaveModemState()136 void ModemSimulator::SaveModemState() {
137 auto iter = modem_services_.find(kSimService);
138 if (iter != modem_services_.end()) {
139 auto sim_service =
140 dynamic_cast<SimService*>(modem_services_[kSimService].get());
141 sim_service->SavePinStateToIccProfile();
142 sim_service->SaveFacilityLockToIccProfile();
143 }
144 }
145
IsWaitingSmsPdu()146 bool ModemSimulator::IsWaitingSmsPdu() {
147 auto iter = modem_services_.find(kSmsService);
148 if (iter != modem_services_.end()) {
149 auto sms_service =
150 dynamic_cast<SmsService*>(modem_services_[kSmsService].get());
151 return (sms_service->IsWaitingSmsPdu() | sms_service->IsWaitingSmsToSim());
152 }
153 return false;
154 }
155
156 } // namespace cuttlefish
157