1 /*
2 * Copyright (C) 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 "esim_file.h"
17
18 #include <unistd.h>
19
20 #include "common_event_manager.h"
21 #include "common_event_support.h"
22 #include "core_manager_inner.h"
23 #include "core_service.h"
24 #include "parameters.h"
25 #include "radio_event.h"
26 #include "sim_number_decode.h"
27 #include "str_convert.h"
28 #include "telephony_common_utils.h"
29 #include "telephony_ext_wrapper.h"
30 #include "telephony_state_registry_client.h"
31 #include "telephony_tag_def.h"
32 #include "vcard_utils.h"
33 using namespace OHOS::AppExecFwk;
34 using namespace OHOS::EventFwk;
35
36 namespace OHOS {
37 namespace Telephony {
EsimFile(std::shared_ptr<SimStateManager> simStateManager)38 EsimFile::EsimFile(std::shared_ptr<SimStateManager> simStateManager) : IccFile("EsimFile", simStateManager)
39 {
40 currentChannelId_ = 0;
41 InitMemberFunc();
42 InitChanneMemberFunc();
43 }
44
StartLoad()45 void EsimFile::StartLoad() {}
46
ObtainChannelSuccessExclusive()47 ResultInnerCode EsimFile::ObtainChannelSuccessExclusive()
48 {
49 std::u16string aid = OHOS::Telephony::ToUtf16(ISDR_AID);
50 std::lock_guard<std::mutex> occupyLck(occupyChannelMutex_);
51 // The channel is in use.
52 if (IsLogicChannelOpen()) {
53 TELEPHONY_LOGE("The channel is in use");
54 return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_IN_USE;
55 }
56
57 ProcessEsimOpenChannel(aid);
58 std::unique_lock<std::mutex> lck(openChannelMutex_);
59 if (!openChannelCv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SHORT_SECOND_FOR_ESIM),
60 [this]() { return IsLogicChannelOpen(); })) {
61 TELEPHONY_LOGE("wait cv failed!");
62 }
63
64 bool isOpenChannelSuccess = IsLogicChannelOpen();
65 if (isOpenChannelSuccess) {
66 aidStr_ = aid;
67 return ResultInnerCode::RESULT_EUICC_CARD_OK;
68 }
69
70 TELEPHONY_LOGE("failed to open the channel");
71 return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_OPEN_FAILED;
72 }
73
74 /**
75 * @brief Channels that support the same aid are not disabled when sending data.
76 */
ObtainChannelSuccessAlllowSameAidReuse(const std::u16string & aid)77 ResultInnerCode EsimFile::ObtainChannelSuccessAlllowSameAidReuse(const std::u16string &aid)
78 {
79 std::lock_guard<std::mutex> lck(occupyChannelMutex_);
80 if (!IsValidAidForAllowSameAidReuseChannel(aid)) {
81 TELEPHONY_LOGE("Aid invalid");
82 return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_OTHER_AID;
83 }
84
85 if (!IsLogicChannelOpen()) {
86 ProcessEsimOpenChannel(aid);
87 std::unique_lock<std::mutex> lck(openChannelMutex_);
88 if (!openChannelCv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SHORT_SECOND_FOR_ESIM),
89 [this]() { return IsLogicChannelOpen(); })) {
90 TELEPHONY_LOGE("wait cv failed!");
91 }
92 }
93
94 bool isOpenChannelSuccess = IsLogicChannelOpen();
95 if (isOpenChannelSuccess) {
96 aidStr_ = aid;
97 return ResultInnerCode::RESULT_EUICC_CARD_OK;
98 }
99 TELEPHONY_LOGE("failed to open the channel");
100 return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_OPEN_FAILED;
101 }
102
SyncCloseChannel()103 void EsimFile::SyncCloseChannel()
104 {
105 uint32_t tryCnt = 0;
106 std::lock_guard<std::mutex> lck(occupyChannelMutex_);
107 while (IsLogicChannelOpen()) {
108 ProcessEsimCloseChannel();
109 std::unique_lock<std::mutex> lck(closeChannelMutex_);
110 if (closeChannelCv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SHORT_SECOND_FOR_ESIM),
111 [this]() { return !IsLogicChannelOpen(); })) {
112 break;
113 }
114 tryCnt++;
115 if (tryCnt >= NUMBER_TWO) {
116 TELEPHONY_LOGE("failed to close the channel");
117 break;
118 }
119 TELEPHONY_LOGW("wait cv failed, retry close channel at %{public}u", tryCnt);
120 }
121 currentChannelId_ = 0;
122 aidStr_ = u"";
123 }
124
ObtainEid()125 std::string EsimFile::ObtainEid()
126 {
127 if (!eid_.empty()) {
128 return eid_;
129 }
130 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
131 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
132 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
133 return "";
134 }
135 AppExecFwk::InnerEvent::Pointer eventGetEid = BuildCallerInfo(MSG_ESIM_OBTAIN_EID_DONE);
136 if (!ProcessObtainEid(slotId_, eventGetEid)) {
137 TELEPHONY_LOGE("ProcessObtainEid encode failed");
138 SyncCloseChannel();
139 return "";
140 }
141 // wait profileInfo is ready
142 isEidReady_ = false;
143 std::unique_lock<std::mutex> lock(getEidMutex_);
144 if (!getEidCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
145 [this]() { return isEidReady_; })) {
146 SyncCloseChannel();
147 return "";
148 }
149 SyncCloseChannel();
150 return eid_;
151 }
152
GetEuiccProfileInfoList()153 GetEuiccProfileInfoListInnerResult EsimFile::GetEuiccProfileInfoList()
154 {
155 euiccProfileInfoList_ = GetEuiccProfileInfoListInnerResult();
156 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
157 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
158 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
159 euiccProfileInfoList_.result_ = static_cast<int32_t>(resultFlag);
160 return euiccProfileInfoList_;
161 }
162 recvCombineStr_ = "";
163 AppExecFwk::InnerEvent::Pointer eventRequestAllProfiles = BuildCallerInfo(MSG_ESIM_REQUEST_ALL_PROFILES);
164 if (!ProcessRequestAllProfiles(slotId_, eventRequestAllProfiles)) {
165 TELEPHONY_LOGE("ProcessRequestAllProfiles encode failed");
166 SyncCloseChannel();
167 euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
168 return euiccProfileInfoList_;
169 }
170 isAllProfileInfoReady_ = false;
171 std::unique_lock<std::mutex> lock(allProfileInfoMutex_);
172 if (!allProfileInfoCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
173 [this]() { return isAllProfileInfoReady_; })) {
174 SyncCloseChannel();
175 euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
176 return euiccProfileInfoList_;
177 }
178 SyncCloseChannel();
179 return euiccProfileInfoList_;
180 }
181
GetEuiccInfo()182 EuiccInfo EsimFile::GetEuiccInfo()
183 {
184 eUiccInfo_ = EuiccInfo();
185 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
186 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
187 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
188 return EuiccInfo();
189 }
190 AppExecFwk::InnerEvent::Pointer eventEUICCInfo1 = BuildCallerInfo(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE);
191 if (!ProcessObtainEuiccInfo1(slotId_, eventEUICCInfo1)) {
192 TELEPHONY_LOGE("ProcessObtainEuiccInfo1 encode failed");
193 SyncCloseChannel();
194 return EuiccInfo();
195 }
196 isEuiccInfo1Ready_ = false;
197 std::unique_lock<std::mutex> lock(euiccInfo1Mutex_);
198 if (!euiccInfo1Cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
199 [this]() { return isEuiccInfo1Ready_; })) {
200 TELEPHONY_LOGE("close channal due to timeout");
201 SyncCloseChannel();
202 return eUiccInfo_;
203 }
204 SyncCloseChannel();
205 return eUiccInfo_;
206 }
207
CopyApdCmdToReqInfo(ApduSimIORequestInfo & requestInfo,ApduCommand * apduCommand)208 void EsimFile::CopyApdCmdToReqInfo(ApduSimIORequestInfo &requestInfo, ApduCommand *apduCommand)
209 {
210 if (apduCommand == nullptr) {
211 TELEPHONY_LOGE("CopyApdCmdToReqInfo failed");
212 return;
213 }
214 requestInfo.serial = nextSerialId_;
215 nextSerialId_++;
216 if (nextSerialId_ >= INT32_MAX) {
217 nextSerialId_ = 0;
218 }
219 requestInfo.channelId = static_cast<int32_t>(apduCommand->channel);
220 requestInfo.type = static_cast<int32_t>(apduCommand->data.cla);
221 requestInfo.instruction = static_cast<int32_t>(apduCommand->data.ins);
222 requestInfo.p1 = static_cast<int32_t>(apduCommand->data.p1);
223 requestInfo.p2 = static_cast<int32_t>(apduCommand->data.p2);
224 requestInfo.p3 = static_cast<int32_t>(apduCommand->data.p3);
225 requestInfo.data = apduCommand->data.cmdHex;
226 TELEPHONY_LOGI("SEND_DATA reqInfo.serial=%{public}d, \
227 reqInfo.channelId=%{public}d, reqInfo.type=%{public}d, reqInfo.instruction=%{public}d, \
228 reqInfo.p1=%{public}02X, reqInfo.p2=%{public}02X, reqInfo.p3=%{public}02X, reqInfo.data.length=%{public}zu",
229 requestInfo.serial, requestInfo.channelId, requestInfo.type, requestInfo.instruction, requestInfo.p1,
230 requestInfo.p2, requestInfo.p3, requestInfo.data.length());
231 }
232
CommBuildOneApduReqInfo(ApduSimIORequestInfo & requestInfo,std::shared_ptr<Asn1Builder> & builder)233 void EsimFile::CommBuildOneApduReqInfo(ApduSimIORequestInfo &requestInfo, std::shared_ptr<Asn1Builder> &builder)
234 {
235 if (builder == nullptr) {
236 TELEPHONY_LOGE("builder is nullptr");
237 return;
238 }
239 std::string hexStr;
240 uint32_t hexStrLen = builder->Asn1BuilderToHexStr(hexStr);
241 if (hexStrLen == 0) {
242 TELEPHONY_LOGE("hexStrLen is zero");
243 return;
244 }
245 RequestApduBuild codec(currentChannelId_);
246 codec.BuildStoreData(hexStr);
247 std::list<std::unique_ptr<ApduCommand>> list = codec.GetCommands();
248 if (list.empty()) {
249 TELEPHONY_LOGE("node is empty");
250 return;
251 }
252 std::unique_ptr<ApduCommand> apduCommand = std::move(list.front());
253 CopyApdCmdToReqInfo(requestInfo, apduCommand.get());
254 }
255
ProcessObtainEid(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)256 bool EsimFile::ProcessObtainEid(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
257 {
258 if (!IsLogicChannelOpen()) {
259 return false;
260 }
261 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EID);
262 if (builder == nullptr) {
263 TELEPHONY_LOGE("builder is nullptr");
264 return false;
265 }
266 std::vector<uint8_t> eidTags;
267 eidTags.push_back(static_cast<unsigned char>(TAG_ESIM_EID));
268 builder->Asn1AddChildAsBytes(TAG_ESIM_TAG_LIST, eidTags, eidTags.size());
269 ApduSimIORequestInfo requestInfo;
270 CommBuildOneApduReqInfo(requestInfo, builder);
271 if (telRilManager_ == nullptr) {
272 return false;
273 }
274 telRilManager_->SimTransmitApduLogicalChannel(slotId, requestInfo, responseEvent);
275 return true;
276 }
277
ProcessObtainEuiccInfo1(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)278 bool EsimFile::ProcessObtainEuiccInfo1(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
279 {
280 if (!IsLogicChannelOpen()) {
281 return false;
282 }
283 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EUICC_INFO_1);
284 ApduSimIORequestInfo requestInfo;
285 CommBuildOneApduReqInfo(requestInfo, builder);
286 if (telRilManager_ == nullptr) {
287 return false;
288 }
289 telRilManager_->SimTransmitApduLogicalChannel(slotId, requestInfo, responseEvent);
290 return true;
291 }
292
ProcessRequestAllProfiles(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)293 bool EsimFile::ProcessRequestAllProfiles(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
294 {
295 if (!IsLogicChannelOpen()) {
296 return false;
297 }
298 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_PROFILES);
299 if (builder == nullptr) {
300 TELEPHONY_LOGE("builder is nullptr");
301 return false;
302 }
303 unsigned char EUICC_PROFILE_TAGS[] = {
304 static_cast<unsigned char>(TAG_ESIM_ICCID),
305 static_cast<unsigned char>(TAG_ESIM_NICKNAME),
306 static_cast<unsigned char>(TAG_ESIM_OBTAIN_OPERATOR_NAME),
307 static_cast<unsigned char>(TAG_ESIM_PROFILE_NAME),
308 static_cast<unsigned char>(TAG_ESIM_OPERATOR_ID),
309 static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE / PROFILE_DEFAULT_NUMBER),
310 static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE % PROFILE_DEFAULT_NUMBER),
311 static_cast<unsigned char>(TAG_ESIM_PROFILE_CLASS),
312 static_cast<unsigned char>(TAG_ESIM_PROFILE_POLICY_RULE),
313 static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES / PROFILE_DEFAULT_NUMBER),
314 static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES % PROFILE_DEFAULT_NUMBER),
315 };
316 std::vector<uint8_t> euiccProfileTags;
317 for (const unsigned char tag : EUICC_PROFILE_TAGS) {
318 euiccProfileTags.push_back(tag);
319 }
320 builder->Asn1AddChildAsBytes(TAG_ESIM_TAG_LIST, euiccProfileTags, euiccProfileTags.size());
321 ApduSimIORequestInfo requestInfo;
322 CommBuildOneApduReqInfo(requestInfo, builder);
323 if (telRilManager_ == nullptr) {
324 return false;
325 }
326 telRilManager_->SimTransmitApduLogicalChannel(slotId, requestInfo, responseEvent);
327 return true;
328 }
329
IsLogicChannelOpen()330 bool EsimFile::IsLogicChannelOpen()
331 {
332 if (currentChannelId_ > 0) {
333 TELEPHONY_LOGI("opened channel id:%{public}d", currentChannelId_.load());
334 return true;
335 }
336 return false;
337 }
338
ProcessEsimOpenChannel(const std::u16string & aid)339 void EsimFile::ProcessEsimOpenChannel(const std::u16string &aid)
340 {
341 std::string appId = OHOS::Telephony::ToUtf8(aid);
342 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_ESIM_OPEN_CHANNEL_DONE);
343 if (telRilManager_ == nullptr) {
344 return;
345 }
346 TELEPHONY_LOGI("set req to open channel:%{public}d", currentChannelId_.load());
347 telRilManager_->SimOpenLogicalChannel(slotId_, appId, PARAMETER_TWO, response);
348 return;
349 }
350
ProcessEsimOpenChannelDone(const AppExecFwk::InnerEvent::Pointer & event)351 bool EsimFile::ProcessEsimOpenChannelDone(const AppExecFwk::InnerEvent::Pointer &event)
352 {
353 if (event == nullptr) {
354 TELEPHONY_LOGE("open logical channel event is nullptr!");
355 return false;
356 }
357 auto resultPtr = event->GetSharedObject<OpenLogicalChannelResponse>();
358 if (resultPtr == nullptr) {
359 TELEPHONY_LOGE("open logical channel fd is nullptr!");
360 return false;
361 }
362 if (resultPtr->channelId <= 0) {
363 TELEPHONY_LOGE("channelId is invalid!");
364 return false;
365 }
366
367 {
368 std::lock_guard<std::mutex> lock(openChannelMutex_);
369 TELEPHONY_LOGI("Logical channel %{public}d->%{public}d open successfully. Notifying waiting thread.",
370 currentChannelId_.load(), resultPtr->channelId);
371 currentChannelId_ = resultPtr->channelId;
372 }
373
374 if (occupyChannelMutex_.try_lock()) {
375 // caller exits waiting, thus lock is obtained and the channel needs released
376 ProcessEsimCloseSpareChannel();
377 occupyChannelMutex_.unlock();
378 return false;
379 }
380
381 openChannelCv_.notify_all();
382 return true;
383 }
384
ProcessEsimCloseChannel()385 void EsimFile::ProcessEsimCloseChannel()
386 {
387 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_ESIM_CLOSE_CHANNEL_DONE);
388 if (telRilManager_ == nullptr) {
389 return;
390 }
391 TELEPHONY_LOGI("set req to close channel:%{public}d", currentChannelId_.load());
392 telRilManager_->SimCloseLogicalChannel(slotId_, currentChannelId_, response);
393 return;
394 }
395
ProcessEsimCloseChannelDone(const AppExecFwk::InnerEvent::Pointer & event)396 bool EsimFile::ProcessEsimCloseChannelDone(const AppExecFwk::InnerEvent::Pointer &event)
397 {
398 std::lock_guard<std::mutex> lock(closeChannelMutex_);
399 currentChannelId_ = 0;
400 aidStr_ = u"";
401 TELEPHONY_LOGI("Logical channel closed successfully. Notifying waiting thread.");
402 closeChannelCv_.notify_all();
403 return true;
404 }
405
ProcessEsimCloseSpareChannel()406 void EsimFile::ProcessEsimCloseSpareChannel()
407 {
408 AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_ESIM_CLOSE_SPARE_CHANNEL_DONE);
409 if (telRilManager_ == nullptr) {
410 return;
411 }
412
413 TELEPHONY_LOGI("set req to close spare channel:%{public}d", currentChannelId_.load());
414 telRilManager_->SimCloseLogicalChannel(slotId_, currentChannelId_, response);
415 }
416
ProcessEsimCloseSpareChannelDone(const AppExecFwk::InnerEvent::Pointer & event)417 bool EsimFile::ProcessEsimCloseSpareChannelDone(const AppExecFwk::InnerEvent::Pointer &event)
418 {
419 std::lock_guard<std::mutex> lock(closeChannelMutex_);
420 TELEPHONY_LOGI("Spare channel %{public}d closed successfully.", currentChannelId_.load());
421 aidStr_ = u"";
422 currentChannelId_ = 0;
423 return true;
424 }
425
MakeVersionString(std::vector<uint8_t> & versionRaw)426 std::string EsimFile::MakeVersionString(std::vector<uint8_t> &versionRaw)
427 {
428 if (versionRaw.size() < NUMBER_THREE) {
429 TELEPHONY_LOGE("versionRaw.size(%{public}zu) error!", versionRaw.size());
430 return "";
431 }
432 std::ostringstream oss;
433 oss << std::hex << std::uppercase << (versionRaw[VERSION_HIGH] & MAX_UINT8) << "." <<
434 (versionRaw[VERSION_MIDDLE] & MAX_UINT8) << "." <<
435 (versionRaw[VERSION_LOW] & MAX_UINT8);
436 return oss.str();
437 }
438
ProcessObtainEidDone(const AppExecFwk::InnerEvent::Pointer & event)439 bool EsimFile::ProcessObtainEidDone(const AppExecFwk::InnerEvent::Pointer &event)
440 {
441 std::shared_ptr<Asn1Node> root = ParseEvent(event);
442 if (root == nullptr) {
443 TELEPHONY_LOGE("Asn1ParseResponse failed");
444 NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
445 return false;
446 }
447 std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_EID);
448 if (profileRoot == nullptr) {
449 TELEPHONY_LOGE("profileRoot is nullptr!");
450 NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
451 return false;
452 }
453 std::vector<uint8_t> outPutBytes;
454 uint32_t byteLen = profileRoot->Asn1AsBytes(outPutBytes);
455 if (byteLen == 0) {
456 TELEPHONY_LOGE("byteLen is zero!");
457 NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
458 return false;
459 }
460 std::string strResult = Asn1Utils::BytesToHexStr(outPutBytes);
461
462 eid_ = strResult;
463 NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
464 return true;
465 }
466
Asn1ParseResponse(const std::vector<uint8_t> & response,uint32_t respLength)467 std::shared_ptr<Asn1Node> EsimFile::Asn1ParseResponse(const std::vector<uint8_t> &response, uint32_t respLength)
468 {
469 if (response.empty() || respLength == 0) {
470 TELEPHONY_LOGE("response null, respLen = %{public}d", respLength);
471 return nullptr;
472 }
473 Asn1Decoder decoder(response, 0, respLength);
474 if (!decoder.Asn1HasNextNode()) {
475 TELEPHONY_LOGE("Empty response");
476 return nullptr;
477 }
478 std::shared_ptr<Asn1Node> node = decoder.Asn1NextNode();
479 return node;
480 }
481
ProcessObtainEuiccInfo1Done(const AppExecFwk::InnerEvent::Pointer & event)482 bool EsimFile::ProcessObtainEuiccInfo1Done(const AppExecFwk::InnerEvent::Pointer &event)
483 {
484 IccFileData rawData;
485 if (!GetRawDataFromEvent(event, rawData)) {
486 TELEPHONY_LOGE("rawData is nullptr within rcvMsg");
487 NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
488 return false;
489 }
490 TELEPHONY_LOGI("input raw data:sw1=%{public}02X, sw2=%{public}02X, length=%{public}zu",
491 rawData.sw1, rawData.sw2, rawData.resultData.length());
492 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(rawData.resultData);
493 uint32_t byteLen = responseByte.size();
494 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
495 if (root == nullptr) {
496 TELEPHONY_LOGE("Asn1ParseResponse error!");
497 NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
498 return false;
499 }
500 if (!ObtainEuiccInfo1ParseTagCtx2(root)) {
501 TELEPHONY_LOGE("ObtainEuiccInfo1ParseTagCtx2 error!");
502 NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
503 return false;
504 }
505 std::string responseHexStr = rawData.resultData;
506 eUiccInfo_.response_ = Str8ToStr16(responseHexStr);
507 TELEPHONY_LOGI("obtain eUiccInfo_ len:%{public}lu", eUiccInfo_.response_.length());
508 NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
509 return true;
510 }
511
ObtainEuiccInfo1ParseTagCtx2(std::shared_ptr<Asn1Node> & root)512 bool EsimFile::ObtainEuiccInfo1ParseTagCtx2(std::shared_ptr<Asn1Node> &root)
513 {
514 std::shared_ptr<Asn1Node> svnNode = root->Asn1GetChild(TAG_ESIM_CTX_2);
515 if (svnNode == nullptr) {
516 TELEPHONY_LOGE("svnNode is nullptr");
517 return false;
518 }
519 std::vector<uint8_t> svnRaw;
520 uint32_t svnRawlen = svnNode->Asn1AsBytes(svnRaw);
521 if (svnRawlen < SVN_RAW_LENGTH_MIN) {
522 TELEPHONY_LOGE("invalid SVN data");
523 return false;
524 }
525 eUiccInfo_.osVersion_ = OHOS::Telephony::ToUtf16(MakeVersionString(svnRaw));
526 return true;
527 }
528
ProcessRequestAllProfilesDone(const AppExecFwk::InnerEvent::Pointer & event)529 bool EsimFile::ProcessRequestAllProfilesDone(const AppExecFwk::InnerEvent::Pointer &event)
530 {
531 if (event == nullptr) {
532 TELEPHONY_LOGE("event is nullptr");
533 NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
534 return false;
535 }
536
537 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
538 if (rcvMsg == nullptr) {
539 TELEPHONY_LOGE("rcvMsg is nullptr");
540 NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
541 return false;
542 }
543
544 newRecvData_ = rcvMsg->fileData;
545 bool isHandleFinish = false;
546 bool retValue = CommMergeRecvData(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_,
547 MSG_ESIM_REQUEST_ALL_PROFILES, isHandleFinish);
548 if (isHandleFinish) {
549 TELEPHONY_LOGI("waits for continuing data...");
550 return retValue;
551 }
552
553 return RealProcessRequestAllProfilesDone();
554 }
555
RealProcessRequestAllProfilesDone()556 bool EsimFile::RealProcessRequestAllProfilesDone()
557 {
558 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
559 uint32_t byteLen = responseByte.size();
560 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
561 if (root == nullptr) {
562 TELEPHONY_LOGE("root is nullptr");
563 NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
564 return false;
565 }
566
567 std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
568 if (profileRoot == nullptr) {
569 TELEPHONY_LOGE("profileRoot is nullptr");
570 NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
571 return false;
572 }
573
574 std::list<std::shared_ptr<Asn1Node>> profileNodes;
575 profileRoot->Asn1GetChildren(TAG_ESIM_PROFILE_INFO, profileNodes);
576 std::shared_ptr<Asn1Node> curNode = nullptr;
577 EuiccProfileInfo euiccProfileInfo = {{0}};
578 euiccProfileInfoList_.profiles_.clear();
579 for (auto it = profileNodes.begin(); it != profileNodes.end(); ++it) {
580 curNode = *it;
581 if (!curNode->Asn1HasChild(TAG_ESIM_ICCID)) {
582 TELEPHONY_LOGE("Profile must have an ICCID.");
583 continue;
584 }
585 BuildBasicProfileInfo(&euiccProfileInfo, curNode);
586 EuiccProfile euiccProfile;
587 ConvertProfileInfoToApiStruct(euiccProfile, euiccProfileInfo);
588 euiccProfileInfoList_.profiles_.push_back(euiccProfile);
589 }
590
591 euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
592 NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
593 TELEPHONY_LOGI("asn decode success");
594 return true;
595 }
596
SplitMccAndMnc(const std::string mccMnc,std::string & mcc,std::string & mnc)597 bool EsimFile::SplitMccAndMnc(const std::string mccMnc, std::string &mcc, std::string &mnc)
598 {
599 std::string mMcc(NUMBER_THREE, '\0');
600 mMcc[NUMBER_ZERO] = mccMnc[NUMBER_ONE];
601 mMcc[NUMBER_ONE] = mccMnc[NUMBER_ZERO];
602 mMcc[NUMBER_TWO] = mccMnc[NUMBER_THREE];
603
604 std::string mMnc(NUMBER_THREE, '\0');
605 if (mccMnc[NUMBER_TWO] == 'F') {
606 mMnc[NUMBER_ZERO] = mccMnc[NUMBER_FIVE];
607 mMnc[NUMBER_ONE] = mccMnc[NUMBER_FOUR];
608 } else {
609 mMnc[NUMBER_ZERO] = mccMnc[NUMBER_FIVE];
610 mMnc[NUMBER_ONE] = mccMnc[NUMBER_FOUR];
611 mMnc[NUMBER_TWO] = mccMnc[NUMBER_TWO];
612 }
613 mcc = mMcc.c_str();
614 mnc = mMnc.c_str();
615 return true;
616 }
617
ConvertProfileInfoToApiStruct(EuiccProfile & dst,EuiccProfileInfo & src)618 void EsimFile::ConvertProfileInfoToApiStruct(EuiccProfile &dst, EuiccProfileInfo &src)
619 {
620 dst.iccId_ = OHOS::Telephony::ToUtf16(src.iccid);
621 dst.nickName_ = OHOS::Telephony::ToUtf16(src.nickname);
622 dst.serviceProviderName_ = OHOS::Telephony::ToUtf16(src.serviceProviderName);
623 dst.profileName_ = OHOS::Telephony::ToUtf16(src.profileName);
624 dst.state_ = static_cast<ProfileState>(src.profileState);
625 dst.profileClass_ = static_cast<ProfileClass>(src.profileClass);
626 dst.policyRules_ = static_cast<PolicyRules>(src.policyRules);
627
628 // split mccMnc to mcc and mnc
629 std::string mcc = "";
630 std::string mnc = "";
631 SplitMccAndMnc(src.operatorId.mccMnc, mcc, mnc);
632 dst.carrierId_.mcc_ = OHOS::Telephony::ToUtf16(mcc);
633 dst.carrierId_.mnc_ = OHOS::Telephony::ToUtf16(mnc);
634 dst.carrierId_.gid1_ = OHOS::Telephony::ToUtf16(src.operatorId.gid1);
635 dst.carrierId_.gid2_ = OHOS::Telephony::ToUtf16(src.operatorId.gid2);
636 dst.accessRules_.clear();
637 }
638
BuildBasicProfileInfo(EuiccProfileInfo * eProfileInfo,std::shared_ptr<Asn1Node> & profileNode)639 void EsimFile::BuildBasicProfileInfo(EuiccProfileInfo *eProfileInfo, std::shared_ptr<Asn1Node> &profileNode)
640 {
641 if (eProfileInfo == nullptr || profileNode == nullptr) {
642 TELEPHONY_LOGE("BuildBasicProfileInfo failed");
643 return;
644 }
645 std::shared_ptr<Asn1Node> iccIdNode = profileNode->Asn1GetChild(TAG_ESIM_ICCID);
646 if (iccIdNode == nullptr) {
647 TELEPHONY_LOGE("iccIdNode is nullptr");
648 return;
649 }
650 std::vector<uint8_t> iccidBytes;
651 uint32_t iccidBytesLen = iccIdNode->Asn1AsBytes(iccidBytes);
652 Asn1Utils::BchToString(iccidBytes, eProfileInfo->iccid);
653 if (profileNode->Asn1HasChild(TAG_ESIM_NICKNAME)) {
654 std::shared_ptr<Asn1Node> nickNameNode = profileNode->Asn1GetChild(TAG_ESIM_NICKNAME);
655 if (nickNameNode == nullptr) {
656 TELEPHONY_LOGE("nickNameNode is nullptr");
657 return;
658 }
659 std::vector<uint8_t> nickNameBytes;
660 nickNameNode->Asn1AsBytes(nickNameBytes);
661 eProfileInfo->nickname = Asn1Utils::BytesToString(nickNameBytes);
662 }
663 if (profileNode->Asn1HasChild(TAG_ESIM_OBTAIN_OPERATOR_NAME)) {
664 std::shared_ptr<Asn1Node> serviceProviderNameNode = profileNode->Asn1GetChild(TAG_ESIM_OBTAIN_OPERATOR_NAME);
665 if (serviceProviderNameNode == nullptr) {
666 TELEPHONY_LOGE("serviceProviderNameNode is nullptr");
667 return;
668 }
669 std::vector<uint8_t> serviceProviderNameBytes;
670 serviceProviderNameNode->Asn1AsBytes(serviceProviderNameBytes);
671 eProfileInfo->serviceProviderName = Asn1Utils::BytesToString(serviceProviderNameBytes);
672 }
673 if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_NAME)) {
674 std::shared_ptr<Asn1Node> profileNameNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_NAME);
675 if (profileNameNode == nullptr) {
676 TELEPHONY_LOGE("profileNameNode is nullptr");
677 return;
678 }
679 std::vector<uint8_t> profileNameBytes;
680 profileNameNode->Asn1AsBytes(profileNameBytes);
681 eProfileInfo->profileName = Asn1Utils::BytesToString(profileNameBytes);
682 }
683 if (profileNode->Asn1HasChild(TAG_ESIM_OPERATOR_ID)) {
684 std::shared_ptr<Asn1Node> pOperatorId = profileNode->Asn1GetChild(TAG_ESIM_OPERATOR_ID);
685 BuildOperatorId(eProfileInfo, pOperatorId);
686 }
687
688 BuildAdvancedProfileInfo(eProfileInfo, profileNode);
689 }
690
BuildAdvancedProfileInfo(EuiccProfileInfo * eProfileInfo,std::shared_ptr<Asn1Node> & profileNode)691 void EsimFile::BuildAdvancedProfileInfo(EuiccProfileInfo *eProfileInfo, std::shared_ptr<Asn1Node> &profileNode)
692 {
693 if (eProfileInfo == nullptr || profileNode == nullptr) {
694 TELEPHONY_LOGE("BuildAdvancedProfileInfo failed");
695 return;
696 }
697 if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_STATE)) {
698 std::shared_ptr<Asn1Node> profileStateNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_STATE);
699 if (profileStateNode == nullptr) {
700 TELEPHONY_LOGE("profileStateNode is nullptr");
701 return;
702 }
703 int32_t ret = profileStateNode->Asn1AsInteger();
704 eProfileInfo->profileState = ((ret == TELEPHONY_ERR_ARGUMENT_INVALID) ? ESIM_PROFILE_STATE_DISABLED : ret);
705 } else {
706 eProfileInfo->profileState = ESIM_PROFILE_STATE_DISABLED;
707 }
708 if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_CLASS)) {
709 std::shared_ptr<Asn1Node> profileClassNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_CLASS);
710 if (profileClassNode == nullptr) {
711 TELEPHONY_LOGE("profileClassNode is nullptr");
712 return;
713 }
714 eProfileInfo->profileClass = profileClassNode->Asn1AsInteger();
715 } else {
716 eProfileInfo->profileClass = PROFILE_CLASS_OPERATIONAL;
717 }
718 if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_POLICY_RULE)) {
719 std::shared_ptr<Asn1Node> profilePolicyRuleNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_POLICY_RULE);
720 if (profilePolicyRuleNode == nullptr) {
721 TELEPHONY_LOGE("profilePolicyRuleNode is nullptr");
722 return;
723 }
724 eProfileInfo->policyRules = profilePolicyRuleNode->Asn1AsBits();
725 }
726 if (profileNode->Asn1HasChild(TAG_ESIM_CARRIER_PRIVILEGE_RULES)) {
727 std::list<std::shared_ptr<Asn1Node>> refArDoNodes;
728 std::shared_ptr<Asn1Node> carrierPrivilegeRulesNode =
729 profileNode->Asn1GetChild(TAG_ESIM_CARRIER_PRIVILEGE_RULES);
730 if (carrierPrivilegeRulesNode == nullptr) {
731 TELEPHONY_LOGE("carrierPrivilegeRulesNode is nullptr");
732 return;
733 }
734 carrierPrivilegeRulesNode->Asn1GetChildren(TAG_ESIM_REF_AR_DO, refArDoNodes);
735 }
736 }
737
BuildOperatorId(EuiccProfileInfo * eProfileInfo,std::shared_ptr<Asn1Node> & operatorIdNode)738 void EsimFile::BuildOperatorId(EuiccProfileInfo *eProfileInfo, std::shared_ptr<Asn1Node> &operatorIdNode)
739 {
740 if (eProfileInfo == nullptr || operatorIdNode == nullptr) {
741 TELEPHONY_LOGE("BuildOperatorId failed");
742 return;
743 }
744 if (operatorIdNode->Asn1HasChild(TAG_ESIM_CTX_0)) {
745 std::shared_ptr<Asn1Node> nodeCtx0 = operatorIdNode->Asn1GetChild(TAG_ESIM_CTX_0);
746 if (nodeCtx0 == nullptr) {
747 TELEPHONY_LOGE("nodeCtx0 is nullptr");
748 return;
749 }
750 nodeCtx0->Asn1AsString(eProfileInfo->operatorId.mccMnc);
751 }
752 if (operatorIdNode->Asn1HasChild(TAG_ESIM_CTX_1)) {
753 std::shared_ptr<Asn1Node> nodeCtx1 = operatorIdNode->Asn1GetChild(TAG_ESIM_CTX_1);
754 if (nodeCtx1 == nullptr) {
755 TELEPHONY_LOGE("nodeCtx1 is nullptr");
756 return;
757 }
758 nodeCtx1->Asn1AsString(eProfileInfo->operatorId.gid1);
759 }
760 if (operatorIdNode->Asn1HasChild(TAG_ESIM_CTX_2)) {
761 std::shared_ptr<Asn1Node> nodeCtx2 = operatorIdNode->Asn1GetChild(TAG_ESIM_CTX_2);
762 if (nodeCtx2 == nullptr) {
763 TELEPHONY_LOGE("nodeCtx2 is nullptr");
764 return;
765 }
766 nodeCtx2->Asn1AsString(eProfileInfo->operatorId.gid2);
767 }
768 return;
769 }
770
DisableProfile(int32_t portIndex,const std::u16string & iccId)771 int32_t EsimFile::DisableProfile(int32_t portIndex, const std::u16string &iccId)
772 {
773 disableProfileResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
774 esimProfile_.portIndex = portIndex;
775 esimProfile_.iccId = iccId;
776
777 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
778 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
779 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
780 disableProfileResult_ = static_cast<int32_t>(resultFlag);
781 return disableProfileResult_;
782 }
783 AppExecFwk::InnerEvent::Pointer eventDisableProfile = BuildCallerInfo(MSG_ESIM_DISABLE_PROFILE);
784 if (!ProcessDisableProfile(slotId_, eventDisableProfile)) {
785 TELEPHONY_LOGE("ProcessDisableProfile encode failed");
786 SyncCloseChannel();
787 return disableProfileResult_;
788 }
789 isDisableProfileReady_ = false;
790 std::unique_lock<std::mutex> lock(disableProfileMutex_);
791 if (!disableProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
792 [this]() { return isDisableProfileReady_; })) {
793 SyncCloseChannel();
794 return disableProfileResult_;
795 }
796 SyncCloseChannel();
797 return disableProfileResult_;
798 }
799
ObtainSmdsAddress(int32_t portIndex)800 std::string EsimFile::ObtainSmdsAddress(int32_t portIndex)
801 {
802 esimProfile_.portIndex = portIndex;
803 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
804 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
805 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
806 return "";
807 }
808 AppExecFwk::InnerEvent::Pointer eventObtainSmdsAddress = BuildCallerInfo(MSG_ESIM_OBTAIN_SMDS_ADDRESS);
809 if (!ProcessObtainSmdsAddress(slotId_, eventObtainSmdsAddress)) {
810 TELEPHONY_LOGE("ProcessObtainSmdsAddress encode failed");
811 SyncCloseChannel();
812 return "";
813 }
814 isSmdsAddressReady_ = false;
815 std::unique_lock<std::mutex> lock(smdsAddressMutex_);
816 if (!smdsAddressCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
817 [this]() { return isSmdsAddressReady_; })) {
818 SyncCloseChannel();
819 return "";
820 }
821 SyncCloseChannel();
822 return smdsAddress_;
823 }
824
ObtainRulesAuthTable(int32_t portIndex)825 EuiccRulesAuthTable EsimFile::ObtainRulesAuthTable(int32_t portIndex)
826 {
827 esimProfile_.portIndex = portIndex;
828 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
829 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
830 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
831 return EuiccRulesAuthTable();
832 }
833 AppExecFwk::InnerEvent::Pointer eventRequestRulesAuthTable = BuildCallerInfo(MSG_ESIM_REQUEST_RULES_AUTH_TABLE);
834 if (!ProcessRequestRulesAuthTable(slotId_, eventRequestRulesAuthTable)) {
835 TELEPHONY_LOGE("ProcessRequestRulesAuthTable encode failed");
836 SyncCloseChannel();
837 return EuiccRulesAuthTable();
838 }
839 isRulesAuthTableReady_ = false;
840 std::unique_lock<std::mutex> lock(rulesAuthTableMutex_);
841 if (!rulesAuthTableCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
842 [this]() { return isRulesAuthTableReady_; })) {
843 SyncCloseChannel();
844 return EuiccRulesAuthTable();
845 }
846 SyncCloseChannel();
847 return eUiccRulesAuthTable_;
848 }
849
ObtainEuiccChallenge(int32_t portIndex)850 ResponseEsimInnerResult EsimFile::ObtainEuiccChallenge(int32_t portIndex)
851 {
852 responseChallengeResult_ = ResponseEsimInnerResult();
853 esimProfile_.portIndex = portIndex;
854 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
855 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
856 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
857 responseChallengeResult_.resultCode_ = static_cast<int32_t>(resultFlag);
858 return responseChallengeResult_;
859 }
860 AppExecFwk::InnerEvent::Pointer eventEUICCChanllenge = BuildCallerInfo(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE);
861 if (!ProcessObtainEuiccChallenge(slotId_, eventEUICCChanllenge)) {
862 TELEPHONY_LOGE("ProcessObtainEuiccChallenge encode failed");
863 SyncCloseChannel();
864 responseChallengeResult_.resultCode_ =
865 static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
866 return responseChallengeResult_;
867 }
868 isEuiccChallengeReady_ = false;
869 std::unique_lock<std::mutex> lock(euiccChallengeMutex_);
870 if (!euiccChallengeCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
871 [this]() { return isEuiccChallengeReady_; })) {
872 SyncCloseChannel();
873 responseChallengeResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
874 return responseChallengeResult_;
875 }
876 SyncCloseChannel();
877 return responseChallengeResult_;
878 }
879
ProcessDisableProfile(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)880 bool EsimFile::ProcessDisableProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
881 {
882 if (!IsLogicChannelOpen()) {
883 return false;
884 }
885 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_DISABLE_PROFILE);
886 std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
887 if (builder == nullptr || subBuilder == nullptr) {
888 TELEPHONY_LOGE("get builder failed");
889 return false;
890 }
891 std::vector<uint8_t> iccidBytes;
892 std::string str = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
893 Asn1Utils::BcdToBytes(str, iccidBytes);
894 subBuilder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
895 std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
896 if (subNode == nullptr) {
897 return false;
898 }
899 builder->Asn1AddChild(subNode);
900 builder->Asn1AddChildAsBoolean(TAG_ESIM_CTX_1, true);
901 ApduSimIORequestInfo reqInfo;
902 CommBuildOneApduReqInfo(reqInfo, builder);
903 if (telRilManager_ == nullptr) {
904 return false;
905 }
906 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
907 if (apduResult == TELEPHONY_ERR_FAIL) {
908 return false;
909 }
910 return true;
911 }
912
ProcessObtainSmdsAddress(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)913 bool EsimFile::ProcessObtainSmdsAddress(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
914 {
915 if (!IsLogicChannelOpen()) {
916 return false;
917 }
918 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_CONFIGURED_ADDRESSES);
919 if (builder == nullptr) {
920 TELEPHONY_LOGE("builder is nullptr");
921 return false;
922 }
923 ApduSimIORequestInfo reqInfo;
924 CommBuildOneApduReqInfo(reqInfo, builder);
925 if (telRilManager_ == nullptr) {
926 return false;
927 }
928 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
929 if (apduResult == TELEPHONY_ERR_FAIL) {
930 return false;
931 }
932 return true;
933 }
934
ProcessRequestRulesAuthTable(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)935 bool EsimFile::ProcessRequestRulesAuthTable(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
936 {
937 if (!IsLogicChannelOpen()) {
938 return false;
939 }
940 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_RAT);
941 ApduSimIORequestInfo reqInfo;
942 CommBuildOneApduReqInfo(reqInfo, builder);
943 if (telRilManager_ == nullptr) {
944 return false;
945 }
946 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
947 if (apduResult == TELEPHONY_ERR_FAIL) {
948 return false;
949 }
950 return true;
951 }
952
ProcessObtainEuiccChallenge(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)953 bool EsimFile::ProcessObtainEuiccChallenge(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
954 {
955 if (!IsLogicChannelOpen()) {
956 return false;
957 }
958 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EUICC_CHALLENGE);
959 if (builder == nullptr) {
960 TELEPHONY_LOGE("builder is nullptr");
961 return false;
962 }
963 ApduSimIORequestInfo reqInfo;
964 CommBuildOneApduReqInfo(reqInfo, builder);
965 if (telRilManager_ == nullptr) {
966 return false;
967 }
968 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
969 if (apduResult == TELEPHONY_ERR_FAIL) {
970 return false;
971 }
972 return true;
973 }
974
ProcessDisableProfileDone(const AppExecFwk::InnerEvent::Pointer & event)975 bool EsimFile::ProcessDisableProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
976 {
977 std::shared_ptr<Asn1Node> root = ParseEvent(event);
978 if (root == nullptr) {
979 TELEPHONY_LOGE("Asn1ParseResponse failed");
980 NotifyReady(disableProfileMutex_, isDisableProfileReady_, disableProfileCv_);
981 return false;
982 }
983 std::shared_ptr<Asn1Node> pAsn1Node = root->Asn1GetChild(TAG_ESIM_CTX_0);
984 if (pAsn1Node == nullptr) {
985 TELEPHONY_LOGE("pAsn1Node is nullptr");
986 NotifyReady(disableProfileMutex_, isDisableProfileReady_, disableProfileCv_);
987 return false;
988 }
989 disableProfileResult_ = pAsn1Node->Asn1AsInteger();
990 NotifyReady(disableProfileMutex_, isDisableProfileReady_, disableProfileCv_);
991 return true;
992 }
993
ProcessObtainSmdsAddressDone(const AppExecFwk::InnerEvent::Pointer & event)994 bool EsimFile::ProcessObtainSmdsAddressDone(const AppExecFwk::InnerEvent::Pointer &event)
995 {
996 std::shared_ptr<Asn1Node> root = ParseEvent(event);
997 if (root == nullptr) {
998 TELEPHONY_LOGE("Asn1ParseResponse failed");
999 NotifyReady(smdsAddressMutex_, isSmdsAddressReady_, smdsAddressCv_);
1000 return false;
1001 }
1002 std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_1);
1003 if (profileRoot == nullptr) {
1004 TELEPHONY_LOGE("profileRoot is nullptr!");
1005 NotifyReady(smdsAddressMutex_, isSmdsAddressReady_, smdsAddressCv_);
1006 return false;
1007 }
1008 std::vector<uint8_t> outPutBytes;
1009 profileRoot->Asn1AsBytes(outPutBytes);
1010 smdsAddress_ = Asn1Utils::BytesToString(outPutBytes);
1011 NotifyReady(smdsAddressMutex_, isSmdsAddressReady_, smdsAddressCv_);
1012 return true;
1013 }
1014
CarrierIdentifiers(const std::vector<uint8_t> & mccMncData,int mccMncLen,const std::u16string & gid1,const std::u16string & gid2)1015 struct CarrierIdentifier CarrierIdentifiers(const std::vector<uint8_t> &mccMncData, int mccMncLen,
1016 const std::u16string &gid1, const std::u16string &gid2)
1017 {
1018 std::string strResult = Asn1Utils::BytesToHexStr(mccMncData);
1019 std::string mMcc(NUMBER_THREE, '\0');
1020 mMcc[NUMBER_ZERO] = strResult[NUMBER_ONE];
1021 mMcc[NUMBER_ONE] = strResult[NUMBER_ZERO];
1022 mMcc[NUMBER_TWO] = strResult[NUMBER_THREE];
1023 std::string mMnc(NUMBER_THREE, '\0');
1024 mMnc[NUMBER_ZERO] = strResult[NUMBER_FIVE];
1025 mMnc[NUMBER_ONE] = strResult[NUMBER_FOUR];
1026 if (strResult[NUMBER_TWO] != 'F') {
1027 mMnc[NUMBER_TWO] = strResult[NUMBER_TWO];
1028 }
1029 CarrierIdentifier carrierId;
1030 carrierId.mcc_ = OHOS::Telephony::ToUtf16(std::string(mMcc.c_str()));
1031 carrierId.mnc_ = OHOS::Telephony::ToUtf16(std::string(mMnc.c_str()));
1032 carrierId.gid1_ = gid1;
1033 carrierId.gid2_ = gid2;
1034 return carrierId;
1035 }
1036
buildCarrierIdentifiers(std::shared_ptr<Asn1Node> & root)1037 struct CarrierIdentifier buildCarrierIdentifiers(std::shared_ptr<Asn1Node> &root)
1038 {
1039 std::u16string gid1;
1040 std::u16string gid2;
1041 std::vector<uint8_t> gid1Byte;
1042 std::vector<uint8_t> gid2Byte;
1043 std::string strResult;
1044 CarrierIdentifier defaultCarrier = CarrierIdentifiers({}, 0, u"", u"");
1045 if (root->Asn1HasChild(TAG_ESIM_CTX_1)) {
1046 std::shared_ptr<Asn1Node> node = root->Asn1GetChild(TAG_ESIM_CTX_1);
1047 if (node == nullptr) {
1048 return defaultCarrier;
1049 }
1050 node->Asn1AsBytes(gid1Byte);
1051 strResult = Asn1Utils::BytesToHexStr(gid1Byte);
1052 gid1 = OHOS::Telephony::ToUtf16(strResult);
1053 }
1054 if (root->Asn1HasChild(TAG_ESIM_CTX_2)) {
1055 std::shared_ptr<Asn1Node> node = root->Asn1GetChild(TAG_ESIM_CTX_2);
1056 if (node == nullptr) {
1057 return defaultCarrier;
1058 }
1059 node->Asn1AsBytes(gid2Byte);
1060 strResult = Asn1Utils::BytesToHexStr(gid2Byte);
1061 gid2 = OHOS::Telephony::ToUtf16(strResult);
1062 }
1063
1064 std::vector<uint8_t> mccMnc;
1065 std::shared_ptr<Asn1Node> ctx0Node = root->Asn1GetChild(TAG_ESIM_CTX_0);
1066 if (ctx0Node == nullptr) {
1067 return defaultCarrier;
1068 }
1069 uint32_t mccMncLen = ctx0Node->Asn1AsBytes(mccMnc);
1070 CarrierIdentifier myCarrier = CarrierIdentifiers(mccMnc, mccMncLen, gid1, gid2);
1071 return myCarrier;
1072 }
1073
RequestRulesAuthTableParseTagCtxComp0(std::shared_ptr<Asn1Node> & root)1074 bool EsimFile::RequestRulesAuthTableParseTagCtxComp0(std::shared_ptr<Asn1Node> &root)
1075 {
1076 std::list<std::shared_ptr<Asn1Node>> Nodes;
1077 std::list<std::shared_ptr<Asn1Node>> opIdNodes;
1078 root->Asn1GetChildren(TAG_ESIM_CTX_COMP_0, Nodes);
1079 for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
1080 std::shared_ptr<Asn1Node> node = *it;
1081 if (node == nullptr) {
1082 return false;
1083 }
1084 std::shared_ptr<Asn1Node> grandson = node->Asn1GetGrandson(TAG_ESIM_SEQUENCE, TAG_ESIM_CTX_COMP_1);
1085 if (grandson == nullptr) {
1086 return false;
1087 }
1088 int32_t opIdNodesRes = grandson->Asn1GetChildren(TAG_ESIM_SEQUENCE, opIdNodes);
1089 if (opIdNodesRes != 0) {
1090 return false;
1091 }
1092 for (auto iter = opIdNodes.begin(); iter != opIdNodes.end(); ++iter) {
1093 std::shared_ptr<Asn1Node> curNode = nullptr;
1094 curNode = *iter;
1095 if (curNode == nullptr) {
1096 return false;
1097 }
1098 eUiccRulesAuthTable_.carrierIds_.push_back(buildCarrierIdentifiers(curNode));
1099 }
1100 grandson = node->Asn1GetGrandson(TAG_ESIM_SEQUENCE, TAG_ESIM_CTX_0);
1101 if (grandson == nullptr) {
1102 return false;
1103 }
1104 int32_t policyRules = grandson->Asn1AsInteger();
1105 grandson = node->Asn1GetGrandson(TAG_ESIM_SEQUENCE, TAG_ESIM_CTX_2);
1106 if (grandson == nullptr) {
1107 return false;
1108 }
1109 int32_t policyRuleFlags = grandson->Asn1AsInteger();
1110 eUiccRulesAuthTable_.policyRules_.push_back(policyRules);
1111 eUiccRulesAuthTable_.policyRuleFlags_.push_back(policyRuleFlags);
1112 }
1113 return true;
1114 }
1115
ProcessRequestRulesAuthTableDone(const AppExecFwk::InnerEvent::Pointer & event)1116 bool EsimFile::ProcessRequestRulesAuthTableDone(const AppExecFwk::InnerEvent::Pointer &event)
1117 {
1118 std::shared_ptr<Asn1Node> root = ParseEvent(event);
1119 if (root == nullptr) {
1120 TELEPHONY_LOGE("root is nullptr");
1121 NotifyReady(rulesAuthTableMutex_, isRulesAuthTableReady_, rulesAuthTableCv_);
1122 return false;
1123 }
1124 if (!RequestRulesAuthTableParseTagCtxComp0(root)) {
1125 TELEPHONY_LOGE("RequestRulesAuthTableParseTagCtxComp0 error");
1126 NotifyReady(rulesAuthTableMutex_, isRulesAuthTableReady_, rulesAuthTableCv_);
1127 return false;
1128 }
1129 NotifyReady(rulesAuthTableMutex_, isRulesAuthTableReady_, rulesAuthTableCv_);
1130 return true;
1131 }
1132
ProcessObtainEuiccChallengeDone(const AppExecFwk::InnerEvent::Pointer & event)1133 bool EsimFile::ProcessObtainEuiccChallengeDone(const AppExecFwk::InnerEvent::Pointer &event)
1134 {
1135 std::shared_ptr<Asn1Node> root = ParseEvent(event);
1136 if (root == nullptr) {
1137 TELEPHONY_LOGE("root is nullptr");
1138 NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
1139 return false;
1140 }
1141 std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_0);
1142 if (profileRoot == nullptr) {
1143 TELEPHONY_LOGE("Asn1GetChild failed");
1144 NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
1145 return false;
1146 }
1147 std::vector<uint8_t> profileResponseByte;
1148 uint32_t byteLen = profileRoot->Asn1AsBytes(profileResponseByte);
1149 if (byteLen == 0) {
1150 TELEPHONY_LOGE("byteLen is zero");
1151 NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
1152 return false;
1153 }
1154 std::string resultStr = Asn1Utils::BytesToHexStr(profileResponseByte);
1155 responseChallengeResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
1156 responseChallengeResult_.response_ = OHOS::Telephony::ToUtf16(resultStr);
1157 NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
1158 return true;
1159 }
1160
ObtainDefaultSmdpAddress()1161 std::string EsimFile::ObtainDefaultSmdpAddress()
1162 {
1163 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1164 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1165 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1166 return "";
1167 }
1168 AppExecFwk::InnerEvent::Pointer eventSmdpAddress = BuildCallerInfo(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE);
1169 if (!ProcessObtainDefaultSmdpAddress(slotId_, eventSmdpAddress)) {
1170 TELEPHONY_LOGE("ProcessObtainDefaultSmdpAddress encode failed");
1171 SyncCloseChannel();
1172 return "";
1173 }
1174 isObtainDefaultSmdpAddressReady_ = false;
1175 std::unique_lock<std::mutex> lock(obtainDefaultSmdpAddressMutex_);
1176 if (!obtainDefaultSmdpAddressCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1177 [this]() { return isObtainDefaultSmdpAddressReady_; })) {
1178 SyncCloseChannel();
1179 return "";
1180 }
1181 SyncCloseChannel();
1182 return defaultDpAddress_;
1183 }
1184
CancelSession(const std::u16string & transactionId,CancelReason cancelReason)1185 ResponseEsimInnerResult EsimFile::CancelSession(const std::u16string &transactionId, CancelReason cancelReason)
1186 {
1187 cancelSessionResult_ = ResponseEsimInnerResult();
1188 esimProfile_.transactionId = transactionId;
1189 esimProfile_.cancelReason = cancelReason;
1190 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1191 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1192 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1193 cancelSessionResult_.resultCode_ = static_cast<int32_t>(resultFlag);
1194 return cancelSessionResult_;
1195 }
1196 AppExecFwk::InnerEvent::Pointer eventCancelSession = BuildCallerInfo(MSG_ESIM_CANCEL_SESSION);
1197 if (!ProcessCancelSession(slotId_, eventCancelSession)) {
1198 TELEPHONY_LOGE("ProcessCancelSession encode failed");
1199 SyncCloseChannel();
1200 cancelSessionResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
1201 return cancelSessionResult_;
1202 }
1203 isCancelSessionReady_ = false;
1204 std::unique_lock<std::mutex> lock(cancelSessionMutex_);
1205 if (!cancelSessionCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1206 [this]() { return isCancelSessionReady_; })) {
1207 SyncCloseChannel();
1208 cancelSessionResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
1209 return cancelSessionResult_;
1210 }
1211 SyncCloseChannel();
1212 return cancelSessionResult_;
1213 }
1214
ObtainProfile(int32_t portIndex,const std::u16string & iccId)1215 EuiccProfile EsimFile::ObtainProfile(int32_t portIndex, const std::u16string &iccId)
1216 {
1217 eUiccProfile_ = EuiccProfile();
1218 esimProfile_.portIndex = portIndex;
1219 esimProfile_.iccId = iccId;
1220 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1221 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1222 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1223 return eUiccProfile_;
1224 }
1225 AppExecFwk::InnerEvent::Pointer eventGetProfile = BuildCallerInfo(MSG_ESIM_GET_PROFILE);
1226 if (!ProcessGetProfile(slotId_, eventGetProfile)) {
1227 TELEPHONY_LOGE("ProcessGetProfile encode failed");
1228 SyncCloseChannel();
1229 return eUiccProfile_;
1230 }
1231 isObtainProfileReady_ = false;
1232 std::unique_lock<std::mutex> lock(obtainProfileMutex_);
1233 if (!obtainProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1234 [this]() { return isObtainProfileReady_; })) {
1235 SyncCloseChannel();
1236 return eUiccProfile_;
1237 }
1238 SyncCloseChannel();
1239 return eUiccProfile_;
1240 }
1241
ProcessObtainDefaultSmdpAddress(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)1242 bool EsimFile::ProcessObtainDefaultSmdpAddress(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
1243 {
1244 if (!IsLogicChannelOpen()) {
1245 return false;
1246 }
1247 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_CONFIGURED_ADDRESSES);
1248 if (builder == nullptr) {
1249 TELEPHONY_LOGE("get builder failed");
1250 return false;
1251 }
1252 ApduSimIORequestInfo reqInfo;
1253 CommBuildOneApduReqInfo(reqInfo, builder);
1254 if (telRilManager_ == nullptr) {
1255 return false;
1256 }
1257 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
1258 if (apduResult == TELEPHONY_ERR_FAIL) {
1259 return false;
1260 }
1261 return true;
1262 }
1263
ProcessGetProfile(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)1264 bool EsimFile::ProcessGetProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
1265 {
1266 if (!IsLogicChannelOpen()) {
1267 return false;
1268 }
1269 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_PROFILES);
1270 std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
1271 if (builder == nullptr || subBuilder == nullptr) {
1272 TELEPHONY_LOGE("get builder failed");
1273 return false;
1274 }
1275 std::vector<uint8_t> iccidBytes;
1276 std::string iccid = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
1277 Asn1Utils::BcdToBytes(iccid, iccidBytes);
1278 subBuilder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
1279 std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
1280 builder->Asn1AddChild(subNode);
1281 std::vector<uint8_t> getProfileTags = GetProfileTagList();
1282 builder->Asn1AddChildAsBytes(TAG_ESIM_TAG_LIST, getProfileTags, getProfileTags.size());
1283 ApduSimIORequestInfo reqInfo;
1284 CommBuildOneApduReqInfo(reqInfo, builder);
1285 if (telRilManager_ == nullptr) {
1286 return false;
1287 }
1288 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
1289 if (apduResult == TELEPHONY_ERR_FAIL) {
1290 return false;
1291 }
1292 return true;
1293 }
1294
GetProfileTagList()1295 std::vector<uint8_t> EsimFile::GetProfileTagList()
1296 {
1297 unsigned char EUICC_PROFILE_TAGS[] = {
1298 static_cast<unsigned char>(TAG_ESIM_ICCID),
1299 static_cast<unsigned char>(TAG_ESIM_NICKNAME),
1300 static_cast<unsigned char>(TAG_ESIM_OBTAIN_OPERATOR_NAME),
1301 static_cast<unsigned char>(TAG_ESIM_PROFILE_NAME),
1302 static_cast<unsigned char>(TAG_ESIM_OPERATOR_ID),
1303 static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE / PROFILE_DEFAULT_NUMBER),
1304 static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE % PROFILE_DEFAULT_NUMBER),
1305 static_cast<unsigned char>(TAG_ESIM_PROFILE_CLASS),
1306 static_cast<unsigned char>(TAG_ESIM_PROFILE_POLICY_RULE),
1307 static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES / PROFILE_DEFAULT_NUMBER),
1308 static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES % PROFILE_DEFAULT_NUMBER),
1309 };
1310 std::vector<uint8_t> getProfileTags;
1311 for (const unsigned char tag : EUICC_PROFILE_TAGS) {
1312 getProfileTags.push_back(tag);
1313 }
1314 return getProfileTags;
1315 }
1316
ProcessCancelSession(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)1317 bool EsimFile::ProcessCancelSession(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
1318 {
1319 if (!IsLogicChannelOpen()) {
1320 return false;
1321 }
1322 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_CANCEL_SESSION);
1323 if (builder == nullptr) {
1324 TELEPHONY_LOGE("builder is nullptr");
1325 return false;
1326 }
1327 std::string transactionIdStr = Str16ToStr8(esimProfile_.transactionId);
1328 std::vector<uint8_t> transactionIdByte = Asn1Utils::HexStrToBytes(transactionIdStr);
1329 builder->Asn1AddChildAsBytes(TAG_ESIM_CTX_0, transactionIdByte, transactionIdByte.size());
1330 builder->Asn1AddChildAsInteger(TAG_ESIM_CTX_1, static_cast<uint32_t>(esimProfile_.cancelReason));
1331 ApduSimIORequestInfo reqInfo;
1332 CommBuildOneApduReqInfo(reqInfo, builder);
1333 if (telRilManager_ == nullptr) {
1334 return false;
1335 }
1336 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
1337 if (apduResult == TELEPHONY_ERR_FAIL) {
1338 return false;
1339 }
1340 return true;
1341 }
1342
ProcessObtainDefaultSmdpAddressDone(const AppExecFwk::InnerEvent::Pointer & event)1343 bool EsimFile::ProcessObtainDefaultSmdpAddressDone(const AppExecFwk::InnerEvent::Pointer &event)
1344 {
1345 if (event == nullptr) {
1346 TELEPHONY_LOGE("event is nullptr");
1347 NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
1348 return false;
1349 }
1350 std::shared_ptr<Asn1Node> root = ParseEvent(event);
1351 if (root == nullptr) {
1352 TELEPHONY_LOGE("Asn1ParseResponse failed");
1353 NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
1354 return false;
1355 }
1356 std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_0);
1357 if (profileRoot == nullptr) {
1358 TELEPHONY_LOGE("profileRoot is nullptr");
1359 NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
1360 return false;
1361 }
1362 std::vector<uint8_t> outPutBytes;
1363 uint32_t byteLen = profileRoot->Asn1AsBytes(outPutBytes);
1364 if (byteLen == 0) {
1365 TELEPHONY_LOGE("byteLen is zero");
1366 NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
1367 return false;
1368 }
1369 defaultDpAddress_ = Asn1Utils::BytesToHexStr(outPutBytes);
1370 NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
1371 return true;
1372 }
1373
ProcessCancelSessionDone(const AppExecFwk::InnerEvent::Pointer & event)1374 bool EsimFile::ProcessCancelSessionDone(const AppExecFwk::InnerEvent::Pointer &event)
1375 {
1376 if (event == nullptr) {
1377 TELEPHONY_LOGE("event is nullptr!");
1378 NotifyReady(cancelSessionMutex_, isCancelSessionReady_, cancelSessionCv_);
1379 return false;
1380 }
1381 IccFileData rawData;
1382 if (!GetRawDataFromEvent(event, rawData)) {
1383 TELEPHONY_LOGE("rawData is nullptr within rcvMsg");
1384 NotifyReady(cancelSessionMutex_, isCancelSessionReady_, cancelSessionCv_);
1385 return false;
1386 }
1387 cancelSessionResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
1388 cancelSessionResult_.response_ = OHOS::Telephony::ToUtf16(rawData.resultData);
1389 NotifyReady(cancelSessionMutex_, isCancelSessionReady_, cancelSessionCv_);
1390 return true;
1391 }
1392
GetProfileDoneParseProfileInfo(std::shared_ptr<Asn1Node> & root)1393 bool EsimFile::GetProfileDoneParseProfileInfo(std::shared_ptr<Asn1Node> &root)
1394 {
1395 std::shared_ptr<Asn1Node> profileInfo = root->Asn1GetGrandson(TAG_ESIM_CTX_COMP_0, TAG_ESIM_PROFILE_INFO);
1396 if (profileInfo == nullptr) {
1397 TELEPHONY_LOGE("get profile list failed");
1398 return false;
1399 }
1400 std::shared_ptr<Asn1Node> iccNode = profileInfo->Asn1GetChild(TAG_ESIM_ICCID);
1401 if (iccNode == nullptr) {
1402 TELEPHONY_LOGE("nodeIcc is nullptr");
1403 return false;
1404 }
1405 EuiccProfileInfo euiccProfileInfo = {{0}};
1406 BuildBasicProfileInfo(&euiccProfileInfo, profileInfo);
1407 ConvertProfileInfoToApiStruct(eUiccProfile_, euiccProfileInfo);
1408 return true;
1409 }
1410
ProcessGetProfileDone(const AppExecFwk::InnerEvent::Pointer & event)1411 bool EsimFile::ProcessGetProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
1412 {
1413 if (event == nullptr) {
1414 TELEPHONY_LOGE("event is nullptr!");
1415 NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
1416 return false;
1417 }
1418 std::shared_ptr<Asn1Node> root = ParseEvent(event);
1419 if (root == nullptr) {
1420 TELEPHONY_LOGE("Asn1ParseResponse failed");
1421 NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
1422 return false;
1423 }
1424 if (!GetProfileDoneParseProfileInfo(root)) {
1425 TELEPHONY_LOGE("GetProfileDoneParseProfileInfo error!");
1426 NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
1427 return false;
1428 }
1429 NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
1430 return true;
1431 }
1432
ResetMemory(ResetOption resetOption)1433 int32_t EsimFile::ResetMemory(ResetOption resetOption)
1434 {
1435 resetResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
1436 esimProfile_.option = resetOption;
1437
1438 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1439 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1440 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1441 resetResult_ = static_cast<int32_t>(resultFlag);
1442 return resetResult_;
1443 }
1444 AppExecFwk::InnerEvent::Pointer eventResetMemory = BuildCallerInfo(MSG_ESIM_RESET_MEMORY);
1445 if (!ProcessResetMemory(slotId_, eventResetMemory)) {
1446 TELEPHONY_LOGE("ProcessResetMemory encode failed");
1447 SyncCloseChannel();
1448 return resetResult_;
1449 }
1450 isResetMemoryReady_ = false;
1451 std::unique_lock<std::mutex> lock(resetMemoryMutex_);
1452 if (!resetMemoryCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1453 [this]() { return isResetMemoryReady_; })) {
1454 SyncCloseChannel();
1455 return resetResult_;
1456 }
1457 SyncCloseChannel();
1458 return resetResult_;
1459 }
1460
SetDefaultSmdpAddress(const std::u16string & defaultSmdpAddress)1461 int32_t EsimFile::SetDefaultSmdpAddress(const std::u16string &defaultSmdpAddress)
1462 {
1463 setDpAddressResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
1464 esimProfile_.defaultSmdpAddress = defaultSmdpAddress;
1465 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1466 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1467 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1468 setDpAddressResult_ = static_cast<int32_t>(resultFlag);
1469 return setDpAddressResult_;
1470 }
1471 AppExecFwk::InnerEvent::Pointer eventSetSmdpAddress = BuildCallerInfo(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE);
1472 if (!ProcessEstablishDefaultSmdpAddress(slotId_, eventSetSmdpAddress)) {
1473 TELEPHONY_LOGE("ProcessEstablishDefaultSmdpAddress encode failed!!");
1474 SyncCloseChannel();
1475 return setDpAddressResult_;
1476 }
1477 isSetDefaultSmdpAddressReady_ = false;
1478 std::unique_lock<std::mutex> lock(setDefaultSmdpAddressMutex_);
1479 if (!setDefaultSmdpAddressCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1480 [this]() { return isSetDefaultSmdpAddressReady_; })) {
1481 SyncCloseChannel();
1482 return setDpAddressResult_;
1483 }
1484 SyncCloseChannel();
1485 return setDpAddressResult_;
1486 }
1487
ProcessEstablishDefaultSmdpAddress(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)1488 bool EsimFile::ProcessEstablishDefaultSmdpAddress(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
1489 {
1490 if (!IsLogicChannelOpen()) {
1491 return false;
1492 }
1493
1494 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_SET_DEFAULT_SMDP_ADDRESS);
1495 if (builder == nullptr) {
1496 TELEPHONY_LOGE("builder is nullptr");
1497 return false;
1498 }
1499 std::string address = OHOS::Telephony::ToUtf8(esimProfile_.defaultSmdpAddress);
1500 builder->Asn1AddChildAsString(TAG_ESIM_TARGET_ADDR, address);
1501 ApduSimIORequestInfo reqInfo;
1502 CommBuildOneApduReqInfo(reqInfo, builder);
1503 if (telRilManager_ == nullptr) {
1504 return false;
1505 }
1506 telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
1507 return true;
1508 }
1509
ProcessEstablishDefaultSmdpAddressDone(const AppExecFwk::InnerEvent::Pointer & event)1510 bool EsimFile::ProcessEstablishDefaultSmdpAddressDone(const AppExecFwk::InnerEvent::Pointer &event)
1511 {
1512 std::shared_ptr<Asn1Node> root = ParseEvent(event);
1513 if (root == nullptr) {
1514 TELEPHONY_LOGE("Asn1ParseResponse failed");
1515 NotifyReady(setDefaultSmdpAddressMutex_, isSetDefaultSmdpAddressReady_, setDefaultSmdpAddressCv_);
1516 return false;
1517 }
1518 std::shared_ptr<Asn1Node> pAsn1Node = root->Asn1GetChild(TAG_ESIM_CTX_0);
1519 if (pAsn1Node == nullptr) {
1520 TELEPHONY_LOGE("pAsn1Node is nullptr");
1521 NotifyReady(setDefaultSmdpAddressMutex_, isSetDefaultSmdpAddressReady_, setDefaultSmdpAddressCv_);
1522 return false;
1523 }
1524 setDpAddressResult_ = pAsn1Node->Asn1AsInteger();
1525 NotifyReady(setDefaultSmdpAddressMutex_, isSetDefaultSmdpAddressReady_, setDefaultSmdpAddressCv_);
1526 return true;
1527 }
1528
IsSupported()1529 bool EsimFile::IsSupported()
1530 {
1531 char buf[ATR_LENGTH + 1] = {0};
1532 if (isSupported_) {
1533 return isSupported_;
1534 }
1535 GetParameter(TEL_ESIM_SUPPORT, "", buf, ATR_LENGTH);
1536 ResetResponse resetResponse;
1537 std::string atr(buf);
1538 if (atr.empty()) {
1539 if (!ObtainEid().empty()) {
1540 isSupported_ = true;
1541 }
1542 return isSupported_;
1543 }
1544 resetResponse.AnalysisAtrData(atr);
1545 isSupported_ = resetResponse.IsEuiccAvailable();
1546 return isSupported_;
1547 }
1548
SendApduData(const std::u16string & aid,const EsimApduData & apduData)1549 ResponseEsimInnerResult EsimFile::SendApduData(const std::u16string &aid, const EsimApduData &apduData)
1550 {
1551 transApduDataResponse_ = ResponseEsimInnerResult();
1552 if (aid.empty()) {
1553 TELEPHONY_LOGE("Aid is empty");
1554 transApduDataResponse_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_AID_EMPTY);
1555 return transApduDataResponse_;
1556 }
1557 if (apduData.closeChannelFlag_) {
1558 if (IsSameAid(aid)) {
1559 SyncCloseChannel();
1560 return ResponseEsimInnerResult();
1561 }
1562
1563 TELEPHONY_LOGE("SendApduData Close Channel failed");
1564 transApduDataResponse_.resultCode_ =
1565 static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_CLOSE_FAILED);
1566 return transApduDataResponse_;
1567 }
1568
1569 esimProfile_.apduData = apduData;
1570 AppExecFwk::InnerEvent::Pointer eventSendApduData = BuildCallerInfo(MSG_ESIM_SEND_APUD_DATA);
1571 ResultInnerCode resultFlag = ObtainChannelSuccessAlllowSameAidReuse(aid);
1572 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1573 TELEPHONY_LOGE("ObtainChannelSuccessAlllowSameAidReuse failed ,%{public}d", resultFlag);
1574 transApduDataResponse_.resultCode_ = static_cast<int32_t>(resultFlag);
1575 return transApduDataResponse_;
1576 }
1577 if (!ProcessSendApduData(slotId_, eventSendApduData)) {
1578 TELEPHONY_LOGE("ProcessSendApduData encode failed");
1579 SyncCloseChannel();
1580 transApduDataResponse_.resultCode_ =
1581 static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
1582 return transApduDataResponse_;
1583 }
1584 isSendApduDataReady_ = false;
1585 std::unique_lock<std::mutex> lock(sendApduDataMutex_);
1586 if (!sendApduDataCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1587 [this]() { return isSendApduDataReady_; })) {
1588 SyncCloseChannel();
1589 transApduDataResponse_.resultCode_ =
1590 static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
1591 return transApduDataResponse_;
1592 }
1593 return transApduDataResponse_;
1594 }
1595
ProcessResetMemory(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)1596 bool EsimFile::ProcessResetMemory(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
1597 {
1598 if (!IsLogicChannelOpen()) {
1599 return false;
1600 }
1601 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_EUICC_MEMORY_RESET);
1602 if (builder == nullptr) {
1603 TELEPHONY_LOGE("get builder failed");
1604 return false;
1605 }
1606 std::vector<uint8_t> resetMemoryTags;
1607 resetMemoryTags.push_back(static_cast<uint8_t>(EUICC_MEMORY_RESET_BIT_STR_FILL_LEN));
1608 resetMemoryTags.push_back(static_cast<uint8_t>(EUICC_MEMORY_RESET_BIT_STR_VALUE));
1609 builder->Asn1AddChildAsBytes(TAG_ESIM_CTX_2, resetMemoryTags, resetMemoryTags.size());
1610 ApduSimIORequestInfo reqInfo;
1611 CommBuildOneApduReqInfo(reqInfo, builder);
1612 if (telRilManager_ == nullptr) {
1613 return false;
1614 }
1615 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
1616 if (apduResult == TELEPHONY_ERR_FAIL) {
1617 return false;
1618 }
1619 return true;
1620 }
1621
ProcessResetMemoryDone(const AppExecFwk::InnerEvent::Pointer & event)1622 bool EsimFile::ProcessResetMemoryDone(const AppExecFwk::InnerEvent::Pointer &event)
1623 {
1624 std::shared_ptr<Asn1Node> root = ParseEvent(event);
1625 if (root == nullptr) {
1626 TELEPHONY_LOGE("Asn1ParseResponse failed");
1627 NotifyReady(resetMemoryMutex_, isResetMemoryReady_, resetMemoryCv_);
1628 return false;
1629 }
1630 std::shared_ptr<Asn1Node> asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
1631 if (asn1NodeData == nullptr) {
1632 TELEPHONY_LOGE("asn1NodeData is nullptr");
1633 NotifyReady(resetMemoryMutex_, isResetMemoryReady_, resetMemoryCv_);
1634 return false;
1635 }
1636 resetResult_ = asn1NodeData->Asn1AsInteger();
1637 NotifyReady(resetMemoryMutex_, isResetMemoryReady_, resetMemoryCv_);
1638 return true;
1639 }
1640
ProcessSendApduData(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)1641 bool EsimFile::ProcessSendApduData(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
1642 {
1643 if (!IsLogicChannelOpen()) {
1644 return false;
1645 }
1646 std::string hexStr = OHOS::Telephony::ToUtf8(esimProfile_.apduData.data_);
1647 RequestApduBuild codec(currentChannelId_);
1648 codec.BuildStoreData(hexStr);
1649 std::list<std::unique_ptr<ApduCommand>> list = codec.GetCommands();
1650 if (list.empty()) {
1651 TELEPHONY_LOGE("node is empty");
1652 return false;
1653 }
1654 std::unique_ptr<ApduCommand> apdCmd = std::move(list.front());
1655 if (apdCmd == nullptr) {
1656 return false;
1657 }
1658 ApduSimIORequestInfo reqInfo;
1659 CopyApdCmdToReqInfo(reqInfo, apdCmd.get());
1660 if (esimProfile_.apduData.unusedDefaultReqHeadFlag_) {
1661 reqInfo.type = esimProfile_.apduData.instructionType_;
1662 reqInfo.instruction = esimProfile_.apduData.instruction_;
1663 reqInfo.p1 = esimProfile_.apduData.p1_;
1664 reqInfo.p2 = esimProfile_.apduData.p2_;
1665 reqInfo.p3 = esimProfile_.apduData.p3_;
1666 }
1667 if (telRilManager_ == nullptr) {
1668 return false;
1669 }
1670 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
1671 if (apduResult == TELEPHONY_ERR_FAIL) {
1672 return false;
1673 }
1674 return true;
1675 }
1676
ProcessSendApduDataDone(const AppExecFwk::InnerEvent::Pointer & event)1677 bool EsimFile::ProcessSendApduDataDone(const AppExecFwk::InnerEvent::Pointer &event)
1678 {
1679 if (event == nullptr) {
1680 TELEPHONY_LOGE("event is nullptr");
1681 NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
1682 return false;
1683 }
1684 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
1685 if (rcvMsg == nullptr) {
1686 TELEPHONY_LOGE("rcvMsg is nullptr");
1687 NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
1688 return false;
1689 }
1690 IccFileData *result = &(rcvMsg->fileData);
1691 if (result == nullptr) {
1692 TELEPHONY_LOGE("result is nullptr");
1693 NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
1694 return false;
1695 }
1696 transApduDataResponse_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
1697 transApduDataResponse_.response_ = OHOS::Telephony::ToUtf16(result->resultData);
1698 transApduDataResponse_.sw1_ = result->sw1;
1699 transApduDataResponse_.sw2_ = result->sw2;
1700 NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
1701 return true;
1702 }
1703
ObtainPrepareDownload(const DownLoadConfigInfo & downLoadConfigInfo)1704 ResponseEsimInnerResult EsimFile::ObtainPrepareDownload(const DownLoadConfigInfo &downLoadConfigInfo)
1705 {
1706 preDownloadResult_ = ResponseEsimInnerResult();
1707 esimProfile_.portIndex = downLoadConfigInfo.portIndex_;
1708 esimProfile_.hashCc = downLoadConfigInfo.hashCc_;
1709 esimProfile_.smdpSigned2 = downLoadConfigInfo.smdpSigned2_;
1710 esimProfile_.smdpSignature2 = downLoadConfigInfo.smdpSignature2_;
1711 esimProfile_.smdpCertificate = downLoadConfigInfo.smdpCertificate_;
1712
1713 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1714 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1715 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1716 preDownloadResult_.resultCode_ = static_cast<int32_t>(resultFlag);
1717 return preDownloadResult_;
1718 }
1719 recvCombineStr_ = "";
1720 if (!ProcessPrepareDownload(slotId_)) {
1721 TELEPHONY_LOGE("ProcessPrepareDownload encode failed");
1722 SyncCloseChannel();
1723 preDownloadResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
1724 return preDownloadResult_;
1725 }
1726 SyncCloseChannel();
1727 return preDownloadResult_;
1728 }
1729
ObtainLoadBoundProfilePackage(int32_t portIndex,const std::u16string boundProfilePackage)1730 ResponseEsimBppResult EsimFile::ObtainLoadBoundProfilePackage(int32_t portIndex,
1731 const std::u16string boundProfilePackage)
1732 {
1733 esimProfile_.portIndex = portIndex;
1734 esimProfile_.boundProfilePackage = boundProfilePackage;
1735
1736 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1737 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1738 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1739 loadBPPResult_.resultCode_ = static_cast<int32_t>(resultFlag);
1740 return loadBPPResult_;
1741 }
1742 recvCombineStr_ = "";
1743 if (!ProcessLoadBoundProfilePackage(slotId_)) {
1744 TELEPHONY_LOGE("ProcessLoadBoundProfilePackage encode failed");
1745 SyncCloseChannel();
1746 return ResponseEsimBppResult();
1747 }
1748 SyncCloseChannel();
1749 return loadBPPResult_;
1750 }
1751
ListNotifications(int32_t portIndex,Event events)1752 EuiccNotificationList EsimFile::ListNotifications(int32_t portIndex, Event events)
1753 {
1754 esimProfile_.portIndex = portIndex;
1755 esimProfile_.events = events;
1756 AppExecFwk::InnerEvent::Pointer eventListNotif = BuildCallerInfo(MSG_ESIM_LIST_NOTIFICATION);
1757 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
1758 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
1759 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
1760 return EuiccNotificationList();
1761 }
1762 recvCombineStr_ = "";
1763 if (!ProcessListNotifications(slotId_, events, eventListNotif)) {
1764 TELEPHONY_LOGE("ProcessListNotifications encode failed");
1765 SyncCloseChannel();
1766 return EuiccNotificationList();
1767 }
1768 isListNotificationsReady_ = false;
1769 std::unique_lock<std::mutex> lock(listNotificationsMutex_);
1770 if (!listNotificationsCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1771 [this]() { return isListNotificationsReady_; })) {
1772 SyncCloseChannel();
1773 return EuiccNotificationList();
1774 }
1775 SyncCloseChannel();
1776 return eUiccNotificationList_;
1777 }
1778
ConvertPreDownloadParaFromApiStru(PrepareDownloadResp & dst,EsimProfile & src)1779 void EsimFile::ConvertPreDownloadParaFromApiStru(PrepareDownloadResp& dst, EsimProfile& src)
1780 {
1781 dst.smdpSigned2 = OHOS::Telephony::ToUtf8(src.smdpSigned2);
1782 dst.smdpSignature2 = OHOS::Telephony::ToUtf8(src.smdpSignature2);
1783 dst.smdpCertificate = OHOS::Telephony::ToUtf8(src.smdpCertificate);
1784 dst.hashCc = OHOS::Telephony::ToUtf8(src.hashCc);
1785 }
1786
Asn1AddChildAsBase64(std::shared_ptr<Asn1Builder> & builder,std::string & base64Src)1787 void EsimFile::Asn1AddChildAsBase64(std::shared_ptr<Asn1Builder> &builder, std::string &base64Src)
1788 {
1789 std::string destString = VCardUtils::DecodeBase64NoWrap(base64Src);
1790 std::vector<uint8_t> dest = Asn1Utils::StringToBytes(destString);
1791 std::shared_ptr<Asn1Decoder> decoder = std::make_shared<Asn1Decoder>(dest, 0, dest.size());
1792 if (decoder == nullptr) {
1793 TELEPHONY_LOGE("create decoder failed");
1794 return;
1795 }
1796 std::shared_ptr<Asn1Node> node = decoder->Asn1NextNode();
1797 if (builder == nullptr) {
1798 TELEPHONY_LOGE("build is nullptr");
1799 return;
1800 }
1801 builder->Asn1AddChild(node);
1802 }
1803
ProcessPrepareDownload(int32_t slotId)1804 bool EsimFile::ProcessPrepareDownload(int32_t slotId)
1805 {
1806 if (!IsLogicChannelOpen()) {
1807 return false;
1808 }
1809 PrepareDownloadResp dst;
1810 ConvertPreDownloadParaFromApiStru(dst, esimProfile_);
1811 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_PREPARE_DOWNLOAD);
1812 if (builder == nullptr) {
1813 return false;
1814 }
1815 Asn1AddChildAsBase64(builder, dst.smdpSigned2);
1816 Asn1AddChildAsBase64(builder, dst.smdpSignature2);
1817 if (dst.hashCc.size() != 0) {
1818 std::vector<uint8_t> bytes = Asn1Utils::StringToBytes(VCardUtils::DecodeBase64NoWrap(dst.hashCc));
1819 builder->Asn1AddChildAsBytes(TAG_ESIM_OCTET_STRING_TYPE, bytes, bytes.size());
1820 }
1821 Asn1AddChildAsBase64(builder, dst.smdpCertificate);
1822 std::string hexStr;
1823 uint32_t hexStrLen = builder->Asn1BuilderToHexStr(hexStr);
1824 if (hexStrLen == 0) {
1825 return false;
1826 }
1827 RequestApduBuild codec(currentChannelId_);
1828 codec.BuildStoreData(hexStr);
1829 SplitSendLongData(codec, MSG_ESIM_PREPARE_DOWNLOAD_DONE,
1830 prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
1831 return true;
1832 }
1833
SplitSendLongData(RequestApduBuild & codec,int32_t esimMessageId,std::mutex & mtx,bool & flag,std::condition_variable & cv)1834 void EsimFile::SplitSendLongData(
1835 RequestApduBuild &codec, int32_t esimMessageId, std::mutex &mtx, bool &flag, std::condition_variable &cv)
1836 {
1837 std::list<std::unique_ptr<ApduCommand>> apduCommandList = codec.GetCommands();
1838 for (const auto &cmd : apduCommandList) {
1839 if (!cmd) {
1840 return;
1841 }
1842 ApduSimIORequestInfo reqInfo;
1843 CopyApdCmdToReqInfo(reqInfo, cmd.get());
1844 AppExecFwk::InnerEvent::Pointer tmpResponseEvent = BuildCallerInfo(esimMessageId);
1845 if (telRilManager_ == nullptr) {
1846 return;
1847 }
1848 std::unique_lock<std::mutex> lock(mtx);
1849 flag = false;
1850 telRilManager_->SimTransmitApduLogicalChannel(slotId_, reqInfo, tmpResponseEvent);
1851 if (!cv.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
1852 [&flag]() { return flag; })) {
1853 return;
1854 }
1855 }
1856 }
1857
CombineResponseDataFinish(IccFileData & fileData)1858 uint32_t EsimFile::CombineResponseDataFinish(IccFileData &fileData)
1859 {
1860 if (fileData.sw1 == SW1_MORE_RESPONSE) {
1861 return RESPONS_DATA_NOT_FINISH;
1862 } else if (fileData.sw1 == SW1_VALUE_90 && fileData.sw2 == SW2_VALUE_00) {
1863 return RESPONS_DATA_FINISH;
1864 } else {
1865 return RESPONS_DATA_ERROR;
1866 }
1867 }
1868
ProcessIfNeedMoreResponse(IccFileData & fileData,int32_t eventId)1869 void EsimFile::ProcessIfNeedMoreResponse(IccFileData &fileData, int32_t eventId)
1870 {
1871 if (fileData.sw1 == SW1_MORE_RESPONSE) {
1872 ApduSimIORequestInfo reqInfo;
1873 RequestApduBuild codec(currentChannelId_);
1874 codec.BuildStoreData("");
1875 std::list<std::unique_ptr<ApduCommand>> list = codec.GetCommands();
1876 if (list.empty()) {
1877 TELEPHONY_LOGE("node is empty");
1878 return;
1879 }
1880 std::unique_ptr<ApduCommand> apdCmd = std::move(list.front());
1881 if (apdCmd == nullptr) {
1882 return;
1883 }
1884 apdCmd->data.cla = 0;
1885 apdCmd->data.ins = INS_GET_MORE_RESPONSE;
1886 apdCmd->data.p1 = 0;
1887 apdCmd->data.p2 = 0;
1888 apdCmd->data.p3 = static_cast<uint32_t>(fileData.sw2);
1889 CopyApdCmdToReqInfo(reqInfo, apdCmd.get());
1890 AppExecFwk::InnerEvent::Pointer responseEvent = BuildCallerInfo(eventId);
1891 if (telRilManager_ == nullptr) {
1892 return;
1893 }
1894 telRilManager_->SimTransmitApduLogicalChannel(slotId_, reqInfo, responseEvent);
1895 }
1896 }
1897
MergeRecvLongDataComplete(IccFileData & fileData,int32_t eventId)1898 uint32_t EsimFile::MergeRecvLongDataComplete(IccFileData &fileData, int32_t eventId)
1899 {
1900 TELEPHONY_LOGI("eventId=%{public}d input sw1=%{public}02X, sw2=%{public}02X, data.length=%{public}zu",
1901 eventId, fileData.sw1, fileData.sw2, fileData.resultData.length());
1902 uint32_t result = CombineResponseDataFinish(fileData);
1903 if (result == RESPONS_DATA_ERROR) {
1904 TELEPHONY_LOGE("RESPONS_DATA_ERROR current_len:%{public}zu", recvCombineStr_.length());
1905 return result;
1906 }
1907 recvCombineStr_ = recvCombineStr_ + fileData.resultData;
1908 if (result == RESPONS_DATA_NOT_FINISH) {
1909 ProcessIfNeedMoreResponse(fileData, eventId);
1910 TELEPHONY_LOGI("RESPONS_DATA_NOT_FINISH current_len:%{public}zu", recvCombineStr_.length());
1911 return result;
1912 }
1913 TELEPHONY_LOGI("RESPONS_DATA_FINISH current_len:%{public}zu", recvCombineStr_.length());
1914 return result;
1915 }
1916
ProcessPrepareDownloadDone(const AppExecFwk::InnerEvent::Pointer & event)1917 bool EsimFile::ProcessPrepareDownloadDone(const AppExecFwk::InnerEvent::Pointer &event)
1918 {
1919 if (event == nullptr) {
1920 TELEPHONY_LOGE("event is nullptr");
1921 NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
1922 return false;
1923 }
1924 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
1925 if (rcvMsg == nullptr) {
1926 TELEPHONY_LOGE("rcvMsg is nullptr");
1927 NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
1928 return false;
1929 }
1930 newRecvData_ = rcvMsg->fileData;
1931 bool isHandleFinish = false;
1932 bool retValue = CommMergeRecvData(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_,
1933 MSG_ESIM_PREPARE_DOWNLOAD_DONE, isHandleFinish);
1934 if (isHandleFinish) {
1935 return retValue;
1936 }
1937 return RealProcessPrepareDownloadDone();
1938 }
1939
RealProcessPrepareDownloadDone()1940 bool EsimFile::RealProcessPrepareDownloadDone()
1941 {
1942 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
1943 uint32_t byteLen = responseByte.size();
1944 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
1945 if (root == nullptr) {
1946 TELEPHONY_LOGE("root is nullptr");
1947 NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
1948 return false;
1949 }
1950 std::shared_ptr<Asn1Node> childNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_1);
1951 if (childNode != nullptr) {
1952 std::shared_ptr<Asn1Node> errCodeNode = childNode->Asn1GetChild(TAG_ESIM_UNI_2);
1953 if (errCodeNode != nullptr) {
1954 int32_t protocolErr = errCodeNode->Asn1AsInteger();
1955 if (protocolErr != TELEPHONY_ERR_ARGUMENT_INVALID) {
1956 TELEPHONY_LOGE("Prepare download error, es10x errcode: %{public}d", protocolErr);
1957 preDownloadResult_.resultCode_ = protocolErr;
1958 preDownloadResult_.response_ = u"";
1959 NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
1960 return false;
1961 }
1962 }
1963 }
1964 preDownloadResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
1965 std::string responseByteStr = Asn1Utils::BytesToString(responseByte);
1966 std::string destString = VCardUtils::EncodeBase64(responseByteStr);
1967 preDownloadResult_.response_ = OHOS::Telephony::ToUtf16(destString);
1968 NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
1969 return true;
1970 }
1971
DecodeBoundProfilePackage(const std::string & boundProfilePackageStr,std::shared_ptr<Asn1Node> & bppNode)1972 bool EsimFile::DecodeBoundProfilePackage(const std::string &boundProfilePackageStr, std::shared_ptr<Asn1Node> &bppNode)
1973 {
1974 std::string destString = VCardUtils::DecodeBase64NoWrap(boundProfilePackageStr);
1975 std::vector<uint8_t> dest = Asn1Utils::StringToBytes(destString);
1976 std::shared_ptr<Asn1Decoder> decoder = std::make_shared<Asn1Decoder>(dest, 0, dest.size());
1977 if (decoder == nullptr) {
1978 TELEPHONY_LOGE("decoder is nullptr");
1979 return false;
1980 }
1981 bppNode = decoder->Asn1NextNode();
1982 if (bppNode == nullptr) {
1983 TELEPHONY_LOGE("bppNode is nullptr");
1984 return false;
1985 }
1986 return true;
1987 }
1988
BuildApduForInitSecureChannel(RequestApduBuild & codec,std::shared_ptr<Asn1Node> & bppNode,std::shared_ptr<Asn1Node> & initSecureChannelReq)1989 void EsimFile::BuildApduForInitSecureChannel(
1990 RequestApduBuild& codec, std::shared_ptr<Asn1Node> &bppNode, std::shared_ptr<Asn1Node> &initSecureChannelReq)
1991 {
1992 std::string hexStr;
1993 std::string destStr;
1994 uint32_t cursorLen = bppNode->Asn1GetHeadAsHexStr(hexStr);
1995 cursorLen += initSecureChannelReq->Asn1NodeToHexStr(destStr);
1996 hexStr += destStr;
1997 codec.BuildStoreData(hexStr);
1998 }
1999
BuildApduForFirstSequenceOf87(RequestApduBuild & codec,std::shared_ptr<Asn1Node> & firstSequenceOf87)2000 void EsimFile::BuildApduForFirstSequenceOf87(RequestApduBuild &codec, std::shared_ptr<Asn1Node> &firstSequenceOf87)
2001 {
2002 std::string hexStr;
2003 uint32_t cursorLen = firstSequenceOf87->Asn1NodeToHexStr(hexStr);
2004 codec.BuildStoreData(hexStr);
2005 }
2006
BuildApduForSequenceOf88(RequestApduBuild & codec,std::shared_ptr<Asn1Node> & sequenceOf88)2007 void EsimFile::BuildApduForSequenceOf88(RequestApduBuild &codec, std::shared_ptr<Asn1Node> &sequenceOf88)
2008 {
2009 std::list<std::shared_ptr<Asn1Node>> metaDataSeqs;
2010 int32_t metaDataRes = sequenceOf88->Asn1GetChildren(TAG_ESIM_CTX_8, metaDataSeqs);
2011 if (metaDataRes != 0) {
2012 return;
2013 }
2014 std::string hexStr;
2015 uint32_t cursorLen = sequenceOf88->Asn1GetHeadAsHexStr(hexStr);
2016 codec.BuildStoreData(hexStr);
2017 std::shared_ptr<Asn1Node> curNode = nullptr;
2018 for (auto it = metaDataSeqs.begin(); it != metaDataSeqs.end(); ++it) {
2019 curNode = *it;
2020 if (curNode == nullptr) {
2021 break;
2022 }
2023 curNode->Asn1NodeToHexStr(hexStr);
2024 codec.BuildStoreData(hexStr);
2025 }
2026 }
2027
BuildApduForSequenceOf86(RequestApduBuild & codec,std::shared_ptr<Asn1Node> & bppNode,std::shared_ptr<Asn1Node> & sequenceOf86)2028 void EsimFile::BuildApduForSequenceOf86(RequestApduBuild &codec, std::shared_ptr<Asn1Node> &bppNode,
2029 std::shared_ptr<Asn1Node> &sequenceOf86)
2030 {
2031 std::string hexStr;
2032 std::list<std::shared_ptr<Asn1Node>> elementSeqs;
2033 int32_t elementRes = sequenceOf86->Asn1GetChildren(TAG_ESIM_CTX_6, elementSeqs);
2034 if (elementRes != 0) {
2035 TELEPHONY_LOGE("sequenceOf86 encode error");
2036 return;
2037 }
2038 if (bppNode->Asn1HasChild(TAG_ESIM_CTX_COMP_2)) {
2039 std::shared_ptr<Asn1Node> pGetChild = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_2);
2040 if (pGetChild == nullptr) {
2041 TELEPHONY_LOGE("pGetChild is nullptr");
2042 return;
2043 }
2044 pGetChild->Asn1NodeToHexStr(hexStr);
2045 codec.BuildStoreData(hexStr);
2046 }
2047 uint32_t cursorLen = sequenceOf86->Asn1GetHeadAsHexStr(hexStr);
2048 codec.BuildStoreData(hexStr);
2049 std::shared_ptr<Asn1Node> curNode = nullptr;
2050 for (auto it = elementSeqs.begin(); it != elementSeqs.end(); ++it) {
2051 curNode = *it;
2052 if (curNode == nullptr) {
2053 break;
2054 }
2055 curNode->Asn1NodeToHexStr(hexStr);
2056 codec.BuildStoreData(hexStr);
2057 }
2058 }
2059
ProcessLoadBoundProfilePackage(int32_t slotId)2060 bool EsimFile::ProcessLoadBoundProfilePackage(int32_t slotId)
2061 {
2062 if (!IsLogicChannelOpen()) {
2063 TELEPHONY_LOGE("open channel is failed");
2064 return false;
2065 }
2066 std::string boundProfilePackage = OHOS::Telephony::ToUtf8(esimProfile_.boundProfilePackage);
2067 std::shared_ptr<Asn1Node> bppNode = nullptr;
2068 if (!DecodeBoundProfilePackage(boundProfilePackage, bppNode)) {
2069 TELEPHONY_LOGE("DecodeBoundProfilePackage failed");
2070 return false;
2071 }
2072 RequestApduBuild codec(currentChannelId_);
2073 std::shared_ptr<Asn1Node> initSecureChannelReq = bppNode->Asn1GetChild(TAG_ESIM_INITIALISE_SECURE_CHANNEL);
2074 if (initSecureChannelReq != nullptr) {
2075 BuildApduForInitSecureChannel(codec, bppNode, initSecureChannelReq);
2076 }
2077 // 1. The BPP came with extraneous tags other than what the spec
2078 // mandates. We keep track of the total length of the BPP and compare it
2079 // to the length of the segments we care about. If they're different,
2080 // we'll throw an exception to indicate this.
2081 std::shared_ptr<Asn1Node> unknownBppSegment = bppNode->Asn1GetChild(TAG_ESIM_UNKNOWN_BPP_SEGMENT);
2082 if (unknownBppSegment != nullptr) {
2083 TELEPHONY_LOGE("recv GET_BPP_LOAD_ERROR_UNKNOWN_TAG");
2084 return false;
2085 }
2086 std::shared_ptr<Asn1Node> firstSequenceOf87 = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
2087 if (firstSequenceOf87 != nullptr) {
2088 BuildApduForFirstSequenceOf87(codec, firstSequenceOf87);
2089 }
2090 std::shared_ptr<Asn1Node> sequenceOf88 = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_1);
2091 if (sequenceOf88 != nullptr) {
2092 BuildApduForSequenceOf88(codec, sequenceOf88);
2093 }
2094 std::shared_ptr<Asn1Node> sequenceOf86 = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_3);
2095 if (sequenceOf86 == nullptr) {
2096 // 2. The BPP is missing a required tag. Upon calling bppNode.getChild,
2097 // an exception will occur if the expected tag is missing, though we
2098 // should make sure that the sequences are non-empty when appropriate as
2099 // well. A profile with no profile elements is invalid.
2100 TELEPHONY_LOGE("recv GET_BPP_LOAD_ERROR");
2101 return false;
2102 }
2103 BuildApduForSequenceOf86(codec, bppNode, sequenceOf86);
2104 SplitSendLongData(codec, MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE, loadBppMutex_, isLoadBppReady_, loadBppCv_);
2105 return true;
2106 }
2107
ProcessLoadBoundProfilePackageDone(const AppExecFwk::InnerEvent::Pointer & event)2108 bool EsimFile::ProcessLoadBoundProfilePackageDone(const AppExecFwk::InnerEvent::Pointer &event)
2109 {
2110 if (event == nullptr) {
2111 TELEPHONY_LOGE("event is nullptr");
2112 NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
2113 return false;
2114 }
2115 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
2116 if (rcvMsg == nullptr) {
2117 TELEPHONY_LOGE("rcvMsg is nullptr");
2118 NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
2119 return false;
2120 }
2121 newRecvData_ = rcvMsg->fileData;
2122 bool isHandleFinish = false;
2123 bool retValue = CommMergeRecvData(loadBppMutex_, isLoadBppReady_, loadBppCv_,
2124 MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE, isHandleFinish);
2125 if (isHandleFinish) {
2126 return retValue;
2127 }
2128 return RealProcessLoadBoundProfilePackageDone();
2129 }
RealProcessLoadBoundProfilePackageDone()2130 bool EsimFile::RealProcessLoadBoundProfilePackageDone()
2131 {
2132 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
2133 uint32_t byteLen = responseByte.size();
2134 loadBPPResult_.response_ = OHOS::Telephony::ToUtf16(recvCombineStr_);
2135 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
2136 if (root == nullptr) {
2137 TELEPHONY_LOGE("root is nullptr");
2138 NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
2139 return false;
2140 }
2141 std::shared_ptr<Asn1Node> nodeNotificationMetadata = LoadBoundProfilePackageParseProfileInstallResult(root);
2142 if (nodeNotificationMetadata == nullptr) {
2143 TELEPHONY_LOGE("nodeNotificationMetadata is nullptr");
2144 NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
2145 return false;
2146 }
2147 if (!LoadBoundProfilePackageParseNotificationMetadata(nodeNotificationMetadata)) {
2148 TELEPHONY_LOGE("LoadBoundProfilePackageParseNotificationMetadata error");
2149 NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
2150 return false;
2151 }
2152 loadBPPResult_.resultCode_ = 0;
2153 NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
2154 return true;
2155 }
2156
LoadBoundProfilePackageParseNotificationMetadata(std::shared_ptr<Asn1Node> & notificationMetadata)2157 bool EsimFile::LoadBoundProfilePackageParseNotificationMetadata(std::shared_ptr<Asn1Node> ¬ificationMetadata)
2158 {
2159 if (notificationMetadata == nullptr) {
2160 TELEPHONY_LOGE("notification metadata is empty");
2161 return false;
2162 }
2163 std::shared_ptr<Asn1Node> sequenceNumberAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_CTX_0);
2164 if (sequenceNumberAsn != nullptr) {
2165 loadBPPResult_.seqNumber_ = sequenceNumberAsn->Asn1AsInteger();
2166 } else {
2167 TELEPHONY_LOGE("sequenceNumber tag missing");
2168 return false;
2169 }
2170 std::shared_ptr<Asn1Node> profileManagementOpAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_CTX_1);
2171 if (profileManagementOpAsn != nullptr) {
2172 loadBPPResult_.profileManagementOperation_ = EVENT_INSTALL;
2173 } else {
2174 TELEPHONY_LOGE("profileManagementOperation tag missing");
2175 return false;
2176 }
2177 std::shared_ptr<Asn1Node> addressAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_TARGET_ADDR);
2178 if (addressAsn != nullptr) {
2179 std::string hexString;
2180 addressAsn->Asn1AsString(hexString);
2181 std::string address = Asn1Utils::HexStrToString(hexString);
2182 loadBPPResult_.notificationAddress_ = OHOS::Telephony::ToUtf16(address);
2183 } else {
2184 TELEPHONY_LOGE("notificationAddress tag missing");
2185 return false;
2186 }
2187 std::shared_ptr<Asn1Node> iccidAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_EID);
2188 if (iccidAsn == nullptr) {
2189 TELEPHONY_LOGE("iccidAsn is nullptr");
2190 return false;
2191 }
2192 std::vector<uint8_t> iccid;
2193 std::string iccString;
2194 uint32_t iccidLen = iccidAsn->Asn1AsBytes(iccid);
2195 Asn1Utils::BchToString(iccid, iccString);
2196 loadBPPResult_.iccId_ = OHOS::Telephony::ToUtf16(iccString);
2197 return true;
2198 }
2199
LoadBoundProfilePackageParseProfileInstallResult(std::shared_ptr<Asn1Node> & root)2200 std::shared_ptr<Asn1Node> EsimFile::LoadBoundProfilePackageParseProfileInstallResult(std::shared_ptr<Asn1Node> &root)
2201 {
2202 if (root == nullptr) {
2203 TELEPHONY_LOGE("failed to parse load BPP file response");
2204 return nullptr;
2205 }
2206 std::shared_ptr<Asn1Node> resultData = root->Asn1GetChild(TAG_ESIM_PROFILE_INSTALLATION_RESULT_DATA);
2207 if (resultData == nullptr) {
2208 TELEPHONY_LOGE("failed to find ProfileInstallationResult tag");
2209 return nullptr;
2210 }
2211 std::shared_ptr<Asn1Node> errNode = resultData->Asn1GetGreatGrandson(TAG_ESIM_CTX_COMP_2,
2212 TAG_ESIM_CTX_COMP_1, TAG_ESIM_CTX_1);
2213 if (errNode != nullptr) {
2214 loadBPPResult_.resultCode_ = errNode->Asn1AsInteger();
2215 return nullptr;
2216 }
2217 std::shared_ptr<Asn1Node> notificationMetadataAsn = resultData->Asn1GetChild(TAG_ESIM_NOTIFICATION_METADATA);
2218 if (notificationMetadataAsn == nullptr) {
2219 TELEPHONY_LOGE("extProfileInstallRsp: failed to find finalResult tag");
2220 return nullptr;
2221 }
2222 return notificationMetadataAsn;
2223 }
2224
ProcessListNotifications(int32_t slotId,Event events,const AppExecFwk::InnerEvent::Pointer & responseEvent)2225 bool EsimFile::ProcessListNotifications(
2226 int32_t slotId, Event events, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2227 {
2228 if (!IsLogicChannelOpen()) {
2229 return false;
2230 }
2231 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_LIST_NOTIFICATION);
2232 if (builder == nullptr) {
2233 TELEPHONY_LOGE("builder is nullptr");
2234 return false;
2235 }
2236 builder->Asn1AddChildAsBits(TAG_ESIM_CTX_1, static_cast<int32_t>(events));
2237 ApduSimIORequestInfo reqInfo;
2238 CommBuildOneApduReqInfo(reqInfo, builder);
2239 if (telRilManager_ == nullptr) {
2240 return false;
2241 }
2242 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2243 if (apduResult == TELEPHONY_ERR_FAIL) {
2244 return false;
2245 }
2246 return true;
2247 }
2248
createNotification(std::shared_ptr<Asn1Node> & node,EuiccNotification & euicc)2249 void EsimFile::createNotification(std::shared_ptr<Asn1Node> &node, EuiccNotification &euicc)
2250 {
2251 if (node == nullptr) {
2252 TELEPHONY_LOGE("createNotification node is nullptr");
2253 return;
2254 }
2255 std::shared_ptr<Asn1Node> metadataNode;
2256 if (node->GetNodeTag() == TAG_ESIM_NOTIFICATION_METADATA) {
2257 metadataNode = node;
2258 } else if (node->GetNodeTag() == TAG_ESIM_PROFILE_INSTALLATION_RESULT) {
2259 std::shared_ptr<Asn1Node> findNode =
2260 node->Asn1GetGrandson(TAG_ESIM_PROFILE_INSTALLATION_RESULT_DATA,
2261 TAG_ESIM_NOTIFICATION_METADATA);
2262 metadataNode = findNode;
2263 } else {
2264 // Other signed notification
2265 std::shared_ptr<Asn1Node> findNode = node->Asn1GetChild(TAG_ESIM_NOTIFICATION_METADATA);
2266 metadataNode = findNode;
2267 }
2268 if (metadataNode == nullptr) {
2269 TELEPHONY_LOGE("metadataNode is nullptr");
2270 return;
2271 }
2272 std::shared_ptr<Asn1Node> nodeSeq = metadataNode->Asn1GetChild(TAG_ESIM_SEQ);
2273 if (nodeSeq == nullptr) {
2274 TELEPHONY_LOGE("nodeSeq is nullptr");
2275 return;
2276 }
2277 euicc.seq_ = nodeSeq->Asn1AsInteger();
2278
2279 std::shared_ptr<Asn1Node> nodeTargetAddr = metadataNode->Asn1GetChild(TAG_ESIM_TARGET_ADDR);
2280 if (nodeTargetAddr == nullptr) {
2281 TELEPHONY_LOGE("nodeTargetAddr is nullptr");
2282 return;
2283 }
2284 std::vector<uint8_t> resultStr;
2285 nodeTargetAddr->Asn1AsBytes(resultStr);
2286 euicc.targetAddr_ = OHOS::Telephony::ToUtf16(Asn1Utils::BytesToString(resultStr));
2287
2288 std::shared_ptr<Asn1Node> nodeEvent = metadataNode->Asn1GetChild(TAG_ESIM_EVENT);
2289 if (nodeEvent == nullptr) {
2290 TELEPHONY_LOGE("nodeEvent is nullptr");
2291 return;
2292 }
2293 euicc.event_ = nodeEvent->Asn1AsBits();
2294
2295 std::string strmData;
2296 node->Asn1NodeToHexStr(strmData);
2297 euicc.data_ = Str8ToStr16(strmData);
2298 }
2299
ProcessListNotificationsAsn1Response(std::shared_ptr<Asn1Node> & root)2300 bool EsimFile::ProcessListNotificationsAsn1Response(std::shared_ptr<Asn1Node> &root)
2301 {
2302 if (root->Asn1HasChild(TAG_ESIM_CTX_1)) {
2303 TELEPHONY_LOGE("child is nullptr");
2304 return false;
2305 }
2306 std::list<std::shared_ptr<Asn1Node>> ls;
2307 std::shared_ptr<Asn1Node> compTag = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
2308 if (compTag == nullptr) {
2309 TELEPHONY_LOGE("compTag is nullptr");
2310 return false;
2311 }
2312 int32_t metaDataRes = compTag->Asn1GetChildren(TAG_ESIM_NOTIFICATION_METADATA, ls);
2313 if (metaDataRes != 0) {
2314 TELEPHONY_LOGE("metaDataTag is zero");
2315 return false;
2316 }
2317 std::shared_ptr<Asn1Node> curNode = nullptr;
2318 EuiccNotificationList euiccList;
2319 for (auto it = ls.begin(); it != ls.end(); ++it) {
2320 curNode = *it;
2321 EuiccNotification euicc;
2322 createNotification(curNode, euicc);
2323 euiccList.euiccNotification_.push_back(euicc);
2324 }
2325 eUiccNotificationList_ = euiccList;
2326 return true;
2327 }
2328
ProcessListNotificationsDone(const AppExecFwk::InnerEvent::Pointer & event)2329 bool EsimFile::ProcessListNotificationsDone(const AppExecFwk::InnerEvent::Pointer &event)
2330 {
2331 if (event == nullptr) {
2332 TELEPHONY_LOGE("event is nullptr!");
2333 NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
2334 return false;
2335 }
2336 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
2337 if (rcvMsg == nullptr) {
2338 TELEPHONY_LOGE("rcvMsg is nullptr");
2339 NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
2340 return false;
2341 }
2342 newRecvData_ = rcvMsg->fileData;
2343 bool isHandleFinish = false;
2344 bool retValue = CommMergeRecvData(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_,
2345 MSG_ESIM_LIST_NOTIFICATION, isHandleFinish);
2346 if (isHandleFinish) {
2347 return retValue;
2348 }
2349 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
2350 uint32_t byteLen = responseByte.size();
2351 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
2352 if (root == nullptr) {
2353 TELEPHONY_LOGE("root is nullptr");
2354 NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
2355 return false;
2356 }
2357 if (!ProcessListNotificationsAsn1Response(root)) {
2358 TELEPHONY_LOGE("ProcessListNotificationsAsn1Response error");
2359 NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
2360 return false;
2361 }
2362 NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
2363 return true;
2364 }
2365
RetrieveNotificationList(int32_t portIndex,Event events)2366 EuiccNotificationList EsimFile::RetrieveNotificationList(int32_t portIndex, Event events)
2367 {
2368 esimProfile_.portIndex = portIndex;
2369 esimProfile_.events = events;
2370 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2371 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2372 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2373 return EuiccNotificationList();
2374 }
2375 recvCombineStr_ = "";
2376 AppExecFwk::InnerEvent::Pointer eventRetrieveListNotif = BuildCallerInfo(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST);
2377 if (!ProcessRetrieveNotificationList(slotId_, events, eventRetrieveListNotif)) {
2378 TELEPHONY_LOGE("ProcessRetrieveNotificationList encode failed");
2379 SyncCloseChannel();
2380 return EuiccNotificationList();
2381 }
2382 isRetrieveNotificationListReady_ = false;
2383 std::unique_lock<std::mutex> lock(retrieveNotificationListMutex_);
2384 if (!retrieveNotificationListCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2385 [this]() { return isRetrieveNotificationListReady_; })) {
2386 SyncCloseChannel();
2387 return EuiccNotificationList();
2388 }
2389 SyncCloseChannel();
2390 return retrieveNotificationList_;
2391 }
2392
ObtainRetrieveNotification(int32_t portIndex,int32_t seqNumber)2393 EuiccNotification EsimFile::ObtainRetrieveNotification(int32_t portIndex, int32_t seqNumber)
2394 {
2395 esimProfile_.portIndex = portIndex;
2396 esimProfile_.seqNumber = seqNumber;
2397 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2398 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2399 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2400 return EuiccNotification();
2401 }
2402 recvCombineStr_ = "";
2403 AppExecFwk::InnerEvent::Pointer eventRetrieveNotification = BuildCallerInfo(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE);
2404 if (!ProcessRetrieveNotification(slotId_, eventRetrieveNotification)) {
2405 TELEPHONY_LOGE("ProcessRetrieveNotification encode failed");
2406 SyncCloseChannel();
2407 return EuiccNotification();
2408 }
2409 isRetrieveNotificationReady_ = false;
2410 std::unique_lock<std::mutex> lock(retrieveNotificationMutex_);
2411 if (!retrieveNotificationCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2412 [this]() { return isRetrieveNotificationReady_; })) {
2413 SyncCloseChannel();
2414 return EuiccNotification();
2415 }
2416 SyncCloseChannel();
2417 return notification_;
2418 }
2419
RemoveNotificationFromList(int32_t portIndex,int32_t seqNumber)2420 int32_t EsimFile::RemoveNotificationFromList(int32_t portIndex, int32_t seqNumber)
2421 {
2422 removeNotifResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
2423 esimProfile_.portIndex = portIndex;
2424 esimProfile_.seqNumber = seqNumber;
2425
2426 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2427 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2428 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2429 removeNotifResult_ = static_cast<int32_t>(resultFlag);
2430 return removeNotifResult_;
2431 }
2432 AppExecFwk::InnerEvent::Pointer eventRemoveNotif = BuildCallerInfo(MSG_ESIM_REMOVE_NOTIFICATION);
2433 if (!ProcessRemoveNotification(slotId_, eventRemoveNotif)) {
2434 TELEPHONY_LOGE("ProcessRemoveNotification encode failed");
2435 SyncCloseChannel();
2436 return removeNotifResult_;
2437 }
2438 isRemoveNotificationReady_ = false;
2439 std::unique_lock<std::mutex> lock(removeNotificationMutex_);
2440 if (!removeNotificationCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2441 [this]() { return isRemoveNotificationReady_; })) {
2442 SyncCloseChannel();
2443 return removeNotifResult_;
2444 }
2445 SyncCloseChannel();
2446 return removeNotifResult_;
2447 }
2448
ProcessRetrieveNotificationList(int32_t slotId,Event events,const AppExecFwk::InnerEvent::Pointer & responseEvent)2449 bool EsimFile::ProcessRetrieveNotificationList(
2450 int32_t slotId, Event events, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2451 {
2452 if (!IsLogicChannelOpen()) {
2453 return false;
2454 }
2455 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_RETRIEVE_NOTIFICATIONS_LIST);
2456 if (builder == nullptr) {
2457 TELEPHONY_LOGE("builder is nullptr!");
2458 return false;
2459 }
2460 std::shared_ptr<Asn1Builder> compBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
2461 if (compBuilder == nullptr) {
2462 TELEPHONY_LOGE("compBuilder is nullptr!");
2463 return false;
2464 }
2465 compBuilder->Asn1AddChildAsBits(TAG_ESIM_CTX_1, static_cast<int32_t>(events));
2466 std::shared_ptr<Asn1Node> compNode = compBuilder->Asn1Build();
2467 builder->Asn1AddChild(compNode);
2468 ApduSimIORequestInfo reqInfo;
2469 CommBuildOneApduReqInfo(reqInfo, builder);
2470 if (telRilManager_ == nullptr) {
2471 TELEPHONY_LOGE("telRilManager_ is nullptr");
2472 return false;
2473 }
2474 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2475 if (apduResult == TELEPHONY_ERR_FAIL) {
2476 return false;
2477 }
2478 return true;
2479 }
2480
ProcessRetrieveNotificationListDone(const AppExecFwk::InnerEvent::Pointer & event)2481 bool EsimFile::ProcessRetrieveNotificationListDone(const AppExecFwk::InnerEvent::Pointer &event)
2482 {
2483 if (event == nullptr) {
2484 TELEPHONY_LOGE("event is nullptr");
2485 NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
2486 return false;
2487 }
2488 std::shared_ptr<Asn1Node> root = ParseEvent(event);
2489 if (root == nullptr) {
2490 TELEPHONY_LOGE("root is nullptr");
2491 NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
2492 return false;
2493 }
2494 if (!RetrieveNotificationParseCompTag(root)) {
2495 TELEPHONY_LOGE("RetrieveNotificationParseCompTag error");
2496 NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
2497 return false;
2498 }
2499 NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
2500 return true;
2501 }
2502
RetrieveNotificationParseCompTag(std::shared_ptr<Asn1Node> & root)2503 bool EsimFile::RetrieveNotificationParseCompTag(std::shared_ptr<Asn1Node> &root)
2504 {
2505 std::list<std::shared_ptr<Asn1Node>> ls;
2506 std::shared_ptr<Asn1Node> compTag = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
2507 if (compTag == nullptr) {
2508 TELEPHONY_LOGE("compTag is nullptr");
2509 return false;
2510 }
2511 int32_t metaDataRes = compTag->Asn1GetChildren(TAG_ESIM_SEQUENCE, ls);
2512 if (metaDataRes != 0) {
2513 TELEPHONY_LOGE("metaDataTag is zero");
2514 return false;
2515 }
2516 std::shared_ptr<Asn1Node> curNode = nullptr;
2517 EuiccNotificationList euiccList;
2518 for (auto it = ls.begin(); it != ls.end(); ++it) {
2519 curNode = *it;
2520 EuiccNotification euicc;
2521 createNotification(curNode, euicc);
2522 euiccList.euiccNotification_.push_back(euicc);
2523 }
2524 eUiccNotificationList_ = euiccList;
2525 return true;
2526 }
2527
ProcessRetrieveNotification(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)2528 bool EsimFile::ProcessRetrieveNotification(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2529 {
2530 if (!IsLogicChannelOpen()) {
2531 return false;
2532 }
2533 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_RETRIEVE_NOTIFICATIONS_LIST);
2534 std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
2535 if (builder == nullptr || subBuilder == nullptr) {
2536 TELEPHONY_LOGE("get builder failed");
2537 return false;
2538 }
2539 subBuilder->Asn1AddChildAsSignedInteger(TAG_ESIM_CTX_0, esimProfile_.seqNumber);
2540 std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
2541 builder->Asn1AddChild(subNode);
2542 ApduSimIORequestInfo reqInfo;
2543 CommBuildOneApduReqInfo(reqInfo, builder);
2544 if (telRilManager_ == nullptr) {
2545 TELEPHONY_LOGE("telRilManager_ is nullptr");
2546 return false;
2547 }
2548 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2549 if (apduResult == TELEPHONY_ERR_FAIL) {
2550 return false;
2551 }
2552 return true;
2553 }
2554
ProcessRetrieveNotificationDone(const AppExecFwk::InnerEvent::Pointer & event)2555 bool EsimFile::ProcessRetrieveNotificationDone(const AppExecFwk::InnerEvent::Pointer &event)
2556 {
2557 ResetEuiccNotification();
2558 if (event == nullptr) {
2559 TELEPHONY_LOGE("event is nullptr");
2560 NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
2561 return false;
2562 }
2563 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
2564 if (rcvMsg == nullptr) {
2565 TELEPHONY_LOGE("rcvMsg is nullptr");
2566 NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
2567 return false;
2568 }
2569 newRecvData_ = rcvMsg->fileData;
2570 bool isHandleFinish = false;
2571 bool retValue = CommMergeRecvData(retrieveNotificationMutex_, isRetrieveNotificationReady_,
2572 retrieveNotificationCv_, MSG_ESIM_RETRIEVE_NOTIFICATION_DONE, isHandleFinish);
2573 if (isHandleFinish) {
2574 return retValue;
2575 }
2576 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
2577 uint32_t byteLen = responseByte.size();
2578 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
2579 if (root == nullptr) {
2580 TELEPHONY_LOGE("root is nullptr");
2581 NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
2582 return false;
2583 }
2584 if (!RetrieveNotificatioParseTagCtxComp0(root)) {
2585 TELEPHONY_LOGE("RetrieveNotificatioParseTagCtxComp0 error");
2586 NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
2587 return false;
2588 }
2589 NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
2590 return true;
2591 }
2592
RetrieveNotificatioParseTagCtxComp0(std::shared_ptr<Asn1Node> & root)2593 bool EsimFile::RetrieveNotificatioParseTagCtxComp0(std::shared_ptr<Asn1Node> &root)
2594 {
2595 std::list<std::shared_ptr<Asn1Node>> nodes;
2596 std::shared_ptr<Asn1Node> compNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
2597 if (compNode == nullptr) {
2598 TELEPHONY_LOGE("compNode is nullptr");
2599 return false;
2600 }
2601
2602 int32_t ret = compNode->Asn1GetChildren(TAG_ESIM_SEQUENCE, nodes);
2603 if ((ret != TELEPHONY_ERR_SUCCESS) || nodes.empty()) {
2604 ret = compNode->Asn1GetChildren(TAG_ESIM_PROFILE_INSTALLATION_RESULT, nodes);
2605 if ((ret != TELEPHONY_ERR_SUCCESS) || nodes.empty()) {
2606 TELEPHONY_LOGE("Asn1GetChildren error");
2607 return false;
2608 }
2609 }
2610
2611 EuiccNotification notification;
2612 std::shared_ptr<Asn1Node> firstNode = nodes.front();
2613 createNotification(firstNode, notification);
2614 notification_.seq_ = notification.seq_;
2615 notification_.targetAddr_ = notification.targetAddr_;
2616 notification_.event_ = notification.event_;
2617 notification_.data_ = notification.data_;
2618 return true;
2619 }
2620
ProcessRemoveNotification(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)2621 bool EsimFile::ProcessRemoveNotification(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2622 {
2623 if (!IsLogicChannelOpen()) {
2624 return false;
2625 }
2626 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_REMOVE_NOTIFICATION_FROM_LIST);
2627 if (builder == nullptr) {
2628 TELEPHONY_LOGE("builder is nullptr");
2629 return false;
2630 }
2631 builder->Asn1AddChildAsSignedInteger(TAG_ESIM_CTX_0, esimProfile_.seqNumber);
2632 ApduSimIORequestInfo reqInfo;
2633 CommBuildOneApduReqInfo(reqInfo, builder);
2634 if (telRilManager_ == nullptr) {
2635 TELEPHONY_LOGE("telRilManager is nullptr");
2636 return false;
2637 }
2638 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2639 if (apduResult == TELEPHONY_ERR_FAIL) {
2640 return false;
2641 }
2642 return true;
2643 }
2644
ProcessRemoveNotificationDone(const AppExecFwk::InnerEvent::Pointer & event)2645 bool EsimFile::ProcessRemoveNotificationDone(const AppExecFwk::InnerEvent::Pointer &event)
2646 {
2647 if (event == nullptr) {
2648 TELEPHONY_LOGE("event is nullptr!");
2649 NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
2650 return false;
2651 }
2652 std::shared_ptr<Asn1Node> root = ParseEvent(event);
2653 if (root == nullptr) {
2654 TELEPHONY_LOGE("Asn1ParseResponse failed");
2655 NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
2656 return false;
2657 }
2658 std::shared_ptr<Asn1Node> node = root->Asn1GetChild(TAG_ESIM_CTX_0);
2659 if (node == nullptr) {
2660 TELEPHONY_LOGE("node is nullptr");
2661 NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
2662 return false;
2663 }
2664 removeNotifResult_ = node->Asn1AsInteger();
2665 NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
2666 return true;
2667 }
2668
DeleteProfile(const std::u16string & iccId)2669 int32_t EsimFile::DeleteProfile(const std::u16string &iccId)
2670 {
2671 delProfile_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
2672 esimProfile_.iccId = iccId;
2673
2674 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2675 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2676 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2677 delProfile_ = static_cast<int32_t>(resultFlag);
2678 return delProfile_;
2679 }
2680 AppExecFwk::InnerEvent::Pointer eventDeleteProfile = BuildCallerInfo(MSG_ESIM_DELETE_PROFILE);
2681 if (!ProcessDeleteProfile(slotId_, eventDeleteProfile)) {
2682 TELEPHONY_LOGE("ProcessDeleteProfile encode failed");
2683 SyncCloseChannel();
2684 return delProfile_;
2685 }
2686 isDeleteProfileReady_ = false;
2687 std::unique_lock<std::mutex> lock(deleteProfileMutex_);
2688 if (!deleteProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2689 [this]() { return isDeleteProfileReady_; })) {
2690 SyncCloseChannel();
2691 return delProfile_;
2692 }
2693 SyncCloseChannel();
2694 return delProfile_;
2695 }
2696
SwitchToProfile(int32_t portIndex,const std::u16string & iccId,bool forceDisableProfile)2697 int32_t EsimFile::SwitchToProfile(int32_t portIndex, const std::u16string &iccId, bool forceDisableProfile)
2698 {
2699 switchResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
2700 esimProfile_.portIndex = portIndex;
2701 esimProfile_.iccId = iccId;
2702 esimProfile_.forceDisableProfile = forceDisableProfile;
2703 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2704 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2705 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2706 switchResult_ = static_cast<int32_t>(resultFlag);
2707 return switchResult_;
2708 }
2709 AppExecFwk::InnerEvent::Pointer eventSwitchToProfile = BuildCallerInfo(MSG_ESIM_SWITCH_PROFILE);
2710 if (!ProcessSwitchToProfile(slotId_, eventSwitchToProfile)) {
2711 TELEPHONY_LOGE("ProcessSwitchToProfile encode failed");
2712 SyncCloseChannel();
2713 return switchResult_;
2714 }
2715 isSwitchToProfileReady_ = false;
2716 std::unique_lock<std::mutex> lock(switchToProfileMutex_);
2717 if (!switchToProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2718 [this]() { return isSwitchToProfileReady_; })) {
2719 SyncCloseChannel();
2720 return switchResult_;
2721 }
2722 SyncCloseChannel();
2723 return switchResult_;
2724 }
2725
SetProfileNickname(const std::u16string & iccId,const std::u16string & nickname)2726 int32_t EsimFile::SetProfileNickname(const std::u16string &iccId, const std::u16string &nickname)
2727 {
2728 setNicknameResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
2729 esimProfile_.iccId = iccId;
2730 esimProfile_.nickname = nickname;
2731 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2732 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2733 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2734 setNicknameResult_ = static_cast<int32_t>(resultFlag);
2735 return setNicknameResult_;
2736 }
2737 AppExecFwk::InnerEvent::Pointer eventSetNickName = BuildCallerInfo(MSG_ESIM_SET_NICK_NAME);
2738 if (!ProcessSetNickname(slotId_, eventSetNickName)) {
2739 TELEPHONY_LOGE("ProcessSetNickname encode failed");
2740 SyncCloseChannel();
2741 return setNicknameResult_;
2742 }
2743 isSetNicknameReady_ = false;
2744 std::unique_lock<std::mutex> lock(setNicknameMutex_);
2745 if (!setNicknameCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2746 [this]() { return isSetNicknameReady_; })) {
2747 SyncCloseChannel();
2748 return setNicknameResult_;
2749 }
2750 SyncCloseChannel();
2751 return setNicknameResult_;
2752 }
2753
ProcessDeleteProfile(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)2754 bool EsimFile::ProcessDeleteProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2755 {
2756 if (!IsLogicChannelOpen()) {
2757 return false;
2758 }
2759 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_DELETE_PROFILE);
2760 if (builder == nullptr) {
2761 TELEPHONY_LOGE("builder is nullptr");
2762 return false;
2763 }
2764 std::vector<uint8_t> iccidBytes;
2765 std::string strIccId = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
2766 Asn1Utils::BcdToBytes(strIccId, iccidBytes);
2767 builder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
2768 ApduSimIORequestInfo reqInfo;
2769 CommBuildOneApduReqInfo(reqInfo, builder);
2770 if (telRilManager_ == nullptr) {
2771 return false;
2772 }
2773 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2774 if (apduResult == TELEPHONY_ERR_FAIL) {
2775 return false;
2776 }
2777 return true;
2778 }
2779
ProcessSetNickname(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)2780 bool EsimFile::ProcessSetNickname(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2781 {
2782 if (!IsLogicChannelOpen()) {
2783 return false;
2784 }
2785 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_SET_NICKNAME);
2786 if (builder == nullptr) {
2787 TELEPHONY_LOGE("builder is nullptr");
2788 return false;
2789 }
2790 std::vector<uint8_t> iccidBytes;
2791 std::string strIccId = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
2792 std::string childStr = OHOS::Telephony::ToUtf8(esimProfile_.nickname);
2793 Asn1Utils::BcdToBytes(strIccId, iccidBytes);
2794
2795 builder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
2796 builder->Asn1AddChildAsString(TAG_ESIM_NICKNAME, childStr);
2797 ApduSimIORequestInfo reqInfo;
2798 CommBuildOneApduReqInfo(reqInfo, builder);
2799 if (telRilManager_ == nullptr) {
2800 return false;
2801 }
2802 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2803 if (apduResult == TELEPHONY_ERR_FAIL) {
2804 return false;
2805 }
2806 return true;
2807 }
2808
ProcessDeleteProfileDone(const AppExecFwk::InnerEvent::Pointer & event)2809 bool EsimFile::ProcessDeleteProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
2810 {
2811 std::shared_ptr<Asn1Node> root = ParseEvent(event);
2812 if (root == nullptr) {
2813 TELEPHONY_LOGE("Asn1ParseResponse failed");
2814 NotifyReady(deleteProfileMutex_, isDeleteProfileReady_, deleteProfileCv_);
2815 return false;
2816 }
2817 std::shared_ptr<Asn1Node> Asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
2818 if (Asn1NodeData == nullptr) {
2819 TELEPHONY_LOGE("pAsn1Node is nullptr");
2820 NotifyReady(deleteProfileMutex_, isDeleteProfileReady_, deleteProfileCv_);
2821 return false;
2822 }
2823 delProfile_ = Asn1NodeData->Asn1AsInteger();
2824 NotifyReady(deleteProfileMutex_, isDeleteProfileReady_, deleteProfileCv_);
2825 return true;
2826 }
2827
ProcessSwitchToProfile(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)2828 bool EsimFile::ProcessSwitchToProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2829 {
2830 if (!IsLogicChannelOpen()) {
2831 return false;
2832 }
2833 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_ENABLE_PROFILE);
2834 std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
2835 if (builder == nullptr || subBuilder == nullptr) {
2836 TELEPHONY_LOGE("get builder failed");
2837 return false;
2838 }
2839 std::vector<uint8_t> iccidBytes;
2840 std::string strIccId = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
2841 Asn1Utils::BcdToBytes(strIccId, iccidBytes);
2842 subBuilder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
2843 std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
2844 if (subNode == nullptr) {
2845 TELEPHONY_LOGE("subNode is nullptr");
2846 return false;
2847 }
2848 builder->Asn1AddChild(subNode);
2849 builder->Asn1AddChildAsBoolean(TAG_ESIM_CTX_1, true);
2850 ApduSimIORequestInfo reqInfo;
2851 CommBuildOneApduReqInfo(reqInfo, builder);
2852 if (telRilManager_ == nullptr) {
2853 return false;
2854 }
2855 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2856 if (apduResult == TELEPHONY_ERR_FAIL) {
2857 return false;
2858 }
2859 return true;
2860 }
2861
ProcessSwitchToProfileDone(const AppExecFwk::InnerEvent::Pointer & event)2862 bool EsimFile::ProcessSwitchToProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
2863 {
2864 std::shared_ptr<Asn1Node> root = ParseEvent(event);
2865 if (root == nullptr) {
2866 TELEPHONY_LOGE("Asn1ParseResponse failed");
2867 NotifyReady(switchToProfileMutex_, isSwitchToProfileReady_, switchToProfileCv_);
2868 return false;
2869 }
2870 std::shared_ptr<Asn1Node> asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
2871 if (asn1NodeData == nullptr) {
2872 TELEPHONY_LOGE("asn1NodeData is nullptr");
2873 NotifyReady(switchToProfileMutex_, isSwitchToProfileReady_, switchToProfileCv_);
2874 return false;
2875 }
2876 switchResult_ = asn1NodeData->Asn1AsInteger();
2877 NotifyReady(switchToProfileMutex_, isSwitchToProfileReady_, switchToProfileCv_);
2878 return true;
2879 }
2880
ProcessSetNicknameDone(const AppExecFwk::InnerEvent::Pointer & event)2881 bool EsimFile::ProcessSetNicknameDone(const AppExecFwk::InnerEvent::Pointer &event)
2882 {
2883 std::shared_ptr<Asn1Node> root = ParseEvent(event);
2884 if (root == nullptr) {
2885 TELEPHONY_LOGE("Asn1ParseResponse failed");
2886 NotifyReady(setNicknameMutex_, isSetNicknameReady_, setNicknameCv_);
2887 return false;
2888 }
2889 std::shared_ptr<Asn1Node> asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
2890 if (asn1NodeData == nullptr) {
2891 TELEPHONY_LOGE("asn1NodeData is nullptr");
2892 NotifyReady(setNicknameMutex_, isSetNicknameReady_, setNicknameCv_);
2893 return false;
2894 }
2895 setNicknameResult_ = asn1NodeData->Asn1AsInteger();
2896 NotifyReady(setNicknameMutex_, isSetNicknameReady_, setNicknameCv_);
2897 return true;
2898 }
2899
ObtainEuiccInfo2(int32_t portIndex)2900 EuiccInfo2 EsimFile::ObtainEuiccInfo2(int32_t portIndex)
2901 {
2902 euiccInfo2Result_ = EuiccInfo2();
2903 esimProfile_.portIndex = portIndex;
2904
2905 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2906 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2907 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2908 euiccInfo2Result_.resultCode_ = static_cast<int32_t>(resultFlag);
2909 return euiccInfo2Result_;
2910 }
2911 AppExecFwk::InnerEvent::Pointer eventEUICCInfo2 = BuildCallerInfo(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE);
2912 recvCombineStr_ = "";
2913 if (!ProcessObtainEuiccInfo2(slotId_, eventEUICCInfo2)) {
2914 TELEPHONY_LOGE("ProcessObtainEuiccInfo2 encode failed");
2915 SyncCloseChannel();
2916 euiccInfo2Result_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
2917 return euiccInfo2Result_;
2918 }
2919 isEuiccInfo2Ready_ = false;
2920 std::unique_lock<std::mutex> lock(euiccInfo2Mutex_);
2921 if (!euiccInfo2Cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
2922 [this]() { return isEuiccInfo2Ready_; })) {
2923 SyncCloseChannel();
2924 euiccInfo2Result_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
2925 return euiccInfo2Result_;
2926 }
2927 SyncCloseChannel();
2928 return euiccInfo2Result_;
2929 }
2930
AuthenticateServer(const AuthenticateConfigInfo & authenticateConfigInfo)2931 ResponseEsimInnerResult EsimFile::AuthenticateServer(const AuthenticateConfigInfo &authenticateConfigInfo)
2932 {
2933 responseAuthenticateResult_ = ResponseEsimInnerResult();
2934 esimProfile_.portIndex = authenticateConfigInfo.portIndex_;
2935 esimProfile_.matchingId = authenticateConfigInfo.matchingId_;
2936 esimProfile_.serverSigned1 = authenticateConfigInfo.serverSigned1_;
2937 esimProfile_.serverSignature1 = authenticateConfigInfo.serverSignature1_;
2938 esimProfile_.euiccCiPkIdToBeUsed = authenticateConfigInfo.euiccCiPkIdToBeUsed_;
2939 esimProfile_.serverCertificate = authenticateConfigInfo.serverCertificate_;
2940
2941 std::u16string imei = u"";
2942 CoreManagerInner::GetInstance().GetImei(slotId_, imei);
2943 esimProfile_.imei = imei;
2944 ResultInnerCode resultFlag = ObtainChannelSuccessExclusive();
2945 if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
2946 TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
2947 responseAuthenticateResult_.resultCode_ = static_cast<int32_t>(resultFlag);
2948 return responseAuthenticateResult_;
2949 }
2950 recvCombineStr_ = "";
2951 if (!ProcessAuthenticateServer(slotId_)) {
2952 TELEPHONY_LOGE("ProcessAuthenticateServer encode failed");
2953 SyncCloseChannel();
2954 responseAuthenticateResult_.resultCode_ =
2955 static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
2956 return responseAuthenticateResult_;
2957 }
2958 SyncCloseChannel();
2959 return responseAuthenticateResult_;
2960 }
2961
ProcessObtainEuiccInfo2(int32_t slotId,const AppExecFwk::InnerEvent::Pointer & responseEvent)2962 bool EsimFile::ProcessObtainEuiccInfo2(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
2963 {
2964 if (!IsLogicChannelOpen()) {
2965 return false;
2966 }
2967 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EUICC_INFO_2);
2968 if (builder == nullptr) {
2969 TELEPHONY_LOGE("builder is nullptr");
2970 return false;
2971 }
2972 std::string hexStr;
2973 uint32_t strLen = builder->Asn1BuilderToHexStr(hexStr);
2974 ApduSimIORequestInfo reqInfo;
2975 CommBuildOneApduReqInfo(reqInfo, builder);
2976 if (telRilManager_ == nullptr) {
2977 return false;
2978 }
2979 int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
2980 if (apduResult == TELEPHONY_ERR_FAIL) {
2981 return false;
2982 }
2983 return true;
2984 }
2985
ResetEuiccNotification()2986 void EsimFile::ResetEuiccNotification()
2987 {
2988 notification_.seq_ = 0;
2989 notification_.targetAddr_ = u"";
2990 notification_.event_ = 0;
2991 notification_.data_ = u"";
2992 }
2993
ConvertAuthInputParaFromApiStru(Es9PlusInitAuthResp & dst,EsimProfile & src)2994 void EsimFile::ConvertAuthInputParaFromApiStru(Es9PlusInitAuthResp &dst, EsimProfile &src)
2995 {
2996 dst.serverSigned1 = OHOS::Telephony::ToUtf8(src.serverSigned1);
2997 dst.serverSignature1 = OHOS::Telephony::ToUtf8(src.serverSignature1);
2998 dst.euiccCiPKIdToBeUsed = OHOS::Telephony::ToUtf8(src.euiccCiPkIdToBeUsed);
2999 dst.serverCertificate = OHOS::Telephony::ToUtf8(src.serverCertificate);
3000 dst.matchingId = OHOS::Telephony::ToUtf8(src.matchingId);
3001 dst.imei = OHOS::Telephony::ToUtf8(src.imei);
3002 }
3003
ProcessAuthenticateServer(int32_t slotId)3004 bool EsimFile::ProcessAuthenticateServer(int32_t slotId)
3005 {
3006 if (!IsLogicChannelOpen()) {
3007 return false;
3008 }
3009 Es9PlusInitAuthResp authRespData;
3010 ConvertAuthInputParaFromApiStru(authRespData, esimProfile_);
3011 std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_AUTHENTICATE_SERVER);
3012 if (builder == nullptr) {
3013 TELEPHONY_LOGE("builder create failed");
3014 return false;
3015 }
3016 Asn1AddChildAsBase64(builder, authRespData.serverSigned1);
3017 Asn1AddChildAsBase64(builder, authRespData.serverSignature1);
3018 Asn1AddChildAsBase64(builder, authRespData.euiccCiPKIdToBeUsed);
3019 Asn1AddChildAsBase64(builder, authRespData.serverCertificate);
3020 std::shared_ptr<Asn1Builder> ctxParams1Builder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
3021 AddCtxParams1(ctxParams1Builder, authRespData);
3022 if (ctxParams1Builder == nullptr) {
3023 TELEPHONY_LOGE("AddCtxParams1 failed");
3024 return false;
3025 }
3026 std::shared_ptr<Asn1Node> ctxNode = ctxParams1Builder->Asn1Build();
3027 if (ctxNode == nullptr) {
3028 TELEPHONY_LOGE("ctxNode is nullptr");
3029 return false;
3030 }
3031 builder->Asn1AddChild(ctxNode);
3032 std::string hexStr;
3033 uint32_t hexStrLen = builder->Asn1BuilderToHexStr(hexStr);
3034 RequestApduBuild codec(currentChannelId_);
3035 codec.BuildStoreData(hexStr);
3036 SplitSendLongData(codec, MSG_ESIM_AUTHENTICATE_SERVER,
3037 authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3038 return true;
3039 }
3040
AddDeviceCapability(std::shared_ptr<Asn1Builder> & devCapsBuilder)3041 void EsimFile::AddDeviceCapability(std::shared_ptr<Asn1Builder> &devCapsBuilder)
3042 {
3043 std::vector<uint8_t> versionBytes;
3044 Asn1Utils::UintToBytes(VERSION_NUMBER, versionBytes);
3045 versionBytes.push_back(0);
3046 versionBytes.push_back(0);
3047 devCapsBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_0, versionBytes, versionBytes.size());
3048 devCapsBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_1, versionBytes, versionBytes.size());
3049 devCapsBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_5, versionBytes, versionBytes.size());
3050 }
3051
GetImeiBytes(std::vector<uint8_t> & imeiBytes,const std::string & imei)3052 void EsimFile::GetImeiBytes(std::vector<uint8_t> &imeiBytes, const std::string &imei)
3053 {
3054 size_t imeiLen = imei.length();
3055 if (imeiLen < AUTH_SERVER_IMEI_LEN * BYTE_TO_HEX_LEN - 1) {
3056 return;
3057 }
3058 if (imeiLen != AUTH_SERVER_IMEI_LEN * BYTE_TO_HEX_LEN) {
3059 std::string newImei = imei;
3060 newImei += 'F';
3061 Asn1Utils::BcdToBytes(newImei, imeiBytes);
3062 unsigned char last = imeiBytes[LAST_BYTE_OF_IMEI];
3063 imeiBytes[LAST_BYTE_OF_IMEI] = static_cast<unsigned char>((last & 0xFF) <<
3064 OFFSET_FOUR_BIT | ((last & 0xFF) >> OFFSET_FOUR_BIT));
3065 } else {
3066 Asn1Utils::BcdToBytes(imei, imeiBytes);
3067 }
3068 }
3069
AddCtxParams1(std::shared_ptr<Asn1Builder> & ctxParams1Builder,Es9PlusInitAuthResp & authRespData)3070 void EsimFile::AddCtxParams1(std::shared_ptr<Asn1Builder> &ctxParams1Builder, Es9PlusInitAuthResp &authRespData)
3071 {
3072 if (ctxParams1Builder == nullptr) {
3073 return;
3074 }
3075 ctxParams1Builder->Asn1AddChildAsString(TAG_ESIM_CTX_0, authRespData.matchingId);
3076 std::shared_ptr<Asn1Node> subNode = nullptr;
3077 std::vector<uint8_t> tmpBytes;
3078 std::vector<uint8_t> imeiBytes;
3079 Asn1Utils::BcdToBytes(authRespData.imei, tmpBytes);
3080 if (tmpBytes.size() < AUTH_SERVER_TAC_LEN) {
3081 TELEPHONY_LOGE("tmpBytes.size is small than AUTH_SERVER_TAC_LEN");
3082 return;
3083 }
3084 std::vector<uint8_t> tacBytes(tmpBytes.begin(), tmpBytes.begin() + AUTH_SERVER_TAC_LEN);
3085 GetImeiBytes(imeiBytes, authRespData.imei);
3086 std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_1);
3087 if (subBuilder == nullptr) {
3088 TELEPHONY_LOGE("AddCtxParams1 subBuilder is nullptr");
3089 return;
3090 }
3091 subBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_0, tacBytes, tacBytes.size());
3092 // add devCap
3093 std::shared_ptr<Asn1Builder> devCapsBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_1);
3094 if (devCapsBuilder == nullptr) {
3095 TELEPHONY_LOGE("AddCtxParams1 devCapsBuilder is nullptr");
3096 return;
3097 }
3098 AddDeviceCapability(devCapsBuilder);
3099 std::shared_ptr<Asn1Node> devCapNode = devCapsBuilder->Asn1Build();
3100 if (devCapNode == nullptr) {
3101 TELEPHONY_LOGE("devCapNode is nullptr");
3102 return;
3103 }
3104 subBuilder->Asn1AddChild(devCapNode);
3105 subBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_2, imeiBytes, imeiBytes.size());
3106 subNode = subBuilder->Asn1Build();
3107 ctxParams1Builder->Asn1AddChild(subNode);
3108 }
3109
ProcessObtainEuiccInfo2Done(const AppExecFwk::InnerEvent::Pointer & event)3110 bool EsimFile::ProcessObtainEuiccInfo2Done(const AppExecFwk::InnerEvent::Pointer &event)
3111 {
3112 if (event == nullptr) {
3113 TELEPHONY_LOGE("event is nullptr!");
3114 NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
3115 return false;
3116 }
3117 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
3118 if (rcvMsg == nullptr) {
3119 TELEPHONY_LOGE("rcvMsg is nullptr");
3120 NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
3121 return false;
3122 }
3123 newRecvData_ = rcvMsg->fileData;
3124 bool isHandleFinish = false;
3125 bool retValue = CommMergeRecvData(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_,
3126 MSG_ESIM_OBTAIN_EUICC_INFO2_DONE, isHandleFinish);
3127 if (isHandleFinish) {
3128 return retValue;
3129 }
3130 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
3131 uint32_t byteLen = responseByte.size();
3132 std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
3133 if (root == nullptr) {
3134 TELEPHONY_LOGE("Asn1ParseResponse failed");
3135 NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
3136 return false;
3137 }
3138 this->EuiccInfo2ParseProfileVersion(euiccInfo2Result_, root);
3139 this->EuiccInfo2ParseSvn(euiccInfo2Result_, root);
3140 this->EuiccInfo2ParseEuiccFirmwareVer(euiccInfo2Result_, root);
3141 this->EuiccInfo2ParseExtCardResource(euiccInfo2Result_, root);
3142 this->EuiccInfo2ParseUiccCapability(euiccInfo2Result_, root);
3143 this->EuiccInfo2ParseTs102241Version(euiccInfo2Result_, root);
3144 this->EuiccInfo2ParseGlobalPlatformVersion(euiccInfo2Result_, root);
3145 this->EuiccInfo2ParseRspCapability(euiccInfo2Result_, root);
3146 this->EuiccInfo2ParseEuiccCiPKIdListForVerification(euiccInfo2Result_, root);
3147 this->EuiccInfo2ParseEuiccCiPKIdListForSigning(euiccInfo2Result_, root);
3148 this->EuiccInfo2ParseEuiccCategory(euiccInfo2Result_, root);
3149 this->EuiccInfo2ParsePpVersion(euiccInfo2Result_, root);
3150 euiccInfo2Result_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
3151 euiccInfo2Result_.response_ = newRecvData_.resultData;
3152 NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
3153 return true;
3154 }
3155
EuiccInfo2ParseProfileVersion(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3156 void EsimFile::EuiccInfo2ParseProfileVersion(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3157 {
3158 std::shared_ptr<Asn1Node> profileVerNode = root->Asn1GetChild(TAG_ESIM_CTX_1);
3159 if (profileVerNode == nullptr) {
3160 TELEPHONY_LOGE("profileVerNode is nullptr");
3161 return;
3162 }
3163 std::vector<uint8_t> profileVersionRaw = {};
3164 uint32_t profileVersionRawLen = profileVerNode->Asn1AsBytes(profileVersionRaw);
3165 if (profileVersionRawLen < EUICC_INFO_VERSION_MIN_LENGTH) {
3166 TELEPHONY_LOGE("invalid profileVersion data");
3167 return;
3168 }
3169 euiccInfo2.profileVersion_ = MakeVersionString(profileVersionRaw);
3170 }
3171
EuiccInfo2ParseSvn(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3172 void EsimFile::EuiccInfo2ParseSvn(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3173 {
3174 std::shared_ptr<Asn1Node> svnNode = root->Asn1GetChild(TAG_ESIM_CTX_2);
3175 if (svnNode == nullptr) {
3176 TELEPHONY_LOGE("svnNode is nullptr");
3177 return;
3178 }
3179 std::vector<uint8_t> svnRaw = {};
3180 uint32_t svnRawLen = svnNode->Asn1AsBytes(svnRaw);
3181 if (svnRawLen < EUICC_INFO_VERSION_MIN_LENGTH) {
3182 TELEPHONY_LOGE("invalid SVN data");
3183 return;
3184 }
3185 euiccInfo2.svn_ = MakeVersionString(svnRaw);
3186 }
3187
EuiccInfo2ParseEuiccFirmwareVer(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3188 void EsimFile::EuiccInfo2ParseEuiccFirmwareVer(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3189 {
3190 std::shared_ptr<Asn1Node> euiccFirmwareVerNode = root->Asn1GetChild(TAG_ESIM_CTX_3);
3191 if (euiccFirmwareVerNode == nullptr) {
3192 TELEPHONY_LOGE("euiccFirmwareVerNode is nullptr");
3193 return;
3194 }
3195 std::vector<uint8_t> euiccFirmwareVerRaw = {};
3196 uint32_t versionLen = euiccFirmwareVerNode->Asn1AsBytes(euiccFirmwareVerRaw);
3197 if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
3198 TELEPHONY_LOGE("invalid firmwareVer data");
3199 return;
3200 }
3201 euiccInfo2.firmwareVer_ = MakeVersionString(euiccFirmwareVerRaw);
3202 }
3203
EuiccInfo2ParseExtCardResource(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3204 void EsimFile::EuiccInfo2ParseExtCardResource(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3205 {
3206 std::shared_ptr<Asn1Node> extCardResourceNode = root->Asn1GetChild(TAG_ESIM_CTX_4);
3207 if (extCardResourceNode == nullptr) {
3208 TELEPHONY_LOGE("extCardResourceNode is nullptr");
3209 return;
3210 }
3211 extCardResourceNode->Asn1AsString(euiccInfo2.extCardResource_);
3212 }
3213
EuiccInfo2ParseUiccCapability(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3214 void EsimFile::EuiccInfo2ParseUiccCapability(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3215 {
3216 std::shared_ptr<Asn1Node> uiccCapabilityNode = root->Asn1GetChild(TAG_ESIM_CTX_5);
3217 if (uiccCapabilityNode == nullptr) {
3218 TELEPHONY_LOGE("uiccCapabilityNode is nullptr");
3219 return;
3220 }
3221 uiccCapabilityNode->Asn1AsString(euiccInfo2.uiccCapability_);
3222 }
3223
EuiccInfo2ParseTs102241Version(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3224 void EsimFile::EuiccInfo2ParseTs102241Version(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3225 {
3226 std::shared_ptr<Asn1Node> ts102241VersionNode = root->Asn1GetChild(TAG_ESIM_CTX_6);
3227 if (ts102241VersionNode == nullptr) {
3228 TELEPHONY_LOGE("ts102241VersionNode is nullptr");
3229 return;
3230 }
3231 std::vector<uint8_t> ts102241VersionRaw = {};
3232 uint32_t versionLen = ts102241VersionNode->Asn1AsBytes(ts102241VersionRaw);
3233 if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
3234 TELEPHONY_LOGE("invalid ts102241VersionNode data");
3235 return;
3236 }
3237 euiccInfo2.ts102241Version_ = MakeVersionString(ts102241VersionRaw);
3238 }
3239
EuiccInfo2ParseGlobalPlatformVersion(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3240 void EsimFile::EuiccInfo2ParseGlobalPlatformVersion(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3241 {
3242 std::shared_ptr<Asn1Node> globalPlatformVersionNode = root->Asn1GetChild(TAG_ESIM_CTX_7);
3243 if (globalPlatformVersionNode == nullptr) {
3244 TELEPHONY_LOGE("globalPlatformVersionNode is nullptr");
3245 return;
3246 }
3247 std::vector<uint8_t> globalPlatformVersionRaw = {};
3248 uint32_t versionLen = globalPlatformVersionNode->Asn1AsBytes(globalPlatformVersionRaw);
3249 if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
3250 TELEPHONY_LOGE("invalid globalplatformVersionRaw data");
3251 return;
3252 }
3253 euiccInfo2.globalPlatformVersion_ = MakeVersionString(globalPlatformVersionRaw);
3254 }
3255
EuiccInfo2ParseRspCapability(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3256 void EsimFile::EuiccInfo2ParseRspCapability(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3257 {
3258 std::shared_ptr<Asn1Node> rspCapabilityNode = root->Asn1GetChild(TAG_ESIM_CTX_8);
3259 if (rspCapabilityNode == nullptr) {
3260 TELEPHONY_LOGE("rspCapabilityNode is nullptr");
3261 return;
3262 }
3263 rspCapabilityNode->Asn1AsString(euiccInfo2.rspCapability_);
3264 }
3265
EuiccInfo2ParseEuiccCiPKIdListForVerification(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3266 void EsimFile::EuiccInfo2ParseEuiccCiPKIdListForVerification(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3267 {
3268 std::shared_ptr<Asn1Node> ciPKIdListForVerificationNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_9);
3269 if (ciPKIdListForVerificationNode == nullptr) {
3270 TELEPHONY_LOGE("ciPKIdListForVerificationNode is nullptr");
3271 return;
3272 }
3273 ciPKIdListForVerificationNode->Asn1NodeToHexStr(euiccInfo2.euiccCiPKIdListForVerification_);
3274 }
3275
EuiccInfo2ParseEuiccCiPKIdListForSigning(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3276 void EsimFile::EuiccInfo2ParseEuiccCiPKIdListForSigning(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3277 {
3278 std::shared_ptr<Asn1Node> euiccCiPKIdListForSigningNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_A);
3279 if (euiccCiPKIdListForSigningNode == nullptr) {
3280 TELEPHONY_LOGE("euiccCiPKIdListForSigningNode is nullptr");
3281 return;
3282 }
3283 euiccCiPKIdListForSigningNode->Asn1NodeToHexStr(euiccInfo2.euiccCiPKIdListForSigning_);
3284 }
3285
EuiccInfo2ParseEuiccCategory(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3286 void EsimFile::EuiccInfo2ParseEuiccCategory(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3287 {
3288 std::shared_ptr<Asn1Node> euiccCategoryNode = root->Asn1GetChild(TAG_ESIM_CTX_B);
3289 if (euiccCategoryNode == nullptr) {
3290 TELEPHONY_LOGE("euiccCategoryNode is nullptr");
3291 return;
3292 }
3293 euiccInfo2.euiccCategory_ = euiccCategoryNode->Asn1AsInteger();
3294 }
3295
EuiccInfo2ParsePpVersion(EuiccInfo2 & euiccInfo2,std::shared_ptr<Asn1Node> & root)3296 void EsimFile::EuiccInfo2ParsePpVersion(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
3297 {
3298 std::shared_ptr<Asn1Node> ppVersionNode = root->Asn1GetChild(TAG_ESIM_OCTET_STRING_TYPE);
3299 if (ppVersionNode == nullptr) {
3300 TELEPHONY_LOGE("ppVersionNode is nullptr");
3301 return;
3302 }
3303 std::vector<uint8_t> ppVersionNodeRaw = {};
3304 uint32_t versionLen = ppVersionNode->Asn1AsBytes(ppVersionNodeRaw);
3305 if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
3306 TELEPHONY_LOGE("invalid ppVersion data");
3307 return;
3308 }
3309 euiccInfo2.ppVersion_ = MakeVersionString(ppVersionNodeRaw);
3310 }
3311
RealProcessAuthenticateServerDone()3312 bool EsimFile::RealProcessAuthenticateServerDone()
3313 {
3314 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
3315 std::shared_ptr<Asn1Node> responseNode = Asn1ParseResponse(responseByte, responseByte.size());
3316 if (responseNode == nullptr) {
3317 TELEPHONY_LOGE("Asn1ParseResponse failed");
3318 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3319 return false;
3320 }
3321 AuthServerResponse authServerResp = { 0 };
3322 if (responseNode->Asn1HasChild(TAG_ESIM_CTX_COMP_1)) {
3323 std::shared_ptr<Asn1Node> authServerRespNode = responseNode->Asn1GetChild(TAG_ESIM_CTX_COMP_1);
3324 if (authServerRespNode == nullptr) {
3325 TELEPHONY_LOGE("authServerRespNode is nullptr");
3326 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3327 return false;
3328 }
3329 if (authServerRespNode->Asn1HasChild(TAG_ESIM_CTX_0) &&
3330 authServerRespNode->Asn1HasChild(TAG_ESIM_INTEGER_TYPE)) {
3331 std::shared_ptr<Asn1Node> transactionIdNode = authServerRespNode->Asn1GetChild(TAG_ESIM_CTX_0);
3332 std::shared_ptr<Asn1Node> errCodeNode = authServerRespNode->Asn1GetChild(TAG_ESIM_INTEGER_TYPE);
3333 if (transactionIdNode == nullptr || errCodeNode == nullptr) {
3334 TELEPHONY_LOGE("authServerRespNode failed");
3335 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3336 return false;
3337 }
3338 uint32_t tidByteLen = transactionIdNode->Asn1AsString(authServerResp.transactionId);
3339 if (tidByteLen == 0) {
3340 TELEPHONY_LOGE("tidByteLen is zero.");
3341 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3342 return false;
3343 }
3344 authServerResp.errCode = errCodeNode->Asn1AsInteger();
3345 } else {
3346 TELEPHONY_LOGE("the auth server response has no right child");
3347 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3348 return false;
3349 }
3350 } else {
3351 authServerResp.respStr = responseByte;
3352 authServerResp.respLength = responseByte.size();
3353 }
3354 CovertAuthToApiStruct(responseAuthenticateResult_, authServerResp);
3355 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3356 return true;
3357 }
3358
ProcessAuthenticateServerDone(const AppExecFwk::InnerEvent::Pointer & event)3359 bool EsimFile::ProcessAuthenticateServerDone(const AppExecFwk::InnerEvent::Pointer &event)
3360 {
3361 if (event == nullptr) {
3362 TELEPHONY_LOGE("event is nullptr!");
3363 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3364 return false;
3365 }
3366 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
3367 if (rcvMsg == nullptr) {
3368 TELEPHONY_LOGE("rcvMsg is nullptr");
3369 NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
3370 return false;
3371 }
3372 newRecvData_ = rcvMsg->fileData;
3373 bool isHandleFinish = false;
3374 bool retValue = CommMergeRecvData(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_,
3375 MSG_ESIM_AUTHENTICATE_SERVER, isHandleFinish);
3376 if (isHandleFinish) {
3377 return retValue;
3378 }
3379 return RealProcessAuthenticateServerDone();
3380 }
3381
CovertAuthToApiStruct(ResponseEsimInnerResult & dst,AuthServerResponse & src)3382 void EsimFile::CovertAuthToApiStruct(ResponseEsimInnerResult &dst, AuthServerResponse &src)
3383 {
3384 dst.resultCode_ = src.errCode;
3385 std::string hexStr = Asn1Utils::BytesToHexStr(src.respStr);
3386 dst.response_ = OHOS::Telephony::ToUtf16(hexStr);
3387 }
3388
NotifyReady(std::mutex & mtx,bool & flag,std::condition_variable & cv)3389 void EsimFile::NotifyReady(std::mutex &mtx, bool &flag, std::condition_variable &cv)
3390 {
3391 std::lock_guard<std::mutex> lock(mtx);
3392 flag = true;
3393 cv.notify_all();
3394 }
3395
CommMergeRecvData(std::mutex & mtx,bool & flag,std::condition_variable & cv,int32_t eventId,bool & isHandleFinish)3396 bool EsimFile::CommMergeRecvData(
3397 std::mutex &mtx, bool &flag, std::condition_variable &cv, int32_t eventId, bool &isHandleFinish)
3398 {
3399 uint32_t mergeResult = MergeRecvLongDataComplete(newRecvData_, eventId);
3400 if (mergeResult == RESPONS_DATA_ERROR) {
3401 NotifyReady(mtx, flag, cv);
3402 isHandleFinish = true;
3403 return false;
3404 }
3405 if ((mergeResult == RESPONS_DATA_FINISH) && (newRecvData_.resultData.length() == 0)) {
3406 NotifyReady(mtx, flag, cv);
3407 isHandleFinish = true;
3408 return true;
3409 }
3410 if (mergeResult == RESPONS_DATA_NOT_FINISH) {
3411 isHandleFinish = true;
3412 return true;
3413 }
3414 isHandleFinish = false;
3415 return false;
3416 }
3417
InitChanneMemberFunc()3418 void EsimFile::InitChanneMemberFunc()
3419 {
3420 memberFuncMap_[MSG_ESIM_OPEN_CHANNEL_DONE] =
3421 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEsimOpenChannelDone(event); };
3422 memberFuncMap_[MSG_ESIM_CLOSE_CHANNEL_DONE] =
3423 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEsimCloseChannelDone(event); };
3424 memberFuncMap_[MSG_ESIM_SEND_APUD_DATA] =
3425 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessSendApduDataDone(event); };
3426 memberFuncMap_[MSG_ESIM_CLOSE_SPARE_CHANNEL_DONE] =
3427 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEsimCloseSpareChannelDone(event); };
3428 }
3429
InitMemberFunc()3430 void EsimFile::InitMemberFunc()
3431 {
3432 memberFuncMap_[MSG_ESIM_OBTAIN_EID_DONE] =
3433 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEidDone(event); };
3434 memberFuncMap_[MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE] =
3435 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEuiccInfo1Done(event); };
3436 memberFuncMap_[MSG_ESIM_REQUEST_ALL_PROFILES] =
3437 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRequestAllProfilesDone(event); };
3438 memberFuncMap_[MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE] =
3439 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEuiccChallengeDone(event); };
3440 memberFuncMap_[MSG_ESIM_REQUEST_RULES_AUTH_TABLE] =
3441 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRequestRulesAuthTableDone(event); };
3442 memberFuncMap_[MSG_ESIM_OBTAIN_SMDS_ADDRESS] =
3443 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainSmdsAddressDone(event); };
3444 memberFuncMap_[MSG_ESIM_DISABLE_PROFILE] =
3445 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessDisableProfileDone(event); };
3446 memberFuncMap_[MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE] =
3447 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainDefaultSmdpAddressDone(event); };
3448 memberFuncMap_[MSG_ESIM_CANCEL_SESSION] =
3449 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessCancelSessionDone(event); };
3450 memberFuncMap_[MSG_ESIM_GET_PROFILE] =
3451 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessGetProfileDone(event); };
3452 memberFuncMap_[MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE] =
3453 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEstablishDefaultSmdpAddressDone(event); };
3454 memberFuncMap_[MSG_ESIM_RESET_MEMORY] =
3455 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessResetMemoryDone(event); };
3456 memberFuncMap_[MSG_ESIM_LIST_NOTIFICATION] =
3457 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessListNotificationsDone(event); };
3458 memberFuncMap_[MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE] =
3459 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessLoadBoundProfilePackageDone(event); };
3460 memberFuncMap_[MSG_ESIM_PREPARE_DOWNLOAD_DONE] =
3461 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessPrepareDownloadDone(event); };
3462 memberFuncMap_[MSG_ESIM_REMOVE_NOTIFICATION] =
3463 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRemoveNotificationDone(event); };
3464 memberFuncMap_[MSG_ESIM_RETRIEVE_NOTIFICATION_DONE] =
3465 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRetrieveNotificationDone(event); };
3466 memberFuncMap_[MSG_ESIM_RETRIEVE_NOTIFICATION_LIST] =
3467 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRetrieveNotificationListDone(event); };
3468 memberFuncMap_[MSG_ESIM_DELETE_PROFILE] =
3469 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessDeleteProfileDone(event); };
3470 memberFuncMap_[MSG_ESIM_SWITCH_PROFILE] =
3471 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessSwitchToProfileDone(event); };
3472 memberFuncMap_[MSG_ESIM_SET_NICK_NAME] =
3473 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessSetNicknameDone(event); };
3474 memberFuncMap_[MSG_ESIM_OBTAIN_EUICC_INFO2_DONE] =
3475 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEuiccInfo2Done(event); };
3476 memberFuncMap_[MSG_ESIM_AUTHENTICATE_SERVER] =
3477 [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessAuthenticateServerDone(event); };
3478 }
3479
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)3480 void EsimFile::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
3481 {
3482 if (event == nullptr) {
3483 TELEPHONY_LOGE("event is nullptr");
3484 return;
3485 }
3486 auto id = event->GetInnerEventId();
3487 auto itFunc = memberFuncMap_.find(id);
3488 if (itFunc != memberFuncMap_.end()) {
3489 auto memberFunc = itFunc->second;
3490 if (memberFunc != nullptr) {
3491 bool isFileProcessResponse = memberFunc(event);
3492 return;
3493 }
3494 } else {
3495 IccFile::ProcessEvent(event);
3496 }
3497 }
3498
GetRawDataFromEvent(const AppExecFwk::InnerEvent::Pointer & event,IccFileData & outRawData)3499 bool EsimFile::GetRawDataFromEvent(const AppExecFwk::InnerEvent::Pointer &event, IccFileData &outRawData)
3500 {
3501 if (event == nullptr) {
3502 TELEPHONY_LOGE("event is nullptr!");
3503 return false;
3504 }
3505 std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
3506 if (rcvMsg == nullptr) {
3507 TELEPHONY_LOGE("rcvMsg is nullptr");
3508 return false;
3509 }
3510 outRawData = rcvMsg->fileData;
3511 return true;
3512 }
3513
ParseEvent(const AppExecFwk::InnerEvent::Pointer & event)3514 std::shared_ptr<Asn1Node> EsimFile::ParseEvent(const AppExecFwk::InnerEvent::Pointer &event)
3515 {
3516 IccFileData rawData;
3517 if (!GetRawDataFromEvent(event, rawData)) {
3518 TELEPHONY_LOGE("rawData is nullptr within rcvMsg");
3519 return nullptr;
3520 }
3521 TELEPHONY_LOGI("input raw data:sw1=%{public}02X, sw2=%{public}02X, length=%{public}zu",
3522 rawData.sw1, rawData.sw2, rawData.resultData.length());
3523 std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(rawData.resultData);
3524 uint32_t byteLen = responseByte.size();
3525 return Asn1ParseResponse(responseByte, byteLen);
3526 }
3527
ObtainSpnCondition(bool roaming,const std::string & operatorNum)3528 int32_t EsimFile::ObtainSpnCondition(bool roaming, const std::string &operatorNum)
3529 {
3530 return 0;
3531 }
3532
IsSameAid(const std::u16string & aid)3533 bool EsimFile::IsSameAid(const std::u16string &aid)
3534 {
3535 std::lock_guard<std::mutex> lock(occupyChannelMutex_);
3536 if (aidStr_ == aid) {
3537 return true;
3538 } else {
3539 return false;
3540 }
3541 }
3542
IsValidAidForAllowSameAidReuseChannel(const std::u16string & aid)3543 bool EsimFile::IsValidAidForAllowSameAidReuseChannel(const std::u16string &aid)
3544 {
3545 if (aidStr_ != aid && !aidStr_.empty()) {
3546 return false;
3547 } else {
3548 return true;
3549 }
3550 }
3551
ProcessIccReady(const AppExecFwk::InnerEvent::Pointer & event)3552 bool EsimFile::ProcessIccReady(const AppExecFwk::InnerEvent::Pointer &event)
3553 {
3554 return false;
3555 }
3556
UpdateVoiceMail(const std::string & mailName,const std::string & mailNumber)3557 bool EsimFile::UpdateVoiceMail(const std::string &mailName, const std::string &mailNumber)
3558 {
3559 return false;
3560 }
3561
SetVoiceMailCount(int32_t voiceMailCount)3562 bool EsimFile::SetVoiceMailCount(int32_t voiceMailCount)
3563 {
3564 return false;
3565 }
3566
SetVoiceCallForwarding(bool enable,const std::string & number)3567 bool EsimFile::SetVoiceCallForwarding(bool enable, const std::string &number)
3568 {
3569 return false;
3570 }
3571
GetVoiceMailNumber()3572 std::string EsimFile::GetVoiceMailNumber()
3573 {
3574 return "";
3575 }
3576
SetVoiceMailNumber(const std::string mailNumber)3577 void EsimFile::SetVoiceMailNumber(const std::string mailNumber)
3578 {
3579 return;
3580 }
3581
ProcessIccRefresh(int msgId)3582 void EsimFile::ProcessIccRefresh(int msgId)
3583 {
3584 return;
3585 }
3586
ProcessFileLoaded(bool response)3587 void EsimFile::ProcessFileLoaded(bool response)
3588 {
3589 return;
3590 }
3591
OnAllFilesFetched()3592 void EsimFile::OnAllFilesFetched()
3593 {
3594 return;
3595 }
3596 } // namespace Telephony
3597 } // namespace OHOS
3598