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