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