1 /*
2 * Copyright (C) 2023 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/network/RadioNetwork.h>
18
19 #include <libminradio/debug.h>
20 #include <libminradio/network/structs.h>
21 #include <libminradio/response.h>
22
23 #include <chrono>
24 #include <thread>
25
26 #define RADIO_MODULE "Network"
27
28 namespace android::hardware::radio::minimal {
29
30 using namespace ::android::hardware::radio::minimal::binder_printing;
31 using ::aidl::android::hardware::radio::AccessNetwork;
32 using ::aidl::android::hardware::radio::RadioError;
33 using ::aidl::android::hardware::radio::RadioIndicationType;
34 using ::ndk::ScopedAStatus;
35 namespace aidl = ::aidl::android::hardware::radio::network;
36 namespace aidlRadio = ::aidl::android::hardware::radio;
37 constexpr auto ok = &ScopedAStatus::ok;
38
getCellInfoListBase()39 std::vector<aidl::CellInfo> RadioNetwork::getCellInfoListBase() {
40 if (!mResponseTracker) return {};
41
42 // There's a slight race between get*RegistrationState and getSignalStrength, but
43 // getCellInfoListBase is best-effort anyway, so it's the best we can do here.
44 auto dataRegistrationState = mResponseTracker()->getDataRegistrationState();
45 auto signalStrength = mResponseTracker()->getSignalStrength();
46 if (!dataRegistrationState.expectOk() || !signalStrength.expectOk()) return {};
47
48 return {structs::makeCellInfo(*dataRegistrationState, *signalStrength)};
49 }
50
getAllowedNetworkTypesBitmap(int32_t serial)51 ScopedAStatus RadioNetwork::getAllowedNetworkTypesBitmap(int32_t serial) {
52 LOG_CALL;
53 respond()->getAllowedNetworkTypesBitmapResponse(noError(serial), mAllowedNetworkTypesBitmap);
54 return ok();
55 }
56
getAvailableBandModes(int32_t serial)57 ScopedAStatus RadioNetwork::getAvailableBandModes(int32_t serial) {
58 LOG_AND_RETURN_DEPRECATED();
59 }
60
getAvailableNetworks(int32_t serial)61 ScopedAStatus RadioNetwork::getAvailableNetworks(int32_t serial) {
62 LOG_NOT_SUPPORTED;
63 respond()->getAvailableNetworksResponse(notSupported(serial), {});
64 return ok();
65 }
66
getBarringInfo(int32_t serial)67 ScopedAStatus RadioNetwork::getBarringInfo(int32_t serial) {
68 LOG_NOT_SUPPORTED;
69 respond()->getBarringInfoResponse(notSupported(serial), {}, {});
70 return ok();
71 }
72
getCdmaRoamingPreference(int32_t serial)73 ScopedAStatus RadioNetwork::getCdmaRoamingPreference(int32_t serial) {
74 LOG_AND_RETURN_DEPRECATED();
75 }
76
getCellInfoList(int32_t serial)77 ScopedAStatus RadioNetwork::getCellInfoList(int32_t serial) {
78 LOG_CALL;
79 RESPOND_ERROR_IF_NOT_CONNECTED(getCellInfoListResponse, {});
80 respond()->getCellInfoListResponse(noError(serial), getCellInfoListBase());
81 return ok();
82 }
83
getImsRegistrationState(int32_t serial)84 ScopedAStatus RadioNetwork::getImsRegistrationState(int32_t serial) {
85 LOG_AND_RETURN_DEPRECATED();
86 }
87
getNetworkSelectionMode(int32_t serial)88 ScopedAStatus RadioNetwork::getNetworkSelectionMode(int32_t serial) {
89 LOG_CALL;
90 respond()->getNetworkSelectionModeResponse(noError(serial), /*manual*/ false);
91 return ok();
92 }
93
getOperator(int32_t serial)94 ScopedAStatus RadioNetwork::getOperator(int32_t serial) {
95 LOG_CALL;
96
97 auto dataRegistrationState = mResponseTracker()->getDataRegistrationState();
98 if (!dataRegistrationState.expectOk()) {
99 respond()->getOperatorResponse(errorResponse(serial, RadioError::INTERNAL_ERR), {}, {}, {});
100 return ok();
101 }
102
103 auto opInfo = structs::getOperatorInfo(dataRegistrationState->cellIdentity);
104 respond()->getOperatorResponse(noError(serial), opInfo.alphaLong, opInfo.alphaShort,
105 opInfo.operatorNumeric);
106 return ok();
107 }
108
getSystemSelectionChannels(int32_t serial)109 ScopedAStatus RadioNetwork::getSystemSelectionChannels(int32_t serial) {
110 LOG_CALL_IGNORED;
111 respond()->getSystemSelectionChannelsResponse(noError(serial), {});
112 return ok();
113 }
114
getVoiceRadioTechnology(int32_t serial)115 ScopedAStatus RadioNetwork::getVoiceRadioTechnology(int32_t serial) {
116 LOG_CALL;
117 respond()->getVoiceRadioTechnologyResponse(noError(serial),
118 aidlRadio::RadioTechnology::UNKNOWN);
119 return ok();
120 }
121
getVoiceRegistrationState(int32_t serial)122 ScopedAStatus RadioNetwork::getVoiceRegistrationState(int32_t serial) {
123 LOG_CALL;
124 respond()->getVoiceRegistrationStateResponse(noError(serial),
125 {aidl::RegState::NOT_REG_MT_NOT_SEARCHING_OP});
126 return ok();
127 }
128
isNrDualConnectivityEnabled(int32_t serial)129 ScopedAStatus RadioNetwork::isNrDualConnectivityEnabled(int32_t serial) {
130 // Disabled with modemReducedFeatureSet1.
131 LOG_NOT_SUPPORTED;
132 respond()->isNrDualConnectivityEnabledResponse(notSupported(serial), false);
133 return ok();
134 }
135
responseAcknowledgement()136 ScopedAStatus RadioNetwork::responseAcknowledgement() {
137 LOG_CALL_NOSERIAL;
138 return ok();
139 }
140
setAllowedNetworkTypesBitmap(int32_t serial,int32_t ntype)141 ScopedAStatus RadioNetwork::setAllowedNetworkTypesBitmap(int32_t serial, int32_t ntype) {
142 LOG_CALL_IGNORED << ntype;
143 mAllowedNetworkTypesBitmap = ntype;
144 respond()->setAllowedNetworkTypesBitmapResponse(noError(serial));
145 return ok();
146 }
147
setBandMode(int32_t serial,aidl::RadioBandMode)148 ScopedAStatus RadioNetwork::setBandMode(int32_t serial, aidl::RadioBandMode) {
149 LOG_AND_RETURN_DEPRECATED();
150 }
151
setBarringPassword(int32_t serial,const std::string & facility,const std::string & oldPw,const std::string & newPw)152 ScopedAStatus RadioNetwork::setBarringPassword(int32_t serial, const std::string& facility,
153 const std::string& oldPw, const std::string& newPw) {
154 LOG_NOT_SUPPORTED << facility << ' ' << oldPw << ' ' << newPw;
155 respond()->setBarringPasswordResponse(notSupported(serial));
156 return ok();
157 }
158
setCdmaRoamingPreference(int32_t serial,aidl::CdmaRoamingType)159 ScopedAStatus RadioNetwork::setCdmaRoamingPreference(int32_t serial, aidl::CdmaRoamingType) {
160 LOG_AND_RETURN_DEPRECATED();
161 }
162
setCellInfoListRate(int32_t serial,int32_t rate)163 ScopedAStatus RadioNetwork::setCellInfoListRate(int32_t serial, int32_t rate) {
164 LOG_NOT_SUPPORTED << rate;
165 respond()->setCellInfoListRateResponse(notSupported(serial));
166 return ok();
167 }
168
setIndicationFilter(int32_t serial,int32_t indFilter)169 ScopedAStatus RadioNetwork::setIndicationFilter(int32_t serial, int32_t indFilter) {
170 LOG_CALL_IGNORED << indFilter;
171 respond()->setIndicationFilterResponse(noError(serial));
172 return ok();
173 }
174
setLinkCapacityReportingCriteria(int32_t serial,int32_t hysteresisMs,int32_t hysteresisDlKbps,int32_t hysteresisUlKbps,const std::vector<int32_t> & thrDownlinkKbps,const std::vector<int32_t> & thrUplinkKbps,AccessNetwork accessNetwork)175 ScopedAStatus RadioNetwork::setLinkCapacityReportingCriteria( //
176 int32_t serial, int32_t hysteresisMs, int32_t hysteresisDlKbps, int32_t hysteresisUlKbps,
177 const std::vector<int32_t>& thrDownlinkKbps, const std::vector<int32_t>& thrUplinkKbps,
178 AccessNetwork accessNetwork) {
179 LOG_NOT_SUPPORTED << hysteresisMs << ' ' << hysteresisDlKbps << ' ' << hysteresisUlKbps << ' '
180 << thrDownlinkKbps << ' ' << thrUplinkKbps << ' ' << accessNetwork;
181 respond()->setLinkCapacityReportingCriteriaResponse(notSupported(serial));
182 return ok();
183 }
184
setLocationUpdates(int32_t serial,bool)185 ScopedAStatus RadioNetwork::setLocationUpdates(int32_t serial, bool) {
186 LOG_AND_RETURN_DEPRECATED();
187 }
188
setNetworkSelectionModeAutomatic(int32_t serial)189 ScopedAStatus RadioNetwork::setNetworkSelectionModeAutomatic(int32_t serial) {
190 LOG_NOT_SUPPORTED;
191 respond()->setNetworkSelectionModeAutomaticResponse(notSupported(serial));
192 return ok();
193 }
194
setNetworkSelectionModeManual(int32_t serial,const std::string & opNumeric,AccessNetwork ran)195 ScopedAStatus RadioNetwork::setNetworkSelectionModeManual( //
196 int32_t serial, const std::string& opNumeric, AccessNetwork ran) {
197 LOG_NOT_SUPPORTED << opNumeric << ' ' << ran;
198 respond()->setNetworkSelectionModeManualResponse(notSupported(serial));
199 return ok();
200 }
201
setNrDualConnectivityState(int32_t serial,aidl::NrDualConnectivityState st)202 ScopedAStatus RadioNetwork::setNrDualConnectivityState(int32_t serial,
203 aidl::NrDualConnectivityState st) {
204 // Disabled with modemReducedFeatureSet1.
205 LOG_NOT_SUPPORTED << st;
206 respond()->setNrDualConnectivityStateResponse(notSupported(serial));
207 return ok();
208 }
209
setResponseFunctions(const std::shared_ptr<aidl::IRadioNetworkResponse> & response,const std::shared_ptr<aidl::IRadioNetworkIndication> & indication)210 ScopedAStatus RadioNetwork::setResponseFunctions(
211 const std::shared_ptr<aidl::IRadioNetworkResponse>& response,
212 const std::shared_ptr<aidl::IRadioNetworkIndication>& indication) {
213 LOG_CALL_NOSERIAL << response << ' ' << indication;
214 CHECK(response);
215 CHECK(indication);
216 mResponseTracker = ndk::SharedRefBase::make<RadioNetworkResponseTracker>(
217 ref<aidl::IRadioNetwork>(), response);
218 respond = mResponseTracker.get();
219 indicate = indication;
220 setResponseFunctionsBase();
221 return ok();
222 }
223
onUpdatedResponseFunctions()224 void RadioNetwork::onUpdatedResponseFunctions() {
225 indicate()->cellInfoList(RadioIndicationType::UNSOLICITED, getCellInfoListBase());
226 auto signalStrengthResponse = mResponseTracker()->getSignalStrength();
227 if (signalStrengthResponse.expectOk()) {
228 aidl::SignalStrength signalStrength = *signalStrengthResponse;
229 indicate()->currentSignalStrength(RadioIndicationType::UNSOLICITED, signalStrength);
230
231 // TODO(b/379302126): fix race condition in ServiceStateTracker which doesn't listen for
232 // EVENT_UNSOL_CELL_INFO_LIST for the first ~1.3s after setResponseFunctions
233 // TODO(b/379302126): fix race condition in SignalStrengthController, starting to listen for
234 // EVENT_SIGNAL_STRENGTH_UPDATE after ~3.7s
235 // This workaround thread would be a race condition itself (with use-after-free), but we can
236 // drop it once the two bugs mentioned above are fixed.
237 std::thread([this, signalStrength] {
238 for (int i = 0; i < 10; i++) {
239 using namespace std::chrono_literals;
240 std::this_thread::sleep_for(1s);
241 indicate()->cellInfoList(RadioIndicationType::UNSOLICITED, getCellInfoListBase());
242 indicate()->currentSignalStrength(RadioIndicationType::UNSOLICITED, signalStrength);
243 }
244 }).detach();
245 }
246 }
247
setSignalStrengthReportingCriteria(int32_t serial,const std::vector<aidl::SignalThresholdInfo> & infos)248 ScopedAStatus RadioNetwork::setSignalStrengthReportingCriteria(
249 int32_t serial, const std::vector<aidl::SignalThresholdInfo>& infos) {
250 LOG_CALL_IGNORED << infos;
251 respond()->setSignalStrengthReportingCriteriaResponse(
252 structs::validateSignalThresholdInfos(infos)
253 ? noError(serial)
254 : errorResponse(serial, RadioError::INVALID_ARGUMENTS));
255 return ok();
256 }
257
setSuppServiceNotifications(int32_t serial,bool)258 ScopedAStatus RadioNetwork::setSuppServiceNotifications(int32_t serial, bool) {
259 LOG_AND_RETURN_DEPRECATED();
260 }
261
setSystemSelectionChannels(int32_t serial,bool specifyCh,const std::vector<aidl::RadioAccessSpecifier> & specifiers)262 ScopedAStatus RadioNetwork::setSystemSelectionChannels( //
263 int32_t serial, bool specifyCh, const std::vector<aidl::RadioAccessSpecifier>& specifiers) {
264 LOG_CALL_IGNORED << specifyCh << ' ' << specifiers;
265 if (specifiers.empty()) {
266 respond()->setSystemSelectionChannelsResponse(noError(serial));
267 } else {
268 respond()->setSystemSelectionChannelsResponse(notSupported(serial));
269 }
270 return ok();
271 }
272
startNetworkScan(int32_t serial,const aidl::NetworkScanRequest & req)273 ScopedAStatus RadioNetwork::startNetworkScan(int32_t serial, const aidl::NetworkScanRequest& req) {
274 LOG_NOT_SUPPORTED << req;
275 respond()->startNetworkScanResponse(notSupported(serial));
276 return ok();
277 }
278
stopNetworkScan(int32_t serial)279 ScopedAStatus RadioNetwork::stopNetworkScan(int32_t serial) {
280 LOG_CALL_IGNORED;
281 respond()->stopNetworkScanResponse(noError(serial));
282 return ok();
283 }
284
supplyNetworkDepersonalization(int32_t serial,const std::string & nPin)285 ScopedAStatus RadioNetwork::supplyNetworkDepersonalization(int32_t serial,
286 const std::string& nPin) {
287 LOG_NOT_SUPPORTED << nPin;
288 respond()->supplyNetworkDepersonalizationResponse(notSupported(serial), -1);
289 return ok();
290 }
291
setUsageSetting(int32_t serial,aidl::UsageSetting usageSetting)292 ScopedAStatus RadioNetwork::setUsageSetting(int32_t serial, aidl::UsageSetting usageSetting) {
293 LOG_CALL_IGNORED << usageSetting;
294 if (usageSetting == aidl::UsageSetting::DATA_CENTRIC) {
295 respond()->setUsageSettingResponse(noError(serial));
296 } else {
297 respond()->setUsageSettingResponse(errorResponse(serial, RadioError::INVALID_ARGUMENTS));
298 }
299 return ok();
300 }
301
getUsageSetting(int32_t serial)302 ScopedAStatus RadioNetwork::getUsageSetting(int32_t serial) {
303 LOG_CALL;
304 respond()->getUsageSettingResponse(noError(serial), aidl::UsageSetting::DATA_CENTRIC);
305 return ok();
306 }
307
setEmergencyMode(int32_t serial,aidl::EmergencyMode emergencyMode)308 ScopedAStatus RadioNetwork::setEmergencyMode(int32_t serial, aidl::EmergencyMode emergencyMode) {
309 LOG_NOT_SUPPORTED << emergencyMode;
310 respond()->setEmergencyModeResponse(notSupported(serial), {});
311 return ok();
312 }
313
triggerEmergencyNetworkScan(int32_t serial,const aidl::EmergencyNetworkScanTrigger & trigger)314 ScopedAStatus RadioNetwork::triggerEmergencyNetworkScan(
315 int32_t serial, const aidl::EmergencyNetworkScanTrigger& trigger) {
316 LOG_NOT_SUPPORTED << trigger;
317 respond()->triggerEmergencyNetworkScanResponse(notSupported(serial));
318 return ok();
319 }
320
cancelEmergencyNetworkScan(int32_t serial,bool resetScan)321 ScopedAStatus RadioNetwork::cancelEmergencyNetworkScan(int32_t serial, bool resetScan) {
322 LOG_NOT_SUPPORTED << resetScan;
323 respond()->cancelEmergencyNetworkScanResponse(notSupported(serial));
324 return ok();
325 }
326
exitEmergencyMode(int32_t serial)327 ScopedAStatus RadioNetwork::exitEmergencyMode(int32_t serial) {
328 LOG_NOT_SUPPORTED;
329 respond()->exitEmergencyModeResponse(notSupported(serial));
330 return ok();
331 }
332
setNullCipherAndIntegrityEnabled(int32_t serial,bool enabled)333 ScopedAStatus RadioNetwork::setNullCipherAndIntegrityEnabled(int32_t serial, bool enabled) {
334 LOG_CALL_IGNORED << enabled;
335 respond()->setNullCipherAndIntegrityEnabledResponse(noError(serial));
336 return ok();
337 }
338
isNullCipherAndIntegrityEnabled(int32_t serial)339 ScopedAStatus RadioNetwork::isNullCipherAndIntegrityEnabled(int32_t serial) {
340 LOG_NOT_SUPPORTED;
341 respond()->isNullCipherAndIntegrityEnabledResponse(notSupported(serial), false);
342 return ok();
343 }
344
isN1ModeEnabled(int32_t serial)345 ScopedAStatus RadioNetwork::isN1ModeEnabled(int32_t serial) {
346 LOG_NOT_SUPPORTED;
347 respond()->isN1ModeEnabledResponse(notSupported(serial), false);
348 return ok();
349 }
350
setN1ModeEnabled(int32_t serial,bool enable)351 ScopedAStatus RadioNetwork::setN1ModeEnabled(int32_t serial, bool enable) {
352 LOG_NOT_SUPPORTED << enable;
353 respond()->setN1ModeEnabledResponse(notSupported(serial));
354 return ok();
355 }
356
isCellularIdentifierTransparencyEnabled(int32_t serial)357 ScopedAStatus RadioNetwork::isCellularIdentifierTransparencyEnabled(int32_t serial) {
358 LOG_NOT_SUPPORTED;
359 respond()->isCellularIdentifierTransparencyEnabledResponse(notSupported(serial), false);
360 return ok();
361 }
362
setCellularIdentifierTransparencyEnabled(int32_t serial,bool enabled)363 ScopedAStatus RadioNetwork::setCellularIdentifierTransparencyEnabled(int32_t serial, bool enabled) {
364 LOG_CALL_IGNORED << enabled;
365 respond()->setCellularIdentifierTransparencyEnabledResponse(noError(serial));
366 return ok();
367 }
368
isSecurityAlgorithmsUpdatedEnabled(int32_t serial)369 ScopedAStatus RadioNetwork::isSecurityAlgorithmsUpdatedEnabled(int32_t serial) {
370 LOG_NOT_SUPPORTED;
371 respond()->isSecurityAlgorithmsUpdatedEnabledResponse(notSupported(serial), false);
372 return ok();
373 }
374
setSecurityAlgorithmsUpdatedEnabled(int32_t serial,bool enable)375 ScopedAStatus RadioNetwork::setSecurityAlgorithmsUpdatedEnabled(int32_t serial, bool enable) {
376 LOG_NOT_SUPPORTED << enable;
377 respond()->setSecurityAlgorithmsUpdatedEnabledResponse(notSupported(serial));
378 return ok();
379 }
380
setSatellitePlmn(int32_t serial,const std::vector<std::string> & carrierPlmnArray,const std::vector<std::string> & allSatellitePlmnArray)381 ScopedAStatus RadioNetwork::setSatellitePlmn(
382 int32_t serial, const std::vector<std::string>& carrierPlmnArray,
383 const std::vector<std::string>& allSatellitePlmnArray) {
384 LOG_NOT_SUPPORTED << carrierPlmnArray << ' ' << allSatellitePlmnArray;
385 respond()->setSatellitePlmnResponse(notSupported(serial));
386 return ok();
387 }
388
setSatelliteEnabledForCarrier(int32_t serial,bool satelliteEnabled)389 ScopedAStatus RadioNetwork::setSatelliteEnabledForCarrier(int32_t serial, bool satelliteEnabled) {
390 LOG_NOT_SUPPORTED << satelliteEnabled;
391 respond()->setSatelliteEnabledForCarrierResponse(notSupported(serial));
392 return ok();
393 }
394
isSatelliteEnabledForCarrier(int32_t serial)395 ScopedAStatus RadioNetwork::isSatelliteEnabledForCarrier(int32_t serial) {
396 LOG_NOT_SUPPORTED;
397 respond()->isSatelliteEnabledForCarrierResponse(notSupported(serial), false);
398 return ok();
399 }
400
401 } // namespace android::hardware::radio::minimal
402