/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "esim_file.h"

#include <unistd.h>
#include <memory>
#include <shared_mutex>
#include "common_event_manager.h"
#include "common_event_support.h"
#include "core_manager_inner.h"
#include "core_service.h"
#include "parameters.h"
#include "radio_event.h"
#include "sim_number_decode.h"
#include "str_convert.h"
#include "telephony_common_utils.h"
#include "telephony_ext_wrapper.h"
#include "telephony_state_registry_client.h"
#include "telephony_tag_def.h"
#include "vcard_utils.h"
#include "tel_ril_manager.h"
using namespace OHOS::AppExecFwk;
using namespace OHOS::EventFwk;

namespace OHOS {
namespace Telephony {
static constexpr const char *KEY_IMEI = "kIMEI";
static constexpr const char *KEY_IMEI2 = "kIMEI2";
static constexpr const char *KEY_NONCE = "kNonce";
static constexpr const char *KEY_TIMESTAMP = "kTimestamp";
const std::string LAST_DEACTIVE_PROFILE_SLOT0 = "persist.telephony.last_deactive_profile_slot0";
const std::string LAST_DEACTIVE_PROFILE_SLOT1 = "persist.telephony.last_deactive_profile_slot1";
static constexpr int32_t COMMAND_PORT = 0;
const std::string SUPPORT_ESIM_MEP = "const.ril.sim.esim_support_mep";

EsimFile::EsimFile(std::shared_ptr<ITelRilManager> telRilManager, int32_t slotId,
    std::shared_ptr<AppExecFwk::EventRunner> eventRunner) : AppExecFwk::EventHandler(eventRunner)
{
    slotId_ = slotId;
    telRilManager_ = telRilManager;
    currentChannelId_ = 0;
    InitMemberFunc();
    InitChanneMemberFunc();
    TELEPHONY_LOGI("esimFile init end");
}

AppExecFwk::InnerEvent::Pointer EsimFile::BuildCallerInfo(int eventId)
{
    std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
    if (object == nullptr) {
        TELEPHONY_LOGE("object is nullptr!");
        return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
    }
    int eventParam = 0;
    AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
    }
    event->SetOwner(shared_from_this());
    return event;
}

ResultInnerCode EsimFile::ObtainChannelSuccessExclusive(const SimMessage msgType)
{
    std::u16string aid = OHOS::Telephony::ToUtf16(ISDR_AID);
    std::lock_guard<std::mutex> occupyLck(occupyChannelMutex_);
    // The channel is in use.
    if (IsLogicChannelOpen(msgType)) {
        TELEPHONY_LOGE("The channel is in use");
        return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_IN_USE;
    }

    ProcessEsimOpenChannel(aid, msgType);
    std::unique_lock<std::mutex> lck(openChannelMutex_);
    if (!openChannelCv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_OPEN_CHANNEL_FOR_ESIM),
        [this, msgType] { return IsLogicChannelOpen(msgType); })) {
        TELEPHONY_LOGE("wait cv failed!");
    }

    bool isOpenChannelSuccess = IsLogicChannelOpen(msgType);
    if (isOpenChannelSuccess) {
        aidStr_ = aid;
        return ResultInnerCode::RESULT_EUICC_CARD_OK;
    }

    TELEPHONY_LOGE("failed to open the channel");
    return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_OPEN_FAILED;
}

/**
 * @brief Channels that support the same aid are not disabled when sending data.
 */
ResultInnerCode EsimFile::ObtainChannelSuccessAllowSameAidReuse(const std::u16string &aid)
{
    std::lock_guard<std::mutex> lck(occupyChannelMutex_);
    if (!IsValidAidForAllowSameAidReuseChannel(aid)) {
        TELEPHONY_LOGE("Aid invalid");
        return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_OTHER_AID;
    }

    if (!IsLogicChannelOpen(MSG_ESIM_OPEN_CHANNEL_DONE)) {
        ProcessEsimOpenChannel(aid, MSG_ESIM_OPEN_CHANNEL_DONE);
        std::unique_lock<std::mutex> lck(openChannelMutex_);
        if (!openChannelCv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SHORT_SECOND_FOR_ESIM),
            [this]() { return IsLogicChannelOpen(MSG_ESIM_OPEN_CHANNEL_DONE); })) {
            TELEPHONY_LOGE("wait cv failed!");
        }
    }

    bool isOpenChannelSuccess = IsLogicChannelOpen(MSG_ESIM_OPEN_CHANNEL_DONE);
    if (isOpenChannelSuccess) {
        aidStr_ = aid;
        return ResultInnerCode::RESULT_EUICC_CARD_OK;
    }
    TELEPHONY_LOGE("failed to open the channel");
    return ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_OPEN_FAILED;
}

void EsimFile::SyncCloseChannel(const SimMessage msgType)
{
    uint32_t tryCnt = 0;
    std::lock_guard<std::mutex> lck(occupyChannelMutex_);
    while (IsLogicChannelOpen(msgType)) {
        ProcessEsimCloseChannel(msgType);
        std::unique_lock<std::mutex> lck(closeChannelMutex_);
        if (closeChannelCv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_CLOSE_CHANNEL_FOR_ESIM),
            [this, msgType]() { return !IsLogicChannelOpen(msgType); })) {
            break;
        }
        tryCnt++;
        if (tryCnt >= NUMBER_TWO) {
            TELEPHONY_LOGE("failed to close the channel");
            break;
        }
        TELEPHONY_LOGW("wait cv failed, retry close channel at %{public}u", tryCnt);
    }
    currentChannelId_ = 0;
    aidStr_ = u"";
}

std::string EsimFile::ObtainEid()
{
    if (!eid_.empty()) {
        return eid_;
    }
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_OBTAIN_EID_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return "";
    }
    AppExecFwk::InnerEvent::Pointer eventGetEid = BuildCallerInfo(MSG_ESIM_OBTAIN_EID_DONE);
    if (!ProcessObtainEid(slotId_, eventGetEid)) {
        TELEPHONY_LOGE("ProcessObtainEid encode failed");
        SyncCloseChannel(MSG_ESIM_OBTAIN_EID_DONE);
        return "";
    }
    std::unique_lock<std::mutex> lock(getEidMutex_);
    // wait profileInfo is ready
    isEidReady_ = false;
    if (!getEidCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isEidReady_; })) {
        SyncCloseChannel(MSG_ESIM_OBTAIN_EID_DONE);
        return "";
    }
    SyncCloseChannel(MSG_ESIM_OBTAIN_EID_DONE);
    return eid_;
}

GetEuiccProfileInfoListInnerResult EsimFile::GetEuiccProfileInfoList()
{
    std::unique_lock<std::mutex> lck(currentChannelIdOccupiedMutex_);
    euiccProfileInfoList_ = GetEuiccProfileInfoListInnerResult();
    euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_REQUEST_ALL_PROFILES);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        euiccProfileInfoList_.result_ = static_cast<int32_t>(resultFlag);
        return euiccProfileInfoList_;
    }
    recvCombineStr_ = "";
    AppExecFwk::InnerEvent::Pointer eventRequestAllProfiles = BuildCallerInfo(MSG_ESIM_REQUEST_ALL_PROFILES);
    if (!ProcessRequestAllProfiles(slotId_, eventRequestAllProfiles)) {
        TELEPHONY_LOGE("ProcessRequestAllProfiles encode failed");
        SyncCloseChannel(MSG_ESIM_REQUEST_ALL_PROFILES);
        euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return euiccProfileInfoList_;
    }
    std::unique_lock<std::mutex> lock(allProfileInfoMutex_);
    isAllProfileInfoReady_ = false;
    if (!allProfileInfoCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isAllProfileInfoReady_; })) {
        SyncCloseChannel(MSG_ESIM_REQUEST_ALL_PROFILES);
        euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
        return euiccProfileInfoList_;
    }
    SyncCloseChannel(MSG_ESIM_REQUEST_ALL_PROFILES);
    return euiccProfileInfoList_;
}

EuiccInfo EsimFile::GetEuiccInfo()
{
    eUiccInfo_ = EuiccInfo();
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return EuiccInfo();
    }
    AppExecFwk::InnerEvent::Pointer eventEUICCInfo1 = BuildCallerInfo(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE);
    if (!ProcessObtainEuiccInfo1(slotId_, eventEUICCInfo1)) {
        TELEPHONY_LOGE("ProcessObtainEuiccInfo1 encode failed");
        SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE);
        return EuiccInfo();
    }
    std::unique_lock<std::mutex> lock(euiccInfo1Mutex_);
    isEuiccInfo1Ready_ = false;
    if (!euiccInfo1Cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isEuiccInfo1Ready_; })) {
        TELEPHONY_LOGE("close channal due to timeout");
        SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE);
        return eUiccInfo_;
    }
    SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE);
    return eUiccInfo_;
}

void EsimFile::CopyApdCmdToReqInfo(ApduSimIORequestInfo &requestInfo, ApduCommand *apduCommand)
{
    if (apduCommand == nullptr) {
        TELEPHONY_LOGE("CopyApdCmdToReqInfo failed");
        return;
    }
    requestInfo.serial = nextSerialId_;
    nextSerialId_++;
    if (nextSerialId_ >= INT32_MAX) {
        nextSerialId_ = 0;
    }
    requestInfo.channelId = static_cast<int32_t>(apduCommand->channel);
    requestInfo.type = static_cast<int32_t>(apduCommand->data.cla);
    requestInfo.instruction = static_cast<int32_t>(apduCommand->data.ins);
    requestInfo.p1 = static_cast<int32_t>(apduCommand->data.p1);
    requestInfo.p2 = static_cast<int32_t>(apduCommand->data.p2);
    requestInfo.p3 = static_cast<int32_t>(apduCommand->data.p3);
    requestInfo.data = apduCommand->data.cmdHex;
    TELEPHONY_LOGI("SEND_DATA reqInfo.serial=%{public}d, \
        reqInfo.channelId=%{public}d, reqInfo.type=%{public}d, reqInfo.instruction=%{public}d, \
        reqInfo.p1=%{public}02X, reqInfo.p2=%{public}02X, reqInfo.p3=%{public}02X, reqInfo.data.length=%{public}zu",
        requestInfo.serial, requestInfo.channelId, requestInfo.type, requestInfo.instruction, requestInfo.p1,
        requestInfo.p2, requestInfo.p3, requestInfo.data.length());
}

void EsimFile::CommBuildOneApduReqInfo(ApduSimIORequestInfo &requestInfo, std::shared_ptr<Asn1Builder> &builder)
{
    if (builder == nullptr) {
        TELEPHONY_LOGE("builder is nullptr");
        return;
    }
    std::string hexStr;
    uint32_t hexStrLen = builder->Asn1BuilderToHexStr(hexStr);
    if (hexStrLen == 0) {
        TELEPHONY_LOGE("hexStrLen is zero");
        return;
    }
    RequestApduBuild codec(currentChannelId_);
    codec.BuildStoreData(hexStr);
    std::list<std::unique_ptr<ApduCommand>> list = codec.GetCommands();
    if (list.empty()) {
        TELEPHONY_LOGE("node is empty");
        return;
    }
    std::unique_ptr<ApduCommand> apduCommand = std::move(list.front());
    CopyApdCmdToReqInfo(requestInfo, apduCommand.get());
}

bool EsimFile::ProcessObtainEid(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_OBTAIN_EID_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EID);
    std::vector<uint8_t> eidTags;
    eidTags.push_back(static_cast<unsigned char>(TAG_ESIM_EID));
    builder->Asn1AddChildAsBytes(TAG_ESIM_TAG_LIST, eidTags, eidTags.size());
    ApduSimIORequestInfo requestInfo;
    CommBuildOneApduReqInfo(requestInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    telRilManager_->SimTransmitApduLogicalChannel(slotId, requestInfo, responseEvent);
    return true;
}

bool EsimFile::ProcessObtainEuiccInfo1(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EUICC_INFO_1);
    ApduSimIORequestInfo requestInfo;
    CommBuildOneApduReqInfo(requestInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    telRilManager_->SimTransmitApduLogicalChannel(slotId, requestInfo, responseEvent);
    return true;
}

bool EsimFile::ProcessRequestAllProfiles(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_REQUEST_ALL_PROFILES)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_PROFILES);

    unsigned char EUICC_PROFILE_TAGS[] = {
        static_cast<unsigned char>(TAG_ESIM_ICCID),
        static_cast<unsigned char>(TAG_ESIM_NICKNAME),
        static_cast<unsigned char>(TAG_ESIM_OBTAIN_OPERATOR_NAME),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_NAME),
        static_cast<unsigned char>(TAG_ESIM_OPERATOR_ID),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE / PROFILE_DEFAULT_NUMBER),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE % PROFILE_DEFAULT_NUMBER),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_CLASS),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_POLICY_RULE),
        static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES / PROFILE_DEFAULT_NUMBER),
        static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES % PROFILE_DEFAULT_NUMBER),
    };
    std::vector<uint8_t> euiccProfileTags;
    for (const unsigned char tag : EUICC_PROFILE_TAGS) {
        euiccProfileTags.push_back(tag);
    }
    bool isSupportEsimMep = OHOS::system::GetBoolParameter(SUPPORT_ESIM_MEP, false);
    if (isSupportEsimMep) {
        euiccProfileTags.push_back(static_cast<unsigned char>(TAG_ESIM_PORT / PROFILE_DEFAULT_NUMBER));
        euiccProfileTags.push_back(static_cast<unsigned char>(TAG_ESIM_PORT % PROFILE_DEFAULT_NUMBER));
    }
    builder->Asn1AddChildAsBytes(TAG_ESIM_TAG_LIST, euiccProfileTags, euiccProfileTags.size());
    ApduSimIORequestInfo requestInfo;
    CommBuildOneApduReqInfo(requestInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    telRilManager_->SimTransmitApduLogicalChannel(slotId, requestInfo, responseEvent);
    return true;
}

bool EsimFile::IsLogicChannelOpen(const SimMessage msgType)
{
    if (currentChannelId_ > 0) {
        TELEPHONY_LOGI("opened channel id:%{public}d, msgType is %{public}d", currentChannelId_.load(), msgType);
        return true;
    }
    return false;
}

void EsimFile::ProcessEsimOpenChannel(const std::u16string &aid, const SimMessage msgType)
{
    std::string appId = OHOS::Telephony::ToUtf8(aid);
    bool isSupportEsimMEP = OHOS::system::GetBoolParameter(SUPPORT_ESIM_MEP, false);
    AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_ESIM_OPEN_CHANNEL_DONE);
    if (telRilManager_ == nullptr) {
        return;
    }
    TELEPHONY_LOGI("req to open channel:%{public}d, msgType is %{public}d", currentChannelId_.load(), msgType);
    if (!isSupportEsimMEP) {
        telRilManager_->SimOpenLogicalChannel(slotId_, appId, PARAMETER_TWO, response);
    } else {
        telRilManager_->SimOpenLogicalChannelWithPort(slotId_, appId, PARAMETER_TWO, COMMAND_PORT, response);
    }
    return;
}

bool EsimFile::ProcessEsimOpenChannelDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("open logical channel event is nullptr!");
        return false;
    }
    auto resultPtr = event->GetSharedObject<OpenLogicalChannelResponse>();
    if (resultPtr == nullptr) {
        TELEPHONY_LOGE("open logical channel fd is nullptr!");
        return false;
    }
    if (resultPtr->channelId <= 0) {
        TELEPHONY_LOGE("channelId is invalid!");
        openChannelCv_.notify_all();
        return false;
    }

    {
        std::lock_guard<std::mutex> lock(openChannelMutex_);
        TELEPHONY_LOGI("Logical channel %{public}d->%{public}d open successfully. Notifying waiting thread.",
            currentChannelId_.load(), resultPtr->channelId);
        currentChannelId_ = resultPtr->channelId;
    }

    if (occupyChannelMutex_.try_lock()) {
        // caller exits waiting, thus lock is obtained and the channel needs released
        ProcessEsimCloseSpareChannel();
        occupyChannelMutex_.unlock();
        openChannelCv_.notify_all();
        return false;
    }

    openChannelCv_.notify_all();
    return true;
}

void EsimFile::ProcessEsimCloseChannel(const SimMessage msgType)
{
    AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_ESIM_CLOSE_CHANNEL_DONE);
    if (telRilManager_ == nullptr) {
        return;
    }
    TELEPHONY_LOGI("req to close channel:%{public}d, msgType is %{public}d", currentChannelId_.load(), msgType);
    telRilManager_->SimCloseLogicalChannel(slotId_, currentChannelId_, response);
    return;
}

bool EsimFile::ProcessEsimCloseChannelDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::lock_guard<std::mutex> lock(closeChannelMutex_);
    currentChannelId_ = 0;
    aidStr_ = u"";
    TELEPHONY_LOGI("Logical channel closed successfully. Notifying waiting thread.");
    closeChannelCv_.notify_all();
    return true;
}

void EsimFile::ProcessEsimCloseSpareChannel()
{
    AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_ESIM_CLOSE_SPARE_CHANNEL_DONE);
    if (telRilManager_ == nullptr) {
        return;
    }

    TELEPHONY_LOGI("set req to close spare channel:%{public}d", currentChannelId_.load());
    telRilManager_->SimCloseLogicalChannel(slotId_, currentChannelId_, response);
}

