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