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