bool EsimFile::ProcessEsimCloseSpareChannelDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::lock_guard<std::mutex> lock(closeChannelMutex_);
    TELEPHONY_LOGI("Spare channel %{public}d closed successfully.", currentChannelId_.load());
    aidStr_ = u"";
    currentChannelId_ = 0;
    return true;
}

std::string EsimFile::MakeVersionString(std::vector<uint8_t> &versionRaw)
{
    if (versionRaw.size() < NUMBER_THREE) {
        TELEPHONY_LOGE("versionRaw.size(%{public}zu) error!", versionRaw.size());
        return "";
    }
    std::ostringstream oss;
    oss << std::hex << std::uppercase << (versionRaw[VERSION_HIGH] & MAX_UINT8) << "." <<
        (versionRaw[VERSION_MIDDLE] & MAX_UINT8) << "." <<
        (versionRaw[VERSION_LOW] & MAX_UINT8);
    return oss.str();
}

bool EsimFile::ProcessObtainEidDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_EID);
    if (profileRoot == nullptr) {
        TELEPHONY_LOGE("profileRoot is nullptr!");
        NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
        return false;
    }
    std::vector<uint8_t> outPutBytes;
    uint32_t byteLen = profileRoot->Asn1AsBytes(outPutBytes);
    if (byteLen == 0) {
        TELEPHONY_LOGE("byteLen is zero!");
        NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
        return false;
    }
    std::string strResult = Asn1Utils::BytesToHexStr(outPutBytes);

    eid_ = strResult;
    NotifyReady(getEidMutex_, isEidReady_, getEidCv_);
    return true;
}

std::shared_ptr<Asn1Node> EsimFile::Asn1ParseResponse(const std::vector<uint8_t> &response, uint32_t respLength)
{
    if (response.empty() || respLength == 0) {
        TELEPHONY_LOGE("response null, respLen = %{public}d", respLength);
        return nullptr;
    }
    Asn1Decoder decoder(response, 0, respLength);
    if (!decoder.Asn1HasNextNode()) {
        TELEPHONY_LOGE("Empty response");
        return nullptr;
    }
    std::shared_ptr<Asn1Node> node = decoder.Asn1NextNode();
    return node;
}

bool EsimFile::ProcessObtainEuiccInfo1Done(const AppExecFwk::InnerEvent::Pointer &event)
{
    IccFileData rawData;
    if (!GetRawDataFromEvent(event, rawData)) {
        TELEPHONY_LOGE("rawData is nullptr within rcvMsg");
        NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
        return false;
    }
    TELEPHONY_LOGI("input raw data:sw1=%{public}02X, sw2=%{public}02X, length=%{public}zu",
        rawData.sw1, rawData.sw2, rawData.resultData.length());
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(rawData.resultData);
    uint32_t byteLen = responseByte.size();
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse error!");
        NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
        return false;
    }
    if (!ObtainEuiccInfo1ParseTagCtx2(root)) {
        TELEPHONY_LOGE("ObtainEuiccInfo1ParseTagCtx2 error!");
        NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
        return false;
    }
    std::string responseHexStr = rawData.resultData;
    eUiccInfo_.response_ = Str8ToStr16(responseHexStr);
    NotifyReady(euiccInfo1Mutex_, isEuiccInfo1Ready_, euiccInfo1Cv_);
    return true;
}

bool EsimFile::ObtainEuiccInfo1ParseTagCtx2(std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> svnNode = root->Asn1GetChild(TAG_ESIM_CTX_2);
    if (svnNode == nullptr) {
        TELEPHONY_LOGE("svnNode is nullptr");
        return false;
    }
    std::vector<uint8_t> svnRaw;
    uint32_t svnRawlen = svnNode->Asn1AsBytes(svnRaw);
    if (svnRawlen < SVN_RAW_LENGTH_MIN) {
        TELEPHONY_LOGE("invalid SVN data");
        return false;
    }
    eUiccInfo_.osVersion_ = OHOS::Telephony::ToUtf16(MakeVersionString(svnRaw));
    return true;
}

bool EsimFile::ProcessRequestAllProfilesDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
        return false;
    }

    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
        return false;
    }

    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_,
        MSG_ESIM_REQUEST_ALL_PROFILES, isHandleFinish);
    if (isHandleFinish) {
        TELEPHONY_LOGI("waits for continuing data...");
        return retValue;
    }

    return RealProcessRequestAllProfilesDone();
}

bool EsimFile::RealProcessRequestAllProfilesDone()
{
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    uint32_t byteLen = responseByte.size();
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
        return false;
    }

    std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
    if (profileRoot == nullptr) {
        TELEPHONY_LOGE("profileRoot is nullptr");
        NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
        return false;
    }

    std::list<std::shared_ptr<Asn1Node>> profileNodes;
    profileRoot->Asn1GetChildren(TAG_ESIM_PROFILE_INFO, profileNodes);
    std::shared_ptr<Asn1Node> curNode = nullptr;
    euiccProfileInfoList_.profiles_.clear();
    for (auto it = profileNodes.begin(); it != profileNodes.end(); ++it) {
        EuiccProfileInfo euiccProfileInfo = {{0}};
        curNode = *it;
        if (!curNode->Asn1HasChild(TAG_ESIM_ICCID)) {
            TELEPHONY_LOGE("Profile must have an ICCID.");
            continue;
        }
        BuildBasicProfileInfo(&euiccProfileInfo, curNode);
        EuiccProfile euiccProfile;
        ConvertProfileInfoToApiStruct(euiccProfile, euiccProfileInfo);
        euiccProfileInfoList_.profiles_.push_back(euiccProfile);
    }

    euiccProfileInfoList_.result_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
    NotifyReady(allProfileInfoMutex_, isAllProfileInfoReady_, allProfileInfoCv_);
    TELEPHONY_LOGI("asn decode success");
    return true;
}

bool EsimFile::SplitMccAndMnc(const std::string mccMnc, std::string &mcc, std::string &mnc)
{
    std::string mMcc(NUMBER_THREE, '\0');
    mMcc[NUMBER_ZERO] = mccMnc[NUMBER_ONE];
    mMcc[NUMBER_ONE] = mccMnc[NUMBER_ZERO];
    mMcc[NUMBER_TWO] = mccMnc[NUMBER_THREE];

    std::string mMnc(NUMBER_THREE, '\0');
    if (mccMnc[NUMBER_TWO] == 'F') {
        mMnc[NUMBER_ZERO] = mccMnc[NUMBER_FIVE];
        mMnc[NUMBER_ONE] = mccMnc[NUMBER_FOUR];
    } else {
        mMnc[NUMBER_ZERO] = mccMnc[NUMBER_FIVE];
        mMnc[NUMBER_ONE] = mccMnc[NUMBER_FOUR];
        mMnc[NUMBER_TWO] = mccMnc[NUMBER_TWO];
    }
    mcc = mMcc.c_str();
    mnc = mMnc.c_str();
    return true;
}

void EsimFile::ConvertProfileInfoToApiStruct(EuiccProfile &dst, EuiccProfileInfo &src)
{
    dst.iccId_ = OHOS::Telephony::ToUtf16(src.iccid);
    dst.nickName_ = OHOS::Telephony::ToUtf16(src.nickname);
    dst.serviceProviderName_ = OHOS::Telephony::ToUtf16(src.serviceProviderName);
    dst.profileName_ = OHOS::Telephony::ToUtf16(src.profileName);
    dst.state_ = static_cast<ProfileState>(src.profileState);
    dst.profileClass_ = static_cast<ProfileClass>(src.profileClass);
    dst.policyRules_ = static_cast<PolicyRules>(src.policyRules);
    dst.portIndex = src.portIndex;

    // split mccMnc to mcc and mnc
    std::string mcc = "";
    std::string mnc = "";
    SplitMccAndMnc(src.operatorId.mccMnc, mcc, mnc);
    dst.carrierId_.mcc_ = OHOS::Telephony::ToUtf16(mcc);
    dst.carrierId_.mnc_ = OHOS::Telephony::ToUtf16(mnc);
    dst.carrierId_.gid1_ = OHOS::Telephony::ToUtf16(src.operatorId.gid1);
    dst.carrierId_.gid2_ = OHOS::Telephony::ToUtf16(src.operatorId.gid2);
    dst.accessRules_.clear();
}

void EsimFile::BuildBasicProfileInfo(EuiccProfileInfo *eProfileInfo, std::shared_ptr<Asn1Node> &profileNode)
{
    if (eProfileInfo == nullptr || profileNode == nullptr) {
        TELEPHONY_LOGE("BuildBasicProfileInfo failed");
        return;
    }
    std::shared_ptr<Asn1Node> iccIdNode = profileNode->Asn1GetChild(TAG_ESIM_ICCID);
    if (iccIdNode == nullptr) {
        TELEPHONY_LOGE("iccIdNode is nullptr");
        return;
    }
    std::vector<uint8_t> iccidBytes;
    iccIdNode->Asn1AsBytes(iccidBytes);
    Asn1Utils::BchToString(iccidBytes, eProfileInfo->iccid);
    if (profileNode->Asn1HasChild(TAG_ESIM_NICKNAME)) {
        std::shared_ptr<Asn1Node> nickNameNode = profileNode->Asn1GetChild(TAG_ESIM_NICKNAME);
        if (nickNameNode == nullptr) {
            TELEPHONY_LOGE("nickNameNode is nullptr");
            return;
        }
        std::vector<uint8_t> nickNameBytes;
        nickNameNode->Asn1AsBytes(nickNameBytes);
        eProfileInfo->nickname = Asn1Utils::BytesToString(nickNameBytes);
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_OBTAIN_OPERATOR_NAME)) {
        std::shared_ptr<Asn1Node> serviceProviderNameNode = profileNode->Asn1GetChild(TAG_ESIM_OBTAIN_OPERATOR_NAME);
        if (serviceProviderNameNode == nullptr) {
            TELEPHONY_LOGE("serviceProviderNameNode is nullptr");
            return;
        }
        std::vector<uint8_t> serviceProviderNameBytes;
        serviceProviderNameNode->Asn1AsBytes(serviceProviderNameBytes);
        eProfileInfo->serviceProviderName = Asn1Utils::BytesToString(serviceProviderNameBytes);
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_NAME)) {
        std::shared_ptr<Asn1Node> profileNameNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_NAME);
        if (profileNameNode == nullptr) {
            TELEPHONY_LOGE("profileNameNode is nullptr");
            return;
        }
        std::vector<uint8_t> profileNameBytes;
        profileNameNode->Asn1AsBytes(profileNameBytes);
        eProfileInfo->profileName = Asn1Utils::BytesToString(profileNameBytes);
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_OPERATOR_ID)) {
        std::shared_ptr<Asn1Node> pOperatorId = profileNode->Asn1GetChild(TAG_ESIM_OPERATOR_ID);
        BuildOperatorId(eProfileInfo, pOperatorId);
    }

    BuildAdvancedProfileInfo(eProfileInfo, profileNode);
}

int32_t EsimFile::GetEsimPortIndex()
{
    TELEPHONY_LOGI("GetEsimPortIndex: %{public}d", esimProfile_.portIndex);
    return esimProfile_.portIndex;
}

void EsimFile::BuildAdvancedProfileInfo(EuiccProfileInfo *eProfileInfo, std::shared_ptr<Asn1Node> &profileNode)
{
    if (eProfileInfo == nullptr || profileNode == nullptr) {
        return;
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_STATE)) {
        std::shared_ptr<Asn1Node> profileStateNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_STATE);
        if (profileStateNode == nullptr) {
            return;
        }
        int32_t ret = profileStateNode->Asn1AsInteger();
        eProfileInfo->profileState = ((ret < 0) ? ESIM_PROFILE_STATE_DISABLED : ret);
    } else {
        eProfileInfo->profileState = ESIM_PROFILE_STATE_DISABLED;
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_CLASS)) {
        std::shared_ptr<Asn1Node> profileClassNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_CLASS);
        if (profileClassNode == nullptr) {
            return;
        }
        eProfileInfo->profileClass = profileClassNode->Asn1AsInteger();
    } else {
        eProfileInfo->profileClass = PROFILE_CLASS_OPERATIONAL;
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_PROFILE_POLICY_RULE)) {
        std::shared_ptr<Asn1Node> profilePolicyRuleNode = profileNode->Asn1GetChild(TAG_ESIM_PROFILE_POLICY_RULE);
        if (profilePolicyRuleNode == nullptr) {
            return;
        }
        eProfileInfo->policyRules = profilePolicyRuleNode->Asn1AsBits();
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_CARRIER_PRIVILEGE_RULES)) {
        std::list<std::shared_ptr<Asn1Node>> refArDoNodes;
        std::shared_ptr<Asn1Node> carrierPrivilegeRulesNode =
            profileNode->Asn1GetChild(TAG_ESIM_CARRIER_PRIVILEGE_RULES);
        if (carrierPrivilegeRulesNode == nullptr) {
            return;
        }
        carrierPrivilegeRulesNode->Asn1GetChildren(TAG_ESIM_REF_AR_DO, refArDoNodes);
    }
    if (profileNode->Asn1HasChild(TAG_ESIM_PORT)) {
        std::shared_ptr<Asn1Node> eSIMPort = profileNode->Asn1GetChild(TAG_ESIM_PORT);
        if (eSIMPort == nullptr) {
            return;
        }
        int32_t ret = eSIMPort->Asn1AsInteger();
        eProfileInfo->portIndex = ret;
    }
}

void EsimFile::BuildOperatorId(EuiccProfileInfo *eProfileInfo, std::shared_ptr<Asn1Node> &operatorIdNode)
{
    if (eProfileInfo == nullptr || operatorIdNode == nullptr) {
        TELEPHONY_LOGE("BuildOperatorId failed");
        return;
    }
    if (operatorIdNode->Asn1HasChild(TAG_ESIM_CTX_0)) {
        std::shared_ptr<Asn1Node> nodeCtx0 = operatorIdNode->Asn1GetChild(TAG_ESIM_CTX_0);
        if (nodeCtx0 == nullptr) {
            TELEPHONY_LOGE("nodeCtx0 is nullptr");
            return;
        }
        nodeCtx0->Asn1AsString(eProfileInfo->operatorId.mccMnc);
    }
    if (operatorIdNode->Asn1HasChild(TAG_ESIM_CTX_1)) {
        std::shared_ptr<Asn1Node> nodeCtx1 = operatorIdNode->Asn1GetChild(TAG_ESIM_CTX_1);
        if (nodeCtx1 == nullptr) {
            TELEPHONY_LOGE("nodeCtx1 is nullptr");
            return;
        }
        nodeCtx1->Asn1AsString(eProfileInfo->operatorId.gid1);
    }
    if (operatorIdNode->Asn1HasChild(TAG_ESIM_CTX_2)) {
        std::shared_ptr<Asn1Node> nodeCtx2 = operatorIdNode->Asn1GetChild(TAG_ESIM_CTX_2);
        if (nodeCtx2 == nullptr) {
            TELEPHONY_LOGE("nodeCtx2 is nullptr");
            return;
        }
        nodeCtx2->Asn1AsString(eProfileInfo->operatorId.gid2);
    }
    return;
}

int32_t EsimFile::DisableProfile(int32_t portIndex, const std::u16string &iccId)
{
    if (slotId_ == SLOT_ID_0) {
        OHOS::system::SetParameter(
            LAST_DEACTIVE_PROFILE_SLOT0, std::to_string(CoreManagerInner::GetInstance().GetSimId(slotId_)));
    }
    if (slotId_ == SLOT_ID_1) {
        OHOS::system::SetParameter(
            LAST_DEACTIVE_PROFILE_SLOT1, std::to_string(CoreManagerInner::GetInstance().GetSimId(slotId_)));
    }
    disableProfileResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.portIndex = portIndex;
    esimProfile_.iccId = iccId;
    
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_DISABLE_PROFILE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        disableProfileResult_ = static_cast<int32_t>(resultFlag);
        return disableProfileResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventDisableProfile = BuildCallerInfo(MSG_ESIM_DISABLE_PROFILE);
    if (!ProcessDisableProfile(slotId_, eventDisableProfile)) {
        TELEPHONY_LOGE("ProcessDisableProfile encode failed");
        SyncCloseChannel(MSG_ESIM_DISABLE_PROFILE);
        return disableProfileResult_;
    }
    std::unique_lock<std::mutex> lock(disableProfileMutex_);
    isDisableProfileReady_ = false;
    if (!disableProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isDisableProfileReady_; })) {
        SyncCloseChannel(MSG_ESIM_DISABLE_PROFILE);
        return disableProfileResult_;
    }
    SyncCloseChannel(MSG_ESIM_DISABLE_PROFILE);
    return disableProfileResult_;
}

std::string EsimFile::ObtainSmdsAddress(int32_t portIndex)
{
    esimProfile_.portIndex = portIndex;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_OBTAIN_SMDS_ADDRESS);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return "";
    }
    AppExecFwk::InnerEvent::Pointer eventObtainSmdsAddress = BuildCallerInfo(MSG_ESIM_OBTAIN_SMDS_ADDRESS);
    if (!ProcessObtainSmdsAddress(slotId_, eventObtainSmdsAddress)) {
        TELEPHONY_LOGE("ProcessObtainSmdsAddress encode failed");
        SyncCloseChannel(MSG_ESIM_OBTAIN_SMDS_ADDRESS);
        return "";
    }
    std::unique_lock<std::mutex> lock(smdsAddressMutex_);
    isSmdsAddressReady_ = false;
    if (!smdsAddressCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isSmdsAddressReady_; })) {
        SyncCloseChannel(MSG_ESIM_OBTAIN_SMDS_ADDRESS);
        return "";
    }
    SyncCloseChannel(MSG_ESIM_OBTAIN_SMDS_ADDRESS);
    return smdsAddress_;
}

