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