1 /*
2 * Copyright (C) 2024 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
17 #include <libminradio/sim/RadioSim.h>
18
19 #include <libminradio/debug.h>
20 #include <libminradio/response.h>
21 #include <libminradio/sim/IccUtils.h>
22 #include <libminradio/sim/apps/AraM.h>
23 #include <libminradio/sim/apps/FilesystemApp.h>
24
25 #define RADIO_MODULE "Sim"
26
27 namespace android::hardware::radio::minimal {
28
29 using namespace ::android::hardware::radio::minimal::binder_printing;
30 using ::aidl::android::hardware::radio::RadioError;
31 using ::ndk::ScopedAStatus;
32 namespace aidl = ::aidl::android::hardware::radio::sim;
33 constexpr auto ok = &ScopedAStatus::ok;
34
RadioSim(std::shared_ptr<SlotContext> context)35 RadioSim::RadioSim(std::shared_ptr<SlotContext> context) : RadioSlotBase(context) {
36 mAppManager.addApp(std::make_shared<sim::apps::FilesystemApp>(mFilesystem));
37
38 mFilesystem->write(sim::paths::fplmn, sim::encodeFplmns({}));
39 mFilesystem->write(sim::paths::pl, "en");
40 }
41
setIccid(std::string iccid)42 void RadioSim::setIccid(std::string iccid) {
43 mFilesystem->writeBch(sim::paths::iccid, iccid);
44 }
45
getIccid() const46 std::optional<std::string> RadioSim::getIccid() const {
47 return mFilesystem->readBch(sim::paths::iccid);
48 }
49
addCtsCertificate()50 void RadioSim::addCtsCertificate() {
51 static constexpr char CTS_UICC_2021[] =
52 "CE7B2B47AE2B7552C8F92CC29124279883041FB623A5F194A82C9BF15D492AA0";
53
54 auto aram = std::make_shared<sim::apps::AraM>();
55 mAppManager.addApp(aram);
56 aram->addRule({
57 .deviceAppID = sim::hexStringToBytes(CTS_UICC_2021),
58 .pkg = "android.carrierapi.cts",
59 });
60 }
61
areUiccApplicationsEnabled(int32_t serial)62 ScopedAStatus RadioSim::areUiccApplicationsEnabled(int32_t serial) {
63 LOG_CALL;
64 respond()->areUiccApplicationsEnabledResponse(noError(serial), mAreUiccApplicationsEnabled);
65 return ok();
66 }
67
changeIccPin2ForApp(int32_t serial,const std::string & oldPin2,const std::string & newPin2,const std::string & aid)68 ScopedAStatus RadioSim::changeIccPin2ForApp(int32_t serial, const std::string& oldPin2,
69 const std::string& newPin2, const std::string& aid) {
70 LOG_NOT_SUPPORTED << oldPin2 << ' ' << newPin2 << ' ' << aid;
71 respond()->changeIccPin2ForAppResponse(notSupported(serial), -1);
72 return ok();
73 }
74
changeIccPinForApp(int32_t serial,const std::string & oldPin,const std::string & newPin,const std::string & aid)75 ScopedAStatus RadioSim::changeIccPinForApp(int32_t serial, const std::string& oldPin,
76 const std::string& newPin, const std::string& aid) {
77 LOG_NOT_SUPPORTED << oldPin << ' ' << newPin << ' ' << aid;
78 respond()->changeIccPinForAppResponse(notSupported(serial), -1);
79 return ok();
80 }
81
enableUiccApplications(int32_t serial,bool enable)82 ScopedAStatus RadioSim::enableUiccApplications(int32_t serial, bool enable) {
83 LOG_CALL_IGNORED << enable;
84 mAreUiccApplicationsEnabled = enable;
85 respond()->enableUiccApplicationsResponse(noError(serial));
86 return ok();
87 }
88
getAllowedCarriers(int32_t serial)89 ScopedAStatus RadioSim::getAllowedCarriers(int32_t serial) {
90 LOG_NOT_SUPPORTED;
91 respond()->getAllowedCarriersResponse(notSupported(serial), {}, {});
92 return ok();
93 }
94
getCdmaSubscription(int32_t serial)95 ScopedAStatus RadioSim::getCdmaSubscription(int32_t serial) {
96 LOG_AND_RETURN_DEPRECATED();
97 }
98
getCdmaSubscriptionSource(int32_t serial)99 ScopedAStatus RadioSim::getCdmaSubscriptionSource(int32_t serial) {
100 LOG_AND_RETURN_DEPRECATED();
101 }
102
getFacilityLockForApp(int32_t serial,const std::string & facility,const std::string & password,int32_t serviceClass,const std::string & appId)103 ScopedAStatus RadioSim::getFacilityLockForApp( //
104 int32_t serial, const std::string& facility, const std::string& password,
105 int32_t serviceClass, const std::string& appId) {
106 LOG_CALL << facility << ' ' << password << ' ' << serviceClass << ' ' << appId;
107 respond()->getFacilityLockForAppResponse(noError(serial), 0); // 0 means "disabled for all"
108 return ok();
109 }
110
getSimPhonebookCapacity(int32_t serial)111 ScopedAStatus RadioSim::getSimPhonebookCapacity(int32_t serial) {
112 LOG_NOT_SUPPORTED;
113 respond()->getSimPhonebookCapacityResponse(notSupported(serial), {});
114 return ok();
115 }
116
getSimPhonebookRecords(int32_t serial)117 ScopedAStatus RadioSim::getSimPhonebookRecords(int32_t serial) {
118 LOG_NOT_SUPPORTED;
119 respond()->getSimPhonebookRecordsResponse(notSupported(serial));
120 return ok();
121 }
122
iccCloseLogicalChannel(int32_t serial,int32_t)123 ScopedAStatus RadioSim::iccCloseLogicalChannel(int32_t serial, int32_t) {
124 LOG_AND_RETURN_DEPRECATED();
125 }
126
iccCloseLogicalChannelWithSessionInfo(int32_t serial,const aidl::SessionInfo & sessionInfo)127 ScopedAStatus RadioSim::iccCloseLogicalChannelWithSessionInfo(
128 int32_t serial, const aidl::SessionInfo& sessionInfo) {
129 LOG_CALL << sessionInfo;
130 auto status = mAppManager.closeLogicalChannel(sessionInfo.sessionId);
131 respond()->iccCloseLogicalChannelWithSessionInfoResponse(errorResponse(serial, status));
132 return ok();
133 }
134
iccIoForApp(int32_t serial,const aidl::IccIo & iccIo)135 ScopedAStatus RadioSim::iccIoForApp(int32_t serial, const aidl::IccIo& iccIo) {
136 LOG_CALL << iccIo;
137 respond()->iccIoForAppResponse(noError(serial), mAppManager.iccIo(iccIo));
138 return ok();
139 }
140
iccOpenLogicalChannel(int32_t serial,const std::string & aid,int32_t p2)141 ScopedAStatus RadioSim::iccOpenLogicalChannel(int32_t serial, const std::string& aid, int32_t p2) {
142 LOG_CALL << aid << ' ' << p2;
143 auto [status, channel] = mAppManager.openLogicalChannel(aid, p2);
144 respond()->iccOpenLogicalChannelResponse(
145 errorResponse(serial, status), channel ? channel->getId() : 0,
146 channel ? channel->getSelectResponse() : std::vector<uint8_t>{});
147 return ok();
148 }
149
iccTransmitApduBasicChannel(int32_t serial,const aidl::SimApdu & message)150 ScopedAStatus RadioSim::iccTransmitApduBasicChannel(int32_t serial, const aidl::SimApdu& message) {
151 LOG_CALL << message;
152 if (message.sessionId != 0) {
153 LOG(ERROR) << "Basic channel session ID should be zero, but was " << message.sessionId;
154 respond()->iccTransmitApduBasicChannelResponse(
155 errorResponse(serial, RadioError::INVALID_ARGUMENTS), {});
156 return ok();
157 }
158 respond()->iccTransmitApduBasicChannelResponse(noError(serial), mAppManager.transmit(message));
159 return ok();
160 }
161
iccTransmitApduLogicalChannel(int32_t serial,const aidl::SimApdu & message)162 ScopedAStatus RadioSim::iccTransmitApduLogicalChannel(int32_t serial,
163 const aidl::SimApdu& message) {
164 LOG_CALL << message;
165 respond()->iccTransmitApduLogicalChannelResponse(noError(serial),
166 mAppManager.transmit(message));
167 return ok();
168 }
169
reportStkServiceIsRunning(int32_t serial)170 ScopedAStatus RadioSim::reportStkServiceIsRunning(int32_t serial) {
171 LOG_CALL_IGNORED;
172 respond()->reportStkServiceIsRunningResponse(noError(serial));
173 return ok();
174 }
175
requestIccSimAuthentication(int32_t serial,int32_t authContext,const std::string & authData,const std::string & aid)176 ScopedAStatus RadioSim::requestIccSimAuthentication( //
177 int32_t serial, int32_t authContext, const std::string& authData, const std::string& aid) {
178 LOG_NOT_SUPPORTED << authContext << ' ' << authData << ' ' << aid;
179 respond()->requestIccSimAuthenticationResponse(notSupported(serial), {});
180 return ok();
181 }
182
responseAcknowledgement()183 ScopedAStatus RadioSim::responseAcknowledgement() {
184 LOG_CALL_NOSERIAL;
185 return ok();
186 }
187
sendEnvelope(int32_t serial,const std::string & command)188 ScopedAStatus RadioSim::sendEnvelope(int32_t serial, const std::string& command) {
189 LOG_NOT_SUPPORTED << command;
190 respond()->sendEnvelopeResponse(notSupported(serial), {});
191 return ok();
192 }
193
sendEnvelopeWithStatus(int32_t serial,const std::string & contents)194 ScopedAStatus RadioSim::sendEnvelopeWithStatus(int32_t serial, const std::string& contents) {
195 LOG_NOT_SUPPORTED << contents;
196 respond()->sendEnvelopeWithStatusResponse(notSupported(serial), {});
197 return ok();
198 }
199
sendTerminalResponseToSim(int32_t serial,const std::string & commandResponse)200 ScopedAStatus RadioSim::sendTerminalResponseToSim(int32_t serial,
201 const std::string& commandResponse) {
202 LOG_NOT_SUPPORTED << commandResponse;
203 respond()->sendTerminalResponseToSimResponse(notSupported(serial));
204 return ok();
205 }
206
setAllowedCarriers(int32_t serial,const aidl::CarrierRestrictions & carriers,aidl::SimLockMultiSimPolicy mp)207 ScopedAStatus RadioSim::setAllowedCarriers( //
208 int32_t serial, const aidl::CarrierRestrictions& carriers, aidl::SimLockMultiSimPolicy mp) {
209 LOG_NOT_SUPPORTED << carriers << ' ' << mp;
210 respond()->setAllowedCarriersResponse(notSupported(serial));
211 return ok();
212 }
213
setCarrierInfoForImsiEncryption(int32_t serial,const aidl::ImsiEncryptionInfo & imsiEncryptionInfo)214 ScopedAStatus RadioSim::setCarrierInfoForImsiEncryption(
215 int32_t serial, const aidl::ImsiEncryptionInfo& imsiEncryptionInfo) {
216 LOG_NOT_SUPPORTED << imsiEncryptionInfo;
217 respond()->setCarrierInfoForImsiEncryptionResponse(notSupported(serial));
218 return ok();
219 }
220
setCdmaSubscriptionSource(int32_t serial,aidl::CdmaSubscriptionSource)221 ScopedAStatus RadioSim::setCdmaSubscriptionSource(int32_t serial, aidl::CdmaSubscriptionSource) {
222 LOG_AND_RETURN_DEPRECATED();
223 }
224
setFacilityLockForApp(int32_t serial,const std::string & facility,bool lockState,const std::string & password,int32_t serviceClass,const std::string & appId)225 ScopedAStatus RadioSim::setFacilityLockForApp( //
226 int32_t serial, const std::string& facility, bool lockState, const std::string& password,
227 int32_t serviceClass, const std::string& appId) {
228 LOG_NOT_SUPPORTED << facility << ' ' << lockState << ' ' << password << ' ' << serviceClass
229 << ' ' << appId;
230 respond()->setFacilityLockForAppResponse(notSupported(serial), -1);
231 return ok();
232 }
233
setResponseFunctions(const std::shared_ptr<aidl::IRadioSimResponse> & response,const std::shared_ptr<aidl::IRadioSimIndication> & indication)234 ScopedAStatus RadioSim::setResponseFunctions(
235 const std::shared_ptr<aidl::IRadioSimResponse>& response,
236 const std::shared_ptr<aidl::IRadioSimIndication>& indication) {
237 LOG_CALL_NOSERIAL << response << ' ' << indication;
238 CHECK(response);
239 CHECK(indication);
240 respond = response;
241 indicate = indication;
242 setResponseFunctionsBase();
243 return ok();
244 }
245
setSimCardPower(int32_t serial,aidl::CardPowerState powerUp)246 ScopedAStatus RadioSim::setSimCardPower(int32_t serial, aidl::CardPowerState powerUp) {
247 LOG_NOT_SUPPORTED << powerUp;
248 respond()->setSimCardPowerResponse(notSupported(serial));
249 return ok();
250 }
251
setUiccSubscription(int32_t serial,const aidl::SelectUiccSub &)252 ScopedAStatus RadioSim::setUiccSubscription(int32_t serial, const aidl::SelectUiccSub&) {
253 LOG_AND_RETURN_DEPRECATED();
254 }
255
supplyIccPin2ForApp(int32_t serial,const std::string & pin2,const std::string & aid)256 ScopedAStatus RadioSim::supplyIccPin2ForApp(int32_t serial, const std::string& pin2,
257 const std::string& aid) {
258 LOG_NOT_SUPPORTED << pin2 << ' ' << aid;
259 respond()->supplyIccPin2ForAppResponse(notSupported(serial), -1);
260 return ok();
261 }
262
supplyIccPinForApp(int32_t serial,const std::string & pin,const std::string & aid)263 ScopedAStatus RadioSim::supplyIccPinForApp(int32_t serial, const std::string& pin,
264 const std::string& aid) {
265 LOG_CALL << "string[" << pin.size() << "] " << aid
266 << " (should not be called with PinState::DISABLED)";
267 respond()->supplyIccPinForAppResponse(notSupported(serial), -1);
268 return ok();
269 }
270
supplyIccPuk2ForApp(int32_t serial,const std::string & puk2,const std::string & pin2,const std::string & aid)271 ScopedAStatus RadioSim::supplyIccPuk2ForApp(int32_t serial, const std::string& puk2,
272 const std::string& pin2, const std::string& aid) {
273 LOG_NOT_SUPPORTED << puk2 << ' ' << pin2 << ' ' << aid;
274 respond()->supplyIccPuk2ForAppResponse(notSupported(serial), -1);
275 return ok();
276 }
277
supplyIccPukForApp(int32_t serial,const std::string & puk,const std::string & pin,const std::string & aid)278 ScopedAStatus RadioSim::supplyIccPukForApp(int32_t serial, const std::string& puk,
279 const std::string& pin, const std::string& aid) {
280 LOG_NOT_SUPPORTED << puk << ' ' << pin << ' ' << aid;
281 respond()->supplyIccPukForAppResponse(notSupported(serial), -1);
282 return ok();
283 }
284
supplySimDepersonalization(int32_t serial,aidl::PersoSubstate pss,const std::string & controlKey)285 ScopedAStatus RadioSim::supplySimDepersonalization(int32_t serial, aidl::PersoSubstate pss,
286 const std::string& controlKey) {
287 LOG_NOT_SUPPORTED << pss << ' ' << controlKey;
288 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
289 }
290
updateSimPhonebookRecords(int32_t serial,const aidl::PhonebookRecordInfo & recordInfo)291 ScopedAStatus RadioSim::updateSimPhonebookRecords(int32_t serial,
292 const aidl::PhonebookRecordInfo& recordInfo) {
293 LOG_NOT_SUPPORTED << recordInfo;
294 return ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION);
295 }
296
297 } // namespace android::hardware::radio::minimal
298