EuiccRulesAuthTable EsimFile::ObtainRulesAuthTable(int32_t portIndex)
{
    esimProfile_.portIndex = portIndex;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_REQUEST_RULES_AUTH_TABLE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return EuiccRulesAuthTable();
    }
    AppExecFwk::InnerEvent::Pointer eventRequestRulesAuthTable = BuildCallerInfo(MSG_ESIM_REQUEST_RULES_AUTH_TABLE);
    if (!ProcessRequestRulesAuthTable(slotId_, eventRequestRulesAuthTable)) {
        TELEPHONY_LOGE("ProcessRequestRulesAuthTable encode failed");
        SyncCloseChannel(MSG_ESIM_REQUEST_RULES_AUTH_TABLE);
        return EuiccRulesAuthTable();
    }
    std::unique_lock<std::mutex> lock(rulesAuthTableMutex_);
    isRulesAuthTableReady_ = false;
    if (!rulesAuthTableCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isRulesAuthTableReady_; })) {
        SyncCloseChannel(MSG_ESIM_REQUEST_RULES_AUTH_TABLE);
        return EuiccRulesAuthTable();
    }
    SyncCloseChannel(MSG_ESIM_REQUEST_RULES_AUTH_TABLE);
    return eUiccRulesAuthTable_;
}

ResponseEsimInnerResult EsimFile::ObtainEuiccChallenge(int32_t portIndex)
{
    responseChallengeResult_ = ResponseEsimInnerResult();
    esimProfile_.portIndex = portIndex;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        responseChallengeResult_.resultCode_ = static_cast<int32_t>(resultFlag);
        return responseChallengeResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventEUICCChanllenge = BuildCallerInfo(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE);
    if (!ProcessObtainEuiccChallenge(slotId_, eventEUICCChanllenge)) {
        TELEPHONY_LOGE("ProcessObtainEuiccChallenge encode failed");
        SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE);
        responseChallengeResult_.resultCode_ =
            static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return responseChallengeResult_;
    }
    std::unique_lock<std::mutex> lock(euiccChallengeMutex_);
    isEuiccChallengeReady_ = false;
    if (!euiccChallengeCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isEuiccChallengeReady_; })) {
        SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE);
        responseChallengeResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
        return responseChallengeResult_;
    }
    SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE);
    return responseChallengeResult_;
}

bool EsimFile::ProcessDisableProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_DISABLE_PROFILE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_DISABLE_PROFILE);
    std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
    std::vector<uint8_t> iccidBytes;
    std::string str = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
    Asn1Utils::BcdToBytes(str, iccidBytes);
    subBuilder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
    std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
    if (subNode == nullptr) {
        return false;
    }
    builder->Asn1AddChild(subNode);
    bool refreshFlag = true;
    bool isSupportEsimMep = OHOS::system::GetBoolParameter(SUPPORT_ESIM_MEP, false);
    if (isSupportEsimMep) {
        refreshFlag = OHOS::system::GetBoolParameter("const.ril.sim.esim_mep_refresh_flag", false);
    }
    builder->Asn1AddChildAsBoolean(TAG_ESIM_CTX_1, refreshFlag);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessObtainSmdsAddress(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_OBTAIN_SMDS_ADDRESS)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_CONFIGURED_ADDRESSES);

    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessRequestRulesAuthTable(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_REQUEST_RULES_AUTH_TABLE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_RAT);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessObtainEuiccChallenge(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EUICC_CHALLENGE);

    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessDisableProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(disableProfileMutex_, isDisableProfileReady_, disableProfileCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> pAsn1Node = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (pAsn1Node == nullptr) {
        TELEPHONY_LOGE("pAsn1Node is nullptr");
        NotifyReady(disableProfileMutex_, isDisableProfileReady_, disableProfileCv_);
        return false;
    }
    disableProfileResult_ = pAsn1Node->Asn1AsInteger();
    NotifyReady(disableProfileMutex_, isDisableProfileReady_, disableProfileCv_);
    return true;
}

bool EsimFile::ProcessObtainSmdsAddressDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(smdsAddressMutex_, isSmdsAddressReady_, smdsAddressCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_1);
    if (profileRoot == nullptr) {
        TELEPHONY_LOGE("profileRoot is nullptr!");
        NotifyReady(smdsAddressMutex_, isSmdsAddressReady_, smdsAddressCv_);
        return false;
    }
    std::vector<uint8_t> outPutBytes;
    profileRoot->Asn1AsBytes(outPutBytes);
    smdsAddress_ = Asn1Utils::BytesToString(outPutBytes);
    NotifyReady(smdsAddressMutex_, isSmdsAddressReady_, smdsAddressCv_);
    return true;
}

struct CarrierIdentifier EsimFile::CarrierIdentifiers(const std::vector<uint8_t> &mccMncData, int mccMncLen,
    const std::u16string &gid1, const std::u16string &gid2)
{
    std::string strResult = Asn1Utils::BytesToHexStr(mccMncData);
    std::string mMcc(NUMBER_THREE, '\0');
    mMcc[NUMBER_ZERO] = strResult[NUMBER_ONE];
    mMcc[NUMBER_ONE] = strResult[NUMBER_ZERO];
    mMcc[NUMBER_TWO] = strResult[NUMBER_THREE];
    std::string mMnc(NUMBER_THREE, '\0');
    mMnc[NUMBER_ZERO] = strResult[NUMBER_FIVE];
    mMnc[NUMBER_ONE] = strResult[NUMBER_FOUR];
    if (strResult[NUMBER_TWO] != 'F') {
        mMnc[NUMBER_TWO] = strResult[NUMBER_TWO];
    }
    CarrierIdentifier carrierId;
    carrierId.mcc_ = OHOS::Telephony::ToUtf16(std::string(mMcc.c_str()));
    carrierId.mnc_ = OHOS::Telephony::ToUtf16(std::string(mMnc.c_str()));
    carrierId.gid1_ = gid1;
    carrierId.gid2_ = gid2;
    return carrierId;
}

struct CarrierIdentifier EsimFile::BuildCarrierIdentifiers(const std::shared_ptr<Asn1Node> &root)
{
    std::u16string gid1;
    std::u16string gid2;
    std::vector<uint8_t> gid1Byte;
    std::vector<uint8_t> gid2Byte;
    std::string strResult;
    CarrierIdentifier defaultCarrier = CarrierIdentifiers({}, 0, u"", u"");
    if (root->Asn1HasChild(TAG_ESIM_CTX_1)) {
        std::shared_ptr<Asn1Node> node = root->Asn1GetChild(TAG_ESIM_CTX_1);
        if (node == nullptr) {
            return defaultCarrier;
        }
        node->Asn1AsBytes(gid1Byte);
        strResult = Asn1Utils::BytesToHexStr(gid1Byte);
        gid1 = OHOS::Telephony::ToUtf16(strResult);
    }
    if (root->Asn1HasChild(TAG_ESIM_CTX_2)) {
        std::shared_ptr<Asn1Node> node = root->Asn1GetChild(TAG_ESIM_CTX_2);
        if (node == nullptr) {
            return defaultCarrier;
        }
        node->Asn1AsBytes(gid2Byte);
        strResult = Asn1Utils::BytesToHexStr(gid2Byte);
        gid2 = OHOS::Telephony::ToUtf16(strResult);
    }

    std::vector<uint8_t> mccMnc;
    std::shared_ptr<Asn1Node> ctx0Node = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (ctx0Node == nullptr) {
        return defaultCarrier;
    }
    uint32_t mccMncLen = ctx0Node->Asn1AsBytes(mccMnc);
    CarrierIdentifier myCarrier = CarrierIdentifiers(mccMnc, mccMncLen, gid1, gid2);
    return myCarrier;
}

bool EsimFile::RequestRulesAuthTableParseTagCtxComp0(std::shared_ptr<Asn1Node> &root)
{
    std::list<std::shared_ptr<Asn1Node>> Nodes;
    std::list<std::shared_ptr<Asn1Node>> opIdNodes;
    root->Asn1GetChildren(TAG_ESIM_CTX_COMP_0, Nodes);
    for (auto it = Nodes.begin(); it != Nodes.end(); ++it) {
        std::shared_ptr<Asn1Node> node = *it;
        if (node == nullptr) {
            return false;
        }
        std::shared_ptr<Asn1Node> grandson = node->Asn1GetGrandson(TAG_ESIM_SEQUENCE, TAG_ESIM_CTX_COMP_1);
        if (grandson == nullptr) {
            return false;
        }
        int32_t opIdNodesRes = grandson->Asn1GetChildren(TAG_ESIM_SEQUENCE, opIdNodes);
        if (opIdNodesRes != 0) {
            return false;
        }
        for (auto iter = opIdNodes.begin(); iter != opIdNodes.end(); ++iter) {
            std::shared_ptr<Asn1Node> curNode = nullptr;
            curNode = *iter;
            if (curNode == nullptr) {
                return false;
            }
            eUiccRulesAuthTable_.carrierIds_.push_back(BuildCarrierIdentifiers(curNode));
        }
        grandson = node->Asn1GetGrandson(TAG_ESIM_SEQUENCE, TAG_ESIM_CTX_0);
        if (grandson == nullptr) {
            return false;
        }
        int32_t policyRules = grandson->Asn1AsBits();
        grandson = node->Asn1GetGrandson(TAG_ESIM_SEQUENCE, TAG_ESIM_CTX_2);
        if (grandson == nullptr) {
            return false;
        }
        int32_t policyRuleFlags = grandson->Asn1AsBits();
        eUiccRulesAuthTable_.policyRules_.push_back(policyRules);
        eUiccRulesAuthTable_.policyRuleFlags_.push_back(policyRuleFlags);
    }
    return true;
}

bool EsimFile::ProcessRequestRulesAuthTableDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(rulesAuthTableMutex_, isRulesAuthTableReady_, rulesAuthTableCv_);
        return false;
    }
    if (!RequestRulesAuthTableParseTagCtxComp0(root)) {
        TELEPHONY_LOGE("RequestRulesAuthTableParseTagCtxComp0 error");
        NotifyReady(rulesAuthTableMutex_, isRulesAuthTableReady_, rulesAuthTableCv_);
        return false;
    }
    NotifyReady(rulesAuthTableMutex_, isRulesAuthTableReady_, rulesAuthTableCv_);
    return true;
}

bool EsimFile::ProcessObtainEuiccChallengeDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (profileRoot == nullptr) {
        TELEPHONY_LOGE("Asn1GetChild failed");
        NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
        return false;
    }
    std::vector<uint8_t> profileResponseByte;
    uint32_t byteLen = profileRoot->Asn1AsBytes(profileResponseByte);
    if (byteLen == 0) {
        TELEPHONY_LOGE("byteLen is zero");
        NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
        return false;
    }
    std::string resultStr = Asn1Utils::BytesToHexStr(profileResponseByte);
    responseChallengeResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
    responseChallengeResult_.response_ = OHOS::Telephony::ToUtf16(resultStr);
    NotifyReady(euiccChallengeMutex_, isEuiccChallengeReady_, euiccChallengeCv_);
    return true;
}

std::string EsimFile::ObtainDefaultSmdpAddress()
{
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return "";
    }
    AppExecFwk::InnerEvent::Pointer eventSmdpAddress = BuildCallerInfo(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE);
    if (!ProcessObtainDefaultSmdpAddress(slotId_, eventSmdpAddress)) {
        TELEPHONY_LOGE("ProcessObtainDefaultSmdpAddress encode failed");
        SyncCloseChannel(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE);
        return "";
    }
    std::unique_lock<std::mutex> lock(obtainDefaultSmdpAddressMutex_);
    isObtainDefaultSmdpAddressReady_ = false;
    if (!obtainDefaultSmdpAddressCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isObtainDefaultSmdpAddressReady_; })) {
        SyncCloseChannel(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE);
        return "";
    }
    SyncCloseChannel(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE);
    return defaultDpAddress_;
}

ResponseEsimInnerResult EsimFile::CancelSession(const std::u16string &transactionId, CancelReason cancelReason)
{
    cancelSessionResult_ = ResponseEsimInnerResult();
    esimProfile_.transactionId = transactionId;
    esimProfile_.cancelReason = cancelReason;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_CANCEL_SESSION);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        cancelSessionResult_.resultCode_ = static_cast<int32_t>(resultFlag);
        return cancelSessionResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventCancelSession = BuildCallerInfo(MSG_ESIM_CANCEL_SESSION);
    if (!ProcessCancelSession(slotId_, eventCancelSession)) {
        TELEPHONY_LOGE("ProcessCancelSession encode failed");
        SyncCloseChannel(MSG_ESIM_CANCEL_SESSION);
        cancelSessionResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return cancelSessionResult_;
    }
    std::unique_lock<std::mutex> lock(cancelSessionMutex_);
    isCancelSessionReady_ = false;
    if (!cancelSessionCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isCancelSessionReady_; })) {
        SyncCloseChannel(MSG_ESIM_CANCEL_SESSION);
        cancelSessionResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
        return cancelSessionResult_;
    }
    SyncCloseChannel(MSG_ESIM_CANCEL_SESSION);
    return cancelSessionResult_;
}

EuiccProfile EsimFile::ObtainProfile(int32_t portIndex, const std::u16string &iccId)
{
    eUiccProfile_ = EuiccProfile();
    esimProfile_.portIndex = portIndex;
    esimProfile_.iccId = iccId;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_GET_PROFILE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return eUiccProfile_;
    }
    AppExecFwk::InnerEvent::Pointer eventGetProfile = BuildCallerInfo(MSG_ESIM_GET_PROFILE);
    if (!ProcessGetProfile(slotId_, eventGetProfile)) {
        TELEPHONY_LOGE("ProcessGetProfile encode failed");
        SyncCloseChannel(MSG_ESIM_GET_PROFILE);
        return eUiccProfile_;
    }
    std::unique_lock<std::mutex> lock(obtainProfileMutex_);
    isObtainProfileReady_ = false;
    if (!obtainProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isObtainProfileReady_; })) {
        SyncCloseChannel(MSG_ESIM_GET_PROFILE);
        return eUiccProfile_;
    }
    SyncCloseChannel(MSG_ESIM_GET_PROFILE);
    return eUiccProfile_;
}

bool EsimFile::ProcessObtainDefaultSmdpAddress(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_CONFIGURED_ADDRESSES);

    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessGetProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_GET_PROFILE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_PROFILES);
    std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);

    std::vector<uint8_t> iccidBytes;
    std::string iccid = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
    Asn1Utils::BcdToBytes(iccid, iccidBytes);
    subBuilder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
    std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
    builder->Asn1AddChild(subNode);
    std::vector<uint8_t> getProfileTags = GetProfileTagList();
    builder->Asn1AddChildAsBytes(TAG_ESIM_TAG_LIST, getProfileTags, getProfileTags.size());
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

std::vector<uint8_t> EsimFile::GetProfileTagList()
{
    unsigned char EUICC_PROFILE_TAGS[] = {
        static_cast<unsigned char>(TAG_ESIM_ICCID),
        static_cast<unsigned char>(TAG_ESIM_NICKNAME),
        static_cast<unsigned char>(TAG_ESIM_OBTAIN_OPERATOR_NAME),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_NAME),
        static_cast<unsigned char>(TAG_ESIM_OPERATOR_ID),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE / PROFILE_DEFAULT_NUMBER),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_STATE % PROFILE_DEFAULT_NUMBER),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_CLASS),
        static_cast<unsigned char>(TAG_ESIM_PROFILE_POLICY_RULE),
        static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES / PROFILE_DEFAULT_NUMBER),
        static_cast<unsigned char>(TAG_ESIM_CARRIER_PRIVILEGE_RULES % PROFILE_DEFAULT_NUMBER),
    };
    std::vector<uint8_t> getProfileTags;
    for (const unsigned char tag : EUICC_PROFILE_TAGS) {
        getProfileTags.push_back(tag);
    }
    bool isSupportEsimMep = OHOS::system::GetBoolParameter(SUPPORT_ESIM_MEP, false);
    if (isSupportEsimMep) {
        getProfileTags.push_back(static_cast<unsigned char>(TAG_ESIM_PORT / PROFILE_DEFAULT_NUMBER));
        getProfileTags.push_back(static_cast<unsigned char>(TAG_ESIM_PORT % PROFILE_DEFAULT_NUMBER));
    }
    return getProfileTags;
}

bool EsimFile::ProcessCancelSession(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_CANCEL_SESSION)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_CANCEL_SESSION);

    std::string transactionIdStr = Str16ToStr8(esimProfile_.transactionId);
    std::vector<uint8_t> transactionIdByte = Asn1Utils::HexStrToBytes(transactionIdStr);
    builder->Asn1AddChildAsBytes(TAG_ESIM_CTX_0, transactionIdByte, transactionIdByte.size());
    builder->Asn1AddChildAsInteger(TAG_ESIM_CTX_1, static_cast<uint32_t>(esimProfile_.cancelReason));
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessObtainDefaultSmdpAddressDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> profileRoot = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (profileRoot == nullptr) {
        TELEPHONY_LOGE("profileRoot is nullptr");
        NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
        return false;
    }
    std::vector<uint8_t> outPutBytes;
    uint32_t byteLen = profileRoot->Asn1AsBytes(outPutBytes);
    if (byteLen == 0) {
        TELEPHONY_LOGE("byteLen is zero");
        NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
        return false;
    }
    defaultDpAddress_ = Asn1Utils::BytesToHexStr(outPutBytes);
    NotifyReady(obtainDefaultSmdpAddressMutex_, isObtainDefaultSmdpAddressReady_, obtainDefaultSmdpAddressCv_);
    return true;
}

