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