1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ruim_file.h"
17
18 #include "common_event_manager.h"
19 #include "common_event_support.h"
20 #include "radio_event.h"
21 #include "telephony_common_utils.h"
22
23 using namespace std;
24 using namespace OHOS::AppExecFwk;
25 using namespace OHOS::EventFwk;
26
27 namespace OHOS {
28 namespace Telephony {
RuimFile(const std::shared_ptr<AppExecFwk::EventRunner> & runner,std::shared_ptr<SimStateManager> simStateManager)29 RuimFile::RuimFile(
30 const std::shared_ptr<AppExecFwk::EventRunner> &runner, std::shared_ptr<SimStateManager> simStateManager)
31 : IccFile(runner, simStateManager)
32 {
33 fileQueried_ = false;
34 InitMemberFunc();
35 }
36
StartLoad()37 void RuimFile::StartLoad()
38 {
39 TELEPHONY_LOGI("RuimFile::StartLoad() start");
40 LoadRuimFiles();
41 }
42
ObtainSimOperator()43 std::string RuimFile::ObtainSimOperator()
44 {
45 if (operatorNumeric_.empty()) {
46 std::string imsi = ObtainIMSI();
47 if (imsi.empty()) {
48 TELEPHONY_LOGE("RuimFile::ObtainSimOperator: IMSI is null");
49 return "";
50 }
51 if ((lengthOfMnc_ != UNINITIALIZED_MNC) && (lengthOfMnc_ != UNKNOWN_MNC)) {
52 operatorNumeric_ = imsi.substr(0, MCC_LEN + lengthOfMnc_);
53 }
54 std::string mcc = imsi.substr(0, MCC_LEN);
55 if (operatorNumeric_.empty() && IsValidDecValue(mcc)) {
56 operatorNumeric_ = imsi.substr(0, MCC_LEN + MccPool::ShortestMncLengthFromMcc(std::stoi(mcc)));
57 }
58 }
59 return operatorNumeric_;
60 }
61
ObtainIsoCountryCode()62 std::string RuimFile::ObtainIsoCountryCode()
63 {
64 std::string numeric = ObtainSimOperator();
65 if (numeric.empty()) {
66 TELEPHONY_LOGE("RuimFile ObtainIsoCountryCode: numeric is null");
67 return "";
68 }
69 size_t len = numeric.length();
70 std::string mcc = numeric.substr(0, MCC_LEN);
71 if (len >= MCC_LEN && IsValidDecValue(mcc)) {
72 std::string iso = MccPool::MccCountryCode(std::stoi(mcc));
73 return iso;
74 } else {
75 return "";
76 }
77 }
78
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)79 void RuimFile::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
80 {
81 if (event == nullptr) {
82 TELEPHONY_LOGE("event is nullptr!");
83 return;
84 }
85 auto id = event->GetInnerEventId();
86 TELEPHONY_LOGD("RuimFile::ProcessEvent id %{public}d", id);
87 auto itFunc = memberFuncMap_.find(id);
88 if (itFunc != memberFuncMap_.end()) {
89 auto memberFunc = itFunc->second;
90 if (memberFunc != nullptr) {
91 bool isFileHandleResponse = (this->*memberFunc)(event);
92 ProcessFileLoaded(isFileHandleResponse);
93 }
94 } else {
95 IccFile::ProcessEvent(event);
96 }
97 }
98
ProcessIccRefresh(int msgId)99 void RuimFile::ProcessIccRefresh(int msgId)
100 {
101 LoadRuimFiles();
102 }
103
ProcessFileLoaded(bool response)104 void RuimFile::ProcessFileLoaded(bool response)
105 {
106 if (!response) {
107 return;
108 }
109 fileToGet_ -= LOAD_STEP;
110 TELEPHONY_LOGI("RuimFile::ProcessFileLoaded: %{public}d requested: %{public}d", fileToGet_, fileQueried_);
111 if (ObtainFilesFetched()) {
112 OnAllFilesFetched();
113 } else if (LockQueriedOrNot()) {
114 ProcessLockedAllFilesFetched();
115 } else if (fileToGet_ < 0) {
116 fileToGet_ = 0;
117 }
118 }
119
ProcessLockedAllFilesFetched()120 void RuimFile::ProcessLockedAllFilesFetched()
121 {
122 }
123
OnAllFilesFetched()124 void RuimFile::OnAllFilesFetched()
125 {
126 UpdateLoaded(true);
127 filesFetchedObser_->NotifyObserver(RadioEvent::RADIO_SIM_RECORDS_LOADED, slotId_);
128 PublishSimFileEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SIM_STATE_CHANGED, ICC_STATE_LOADED, "");
129 }
130
ProcessIccReady(const AppExecFwk::InnerEvent::Pointer & event)131 bool RuimFile::ProcessIccReady(const AppExecFwk::InnerEvent::Pointer &event)
132 {
133 TELEPHONY_LOGI("RuimFile::SIM_STATE_READY --received");
134 if (stateManager_->GetCardType() != CardType::SINGLE_MODE_RUIM_CARD) {
135 TELEPHONY_LOGI("invalid RuimFile::SIM_STATE_READY received");
136 return false;
137 }
138 LoadRuimFiles();
139 return false;
140 }
141
ProcessIccLocked(const AppExecFwk::InnerEvent::Pointer & event)142 bool RuimFile::ProcessIccLocked(const AppExecFwk::InnerEvent::Pointer &event)
143 {
144 TELEPHONY_LOGI(
145 "only fetch ELEMENTARY_FILE_LI, ELEMENTARY_FILE_PL and ELEMENTARY_FILE_ICCID in locked state");
146
147 lockQueried_ = true;
148 AppExecFwk::InnerEvent::Pointer eventICCID = BuildCallerInfo(MSG_SIM_OBTAIN_ICCID_DONE);
149 fileController_->ObtainBinaryFile(ELEMENTARY_FILE_ICCID, eventICCID);
150 fileToGet_++;
151 return false;
152 }
153
LoadRuimFiles()154 void RuimFile::LoadRuimFiles()
155 {
156 TELEPHONY_LOGI("LoadRuimFiles started");
157 fileQueried_ = true;
158
159 AppExecFwk::InnerEvent::Pointer eventIMSI = BuildCallerInfo(MSG_SIM_OBTAIN_IMSI_DONE);
160 telRilManager_->GetImsi(slotId_, eventIMSI);
161 fileToGet_++;
162
163 AppExecFwk::InnerEvent::Pointer eventICCID = BuildCallerInfo(MSG_SIM_OBTAIN_ICCID_DONE);
164 fileController_->ObtainBinaryFile(ELEMENTARY_FILE_ICCID, eventICCID);
165 fileToGet_++;
166
167 AppExecFwk::InnerEvent::Pointer eventSpn = BuildCallerInfo(MSG_SIM_OBTAIN_CSIM_SPN_DONE);
168 fileController_->ObtainBinaryFile(ELEMENTARY_FILE_CSIM_SPN, eventSpn);
169 fileToGet_++;
170 }
171
ProcessGetSubscriptionDone(const AppExecFwk::InnerEvent::Pointer & event)172 bool RuimFile::ProcessGetSubscriptionDone(const AppExecFwk::InnerEvent::Pointer &event)
173 {
174 bool isFileHandleResponse = true;
175 return isFileHandleResponse;
176 }
177
ProcessGetIccidDone(const AppExecFwk::InnerEvent::Pointer & event)178 bool RuimFile::ProcessGetIccidDone(const AppExecFwk::InnerEvent::Pointer &event)
179 {
180 bool isFileProcessResponse = true;
181 if (event == nullptr) {
182 TELEPHONY_LOGE("event is nullptr!");
183 return isFileProcessResponse;
184 }
185 std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
186 if (fd == nullptr) {
187 TELEPHONY_LOGE("fd is nullptr!");
188 return isFileProcessResponse;
189 }
190 if (fd->exception == nullptr) {
191 std::string iccData = fd->resultData;
192 TELEPHONY_LOGI("RuimFile::ProcessEvent MSG_SIM_OBTAIN_ICCID_DONE result success");
193 iccId_ = iccData;
194 }
195 return isFileProcessResponse;
196 }
197
ProcessGetImsiDone(const AppExecFwk::InnerEvent::Pointer & event)198 bool RuimFile::ProcessGetImsiDone(const AppExecFwk::InnerEvent::Pointer &event)
199 {
200 bool isFileHandleResponse = true;
201 if (event == nullptr) {
202 TELEPHONY_LOGE("event is nullptr!");
203 return isFileHandleResponse;
204 }
205 std::shared_ptr<std::string> sharedObject = event->GetSharedObject<std::string>();
206 if (sharedObject == nullptr) {
207 TELEPHONY_LOGE("sharedObject is nullptr!");
208 return isFileHandleResponse;
209 }
210 if (sharedObject != nullptr) {
211 imsi_ = *sharedObject;
212 TELEPHONY_LOGI("RuimFile::ProcessEvent MSG_SIM_OBTAIN_IMSI_DONE");
213 SaveCountryCode();
214 if (!imsi_.empty()) {
215 imsiReadyObser_->NotifyObserver(RadioEvent::RADIO_IMSI_LOADED_READY);
216 }
217 }
218 return isFileHandleResponse;
219 }
220
ObtainMdnNumber()221 std::string RuimFile::ObtainMdnNumber()
222 {
223 return phoneNumber_;
224 }
225
ObtainCdmaMin()226 std::string RuimFile::ObtainCdmaMin()
227 {
228 return min2And1_;
229 }
230
ObtainPrlVersion()231 std::string RuimFile::ObtainPrlVersion()
232 {
233 return prlVersion_;
234 }
235
ObtainNAI()236 std::string RuimFile::ObtainNAI()
237 {
238 return nai_;
239 }
ObtainMdn()240 std::string RuimFile::ObtainMdn()
241 {
242 return mdn_;
243 }
244
ObtainMin()245 std::string RuimFile::ObtainMin()
246 {
247 return min_;
248 }
249
ObtainSid()250 std::string RuimFile::ObtainSid()
251 {
252 return systemId_;
253 }
254
ObtainNid()255 std::string RuimFile::ObtainNid()
256 {
257 return networkId_;
258 }
259
ObtainCsimSpnDisplayCondition()260 bool RuimFile::ObtainCsimSpnDisplayCondition()
261 {
262 return displayConditionOfCsimSpn_;
263 }
264
InitMemberFunc()265 void RuimFile::InitMemberFunc()
266 {
267 memberFuncMap_[RadioEvent::RADIO_SIM_STATE_READY] = &RuimFile::ProcessIccReady;
268 memberFuncMap_[RadioEvent::RADIO_SIM_STATE_LOCKED] = &RuimFile::ProcessIccLocked;
269 memberFuncMap_[RadioEvent::RADIO_SIM_STATE_SIMLOCK] = &RuimFile::ProcessIccLocked;
270 memberFuncMap_[MSG_SIM_OBTAIN_IMSI_DONE] = &RuimFile::ProcessGetImsiDone;
271 memberFuncMap_[MSG_SIM_OBTAIN_ICCID_DONE] = &RuimFile::ProcessGetIccidDone;
272 memberFuncMap_[MSG_SIM_OBTAIN_CDMA_SUBSCRIPTION_DONE] = &RuimFile::ProcessGetSubscriptionDone;
273 memberFuncMap_[MSG_SIM_OBTAIN_CSIM_SPN_DONE] = &RuimFile::ProcessGetSpnDone;
274 }
275
ProcessGetSpnDone(const AppExecFwk::InnerEvent::Pointer & event)276 bool RuimFile::ProcessGetSpnDone(const AppExecFwk::InnerEvent::Pointer &event)
277 {
278 bool isFileProcessResponse = true;
279 if (event == nullptr) {
280 TELEPHONY_LOGE("event is nullptr!");
281 return isFileProcessResponse;
282 }
283 std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
284 if (fd == nullptr) {
285 TELEPHONY_LOGE("fd is nullptr!");
286 return isFileProcessResponse;
287 }
288 if (fd->exception != nullptr) {
289 TELEPHONY_LOGE("EfCsimSpnFileWanted ProcessParseFile get exception");
290 return isFileProcessResponse;
291 }
292 std::string iccData = fd->resultData;
293 if (iccData.empty()) {
294 TELEPHONY_LOGE("EfCsimSpnFileWanted ProcessParseFile get empty data");
295 return isFileProcessResponse;
296 }
297 int dataLen = 0;
298 std::shared_ptr<unsigned char> fileData = SIMUtils::HexStringConvertToBytes(iccData, dataLen);
299 unsigned char* data = fileData.get();
300 displayConditionOfCsimSpn_ = ((static_cast<unsigned int>(SPN_FLAG) & static_cast<unsigned int>(data[0])) != 0);
301
302 int encoding = static_cast<int>(data[ENCODING_POS]);
303 int language = static_cast<int>(data[LANG_POS]);
304 unsigned char spnData[BUFFER_SIZE] = {0};
305
306 int len = ((dataLen - FLAG_NUM) < MAX_DATA_BYTE) ? (dataLen - FLAG_NUM) : MAX_DATA_BYTE;
307 SIMUtils::ArrayCopy(data, FLAG_NUM, spnData, 0, len);
308
309 int numBytes = 0;
310 int spnDataLen = strlen((char *)spnData);
311 for (numBytes = 0; numBytes < spnDataLen; numBytes++) {
312 if ((spnData[numBytes] & BYTE_NUM) == BYTE_NUM) {
313 break;
314 }
315 }
316
317 if (numBytes == 0) {
318 UpdateSPN("");
319 return isFileProcessResponse;
320 }
321 TELEPHONY_LOGI("EfCsimSpnFileWanted encoding is %{public}d, languange is %{public}d", encoding, language);
322 ParseSpnName(encoding, spnData, numBytes);
323 return isFileProcessResponse;
324 }
ParseSpnName(int encodeType,const unsigned char * spnData,int dataLen)325 void RuimFile::ParseSpnName(int encodeType, const unsigned char* spnData, int dataLen)
326 {
327 switch (encodeType) {
328 case CSIM_SPN_OCTET:
329 case CSIM_SPN_LATIN: {
330 std::string spnName((char*)spnData, 0, dataLen);
331 UpdateSPN(spnName);
332 }
333 break;
334 case CSIM_SPN_IA5:
335 case CSIM_SPN_7BIT_ALPHABET: {
336 std::string spnName((char*)spnData, 0, dataLen);
337 UpdateSPN(spnName);
338 }
339 break;
340 case CSIM_SPN_7BIT_ASCII: {
341 std::string spnName((char*)spnData, 0, dataLen);
342 if (SIMUtils::IsShowableAsciiOnly(spnName)) {
343 UpdateSPN(spnName);
344 } else {
345 TELEPHONY_LOGI("EfCsimSpnFileWanted Some corruption in SPN decoding = %{public}s", spnName.data());
346 }
347 }
348 break;
349 case CSIM_SPN_UNICODE_16: {
350 int outlen = 0;
351 std::shared_ptr<char16_t> cs = SIMUtils::CharsConvertToChar16(spnData, dataLen, outlen, true);
352 std::u16string hs(cs.get(), 0, outlen);
353 std::string spnName = Str16ToStr8(hs);
354 TELEPHONY_LOGI("ENCODING_UNICODE_16 spn name = %{public}s", spnName.c_str());
355 UpdateSPN(spnName);
356 }
357 break;
358 default:
359 TELEPHONY_LOGI("SPN encoding not supported");
360 }
361 }
362
ObtainSpnCondition(bool roaming,const std::string & operatorNum)363 int RuimFile::ObtainSpnCondition(bool roaming, const std::string &operatorNum)
364 {
365 return 0;
366 }
367
UpdateVoiceMail(const std::string & mailName,const std::string & mailNumber)368 bool RuimFile::UpdateVoiceMail(const std::string &mailName, const std::string &mailNumber)
369 {
370 // cdma not support
371 return false;
372 }
373
SetVoiceMailCount(int32_t voiceMailCount)374 bool RuimFile::SetVoiceMailCount(int32_t voiceMailCount)
375 {
376 // cdma not support
377 return false;
378 }
379
SetVoiceCallForwarding(bool enable,const std::string & number)380 bool RuimFile::SetVoiceCallForwarding(bool enable, const std::string &number)
381 {
382 // cdma not support
383 return false;
384 }
385
~RuimFile()386 RuimFile::~RuimFile() {}
387 } // namespace Telephony
388 } // namespace OHOS
389