bool EsimFile::ProcessCancelSessionDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        NotifyReady(cancelSessionMutex_, isCancelSessionReady_, cancelSessionCv_);
        return false;
    }

    IccFileData rawData;
    if (!GetRawDataFromEvent(event, rawData)) {
        NotifyReady(cancelSessionMutex_, isCancelSessionReady_, cancelSessionCv_);
        return false;
    }
    cancelSessionResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
    cancelSessionResult_.response_ = OHOS::Telephony::ToUtf16(rawData.resultData);
    NotifyReady(cancelSessionMutex_, isCancelSessionReady_, cancelSessionCv_);
    return true;
}

bool EsimFile::GetProfileDoneParseProfileInfo(std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> profileInfo = root->Asn1GetGrandson(TAG_ESIM_CTX_COMP_0, TAG_ESIM_PROFILE_INFO);
    if (profileInfo == nullptr) {
        TELEPHONY_LOGE("get profile list failed");
        return false;
    }
    std::shared_ptr<Asn1Node> iccNode = profileInfo->Asn1GetChild(TAG_ESIM_ICCID);
    if (iccNode == nullptr) {
        TELEPHONY_LOGE("nodeIcc is nullptr");
        return false;
    }
    EuiccProfileInfo euiccProfileInfo = {{0}};
    BuildBasicProfileInfo(&euiccProfileInfo, profileInfo);
    ConvertProfileInfoToApiStruct(eUiccProfile_, euiccProfileInfo);
    return true;
}

bool EsimFile::ProcessGetProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
        return false;
    }
    if (!GetProfileDoneParseProfileInfo(root)) {
        TELEPHONY_LOGE("GetProfileDoneParseProfileInfo error!");
        NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
        return false;
    }
    NotifyReady(obtainProfileMutex_, isObtainProfileReady_, obtainProfileCv_);
    return true;
}

int32_t EsimFile::ResetMemory(ResetOption resetOption)
{
    resetResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.option = resetOption;

    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_RESET_MEMORY);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        resetResult_ = static_cast<int32_t>(resultFlag);
        return resetResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventResetMemory = BuildCallerInfo(MSG_ESIM_RESET_MEMORY);
    if (!ProcessResetMemory(slotId_, eventResetMemory)) {
        TELEPHONY_LOGE("ProcessResetMemory encode failed");
        SyncCloseChannel(MSG_ESIM_RESET_MEMORY);
        return resetResult_;
    }
    std::unique_lock<std::mutex> lock(resetMemoryMutex_);
    isResetMemoryReady_ = false;
    if (!resetMemoryCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isResetMemoryReady_; })) {
        SyncCloseChannel(MSG_ESIM_RESET_MEMORY);
        return resetResult_;
    }
    SyncCloseChannel(MSG_ESIM_RESET_MEMORY);
    return resetResult_;
}

int32_t EsimFile::SetDefaultSmdpAddress(const std::u16string &defaultSmdpAddress)
{
    setDpAddressResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.defaultSmdpAddress = defaultSmdpAddress;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        setDpAddressResult_ = static_cast<int32_t>(resultFlag);
        return setDpAddressResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventSetSmdpAddress = BuildCallerInfo(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE);
    if (!ProcessEstablishDefaultSmdpAddress(slotId_, eventSetSmdpAddress)) {
        TELEPHONY_LOGE("ProcessEstablishDefaultSmdpAddress encode failed!!");
        SyncCloseChannel(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE);
        return setDpAddressResult_;
    }
    std::unique_lock<std::mutex> lock(setDefaultSmdpAddressMutex_);
    isSetDefaultSmdpAddressReady_ = false;
    if (!setDefaultSmdpAddressCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isSetDefaultSmdpAddressReady_; })) {
        SyncCloseChannel(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE);
        return setDpAddressResult_;
    }
    SyncCloseChannel(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE);
    return setDpAddressResult_;
}

bool EsimFile::ProcessEstablishDefaultSmdpAddress(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE)) {
        return false;
    }

    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_SET_DEFAULT_SMDP_ADDRESS);

    std::string address = OHOS::Telephony::ToUtf8(esimProfile_.defaultSmdpAddress);
    builder->Asn1AddChildAsString(TAG_ESIM_TARGET_ADDR, address);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    return true;
}

bool EsimFile::ProcessEstablishDefaultSmdpAddressDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(setDefaultSmdpAddressMutex_, isSetDefaultSmdpAddressReady_, setDefaultSmdpAddressCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> pAsn1Node = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (pAsn1Node == nullptr) {
        TELEPHONY_LOGE("pAsn1Node is nullptr");
        NotifyReady(setDefaultSmdpAddressMutex_, isSetDefaultSmdpAddressReady_, setDefaultSmdpAddressCv_);
        return false;
    }
    setDpAddressResult_ = pAsn1Node->Asn1AsInteger();
    NotifyReady(setDefaultSmdpAddressMutex_, isSetDefaultSmdpAddressReady_, setDefaultSmdpAddressCv_);
    return true;
}

bool EsimFile::IsSupported()
{
    char buf[ATR_LENGTH + 1] = {0};
    if (isSupported_) {
        return isSupported_;
    }
    GetParameter(TEL_ESIM_SUPPORT, "", buf, ATR_LENGTH);
    ResetResponse resetResponse;
    std::string atr(buf);
    if (atr.empty()) {
        if (!ObtainEid().empty()) {
            isSupported_ = true;
        }
        return isSupported_;
    }
    resetResponse.AnalysisAtrData(atr);
    isSupported_ = resetResponse.IsEuiccAvailable();
    return isSupported_;
}

ResponseEsimInnerResult EsimFile::SendApduData(const std::u16string &aid, const EsimApduData &apduData)
{
    std::unique_lock<std::mutex> lck(currentChannelIdOccupiedMutex_);
    transApduDataResponse_ = ResponseEsimInnerResult();
    if (aid.empty()) {
        TELEPHONY_LOGE("Aid is empty");
        transApduDataResponse_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_AID_EMPTY);
        return transApduDataResponse_;
    }
    if (apduData.closeChannelFlag_) {
        if (IsSameAid(aid)) {
            SyncCloseChannel(MSG_ESIM_SEND_APUD_DATA);
            return ResponseEsimInnerResult();
        }

        TELEPHONY_LOGE("SendApduData Close Channel failed");
        transApduDataResponse_.resultCode_ =
            static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_CHANNEL_CLOSE_FAILED);
        return transApduDataResponse_;
    }

    esimProfile_.apduData = apduData;
    AppExecFwk::InnerEvent::Pointer eventSendApduData = BuildCallerInfo(MSG_ESIM_SEND_APUD_DATA);
    ResultInnerCode resultFlag = ObtainChannelSuccessAllowSameAidReuse(aid);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessAllowSameAidReuse failed ,%{public}d", resultFlag);
        transApduDataResponse_.resultCode_ = static_cast<int32_t>(resultFlag);
        return transApduDataResponse_;
    }
    std::unique_lock<std::mutex> lock(sendApduDataMutex_);
    isSendApduDataReady_ = false;
    if (!ProcessSendApduData(slotId_, eventSendApduData)) {
        TELEPHONY_LOGE("ProcessSendApduData encode failed");
        SyncCloseChannel(MSG_ESIM_SEND_APUD_DATA);
        transApduDataResponse_.resultCode_ =
            static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return transApduDataResponse_;
    }
    if (!sendApduDataCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isSendApduDataReady_; })) {
        SyncCloseChannel(MSG_ESIM_SEND_APUD_DATA);
        transApduDataResponse_.resultCode_ =
            static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
        return transApduDataResponse_;
    }
    return transApduDataResponse_;
}

bool EsimFile::ProcessResetMemory(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_RESET_MEMORY)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_EUICC_MEMORY_RESET);

    std::vector<uint8_t> resetMemoryTags;
    resetMemoryTags.push_back(static_cast<uint8_t>(EUICC_MEMORY_RESET_BIT_STR_FILL_LEN));
    resetMemoryTags.push_back(static_cast<uint8_t>(EUICC_MEMORY_RESET_BIT_STR_VALUE));
    builder->Asn1AddChildAsBytes(TAG_ESIM_CTX_2, resetMemoryTags, resetMemoryTags.size());
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessResetMemoryDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(resetMemoryMutex_, isResetMemoryReady_, resetMemoryCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (asn1NodeData == nullptr) {
        TELEPHONY_LOGE("asn1NodeData is nullptr");
        NotifyReady(resetMemoryMutex_, isResetMemoryReady_, resetMemoryCv_);
        return false;
    }
    resetResult_ = asn1NodeData->Asn1AsInteger();
    NotifyReady(resetMemoryMutex_, isResetMemoryReady_, resetMemoryCv_);
    return true;
}

bool EsimFile::ProcessSendApduData(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_SEND_APUD_DATA)) {
        return false;
    }
    std::string hexStr = OHOS::Telephony::ToUtf8(esimProfile_.apduData.data_);
    RequestApduBuild codec(currentChannelId_);
    codec.BuildStoreData(hexStr);
    std::list<std::unique_ptr<ApduCommand>> list = codec.GetCommands();
    if (list.empty()) {
        TELEPHONY_LOGE("node is empty");
        return false;
    }
    std::unique_ptr<ApduCommand> apdCmd = std::move(list.front());
    if (apdCmd == nullptr) {
        return false;
    }
    ApduSimIORequestInfo reqInfo;
    CopyApdCmdToReqInfo(reqInfo, apdCmd.get());
    if (esimProfile_.apduData.unusedDefaultReqHeadFlag_) {
        reqInfo.type = esimProfile_.apduData.instructionType_;
        reqInfo.instruction = esimProfile_.apduData.instruction_;
        reqInfo.p1 = esimProfile_.apduData.p1_;
        reqInfo.p2 = esimProfile_.apduData.p2_;
        reqInfo.p3 = esimProfile_.apduData.p3_;
    }
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessSendApduDataDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
        return false;
    }
    IccFileData *result = &(rcvMsg->fileData);
    if (result == nullptr) {
        TELEPHONY_LOGE("result is nullptr");
        NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
        return false;
    }
    transApduDataResponse_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
    transApduDataResponse_.response_ = OHOS::Telephony::ToUtf16(result->resultData);
    transApduDataResponse_.sw1_ = result->sw1;
    transApduDataResponse_.sw2_ = result->sw2;
    NotifyReady(sendApduDataMutex_, isSendApduDataReady_, sendApduDataCv_);
    return true;
}

ResponseEsimInnerResult EsimFile::ObtainPrepareDownload(const DownLoadConfigInfo &downLoadConfigInfo)
{
    preDownloadResult_ = ResponseEsimInnerResult();
    esimProfile_.portIndex = downLoadConfigInfo.portIndex_;
    esimProfile_.hashCc = downLoadConfigInfo.hashCc_;
    esimProfile_.smdpSigned2 = downLoadConfigInfo.smdpSigned2_;
    esimProfile_.smdpSignature2 = downLoadConfigInfo.smdpSignature2_;
    esimProfile_.smdpCertificate = downLoadConfigInfo.smdpCertificate_;

    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_PREPARE_DOWNLOAD_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        preDownloadResult_.resultCode_ = static_cast<int32_t>(resultFlag);
        return preDownloadResult_;
    }
    recvCombineStr_ = "";
    if (!ProcessPrepareDownload(slotId_)) {
        TELEPHONY_LOGE("ProcessPrepareDownload encode failed");
        SyncCloseChannel(MSG_ESIM_PREPARE_DOWNLOAD_DONE);
        preDownloadResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return preDownloadResult_;
    }
    SyncCloseChannel(MSG_ESIM_PREPARE_DOWNLOAD_DONE);
    return preDownloadResult_;
}

ResponseEsimBppResult EsimFile::ObtainLoadBoundProfilePackage(int32_t portIndex,
    const std::u16string boundProfilePackage)
{
    esimProfile_.portIndex = portIndex;
    esimProfile_.boundProfilePackage = boundProfilePackage;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        loadBPPResult_.resultCode_ = static_cast<int32_t>(resultFlag);
        return loadBPPResult_;
    }
    loadBPPResult_ = ResponseEsimBppResult();
    recvCombineStr_ = "";
    if (!ProcessLoadBoundProfilePackage(slotId_)) {
        TELEPHONY_LOGE("ProcessLoadBoundProfilePackage encode failed");
        SyncCloseChannel(MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE);
        loadBPPResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return ResponseEsimBppResult();
    }
    SyncCloseChannel(MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE);
    return loadBPPResult_;
}

EuiccNotificationList EsimFile::ListNotifications(int32_t portIndex, EsimEvent events)
{
    esimProfile_.portIndex = portIndex;
    esimProfile_.events = events;
    AppExecFwk::InnerEvent::Pointer eventListNotif = BuildCallerInfo(MSG_ESIM_LIST_NOTIFICATION);
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_LIST_NOTIFICATION);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return EuiccNotificationList();
    }
    recvCombineStr_ = "";
    if (!ProcessListNotifications(slotId_, events, eventListNotif)) {
        TELEPHONY_LOGE("ProcessListNotifications encode failed");
        SyncCloseChannel(MSG_ESIM_LIST_NOTIFICATION);
        return EuiccNotificationList();
    }
    std::unique_lock<std::mutex> lock(listNotificationsMutex_);
    isListNotificationsReady_ = false;
    if (!listNotificationsCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isListNotificationsReady_; })) {
        SyncCloseChannel(MSG_ESIM_LIST_NOTIFICATION);
        return EuiccNotificationList();
    }
    SyncCloseChannel(MSG_ESIM_LIST_NOTIFICATION);
    return eUiccNotificationList_;
}

void EsimFile::ConvertPreDownloadParaFromApiStru(PrepareDownloadResp& dst, EsimProfile& src)
{
    dst.smdpSigned2 = OHOS::Telephony::ToUtf8(src.smdpSigned2);
    dst.smdpSignature2 = OHOS::Telephony::ToUtf8(src.smdpSignature2);
    dst.smdpCertificate = OHOS::Telephony::ToUtf8(src.smdpCertificate);
    dst.hashCc = OHOS::Telephony::ToUtf8(src.hashCc);
}

void EsimFile::Asn1AddChildAsBase64(std::shared_ptr<Asn1Builder> &builder, std::string &base64Src)
{
    std::string destString = VCardUtils::DecodeBase64NoWrap(base64Src);
    std::vector<uint8_t> dest = Asn1Utils::StringToBytes(destString);
    std::shared_ptr<Asn1Decoder> decoder = std::make_shared<Asn1Decoder>(dest, 0, dest.size());

    std::shared_ptr<Asn1Node> node = decoder->Asn1NextNode();
    if (builder == nullptr) {
        TELEPHONY_LOGE("build is nullptr");
        return;
    }
    builder->Asn1AddChild(node);
}

bool EsimFile::ProcessPrepareDownload(int32_t slotId)
{
    if (!IsLogicChannelOpen(MSG_ESIM_PREPARE_DOWNLOAD_DONE)) {
        return false;
    }
    PrepareDownloadResp dst;
    ConvertPreDownloadParaFromApiStru(dst, esimProfile_);
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_PREPARE_DOWNLOAD);

    Asn1AddChildAsBase64(builder, dst.smdpSigned2);
    Asn1AddChildAsBase64(builder, dst.smdpSignature2);
    if (dst.hashCc.size() != 0) {
        std::vector<uint8_t> bytes = Asn1Utils::StringToBytes(VCardUtils::DecodeBase64NoWrap(dst.hashCc));
        builder->Asn1AddChildAsBytes(TAG_ESIM_OCTET_STRING_TYPE, bytes, bytes.size());
    }
    Asn1AddChildAsBase64(builder, dst.smdpCertificate);
    std::string hexStr;
    uint32_t hexStrLen = builder->Asn1BuilderToHexStr(hexStr);
    if (hexStrLen == 0) {
        return false;
    }
    RequestApduBuild codec(currentChannelId_);
    codec.BuildStoreData(hexStr);
    SplitSendLongData(codec, MSG_ESIM_PREPARE_DOWNLOAD_DONE,
        prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
    return true;
}

void EsimFile::SplitSendLongData(
    RequestApduBuild &codec, int32_t esimMessageId, std::mutex &mtx, bool &flag, std::condition_variable &cv)
{
    std::list<std::unique_ptr<ApduCommand>> apduCommandList = codec.GetCommands();
    for (const auto &cmd : apduCommandList) {
        if (!cmd) {
            return;
        }
        ApduSimIORequestInfo reqInfo;
        CopyApdCmdToReqInfo(reqInfo, cmd.get());
        AppExecFwk::InnerEvent::Pointer tmpResponseEvent = BuildCallerInfo(esimMessageId);
        if (telRilManager_ == nullptr) {
            return;
        }
        std::unique_lock<std::mutex> lock(mtx);
        flag = false;
        telRilManager_->SimTransmitApduLogicalChannel(slotId_, reqInfo, tmpResponseEvent);
        if (!cv.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
            [&flag]() { return flag; })) {
            return;
        }
    }
}

