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