• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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