uint32_t EsimFile::CombineResponseDataFinish(IccFileData &fileData)
{
    if (fileData.sw1 == SW1_MORE_RESPONSE) {
        return RESPONS_DATA_NOT_FINISH;
    } else if (fileData.sw1 == SW1_VALUE_90 && fileData.sw2 == SW2_VALUE_00) {
        return RESPONS_DATA_FINISH;
    } else {
        return RESPONS_DATA_ERROR;
    }
}

void EsimFile::ProcessIfNeedMoreResponse(IccFileData &fileData, int32_t eventId)
{
    if (fileData.sw1 == SW1_MORE_RESPONSE) {
        ApduSimIORequestInfo reqInfo;
        RequestApduBuild codec(currentChannelId_);
        codec.BuildStoreData("");
        std::list<std::unique_ptr<ApduCommand>> list = codec.GetCommands();
        if (list.empty()) {
            TELEPHONY_LOGE("node is empty");
            return;
        }
        std::unique_ptr<ApduCommand> apdCmd = std::move(list.front());
        if (apdCmd == nullptr) {
            return;
        }
        apdCmd->data.cla = 0;
        apdCmd->data.ins = INS_GET_MORE_RESPONSE;
        apdCmd->data.p1 = 0;
        apdCmd->data.p2 = 0;
        apdCmd->data.p3 = static_cast<uint32_t>(fileData.sw2);
        CopyApdCmdToReqInfo(reqInfo, apdCmd.get());
        AppExecFwk::InnerEvent::Pointer responseEvent = BuildCallerInfo(eventId);
        if (telRilManager_ == nullptr) {
            return;
        }
        telRilManager_->SimTransmitApduLogicalChannel(slotId_, reqInfo, responseEvent);
    }
}

uint32_t EsimFile::MergeRecvLongDataComplete(IccFileData &fileData, int32_t eventId)
{
    TELEPHONY_LOGI("eventId=%{public}d input sw1=%{public}02X, sw2=%{public}02X, data.length=%{public}zu",
        eventId, fileData.sw1, fileData.sw2, fileData.resultData.length());
    uint32_t result = CombineResponseDataFinish(fileData);
    if (result == RESPONS_DATA_ERROR) {
        TELEPHONY_LOGE("RESPONS_DATA_ERROR current_len:%{public}zu", recvCombineStr_.length());
        return result;
    }
    recvCombineStr_ = recvCombineStr_ + fileData.resultData;
    if (result == RESPONS_DATA_NOT_FINISH) {
        ProcessIfNeedMoreResponse(fileData, eventId);
        TELEPHONY_LOGI("RESPONS_DATA_NOT_FINISH current_len:%{public}zu", recvCombineStr_.length());
        return result;
    }
    TELEPHONY_LOGI("RESPONS_DATA_FINISH current_len:%{public}zu", recvCombineStr_.length());
    return result;
}

bool EsimFile::ProcessPrepareDownloadDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_,
        MSG_ESIM_PREPARE_DOWNLOAD_DONE, isHandleFinish);
    if (isHandleFinish) {
        return retValue;
    }
    return RealProcessPrepareDownloadDone();
}

bool EsimFile::RealProcessPrepareDownloadDone()
{
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    uint32_t byteLen = responseByte.size();
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> childNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_1);
    if (childNode != nullptr) {
        std::shared_ptr<Asn1Node> errCodeNode = childNode->Asn1GetChild(TAG_ESIM_UNI_2);
        if (errCodeNode != nullptr) {
            int32_t protocolErr = errCodeNode->Asn1AsInteger();
            if (protocolErr > 0) {
                TELEPHONY_LOGE("Prepare download error, es10x errcode: %{public}d", protocolErr);
                preDownloadResult_.resultCode_ = protocolErr;
                preDownloadResult_.response_ = u"";
                NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
                return false;
            }
        }
    }
    preDownloadResult_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
    std::string responseByteStr = Asn1Utils::BytesToString(responseByte);
    std::string destString = VCardUtils::EncodeBase64(responseByteStr);
    preDownloadResult_.response_ = OHOS::Telephony::ToUtf16(destString);
    NotifyReady(prepareDownloadMutex_, isPrepareDownloadReady_, prepareDownloadCv_);
    return true;
}

bool EsimFile::DecodeBoundProfilePackage(const std::string &boundProfilePackageStr, std::shared_ptr<Asn1Node> &bppNode)
{
    std::string destString = VCardUtils::DecodeBase64NoWrap(boundProfilePackageStr);
    std::vector<uint8_t> dest = Asn1Utils::StringToBytes(destString);
    std::shared_ptr<Asn1Decoder> decoder = std::make_shared<Asn1Decoder>(dest, 0, dest.size());

    bppNode = decoder->Asn1NextNode();
    if (bppNode == nullptr) {
        TELEPHONY_LOGE("bppNode is nullptr");
        return false;
    }
    return true;
}

void EsimFile::BuildApduForInitSecureChannel(
    RequestApduBuild& codec, std::shared_ptr<Asn1Node> &bppNode, std::shared_ptr<Asn1Node> &initSecureChannelReq)
{
    std::string hexStr;
    std::string destStr;
    uint32_t cursorLen = bppNode->Asn1GetHeadAsHexStr(hexStr);
    cursorLen += initSecureChannelReq->Asn1NodeToHexStr(destStr);
    hexStr += destStr;
    codec.BuildStoreData(hexStr);
}

void EsimFile::BuildApduForFirstSequenceOf87(RequestApduBuild &codec, std::shared_ptr<Asn1Node> &firstSequenceOf87)
{
    std::string hexStr;
    firstSequenceOf87->Asn1NodeToHexStr(hexStr);
    codec.BuildStoreData(hexStr);
}

void EsimFile::BuildApduForSequenceOf88(RequestApduBuild &codec, std::shared_ptr<Asn1Node> &sequenceOf88)
{
    std::list<std::shared_ptr<Asn1Node>> metaDataSeqs;
    int32_t metaDataRes = sequenceOf88->Asn1GetChildren(TAG_ESIM_CTX_8, metaDataSeqs);
    if (metaDataRes != 0) {
        return;
    }
    std::string hexStr;
    sequenceOf88->Asn1GetHeadAsHexStr(hexStr);
    codec.BuildStoreData(hexStr);
    std::shared_ptr<Asn1Node> curNode = nullptr;
    for (auto it = metaDataSeqs.begin(); it != metaDataSeqs.end(); ++it) {
        curNode = *it;
        if (curNode == nullptr) {
            break;
        }
        curNode->Asn1NodeToHexStr(hexStr);
        codec.BuildStoreData(hexStr);
    }
}

void EsimFile::BuildApduForSequenceOf86(RequestApduBuild &codec, std::shared_ptr<Asn1Node> &bppNode,
    std::shared_ptr<Asn1Node> &sequenceOf86)
{
    std::string hexStr;
    std::list<std::shared_ptr<Asn1Node>> elementSeqs;
    int32_t elementRes = sequenceOf86->Asn1GetChildren(TAG_ESIM_CTX_6, elementSeqs);
    if (elementRes != 0) {
        TELEPHONY_LOGE("sequenceOf86 encode error");
        return;
    }
    if (bppNode->Asn1HasChild(TAG_ESIM_CTX_COMP_2)) {
        std::shared_ptr<Asn1Node> pGetChild = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_2);
        if (pGetChild == nullptr) {
            TELEPHONY_LOGE("pGetChild is nullptr");
            return;
        }
        pGetChild->Asn1NodeToHexStr(hexStr);
        codec.BuildStoreData(hexStr);
    }
    sequenceOf86->Asn1GetHeadAsHexStr(hexStr);
    codec.BuildStoreData(hexStr);
    std::shared_ptr<Asn1Node> curNode = nullptr;
    for (auto it = elementSeqs.begin(); it != elementSeqs.end(); ++it) {
        curNode = *it;
        if (curNode == nullptr) {
            break;
        }
        curNode->Asn1NodeToHexStr(hexStr);
        codec.BuildStoreData(hexStr);
    }
}

bool EsimFile::ProcessLoadBoundProfilePackage(int32_t slotId)
{
    if (!IsLogicChannelOpen(MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE)) {
        TELEPHONY_LOGE("open channel is failed");
        return false;
    }
    std::string boundProfilePackage = OHOS::Telephony::ToUtf8(esimProfile_.boundProfilePackage);
    std::shared_ptr<Asn1Node> bppNode = nullptr;
    if (!DecodeBoundProfilePackage(boundProfilePackage, bppNode)) {
        TELEPHONY_LOGE("DecodeBoundProfilePackage failed");
        return false;
    }
    RequestApduBuild codec(currentChannelId_);
    std::shared_ptr<Asn1Node> initSecureChannelReq = bppNode->Asn1GetChild(TAG_ESIM_INITIALISE_SECURE_CHANNEL);
    if (initSecureChannelReq != nullptr) {
        BuildApduForInitSecureChannel(codec, bppNode, initSecureChannelReq);
    }
    // check unknown tag error
    std::shared_ptr<Asn1Node> unknownBppSegment = bppNode->Asn1GetChild(TAG_ESIM_UNKNOWN_BPP_SEGMENT);
    if (unknownBppSegment != nullptr) {
        TELEPHONY_LOGE("recv GET_BPP_LOAD_ERROR_UNKNOWN_TAG");
        return false;
    }
    std::shared_ptr<Asn1Node> firstSequenceOf87 = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
    if (firstSequenceOf87 != nullptr) {
        BuildApduForFirstSequenceOf87(codec, firstSequenceOf87);
    }
    std::shared_ptr<Asn1Node> sequenceOf88 = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_1);
    if (sequenceOf88 != nullptr) {
        BuildApduForSequenceOf88(codec, sequenceOf88);
    }
    std::shared_ptr<Asn1Node> sequenceOf86 = bppNode->Asn1GetChild(TAG_ESIM_CTX_COMP_3);
    if (sequenceOf86 == nullptr) {
        TELEPHONY_LOGE("recv GET_BPP_LOAD_ERROR");
        return false;
    }
    if (sequenceOf86->GetEncodedLength() == GET_BPP_LOAD_ERROR_LENGTH) {
        TELEPHONY_LOGE("recv GET_BPP_LOAD_ERROR");
        return false;
    }
    BuildApduForSequenceOf86(codec, bppNode, sequenceOf86);
    SplitSendLongData(codec, MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE, loadBppMutex_, isLoadBppReady_, loadBppCv_);
    return true;
}

bool EsimFile::ProcessLoadBoundProfilePackageDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(loadBppMutex_, isLoadBppReady_, loadBppCv_,
        MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE, isHandleFinish);
    if (isHandleFinish) {
        return retValue;
    }
    return RealProcessLoadBoundProfilePackageDone();
}
bool EsimFile::RealProcessLoadBoundProfilePackageDone()
{
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    uint32_t byteLen = responseByte.size();
    loadBPPResult_.response_ = OHOS::Telephony::ToUtf16(recvCombineStr_);
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> nodeNotificationMetadata = LoadBoundProfilePackageParseProfileInstallResult(root);
    if (nodeNotificationMetadata == nullptr) {
        TELEPHONY_LOGE("nodeNotificationMetadata is nullptr");
        NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
        return false;
    }
    if (!LoadBoundProfilePackageParseNotificationMetadata(nodeNotificationMetadata)) {
        TELEPHONY_LOGE("LoadBoundProfilePackageParseNotificationMetadata error");
        NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
        return false;
    }
    loadBPPResult_.resultCode_ = 0;
    NotifyReady(loadBppMutex_, isLoadBppReady_, loadBppCv_);
    return true;
}

bool EsimFile::LoadBoundProfilePackageParseNotificationMetadata(std::shared_ptr<Asn1Node> &notificationMetadata)
{
    if (notificationMetadata == nullptr) {
        TELEPHONY_LOGE("notification metadata is empty");
        return false;
    }
    std::shared_ptr<Asn1Node> sequenceNumberAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_CTX_0);
    if (sequenceNumberAsn != nullptr) {
        loadBPPResult_.seqNumber_ = sequenceNumberAsn->Asn1AsInteger();
    } else {
        TELEPHONY_LOGE("sequenceNumber tag missing");
        return false;
    }
    std::shared_ptr<Asn1Node> profileManagementOpAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_CTX_1);
    if (profileManagementOpAsn != nullptr) {
        loadBPPResult_.profileManagementOperation_ = EVENT_INSTALL;
    } else {
        TELEPHONY_LOGE("profileManagementOperation tag missing");
        return false;
    }
    std::shared_ptr<Asn1Node> addressAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_TARGET_ADDR);
    if (addressAsn != nullptr) {
        std::string hexString;
        addressAsn->Asn1AsString(hexString);
        std::string address = Asn1Utils::HexStrToString(hexString);
        loadBPPResult_.notificationAddress_ = OHOS::Telephony::ToUtf16(address);
    } else {
        TELEPHONY_LOGE("notificationAddress tag missing");
        return false;
    }
    std::shared_ptr<Asn1Node> iccidAsn = notificationMetadata->Asn1GetChild(TAG_ESIM_EID);
    if (iccidAsn == nullptr) {
        TELEPHONY_LOGE("iccidAsn is nullptr");
        return false;
    }
    std::vector<uint8_t> iccid;
    std::string iccString;
    iccidAsn->Asn1AsBytes(iccid);
    Asn1Utils::BchToString(iccid, iccString);
    loadBPPResult_.iccId_ = OHOS::Telephony::ToUtf16(iccString);
    return true;
}

std::shared_ptr<Asn1Node> EsimFile::LoadBoundProfilePackageParseProfileInstallResult(std::shared_ptr<Asn1Node> &root)
{
    if (root == nullptr) {
        TELEPHONY_LOGE("failed to parse load BPP file response");
        return nullptr;
    }
    std::shared_ptr<Asn1Node> resultData = root->Asn1GetChild(TAG_ESIM_PROFILE_INSTALLATION_RESULT_DATA);
    if (resultData == nullptr) {
        TELEPHONY_LOGE("failed to find ProfileInstallationResult tag");
        return nullptr;
    }
    std::shared_ptr<Asn1Node> errNode = resultData->Asn1GetGreatGrandson(TAG_ESIM_CTX_COMP_2,
        TAG_ESIM_CTX_COMP_1, TAG_ESIM_CTX_1);
    if (errNode != nullptr) {
        loadBPPResult_.resultCode_ = errNode->Asn1AsInteger();
        return nullptr;
    }
    std::shared_ptr<Asn1Node> notificationMetadataAsn = resultData->Asn1GetChild(TAG_ESIM_NOTIFICATION_METADATA);
    if (notificationMetadataAsn == nullptr) {
        TELEPHONY_LOGE("extProfileInstallRsp: failed to find finalResult tag");
        return nullptr;
    }
    return notificationMetadataAsn;
}

bool EsimFile::ProcessListNotifications(
    int32_t slotId, EsimEvent events, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_LIST_NOTIFICATION)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_LIST_NOTIFICATION);

    builder->Asn1AddChildAsBits(TAG_ESIM_CTX_1, static_cast<int32_t>(events));
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

void EsimFile::CreateNotification(std::shared_ptr<Asn1Node> &node, EuiccNotification &euicc)
{
    if (node == nullptr) {
        TELEPHONY_LOGE("CreateNotification node is nullptr");
        return;
    }
    std::shared_ptr<Asn1Node> metadataNode;
    if (node->GetNodeTag() == TAG_ESIM_NOTIFICATION_METADATA) {
        metadataNode = node;
    } else if (node->GetNodeTag() == TAG_ESIM_PROFILE_INSTALLATION_RESULT) {
        std::shared_ptr<Asn1Node> findNode =
            node->Asn1GetGrandson(TAG_ESIM_PROFILE_INSTALLATION_RESULT_DATA,
            TAG_ESIM_NOTIFICATION_METADATA);
        metadataNode = findNode;
    } else {
        // Other signed notification
        std::shared_ptr<Asn1Node> findNode = node->Asn1GetChild(TAG_ESIM_NOTIFICATION_METADATA);
        metadataNode = findNode;
    }
    if (metadataNode == nullptr) {
        TELEPHONY_LOGE("metadataNode is nullptr");
        return;
    }
    std::shared_ptr<Asn1Node> nodeSeq = metadataNode->Asn1GetChild(TAG_ESIM_SEQ);
    if (nodeSeq == nullptr) {
        TELEPHONY_LOGE("nodeSeq is nullptr");
        return;
    }
    euicc.seq_ = nodeSeq->Asn1AsInteger();

    std::shared_ptr<Asn1Node> nodeTargetAddr = metadataNode->Asn1GetChild(TAG_ESIM_TARGET_ADDR);
    if (nodeTargetAddr == nullptr) {
        TELEPHONY_LOGE("nodeTargetAddr is nullptr");
        return;
    }
    std::vector<uint8_t> resultStr;
    nodeTargetAddr->Asn1AsBytes(resultStr);
    euicc.targetAddr_ = OHOS::Telephony::ToUtf16(Asn1Utils::BytesToString(resultStr));

    std::shared_ptr<Asn1Node> nodeEvent = metadataNode->Asn1GetChild(TAG_ESIM_EVENT);
    if (nodeEvent == nullptr) {
        TELEPHONY_LOGE("nodeEvent is nullptr");
        return;
    }
    euicc.event_ = nodeEvent->Asn1AsBits();

    std::string strmData;
    node->Asn1NodeToHexStr(strmData);
    euicc.data_ = Str8ToStr16(strmData);
}

bool EsimFile::ProcessListNotificationsAsn1Response(std::shared_ptr<Asn1Node> &root)
{
    if (root->Asn1HasChild(TAG_ESIM_CTX_1)) {
        TELEPHONY_LOGE("child is nullptr");
        return false;
    }
    std::list<std::shared_ptr<Asn1Node>> ls;
    std::shared_ptr<Asn1Node> compTag = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
    if (compTag == nullptr) {
        TELEPHONY_LOGE("compTag is nullptr");
        return false;
    }
    int32_t metaDataRes = compTag->Asn1GetChildren(TAG_ESIM_NOTIFICATION_METADATA, ls);
    if (metaDataRes != 0) {
        TELEPHONY_LOGE("metaDataTag is zero");
        return false;
    }
    std::shared_ptr<Asn1Node> curNode = nullptr;
    EuiccNotificationList euiccList;
    for (auto it = ls.begin(); it != ls.end(); ++it) {
        curNode = *it;
        EuiccNotification euicc;
        CreateNotification(curNode, euicc);
        euiccList.euiccNotification_.push_back(euicc);
    }
    eUiccNotificationList_ = euiccList;
    return true;
}

bool EsimFile::ProcessListNotificationsDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_,
        MSG_ESIM_LIST_NOTIFICATION, isHandleFinish);
    if (isHandleFinish) {
        return retValue;
    }
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    uint32_t byteLen = responseByte.size();
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
        return false;
    }
    if (!ProcessListNotificationsAsn1Response(root)) {
        TELEPHONY_LOGE("ProcessListNotificationsAsn1Response error");
        NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
        return false;
    }
    NotifyReady(listNotificationsMutex_, isListNotificationsReady_, listNotificationsCv_);
    return true;
}

EuiccNotificationList EsimFile::RetrieveNotificationList(int32_t portIndex, EsimEvent events)
{
    esimProfile_.portIndex = portIndex;
    esimProfile_.events = events;
    std::unique_lock<std::mutex> lck(currentChannelIdOccupiedMutex_);
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return EuiccNotificationList();
    }
    recvCombineStr_ = "";
    AppExecFwk::InnerEvent::Pointer eventRetrieveListNotif = BuildCallerInfo(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST);
    if (!ProcessRetrieveNotificationList(slotId_, events, eventRetrieveListNotif)) {
        TELEPHONY_LOGE("ProcessRetrieveNotificationList encode failed");
        SyncCloseChannel(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST);
        return EuiccNotificationList();
    }
    std::unique_lock<std::mutex> lock(retrieveNotificationListMutex_);
    isRetrieveNotificationListReady_ = false;
    if (!retrieveNotificationListCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isRetrieveNotificationListReady_; })) {
        SyncCloseChannel(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST);
        return EuiccNotificationList();
    }
    SyncCloseChannel(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST);
    return retrieveNotificationList_;
}

EuiccNotification EsimFile::ObtainRetrieveNotification(int32_t portIndex, int32_t seqNumber)
{
    esimProfile_.portIndex = portIndex;
    esimProfile_.seqNumber = seqNumber;
    std::unique_lock<std::mutex> lck(currentChannelIdOccupiedMutex_);
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return EuiccNotification();
    }
    recvCombineStr_ = "";
    AppExecFwk::InnerEvent::Pointer eventRetrieveNotification = BuildCallerInfo(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE);
    if (!ProcessRetrieveNotification(slotId_, eventRetrieveNotification)) {
        TELEPHONY_LOGE("ProcessRetrieveNotification encode failed");
        SyncCloseChannel(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE);
        return EuiccNotification();
    }
    std::unique_lock<std::mutex> lock(retrieveNotificationMutex_);
    isRetrieveNotificationReady_ = false;
    if (!retrieveNotificationCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isRetrieveNotificationReady_; })) {
        SyncCloseChannel(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE);
        return EuiccNotification();
    }
    SyncCloseChannel(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE);
    return notification_;
}

int32_t EsimFile::RemoveNotificationFromList(int32_t portIndex, int32_t seqNumber)
{
    removeNotifResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.portIndex = portIndex;
    esimProfile_.seqNumber = seqNumber;
    std::unique_lock<std::mutex> lck(currentChannelIdOccupiedMutex_);
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_REMOVE_NOTIFICATION);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        removeNotifResult_ = static_cast<int32_t>(resultFlag);
        return removeNotifResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventRemoveNotif = BuildCallerInfo(MSG_ESIM_REMOVE_NOTIFICATION);
    if (!ProcessRemoveNotification(slotId_, eventRemoveNotif)) {
        TELEPHONY_LOGE("ProcessRemoveNotification encode failed");
        SyncCloseChannel(MSG_ESIM_REMOVE_NOTIFICATION);
        return removeNotifResult_;
    }
    std::unique_lock<std::mutex> lock(removeNotificationMutex_);
    isRemoveNotificationReady_ = false;
    if (!removeNotificationCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isRemoveNotificationReady_; })) {
        SyncCloseChannel(MSG_ESIM_REMOVE_NOTIFICATION);
        return removeNotifResult_;
    }
    SyncCloseChannel(MSG_ESIM_REMOVE_NOTIFICATION);
    return removeNotifResult_;
}

bool EsimFile::ProcessRetrieveNotificationList(
    int32_t slotId, EsimEvent events, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_RETRIEVE_NOTIFICATION_LIST)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_RETRIEVE_NOTIFICATIONS_LIST);
    std::shared_ptr<Asn1Builder> compBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);

    compBuilder->Asn1AddChildAsBits(TAG_ESIM_CTX_1, static_cast<int32_t>(events));
    std::shared_ptr<Asn1Node> compNode = compBuilder->Asn1Build();
    builder->Asn1AddChild(compNode);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        TELEPHONY_LOGE("telRilManager_ is nullptr");
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessRetrieveNotificationListDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
        return false;
    }
    if (!RetrieveNotificationParseCompTag(root)) {
        TELEPHONY_LOGE("RetrieveNotificationParseCompTag error");
        NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
        return false;
    }
    NotifyReady(retrieveNotificationListMutex_, isRetrieveNotificationListReady_, retrieveNotificationListCv_);
    return true;
}

bool EsimFile::RetrieveNotificationParseCompTag(std::shared_ptr<Asn1Node> &root)
{
    std::list<std::shared_ptr<Asn1Node>> ls;
    std::shared_ptr<Asn1Node> compTag = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
    if (compTag == nullptr) {
        TELEPHONY_LOGE("compTag is nullptr");
        return false;
    }
    int32_t metaDataRes = compTag->Asn1GetChildren(TAG_ESIM_SEQUENCE, ls);
    if (metaDataRes != 0) {
        TELEPHONY_LOGE("metaDataTag is zero");
        return false;
    }
    std::shared_ptr<Asn1Node> curNode = nullptr;
    EuiccNotificationList euiccList;
    for (auto it = ls.begin(); it != ls.end(); ++it) {
        curNode = *it;
        EuiccNotification euicc;
        CreateNotification(curNode, euicc);
        euiccList.euiccNotification_.push_back(euicc);
    }
    eUiccNotificationList_ = euiccList;
    return true;
}

bool EsimFile::ProcessRetrieveNotification(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_RETRIEVE_NOTIFICATION_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_RETRIEVE_NOTIFICATIONS_LIST);
    std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);

    subBuilder->Asn1AddChildAsSignedInteger(TAG_ESIM_CTX_0, esimProfile_.seqNumber);
    std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
    builder->Asn1AddChild(subNode);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        TELEPHONY_LOGE("telRilManager_ is nullptr");
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessRetrieveNotificationDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    ResetEuiccNotification();
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(retrieveNotificationMutex_, isRetrieveNotificationReady_,
        retrieveNotificationCv_, MSG_ESIM_RETRIEVE_NOTIFICATION_DONE, isHandleFinish);
    if (isHandleFinish) {
        return retValue;
    }
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    uint32_t byteLen = responseByte.size();
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("root is nullptr");
        NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
        return false;
    }
    if (!RetrieveNotificatioParseTagCtxComp0(root)) {
        TELEPHONY_LOGE("RetrieveNotificatioParseTagCtxComp0 error");
        NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
        return false;
    }
    NotifyReady(retrieveNotificationMutex_, isRetrieveNotificationReady_, retrieveNotificationCv_);
    return true;
}

bool EsimFile::RetrieveNotificatioParseTagCtxComp0(std::shared_ptr<Asn1Node> &root)
{
    std::list<std::shared_ptr<Asn1Node>> nodes;
    std::shared_ptr<Asn1Node> compNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_0);
    if (compNode == nullptr) {
        TELEPHONY_LOGE("compNode is nullptr");
        return false;
    }

    int32_t ret = compNode->Asn1GetChildren(TAG_ESIM_SEQUENCE, nodes);
    if ((ret != TELEPHONY_ERR_SUCCESS) || nodes.empty()) {
        ret = compNode->Asn1GetChildren(TAG_ESIM_PROFILE_INSTALLATION_RESULT, nodes);
        if ((ret != TELEPHONY_ERR_SUCCESS) || nodes.empty()) {
            TELEPHONY_LOGE("Asn1GetChildren error");
            return false;
        }
    }

    EuiccNotification notification;
    std::shared_ptr<Asn1Node> firstNode = nodes.front();
    CreateNotification(firstNode, notification);
    notification_.seq_ = notification.seq_;
    notification_.targetAddr_ = notification.targetAddr_;
    notification_.event_ = notification.event_;
    notification_.data_ = notification.data_;
    return true;
}

bool EsimFile::ProcessRemoveNotification(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_REMOVE_NOTIFICATION)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_REMOVE_NOTIFICATION_FROM_LIST);

    builder->Asn1AddChildAsSignedInteger(TAG_ESIM_CTX_0, esimProfile_.seqNumber);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        TELEPHONY_LOGE("telRilManager is nullptr");
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessRemoveNotificationDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> node = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (node == nullptr) {
        TELEPHONY_LOGE("node is nullptr");
        NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
        return false;
    }
    removeNotifResult_ = node->Asn1AsInteger();
    NotifyReady(removeNotificationMutex_, isRemoveNotificationReady_, removeNotificationCv_);
    return true;
}

int32_t EsimFile::DeleteProfile(const std::u16string &iccId)
{
    delProfile_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.iccId = iccId;

    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_DELETE_PROFILE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        delProfile_ = static_cast<int32_t>(resultFlag);
        return delProfile_;
    }
    AppExecFwk::InnerEvent::Pointer eventDeleteProfile = BuildCallerInfo(MSG_ESIM_DELETE_PROFILE);
    if (!ProcessDeleteProfile(slotId_, eventDeleteProfile)) {
        TELEPHONY_LOGE("ProcessDeleteProfile encode failed");
        SyncCloseChannel(MSG_ESIM_DELETE_PROFILE);
        return delProfile_;
    }
    std::unique_lock<std::mutex> lock(deleteProfileMutex_);
    isDeleteProfileReady_ = false;
    if (!deleteProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isDeleteProfileReady_; })) {
        SyncCloseChannel(MSG_ESIM_DELETE_PROFILE);
        return delProfile_;
    }
    SyncCloseChannel(MSG_ESIM_DELETE_PROFILE);
    return delProfile_;
}

int32_t EsimFile::SwitchToProfile(int32_t portIndex, const std::u16string &iccId, bool forceDisableProfile)
{
    switchResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.portIndex = portIndex;
    esimProfile_.iccId = iccId;
    esimProfile_.forceDisableProfile = forceDisableProfile;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_SWITCH_PROFILE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        switchResult_ = static_cast<int32_t>(resultFlag);
        return switchResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventSwitchToProfile = BuildCallerInfo(MSG_ESIM_SWITCH_PROFILE);
    if (!ProcessSwitchToProfile(slotId_, eventSwitchToProfile)) {
        TELEPHONY_LOGE("ProcessSwitchToProfile encode failed");
        SyncCloseChannel(MSG_ESIM_SWITCH_PROFILE);
        return switchResult_;
    }
    std::unique_lock<std::mutex> lock(switchToProfileMutex_);
    isSwitchToProfileReady_ = false;
    if (!switchToProfileCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isSwitchToProfileReady_; })) {
        SyncCloseChannel(MSG_ESIM_SWITCH_PROFILE);
        return switchResult_;
    }
    SyncCloseChannel(MSG_ESIM_SWITCH_PROFILE);
    return switchResult_;
}

int32_t EsimFile::SetProfileNickname(const std::u16string &iccId, const std::u16string &nickname)
{
    setNicknameResult_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DEFALUT_ERROR);
    esimProfile_.iccId = iccId;
    esimProfile_.nickname = nickname;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_SET_NICK_NAME);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        setNicknameResult_ = static_cast<int32_t>(resultFlag);
        return setNicknameResult_;
    }
    AppExecFwk::InnerEvent::Pointer eventSetNickName = BuildCallerInfo(MSG_ESIM_SET_NICK_NAME);
    if (!ProcessSetNickname(slotId_, eventSetNickName)) {
        TELEPHONY_LOGE("ProcessSetNickname encode failed");
        SyncCloseChannel(MSG_ESIM_SET_NICK_NAME);
        return setNicknameResult_;
    }
    std::unique_lock<std::mutex> lock(setNicknameMutex_);
    isSetNicknameReady_ = false;
    if (!setNicknameCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isSetNicknameReady_; })) {
        SyncCloseChannel(MSG_ESIM_SET_NICK_NAME);
        return setNicknameResult_;
    }
    SyncCloseChannel(MSG_ESIM_SET_NICK_NAME);
    return setNicknameResult_;
}

bool EsimFile::ProcessDeleteProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_DELETE_PROFILE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_DELETE_PROFILE);

    std::vector<uint8_t> iccidBytes;
    std::string strIccId = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
    Asn1Utils::BcdToBytes(strIccId, iccidBytes);
    builder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessSetNickname(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_SET_NICK_NAME)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_SET_NICKNAME);

    std::vector<uint8_t> iccidBytes;
    std::string strIccId = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
    std::string childStr = OHOS::Telephony::ToUtf8(esimProfile_.nickname);
    Asn1Utils::BcdToBytes(strIccId, iccidBytes);

    builder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
    builder->Asn1AddChildAsString(TAG_ESIM_NICKNAME, childStr);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessDeleteProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(deleteProfileMutex_, isDeleteProfileReady_, deleteProfileCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> Asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (Asn1NodeData == nullptr) {
        TELEPHONY_LOGE("pAsn1Node is nullptr");
        NotifyReady(deleteProfileMutex_, isDeleteProfileReady_, deleteProfileCv_);
        return false;
    }
    delProfile_ = Asn1NodeData->Asn1AsInteger();
    NotifyReady(deleteProfileMutex_, isDeleteProfileReady_, deleteProfileCv_);
    return true;
}

bool EsimFile::ProcessSwitchToProfile(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_SWITCH_PROFILE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_ENABLE_PROFILE);
    std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);

    std::vector<uint8_t> iccidBytes;
    std::string strIccId = OHOS::Telephony::ToUtf8(esimProfile_.iccId);
    Asn1Utils::BcdToBytes(strIccId, iccidBytes);
    subBuilder->Asn1AddChildAsBytes(TAG_ESIM_ICCID, iccidBytes, iccidBytes.size());
    std::shared_ptr<Asn1Node> subNode = subBuilder->Asn1Build();
    if (subNode == nullptr) {
        TELEPHONY_LOGE("subNode is nullptr");
        return false;
    }
    builder->Asn1AddChild(subNode);
    bool isSupportEsimMep = OHOS::system::GetBoolParameter(SUPPORT_ESIM_MEP, true);
    if (isSupportEsimMep) {
        bool refreshFlag = OHOS::system::GetBoolParameter("const.ril.sim.esim_mep_refresh_flag", false);
        builder->Asn1AddChildAsBoolean(TAG_ESIM_CTX_1, refreshFlag);
        builder->Asn1AddChildAsInteger(TAG_ESIM_CTX_2, esimProfile_.portIndex);
    } else {
        builder->Asn1AddChildAsBoolean(TAG_ESIM_CTX_1, true);
    }
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessSwitchToProfileDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(switchToProfileMutex_, isSwitchToProfileReady_, switchToProfileCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (asn1NodeData == nullptr) {
        TELEPHONY_LOGE("asn1NodeData is nullptr");
        NotifyReady(switchToProfileMutex_, isSwitchToProfileReady_, switchToProfileCv_);
        return false;
    }
    switchResult_ = asn1NodeData->Asn1AsInteger();
    NotifyReady(switchToProfileMutex_, isSwitchToProfileReady_, switchToProfileCv_);
    return true;
}

bool EsimFile::ProcessSetNicknameDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::shared_ptr<Asn1Node> root = ParseEvent(event);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(setNicknameMutex_, isSetNicknameReady_, setNicknameCv_);
        return false;
    }
    std::shared_ptr<Asn1Node> asn1NodeData = root->Asn1GetChild(TAG_ESIM_CTX_0);
    if (asn1NodeData == nullptr) {
        TELEPHONY_LOGE("asn1NodeData is nullptr");
        NotifyReady(setNicknameMutex_, isSetNicknameReady_, setNicknameCv_);
        return false;
    }
    setNicknameResult_ = asn1NodeData->Asn1AsInteger();
    NotifyReady(setNicknameMutex_, isSetNicknameReady_, setNicknameCv_);
    return true;
}

EuiccInfo2 EsimFile::ObtainEuiccInfo2(int32_t portIndex)
{
    std::unique_lock<std::mutex> lck(currentChannelIdOccupiedMutex_);
    euiccInfo2Result_ = EuiccInfo2();
    esimProfile_.portIndex = portIndex;

    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        euiccInfo2Result_.resultCode_ = static_cast<int32_t>(resultFlag);
        return euiccInfo2Result_;
    }
    AppExecFwk::InnerEvent::Pointer eventEUICCInfo2 = BuildCallerInfo(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE);
    recvCombineStr_ = "";
    if (!ProcessObtainEuiccInfo2(slotId_, eventEUICCInfo2)) {
        TELEPHONY_LOGE("ProcessObtainEuiccInfo2 encode failed");
        SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE);
        euiccInfo2Result_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return euiccInfo2Result_;
    }
    std::unique_lock<std::mutex> lock(euiccInfo2Mutex_);
    isEuiccInfo2Ready_ = false;
    if (!euiccInfo2Cv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isEuiccInfo2Ready_; })) {
        SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE);
        euiccInfo2Result_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_WAIT_TIMEOUT);
        return euiccInfo2Result_;
    }
    SyncCloseChannel(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE);
    return euiccInfo2Result_;
}

ResponseEsimInnerResult EsimFile::AuthenticateServer(const AuthenticateConfigInfo &authenticateConfigInfo)
{
    responseAuthenticateResult_ = ResponseEsimInnerResult();
    esimProfile_.portIndex = authenticateConfigInfo.portIndex_;
    esimProfile_.matchingId = authenticateConfigInfo.matchingId_;
    esimProfile_.serverSigned1 = authenticateConfigInfo.serverSigned1_;
    esimProfile_.serverSignature1 = authenticateConfigInfo.serverSignature1_;
    esimProfile_.euiccCiPkIdToBeUsed = authenticateConfigInfo.euiccCiPkIdToBeUsed_;
    esimProfile_.serverCertificate = authenticateConfigInfo.serverCertificate_;

    std::u16string imei = u"";
    CoreManagerInner::GetInstance().GetImei(SLOT_ID_1, imei);
    esimProfile_.imei = imei;
    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_AUTHENTICATE_SERVER);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        responseAuthenticateResult_.resultCode_ = static_cast<int32_t>(resultFlag);
        return responseAuthenticateResult_;
    }
    recvCombineStr_ = "";
    if (!ProcessAuthenticateServer(slotId_)) {
        TELEPHONY_LOGE("ProcessAuthenticateServer encode failed");
        SyncCloseChannel(MSG_ESIM_AUTHENTICATE_SERVER);
        responseAuthenticateResult_.resultCode_ =
            static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_DATA_PROCESS_ERROR);
        return responseAuthenticateResult_;
    }
    SyncCloseChannel(MSG_ESIM_AUTHENTICATE_SERVER);
    return responseAuthenticateResult_;
}

bool EsimFile::ProcessObtainEuiccInfo2(int32_t slotId, const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_OBTAIN_EUICC_INFO2_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_EUICC_INFO_2);
    std::string hexStr;
    builder->Asn1BuilderToHexStr(hexStr);
    ApduSimIORequestInfo reqInfo;
    CommBuildOneApduReqInfo(reqInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId, reqInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

void EsimFile::ResetEuiccNotification()
{
    notification_.seq_ = 0;
    notification_.targetAddr_ = u"";
    notification_.event_ = 0;
    notification_.data_ = u"";
}

void EsimFile::ConvertAuthInputParaFromApiStru(Es9PlusInitAuthResp &dst, EsimProfile &src)
{
    dst.serverSigned1 = OHOS::Telephony::ToUtf8(src.serverSigned1);
    dst.serverSignature1 = OHOS::Telephony::ToUtf8(src.serverSignature1);
    dst.euiccCiPKIdToBeUsed = OHOS::Telephony::ToUtf8(src.euiccCiPkIdToBeUsed);
    dst.serverCertificate = OHOS::Telephony::ToUtf8(src.serverCertificate);
    dst.matchingId = OHOS::Telephony::ToUtf8(src.matchingId);
    dst.imei = OHOS::Telephony::ToUtf8(src.imei);
}

bool EsimFile::ProcessAuthenticateServer(int32_t slotId)
{
    if (!IsLogicChannelOpen(MSG_ESIM_AUTHENTICATE_SERVER)) {
        return false;
    }
    Es9PlusInitAuthResp authRespData;
    ConvertAuthInputParaFromApiStru(authRespData, esimProfile_);
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_AUTHENTICATE_SERVER);

    Asn1AddChildAsBase64(builder, authRespData.serverSigned1);
    Asn1AddChildAsBase64(builder, authRespData.serverSignature1);
    Asn1AddChildAsBase64(builder, authRespData.euiccCiPKIdToBeUsed);
    Asn1AddChildAsBase64(builder, authRespData.serverCertificate);
    std::shared_ptr<Asn1Builder> ctxParams1Builder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_0);
    AddCtxParams1(ctxParams1Builder, authRespData);
    std::shared_ptr<Asn1Node> ctxNode = ctxParams1Builder->Asn1Build();
    if (ctxNode == nullptr) {
        TELEPHONY_LOGE("ctxNode is nullptr");
        return false;
    }
    builder->Asn1AddChild(ctxNode);
    std::string hexStr;
    builder->Asn1BuilderToHexStr(hexStr);
    RequestApduBuild codec(currentChannelId_);
    codec.BuildStoreData(hexStr);
    SplitSendLongData(codec, MSG_ESIM_AUTHENTICATE_SERVER,
        authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
    return true;
}

void EsimFile::AddDeviceCapability(std::shared_ptr<Asn1Builder> &devCapsBuilder)
{
    std::vector<uint8_t> versionBytes;
    Asn1Utils::UintToBytes(VERSION_NUMBER, versionBytes);
    versionBytes.push_back(0);
    versionBytes.push_back(0);
    devCapsBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_0, versionBytes, versionBytes.size());
    devCapsBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_1, versionBytes, versionBytes.size());
    devCapsBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_5, versionBytes, versionBytes.size());
}

void EsimFile::GetImeiBytes(std::vector<uint8_t> &imeiBytes, const std::string &imei)
{
    size_t imeiLen = imei.length();
    if (imeiLen < AUTH_SERVER_IMEI_LEN * BYTE_TO_HEX_LEN - 1) {
        return;
    }
    if (imeiLen != AUTH_SERVER_IMEI_LEN * BYTE_TO_HEX_LEN) {
        std::string newImei = imei;
        newImei += 'F';
        Asn1Utils::BcdToBytes(newImei, imeiBytes);
        unsigned char last = imeiBytes[LAST_BYTE_OF_IMEI];
        imeiBytes[LAST_BYTE_OF_IMEI] = static_cast<unsigned char>((last & 0xFF) <<
            OFFSET_FOUR_BIT | ((last & 0xFF) >> OFFSET_FOUR_BIT));
    } else {
        Asn1Utils::BcdToBytes(imei, imeiBytes);
    }
}

void EsimFile::AddCtxParams1(std::shared_ptr<Asn1Builder> &ctxParams1Builder, Es9PlusInitAuthResp &authRespData)
{
    if (ctxParams1Builder == nullptr) {
        return;
    }
    ctxParams1Builder->Asn1AddChildAsString(TAG_ESIM_CTX_0, authRespData.matchingId);
    std::shared_ptr<Asn1Node> subNode = nullptr;
    std::vector<uint8_t> tmpBytes;
    std::vector<uint8_t> imeiBytes;
    Asn1Utils::BcdToBytes(authRespData.imei, tmpBytes);
    if (tmpBytes.size() < AUTH_SERVER_TAC_LEN) {
        TELEPHONY_LOGE("tmpBytes.size is small than AUTH_SERVER_TAC_LEN");
        return;
    }
    std::vector<uint8_t> tacBytes(tmpBytes.begin(), tmpBytes.begin() + AUTH_SERVER_TAC_LEN);
    GetImeiBytes(imeiBytes, authRespData.imei);
    std::shared_ptr<Asn1Builder> subBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_1);
    subBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_0, tacBytes, tacBytes.size());
    // add devCap
    std::shared_ptr<Asn1Builder> devCapsBuilder = std::make_shared<Asn1Builder>(TAG_ESIM_CTX_COMP_1);
    AddDeviceCapability(devCapsBuilder);
    std::shared_ptr<Asn1Node> devCapNode = devCapsBuilder->Asn1Build();
    if (devCapNode == nullptr) {
        TELEPHONY_LOGE("devCapNode is nullptr");
        return;
    }
    subBuilder->Asn1AddChild(devCapNode);
    subBuilder->Asn1AddChildAsBytes(TAG_ESIM_CTX_2, imeiBytes, imeiBytes.size());
    subNode = subBuilder->Asn1Build();
    ctxParams1Builder->Asn1AddChild(subNode);
}

bool EsimFile::ProcessObtainEuiccInfo2Done(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_,
        MSG_ESIM_OBTAIN_EUICC_INFO2_DONE, isHandleFinish);
    if (isHandleFinish) {
        return retValue;
    }
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    uint32_t byteLen = responseByte.size();
    std::shared_ptr<Asn1Node> root = Asn1ParseResponse(responseByte, byteLen);
    if (root == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
        return false;
    }
    this->EuiccInfo2ParseProfileVersion(euiccInfo2Result_, root);
    this->EuiccInfo2ParseSvn(euiccInfo2Result_, root);
    this->EuiccInfo2ParseEuiccFirmwareVer(euiccInfo2Result_, root);
    this->EuiccInfo2ParseExtCardResource(euiccInfo2Result_, root);
    this->EuiccInfo2ParseUiccCapability(euiccInfo2Result_, root);
    this->EuiccInfo2ParseTs102241Version(euiccInfo2Result_, root);
    this->EuiccInfo2ParseGlobalPlatformVersion(euiccInfo2Result_, root);
    this->EuiccInfo2ParseRspCapability(euiccInfo2Result_, root);
    this->EuiccInfo2ParseEuiccCiPKIdListForVerification(euiccInfo2Result_, root);
    this->EuiccInfo2ParseEuiccCiPKIdListForSigning(euiccInfo2Result_, root);
    this->EuiccInfo2ParseEuiccCategory(euiccInfo2Result_, root);
    this->EuiccInfo2ParsePpVersion(euiccInfo2Result_, root);
    euiccInfo2Result_.resultCode_ = static_cast<int32_t>(ResultInnerCode::RESULT_EUICC_CARD_OK);
    euiccInfo2Result_.response_ = newRecvData_.resultData;
    NotifyReady(euiccInfo2Mutex_, isEuiccInfo2Ready_, euiccInfo2Cv_);
    return true;
}

void EsimFile::EuiccInfo2ParseProfileVersion(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> profileVerNode = root->Asn1GetChild(TAG_ESIM_CTX_1);
    if (profileVerNode == nullptr) {
        TELEPHONY_LOGE("profileVerNode is nullptr");
        return;
    }
    std::vector<uint8_t> profileVersionRaw = {};
    uint32_t profileVersionRawLen = profileVerNode->Asn1AsBytes(profileVersionRaw);
    if (profileVersionRawLen < EUICC_INFO_VERSION_MIN_LENGTH) {
        TELEPHONY_LOGE("invalid profileVersion data");
        return;
    }
    euiccInfo2.profileVersion_ = MakeVersionString(profileVersionRaw);
}

void EsimFile::EuiccInfo2ParseSvn(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> svnNode = root->Asn1GetChild(TAG_ESIM_CTX_2);
    if (svnNode == nullptr) {
        TELEPHONY_LOGE("svnNode is nullptr");
        return;
    }
    std::vector<uint8_t> svnRaw = {};
    uint32_t svnRawLen = svnNode->Asn1AsBytes(svnRaw);
    if (svnRawLen < EUICC_INFO_VERSION_MIN_LENGTH) {
        TELEPHONY_LOGE("invalid SVN data");
        return;
    }
    euiccInfo2.svn_ = MakeVersionString(svnRaw);
}

void EsimFile::EuiccInfo2ParseEuiccFirmwareVer(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> euiccFirmwareVerNode = root->Asn1GetChild(TAG_ESIM_CTX_3);
    if (euiccFirmwareVerNode == nullptr) {
        TELEPHONY_LOGE("euiccFirmwareVerNode is nullptr");
        return;
    }
    std::vector<uint8_t> euiccFirmwareVerRaw = {};
    uint32_t versionLen = euiccFirmwareVerNode->Asn1AsBytes(euiccFirmwareVerRaw);
    if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
        TELEPHONY_LOGE("invalid firmwareVer data");
        return;
    }
    euiccInfo2.firmwareVer_ = MakeVersionString(euiccFirmwareVerRaw);
}

void EsimFile::EuiccInfo2ParseExtCardResource(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> extCardResourceNode = root->Asn1GetChild(TAG_ESIM_CTX_4);
    if (extCardResourceNode == nullptr) {
        TELEPHONY_LOGE("extCardResourceNode is nullptr");
        return;
    }
    extCardResourceNode->Asn1AsString(euiccInfo2.extCardResource_);
}

void EsimFile::EuiccInfo2ParseUiccCapability(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> uiccCapabilityNode = root->Asn1GetChild(TAG_ESIM_CTX_5);
    if (uiccCapabilityNode == nullptr) {
        TELEPHONY_LOGE("uiccCapabilityNode is nullptr");
        return;
    }
    uiccCapabilityNode->Asn1AsString(euiccInfo2.uiccCapability_);
}

void EsimFile::EuiccInfo2ParseTs102241Version(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> ts102241VersionNode = root->Asn1GetChild(TAG_ESIM_CTX_6);
    if (ts102241VersionNode == nullptr) {
        TELEPHONY_LOGE("ts102241VersionNode is nullptr");
        return;
    }
    std::vector<uint8_t> ts102241VersionRaw = {};
    uint32_t versionLen = ts102241VersionNode->Asn1AsBytes(ts102241VersionRaw);
    if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
        TELEPHONY_LOGE("invalid ts102241VersionNode data");
        return;
    }
    euiccInfo2.ts102241Version_ = MakeVersionString(ts102241VersionRaw);
}

void EsimFile::EuiccInfo2ParseGlobalPlatformVersion(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> globalPlatformVersionNode = root->Asn1GetChild(TAG_ESIM_CTX_7);
    if (globalPlatformVersionNode == nullptr) {
        TELEPHONY_LOGE("globalPlatformVersionNode is nullptr");
        return;
    }
    std::vector<uint8_t> globalPlatformVersionRaw = {};
    uint32_t versionLen = globalPlatformVersionNode->Asn1AsBytes(globalPlatformVersionRaw);
    if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
        TELEPHONY_LOGE("invalid globalplatformVersionRaw data");
        return;
    }
    euiccInfo2.globalPlatformVersion_ = MakeVersionString(globalPlatformVersionRaw);
}

void EsimFile::EuiccInfo2ParseRspCapability(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> rspCapabilityNode = root->Asn1GetChild(TAG_ESIM_CTX_8);
    if (rspCapabilityNode == nullptr) {
        TELEPHONY_LOGE("rspCapabilityNode is nullptr");
        return;
    }
    rspCapabilityNode->Asn1AsString(euiccInfo2.rspCapability_);
}

void EsimFile::EuiccInfo2ParseEuiccCiPKIdListForVerification(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> ciPKIdListForVerificationNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_9);
    if (ciPKIdListForVerificationNode == nullptr) {
        TELEPHONY_LOGE("ciPKIdListForVerificationNode is nullptr");
        return;
    }
    ciPKIdListForVerificationNode->Asn1NodeToHexStr(euiccInfo2.euiccCiPKIdListForVerification_);
}

void EsimFile::EuiccInfo2ParseEuiccCiPKIdListForSigning(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> euiccCiPKIdListForSigningNode = root->Asn1GetChild(TAG_ESIM_CTX_COMP_A);
    if (euiccCiPKIdListForSigningNode == nullptr) {
        TELEPHONY_LOGE("euiccCiPKIdListForSigningNode is nullptr");
        return;
    }
    euiccCiPKIdListForSigningNode->Asn1NodeToHexStr(euiccInfo2.euiccCiPKIdListForSigning_);
}

void EsimFile::EuiccInfo2ParseEuiccCategory(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> euiccCategoryNode = root->Asn1GetChild(TAG_ESIM_CTX_B);
    if (euiccCategoryNode == nullptr) {
        TELEPHONY_LOGE("euiccCategoryNode is nullptr");
        return;
    }
    euiccInfo2.euiccCategory_ = euiccCategoryNode->Asn1AsInteger();
}

void EsimFile::EuiccInfo2ParsePpVersion(EuiccInfo2 &euiccInfo2, std::shared_ptr<Asn1Node> &root)
{
    std::shared_ptr<Asn1Node> ppVersionNode = root->Asn1GetChild(TAG_ESIM_OCTET_STRING_TYPE);
    if (ppVersionNode == nullptr) {
        TELEPHONY_LOGE("ppVersionNode is nullptr");
        return;
    }
    std::vector<uint8_t> ppVersionNodeRaw = {};
    uint32_t versionLen = ppVersionNode->Asn1AsBytes(ppVersionNodeRaw);
    if (versionLen < EUICC_INFO_VERSION_MIN_LENGTH) {
        TELEPHONY_LOGE("invalid ppVersion data");
        return;
    }
    euiccInfo2.ppVersion_ = MakeVersionString(ppVersionNodeRaw);
}

bool EsimFile::RealProcessAuthenticateServerDone()
{
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(recvCombineStr_);
    std::shared_ptr<Asn1Node> responseNode = Asn1ParseResponse(responseByte, responseByte.size());
    if (responseNode == nullptr) {
        TELEPHONY_LOGE("Asn1ParseResponse failed");
        NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
        return false;
    }
    AuthServerResponse authServerResp = { 0 };
    if (responseNode->Asn1HasChild(TAG_ESIM_CTX_COMP_1)) {
        std::shared_ptr<Asn1Node> authServerRespNode = responseNode->Asn1GetChild(TAG_ESIM_CTX_COMP_1);
        if (authServerRespNode == nullptr) {
            TELEPHONY_LOGE("authServerRespNode is nullptr");
            NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
            return false;
        }
        if (authServerRespNode->Asn1HasChild(TAG_ESIM_CTX_0) &&
            authServerRespNode->Asn1HasChild(TAG_ESIM_INTEGER_TYPE)) {
            std::shared_ptr<Asn1Node> transactionIdNode = authServerRespNode->Asn1GetChild(TAG_ESIM_CTX_0);
            std::shared_ptr<Asn1Node> errCodeNode = authServerRespNode->Asn1GetChild(TAG_ESIM_INTEGER_TYPE);
            if (transactionIdNode == nullptr || errCodeNode == nullptr) {
                TELEPHONY_LOGE("authServerRespNode failed");
                NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
                return false;
            }
            uint32_t tidByteLen = transactionIdNode->Asn1AsString(authServerResp.transactionId);
            if (tidByteLen == 0) {
                TELEPHONY_LOGE("tidByteLen is zero.");
                NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
                return false;
            }
            authServerResp.errCode = errCodeNode->Asn1AsInteger();
        } else {
            TELEPHONY_LOGE("the auth server response has no right child");
            NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
            return false;
        }
    } else {
        authServerResp.respStr = responseByte;
        authServerResp.respLength = responseByte.size();
    }
    CovertAuthToApiStruct(responseAuthenticateResult_, authServerResp);
    NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
    return true;
}

bool EsimFile::ProcessAuthenticateServerDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        NotifyReady(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(authenticateServerMutex_, isAuthenticateServerReady_, authenticateServerCv_,
        MSG_ESIM_AUTHENTICATE_SERVER, isHandleFinish);
    if (isHandleFinish) {
        return retValue;
    }
    return RealProcessAuthenticateServerDone();
}

void EsimFile::CovertAuthToApiStruct(ResponseEsimInnerResult &dst, AuthServerResponse &src)
{
    dst.resultCode_ = src.errCode;
    std::string hexStr = Asn1Utils::BytesToHexStr(src.respStr);
    dst.response_ = OHOS::Telephony::ToUtf16(hexStr);
}

void EsimFile::NotifyReady(std::mutex &mtx, bool &flag, std::condition_variable &cv)
{
    std::lock_guard<std::mutex> lock(mtx);
    flag = true;
    cv.notify_all();
}

std::shared_ptr<Asn1Node> EsimFile::GetKeyValueSequenceNode(
    uint32_t kTag, const std::string &key, uint32_t vTag, std::string &value)
{
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_SEQUENCE);
    builder->Asn1AddChildAsString(kTag, key);
    if (vTag == TAG_ESIM_OCTET_STRING_TYPE) {
        std::vector<uint8_t> valueVec = Asn1Utils::HexStrToBytes(value);
        builder->Asn1AddChildAsBytes(vTag, valueVec, valueVec.size());
    } else {
        builder->Asn1AddChildAsString(vTag, value);
    }
    return builder->Asn1Build();
}

std::shared_ptr<Asn1Node> EsimFile::GetMapMetaDataNode()
{
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_SEQUENCE);
    // add imei node
    std::string imeiStr = OHOS::Telephony::ToUtf8(getContractInfoRequest_.mapMetaData.imei);
    std::shared_ptr<Asn1Node> imeiNode = GetKeyValueSequenceNode(
        TAG_ESIM_TARGET_ADDR, KEY_IMEI, TAG_ESIM_TARGET_ADDR, imeiStr);
    builder->Asn1AddChild(imeiNode);
    // add imei2 node
    std::string imei2Str = OHOS::Telephony::ToUtf8(getContractInfoRequest_.mapMetaData.imei2);
    std::shared_ptr<Asn1Node> imei2Node = GetKeyValueSequenceNode(
        TAG_ESIM_TARGET_ADDR, KEY_IMEI2, TAG_ESIM_TARGET_ADDR, imei2Str);
    builder->Asn1AddChild(imei2Node);
    // add nonce node
    std::string nonceStr = OHOS::Telephony::ToUtf8(getContractInfoRequest_.mapMetaData.nonce);
    std::shared_ptr<Asn1Node> nonceNode = GetKeyValueSequenceNode(
        TAG_ESIM_TARGET_ADDR, KEY_NONCE, TAG_ESIM_OCTET_STRING_TYPE, nonceStr);
    builder->Asn1AddChild(nonceNode);
    // add timestamp node
    std::string timestampStr = OHOS::Telephony::ToUtf8(getContractInfoRequest_.mapMetaData.timestamp);
    std::shared_ptr<Asn1Node> timestampNode = GetKeyValueSequenceNode(
        TAG_ESIM_TARGET_ADDR, KEY_TIMESTAMP, TAG_ESIM_TARGET_ADDR, timestampStr);
    builder->Asn1AddChild(timestampNode);
    return builder->Asn1Build();
}

bool EsimFile::ProcessGetContractInfo(const AppExecFwk::InnerEvent::Pointer &responseEvent)
{
    if (!IsLogicChannelOpen(MSG_ESIM_GET_CONTRACT_INFO_DONE)) {
        return false;
    }
    std::shared_ptr<Asn1Builder> builder = std::make_shared<Asn1Builder>(TAG_ESIM_GET_CONTRACT_INFO);
    // euiccCiPkidToBeUsed
    std::string pkidStr = OHOS::Telephony::ToUtf8(getContractInfoRequest_.euiccCiPkidToBeUsed);
    std::vector<uint8_t> pkidVec = Asn1Utils::HexStrToBytes(pkidStr);
    builder->Asn1AddChildAsBytes(TAG_ESIM_OCTET_STRING_TYPE, pkidVec, pkidVec.size());
    // mapMetaData
    std::shared_ptr<Asn1Node> mapMetaDataNode = GetMapMetaDataNode();
    if (mapMetaDataNode == nullptr) {
        TELEPHONY_LOGE("mapMetaDataNode is nullptr");
        return false;
    }
    builder->Asn1AddChild(mapMetaDataNode);
    // publicKey
    std::string publicKeyStr = OHOS::Telephony::ToUtf8(getContractInfoRequest_.ePkPosHpke);
    std::vector<uint8_t> publicKeyVec = Asn1Utils::HexStrToBytes(publicKeyStr);
    builder->Asn1AddChildAsBytes(TAG_ESIM_OCTET_STRING_TYPE, publicKeyVec, publicKeyVec.size());

    ApduSimIORequestInfo requestInfo;
    CommBuildOneApduReqInfo(requestInfo, builder);
    if (telRilManager_ == nullptr) {
        return false;
    }
    int32_t apduResult = telRilManager_->SimTransmitApduLogicalChannel(slotId_, requestInfo, responseEvent);
    if (apduResult == TELEPHONY_ERR_FAIL) {
        return false;
    }
    return true;
}

bool EsimFile::ProcessGetContractInfoDone(const AppExecFwk::InnerEvent::Pointer &event)
{
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("receive message is nullptr");
        NotifyReady(getContractInfoMutex_, isGetContractInfoReady_, getContractInfoCv_);
        return false;
    }
    newRecvData_ = rcvMsg->fileData;
    bool isHandleFinish = false;
    bool retValue = CommMergeRecvData(getContractInfoMutex_, isGetContractInfoReady_, getContractInfoCv_,
        MSG_ESIM_GET_CONTRACT_INFO_DONE, isHandleFinish);
    if (isHandleFinish) {
        TELEPHONY_LOGI("waits for continuing data...");
        return retValue;
    }

    TELEPHONY_LOGI("recv contract info len: %{public}lu", recvCombineStr_.length());
    if (recvCombineStr_.length() <= CONTRACT_INFO_CONTENT_IDX) {
        TELEPHONY_LOGE("recv message len illegal");
        NotifyReady(getContractInfoMutex_, isGetContractInfoReady_, getContractInfoCv_);
        return false;
    }
    getContractInfoResult_ = recvCombineStr_.substr(CONTRACT_INFO_CONTENT_IDX);
    NotifyReady(getContractInfoMutex_, isGetContractInfoReady_, getContractInfoCv_);
    return true;
}

std::string EsimFile::GetContractInfo(const GetContractInfoRequest &getContractInfoRequest)
{
    getContractInfoResult_ = "";
    getContractInfoRequest_.euiccCiPkidToBeUsed = getContractInfoRequest.euiccCiPkidToBeUsed;
    getContractInfoRequest_.mapMetaData = getContractInfoRequest.mapMetaData;
    getContractInfoRequest_.ePkPosHpke = getContractInfoRequest.ePkPosHpke;

    ResultInnerCode resultFlag = ObtainChannelSuccessExclusive(MSG_ESIM_GET_CONTRACT_INFO_DONE);
    if (resultFlag != ResultInnerCode::RESULT_EUICC_CARD_OK) {
        TELEPHONY_LOGE("ObtainChannelSuccessExclusive failed ,%{public}d", resultFlag);
        return getContractInfoResult_;
    }

    recvCombineStr_ = "";
    AppExecFwk::InnerEvent::Pointer eventGetContractInfo = BuildCallerInfo(MSG_ESIM_GET_CONTRACT_INFO_DONE);
    if (!ProcessGetContractInfo(eventGetContractInfo)) {
        TELEPHONY_LOGE("GetContractInfo failed");
        SyncCloseChannel(MSG_ESIM_GET_CONTRACT_INFO_DONE);
        return getContractInfoResult_;
    }
    std::unique_lock<std::mutex> lock(getContractInfoMutex_);
    isGetContractInfoReady_ = false;
    if (!getContractInfoCv_.wait_for(lock, std::chrono::seconds(WAIT_TIME_LONG_SECOND_FOR_ESIM),
        [this]() { return isGetContractInfoReady_; })) {
        SyncCloseChannel(MSG_ESIM_GET_CONTRACT_INFO_DONE);
        return getContractInfoResult_;
    }
    SyncCloseChannel(MSG_ESIM_GET_CONTRACT_INFO_DONE);
    return getContractInfoResult_;
}

bool EsimFile::CommMergeRecvData(
    std::mutex &mtx, bool &flag, std::condition_variable &cv, int32_t eventId, bool &isHandleFinish)
{
    uint32_t mergeResult = MergeRecvLongDataComplete(newRecvData_, eventId);
    if (mergeResult == RESPONS_DATA_ERROR) {
        NotifyReady(mtx, flag, cv);
        isHandleFinish = true;
        return false;
    }
    if ((mergeResult == RESPONS_DATA_FINISH) && (newRecvData_.resultData.length() == 0)) {
        NotifyReady(mtx, flag, cv);
        isHandleFinish = true;
        return true;
    }
    if (mergeResult == RESPONS_DATA_NOT_FINISH) {
        isHandleFinish = true;
        return true;
    }
    isHandleFinish = false;
    return false;
}

void EsimFile::InitChanneMemberFunc()
{
    memberFuncMap_[MSG_ESIM_OPEN_CHANNEL_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEsimOpenChannelDone(event); };
    memberFuncMap_[MSG_ESIM_CLOSE_CHANNEL_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEsimCloseChannelDone(event); };
    memberFuncMap_[MSG_ESIM_SEND_APUD_DATA] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessSendApduDataDone(event); };
    memberFuncMap_[MSG_ESIM_CLOSE_SPARE_CHANNEL_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEsimCloseSpareChannelDone(event); };
}

void EsimFile::InitMemberFunc()
{
    memberFuncMap_[MSG_ESIM_OBTAIN_EID_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEidDone(event); };
    memberFuncMap_[MSG_ESIM_OBTAIN_EUICC_INFO_1_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEuiccInfo1Done(event); };
    memberFuncMap_[MSG_ESIM_REQUEST_ALL_PROFILES] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRequestAllProfilesDone(event); };
    memberFuncMap_[MSG_ESIM_OBTAIN_EUICC_CHALLENGE_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEuiccChallengeDone(event); };
    memberFuncMap_[MSG_ESIM_REQUEST_RULES_AUTH_TABLE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRequestRulesAuthTableDone(event); };
    memberFuncMap_[MSG_ESIM_OBTAIN_SMDS_ADDRESS] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainSmdsAddressDone(event); };
    memberFuncMap_[MSG_ESIM_DISABLE_PROFILE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessDisableProfileDone(event); };
    memberFuncMap_[MSG_ESIM_OBTAIN_DEFAULT_SMDP_ADDRESS_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainDefaultSmdpAddressDone(event); };
    memberFuncMap_[MSG_ESIM_CANCEL_SESSION] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessCancelSessionDone(event); };
    memberFuncMap_[MSG_ESIM_GET_PROFILE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessGetProfileDone(event); };
    memberFuncMap_[MSG_ESIM_ESTABLISH_DEFAULT_SMDP_ADDRESS_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessEstablishDefaultSmdpAddressDone(event); };
    memberFuncMap_[MSG_ESIM_RESET_MEMORY] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessResetMemoryDone(event); };
    memberFuncMap_[MSG_ESIM_LIST_NOTIFICATION] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessListNotificationsDone(event); };
    memberFuncMap_[MSG_ESIM_LOAD_BOUND_PROFILE_PACKAGE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessLoadBoundProfilePackageDone(event); };
    memberFuncMap_[MSG_ESIM_PREPARE_DOWNLOAD_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessPrepareDownloadDone(event); };
    memberFuncMap_[MSG_ESIM_REMOVE_NOTIFICATION] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRemoveNotificationDone(event); };
    memberFuncMap_[MSG_ESIM_RETRIEVE_NOTIFICATION_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRetrieveNotificationDone(event); };
    memberFuncMap_[MSG_ESIM_RETRIEVE_NOTIFICATION_LIST] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessRetrieveNotificationListDone(event); };
    memberFuncMap_[MSG_ESIM_DELETE_PROFILE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessDeleteProfileDone(event); };
    memberFuncMap_[MSG_ESIM_SWITCH_PROFILE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessSwitchToProfileDone(event); };
    memberFuncMap_[MSG_ESIM_SET_NICK_NAME] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessSetNicknameDone(event); };
    memberFuncMap_[MSG_ESIM_OBTAIN_EUICC_INFO2_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessObtainEuiccInfo2Done(event); };
    memberFuncMap_[MSG_ESIM_AUTHENTICATE_SERVER] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessAuthenticateServerDone(event); };
    memberFuncMap_[MSG_ESIM_GET_CONTRACT_INFO_DONE] =
        [this](const AppExecFwk::InnerEvent::Pointer &event) { return ProcessGetContractInfoDone(event); };
}

void EsimFile::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr");
        return;
    }
    auto id = event->GetInnerEventId();
    auto itFunc = memberFuncMap_.find(id);
    if (itFunc != memberFuncMap_.end()) {
        auto memberFunc = itFunc->second;
        if (memberFunc != nullptr) {
            memberFunc(event);
            return;
        }
    }
}

bool EsimFile::GetRawDataFromEvent(const AppExecFwk::InnerEvent::Pointer &event, IccFileData &outRawData)
{
    if (event == nullptr) {
        TELEPHONY_LOGE("event is nullptr!");
        return false;
    }
    std::unique_ptr<IccFromRilMsg> rcvMsg = event->GetUniqueObject<IccFromRilMsg>();
    if (rcvMsg == nullptr) {
        TELEPHONY_LOGE("rcvMsg is nullptr");
        return false;
    }
    outRawData = rcvMsg->fileData;
    return true;
}

std::shared_ptr<Asn1Node> EsimFile::ParseEvent(const AppExecFwk::InnerEvent::Pointer &event)
{
    IccFileData rawData;
    if (!GetRawDataFromEvent(event, rawData)) {
        TELEPHONY_LOGE("rawData is nullptr within rcvMsg");
        return nullptr;
    }
    TELEPHONY_LOGI("input raw data:sw1=%{public}02X, sw2=%{public}02X, length=%{public}zu",
        rawData.sw1, rawData.sw2, rawData.resultData.length());
    std::vector<uint8_t> responseByte = Asn1Utils::HexStrToBytes(rawData.resultData);
    uint32_t byteLen = responseByte.size();
    return Asn1ParseResponse(responseByte, byteLen);
}

bool EsimFile::IsSameAid(const std::u16string &aid)
{
    std::lock_guard<std::mutex> lock(occupyChannelMutex_);
    if (aidStr_ == aid) {
        return true;
    } else {
        return false;
    }
}

bool EsimFile::IsValidAidForAllowSameAidReuseChannel(const std::u16string &aid)
{
    if (aidStr_ != aid && !aidStr_.empty()) {
        return false;
    } else {
        return true;
    }
}
} // namespace Telephony
} // namespace OHOS