1 /*
2  * Copyright (C) 2021 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 "icc_dialling_numbers_handler.h"
17 
18 using namespace std;
19 using namespace OHOS::AppExecFwk;
20 
21 namespace OHOS {
22 namespace Telephony {
23 std::atomic_int IccDiallingNumbersHandler::nextSerialId_(1);
24 std::unordered_map<int, std::shared_ptr<DiallingNumberLoadRequest>> IccDiallingNumbersHandler::requestMap_;
25 static std::mutex requestLock_;
26 
IccDiallingNumbersHandler(std::shared_ptr<IccFileController> fh)27 IccDiallingNumbersHandler::IccDiallingNumbersHandler(std::shared_ptr<IccFileController> fh)
28     : TelEventHandler("IccDiallingNumbersHandler"), fileController_(fh)
29 {
30     InitFuncMap();
31 }
32 
CreateLoadRequest(int fileId,int exId,int indexNum,const std::string & pin2Str,const AppExecFwk::InnerEvent::Pointer & result)33 std::shared_ptr<DiallingNumberLoadRequest> IccDiallingNumbersHandler::CreateLoadRequest(
34     int fileId, int exId, int indexNum, const std::string &pin2Str, const AppExecFwk::InnerEvent::Pointer &result)
35 {
36     std::lock_guard<std::mutex> lock(requestLock_);
37     std::shared_ptr<DiallingNumberLoadRequest> loadRequest =
38         std::make_shared<DiallingNumberLoadRequest>(GetNextSerialId(), fileId, exId, indexNum, pin2Str, result);
39     if (loadRequest == nullptr) {
40         TELEPHONY_LOGE("IccDiallingNumbersHandler loadRequest is nullptr");
41         return nullptr;
42     }
43     IccDiallingNumbersHandler::requestMap_.insert(std::make_pair(loadRequest->GetLoadId(), loadRequest));
44     return loadRequest;
45 }
46 
GetFilePath(int elementaryFileId)47 std::string IccDiallingNumbersHandler::GetFilePath(int elementaryFileId)
48 {
49     // GSM SIM file path from TS 51.011
50     std::string mf = MASTER_FILE_SIM;
51     mf.append(DEDICATED_FILE_TELECOM);
52     return elementaryFileId == ELEMENTARY_FILE_ADN ? mf : "";
53 }
54 
GetDiallingNumbers(int ef,int exid,int index,AppExecFwk::InnerEvent::Pointer & response)55 void IccDiallingNumbersHandler::GetDiallingNumbers(
56     int ef, int exid, int index, AppExecFwk::InnerEvent::Pointer &response)
57 {
58     if (fileController_ == nullptr) {
59         TELEPHONY_LOGE("fileController_ is null pointer");
60         return;
61     }
62     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = CreateLoadRequest(ef, exid, index, "", response);
63     if (loadRequest == nullptr) {
64         TELEPHONY_LOGE("loadRequest is null pointer");
65         return;
66     }
67     AppExecFwk::InnerEvent::Pointer ptDiallingNumberRead =
68         BuildCallerInfo(MSG_SIM_OBTAIN_ADN_DONE, loadRequest->GetLoadId());
69     fileController_->ObtainLinearFixedFile(ef, GetFilePath(ef), index, ptDiallingNumberRead);
70 }
71 
GetAllDiallingNumbers(int ef,int exid,AppExecFwk::InnerEvent::Pointer & response)72 void IccDiallingNumbersHandler::GetAllDiallingNumbers(int ef, int exid, AppExecFwk::InnerEvent::Pointer &response)
73 {
74     if (fileController_ == nullptr) {
75         TELEPHONY_LOGE("fileController_ is null pointer");
76         return;
77     }
78     TELEPHONY_LOGI("IccDiallingNumbersHandler::GetAllDiallingNumbers start");
79     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = CreateLoadRequest(ef, exid, 0, "", response);
80     if (loadRequest == nullptr) {
81         TELEPHONY_LOGE("loadRequest is null pointer");
82         return;
83     }
84     AppExecFwk::InnerEvent::Pointer ptDiallingNumberReadAll =
85         BuildCallerInfo(MSG_SIM_OBTAIN_ALL_ADN_DONE, loadRequest->GetLoadId());
86     fileController_->ObtainAllLinearFixedFile(ef, GetFilePath(ef), ptDiallingNumberReadAll);
87 }
88 
UpdateDiallingNumbers(const DiallingNumberUpdateInfor & infor,AppExecFwk::InnerEvent::Pointer & response)89 void IccDiallingNumbersHandler::UpdateDiallingNumbers(
90     const DiallingNumberUpdateInfor &infor, AppExecFwk::InnerEvent::Pointer &response)
91 {
92     if (fileController_ == nullptr) {
93         TELEPHONY_LOGE("fileController_ is null pointer");
94         return;
95     }
96     std::shared_ptr<DiallingNumberLoadRequest> loadRequest =
97         CreateLoadRequest(infor.fileId, infor.extFile, infor.index, infor.pin2, response);
98     if (loadRequest == nullptr) {
99         TELEPHONY_LOGE("loadRequest is null pointer");
100         return;
101     }
102     loadRequest->SetIsDelete(infor.isDel);
103     TELEPHONY_LOGI("UpdateDiallingNumbers contents ready");
104     std::shared_ptr<void> diallingNumberObj = static_cast<std::shared_ptr<void>>(infor.diallingNumber);
105     AppExecFwk::InnerEvent::Pointer linearFileSize =
106         BuildCallerInfo(MSG_SIM_OBTAIN_LINEAR_FILE_SIZE_DONE, diallingNumberObj, loadRequest->GetLoadId());
107     fileController_->ObtainLinearFileSize(infor.fileId, GetFilePath(infor.fileId), linearFileSize);
108 }
109 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)110 void IccDiallingNumbersHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
111 {
112     if (event == nullptr) {
113         TELEPHONY_LOGE("event is nullptr!");
114         return;
115     }
116     auto id = event->GetInnerEventId();
117     int loadId = 0;
118     TELEPHONY_LOGD("IccDiallingNumbersHandler::ProcessEvent id %{public}d", id);
119     auto itFunc = memberFuncMap_.find(id);
120     if (itFunc != memberFuncMap_.end()) {
121         auto memberFunc = itFunc->second;
122         if (memberFunc != nullptr) {
123             memberFunc(event, loadId);
124             SendBackResult(loadId);
125         }
126     } else {
127         TELEPHONY_LOGI("IccDiallingNumbersHandler::ProcessEvent unknown id %{public}d", id);
128     }
129 }
130 
ProcessLinearSizeDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)131 void IccDiallingNumbersHandler::ProcessLinearSizeDone(const AppExecFwk::InnerEvent::Pointer &event, int &id)
132 {
133     if (event == nullptr) {
134         TELEPHONY_LOGE("event is nullptr!");
135         return;
136     }
137     std::unique_ptr<ControllerToFileMsg> fdError = event->GetUniqueObject<ControllerToFileMsg>();
138     int loadId = 0;
139     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = nullptr;
140     if (fdError != nullptr) {
141         loadId = fdError->arg1;
142         id = loadId;
143         loadRequest = FindLoadRequest(loadId);
144         if (loadRequest != nullptr) {
145             loadRequest->SetException(fdError->exception);
146         }
147         TELEPHONY_LOGE("ProcessLinearSizeDone error occured");
148         return;
149     }
150     std::shared_ptr<EfLinearResult> object = event->GetSharedObject<EfLinearResult>();
151     if (object == nullptr) {
152         TELEPHONY_LOGE("object is nullptr!");
153         return;
154     }
155     std::shared_ptr<DiallingNumbersInfo> diallingNumberLoad = nullptr;
156     loadId = object->arg1;
157     id = loadId;
158     loadRequest = FindLoadRequest(loadId);
159     if (loadRequest == nullptr) {
160         TELEPHONY_LOGE("loadRequest is nullptr!");
161         return;
162     }
163     if (object->exception == nullptr) {
164         std::shared_ptr<void> baseLoad = object->iccLoader;
165         int *dataSize = object->valueData;
166         if (baseLoad != nullptr) {
167             diallingNumberLoad = std::static_pointer_cast<DiallingNumbersInfo>(baseLoad);
168         }
169         if (!FormatNameAndNumber(diallingNumberLoad, loadRequest->GetIsDelete())) {
170             loadRequest->SetException(static_cast<std::shared_ptr<void>>(MakeExceptionResult(PARAMETER_INCORRECT)));
171             return;
172         }
173         SendUpdateCommand(diallingNumberLoad, dataSize[0], loadRequest, loadId);
174     }
175 }
176 
ProcessUpdateRecordDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)177 void IccDiallingNumbersHandler::ProcessUpdateRecordDone(const AppExecFwk::InnerEvent::Pointer &event, int &id)
178 {
179     if (event == nullptr) {
180         TELEPHONY_LOGE("event is nullptr!");
181         return;
182     }
183     std::unique_ptr<ControllerToFileMsg> object = event->GetUniqueObject<ControllerToFileMsg>();
184     if (object == nullptr) {
185         TELEPHONY_LOGE("object is nullptr!");
186         return;
187     }
188     int loadId = object->arg1;
189     id = loadId;
190     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
191     if (loadRequest != nullptr) {
192         loadRequest->ClearCount();
193         loadRequest->SetException(object->exception);
194         if (loadRequest->GetException() == nullptr) {
195             loadRequest->SetResult(object->iccLoader);
196         }
197     }
198 }
199 
ProcessDiallingNumberAllLoadDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)200 void IccDiallingNumbersHandler::ProcessDiallingNumberAllLoadDone(
201     const AppExecFwk::InnerEvent::Pointer &event, int &id)
202 {
203     if (event == nullptr) {
204         TELEPHONY_LOGE("event is nullptr!");
205         return;
206     }
207     std::unique_ptr<ControllerToFileMsg> fdError = event->GetUniqueObject<ControllerToFileMsg>();
208     int loadId = 0;
209     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = nullptr;
210     if (fdError != nullptr) {
211         loadId = fdError->arg1;
212         id = loadId;
213         loadRequest = FindLoadRequest(loadId);
214         if (loadRequest != nullptr) {
215             loadRequest->SetException(fdError->exception);
216         }
217         TELEPHONY_LOGE("ProcessDiallingNumberAllLoadDone error occured");
218         return;
219     }
220 
221     std::shared_ptr<MultiRecordResult> object = event->GetSharedObject<MultiRecordResult>();
222     if (object == nullptr) {
223         TELEPHONY_LOGE("object is nullptr!");
224         return;
225     }
226     loadId = object->arg1;
227     id = loadId;
228     loadRequest = FindLoadRequest(loadId);
229     if (object->exception != nullptr) {
230         TELEPHONY_LOGE("ProcessDiallingNumberAllLoadDone load failed");
231         if (loadRequest != nullptr) {
232             loadRequest->SetException(object->exception);
233         }
234         return;
235     }
236 
237     ProcessDiallingNumber(loadRequest, object);
238 }
239 
ProcessDiallingNumber(const std::shared_ptr<DiallingNumberLoadRequest> & loadRequest,const std::shared_ptr<MultiRecordResult> & object)240 void IccDiallingNumbersHandler::ProcessDiallingNumber(
241     const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest, const std::shared_ptr<MultiRecordResult> &object)
242 {
243     if (loadRequest == nullptr || object == nullptr) {
244         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessDiallingNumber loadRequest or object is nullptr");
245         return;
246     }
247     loadRequest->ClearCount();
248     std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
249         std::make_shared<std::vector<std::shared_ptr<DiallingNumbersInfo>>>();
250     loadRequest->SetResult(static_cast<std::shared_ptr<void>>(diallingNumberList));
251 
252     std::vector<std::string> &dataList = object->fileResults;
253     TELEPHONY_LOGI("ProcessDiallingNumberAllLoadDone start: %{public}zu", dataList.size());
254     int i = 0;
255     for (std::vector<std::string>::iterator it = dataList.begin(); it != dataList.end(); ++it, i++) {
256         std::string item = *it;
257         std::shared_ptr<DiallingNumbersInfo> diallingNumber =
258             std::make_shared<DiallingNumbersInfo>(loadRequest->GetElementaryFileId(), 1 + i);
259         FetchDiallingNumberContent(diallingNumber, item);
260         diallingNumberList->push_back(diallingNumber);
261     }
262 }
263 
ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)264 void IccDiallingNumbersHandler::ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer &event, int &id)
265 {
266     if (event == nullptr) {
267         TELEPHONY_LOGE("event is nullptr!");
268         return;
269     }
270     std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
271     if (fd == nullptr) {
272         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessDiallingNumberLoadDone fd is nullptr");
273         return;
274     }
275     int loadId = fd->arg1;
276     id = loadId;
277     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
278     if (fd->exception != nullptr) {
279         if (loadRequest != nullptr) {
280             loadRequest->SetException(fd->exception);
281         }
282         TELEPHONY_LOGE("ProcessDiallingNumberLoadDone load failed with exception");
283         return;
284     }
285 
286     std::string iccData = fd->resultData;
287     TELEPHONY_LOGI("ProcessDiallingNumberLoadDone handle start");
288     if (loadRequest == nullptr) {
289         TELEPHONY_LOGE("ProcessDiallingNumberLoadDone loadRequest is nullptr");
290         return;
291     }
292     std::shared_ptr<DiallingNumbersInfo> diallingNumber =
293     std::make_shared<DiallingNumbersInfo>(loadRequest->GetElementaryFileId(), loadRequest->GetIndex());
294     FetchDiallingNumberContent(diallingNumber, iccData);
295     loadRequest->SetResult(static_cast<std::shared_ptr<void>>(diallingNumber));
296 }
297 
SendUpdateCommand(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,int length,const std::shared_ptr<DiallingNumberLoadRequest> & loadRequest,int loadId)298 void IccDiallingNumbersHandler::SendUpdateCommand(const std::shared_ptr<DiallingNumbersInfo> &diallingNumber,
299     int length, const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest, int loadId)
300 {
301     int dataLen = length;
302     if (dataLen == INVALID_LENGTH) {
303         dataLen = RECORD_LENGTH;
304     }
305     TELEPHONY_LOGI("DiallingNumbersHandler::SendUpdateCommand start!! %{public}d %{public}d", dataLen, length);
306     std::shared_ptr<unsigned char> dataDiallingNumber = nullptr;
307     if (dataLen > 0) {
308         dataDiallingNumber = CreateSavingSequence(diallingNumber, dataLen);
309     }
310     if (dataDiallingNumber != nullptr) {
311         std::string data = SIMUtils::BytesConvertToHexString(dataDiallingNumber.get(), dataLen);
312         AppExecFwk::InnerEvent::Pointer event =
313             BuildCallerInfo(MSG_SIM_RENEW_ADN_DONE, diallingNumber, loadId);
314         fileController_->UpdateLinearFixedFile(loadRequest->GetElementaryFileId(),
315             GetFilePath(loadRequest->GetElementaryFileId()), loadRequest->GetIndex(), data, dataLen,
316             loadRequest->GetPin2(), event);
317         loadRequest->InitCount();
318     } else {
319         TELEPHONY_LOGE("invalid adn data");
320         loadRequest->SetException(static_cast<std::shared_ptr<void>>(MakeExceptionResult(
321             PARAMETER_INCORRECT)));
322     }
323 }
324 
SendBackResult(int loadId)325 bool IccDiallingNumbersHandler::SendBackResult(int loadId)
326 {
327     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
328     if (loadRequest == nullptr) {
329         return false;
330     }
331     if (loadRequest->GetCaller() == nullptr || loadRequest->HasCount()) {
332         return false;
333     }
334     auto owner = loadRequest->GetCaller()->GetOwner();
335     uint32_t id = loadRequest->GetCaller()->GetInnerEventId();
336     std::unique_ptr<DiallingNumbersHandleHolder> fd =
337         loadRequest->GetCaller()->GetUniqueObject<DiallingNumbersHandleHolder>();
338     if (fd == nullptr) {
339         TELEPHONY_LOGE("fd is nullptr!");
340         return false;
341     }
342     std::unique_ptr<DiallingNumbersHandlerResult> data = make_unique<DiallingNumbersHandlerResult>(fd.get());
343     if (data == nullptr) {
344         TELEPHONY_LOGE("data is nullptr!");
345         return false;
346     }
347     data->result = loadRequest->GetResult();
348     data->exception = loadRequest->GetException();
349     if (owner == nullptr) {
350         TELEPHONY_LOGE("IccDiallingNumbersHandler::SendBackResult owner null pointer");
351         return false;
352     }
353     TelEventHandler::SendTelEvent(owner, id, data);
354     ClearLoadRequest(loadId);
355     TELEPHONY_LOGI("IccDiallingNumbersHandler::SendBackResult send end");
356     return true;
357 }
358 
BuildCallerInfo(int eventId,int loadId)359 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersHandler::BuildCallerInfo(int eventId, int loadId)
360 {
361     std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
362     if (object == nullptr) {
363         TELEPHONY_LOGE("object is nullptr!");
364         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
365     }
366     object->arg1 = loadId;
367     int eventParam = 0;
368     AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
369     if (event == nullptr) {
370         TELEPHONY_LOGE("event is nullptr!");
371         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
372     }
373     event->SetOwner(shared_from_this());
374     return event;
375 }
376 
BuildCallerInfo(int eventId,std::shared_ptr<void> pobj,int loadId)377 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersHandler::BuildCallerInfo(
378     int eventId, std::shared_ptr<void> pobj, int loadId)
379 {
380     std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
381     if (object == nullptr) {
382         TELEPHONY_LOGE("object is nullptr!");
383         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
384     }
385     object->arg1 = loadId;
386     object->iccLoader = pobj;
387     int eventParam = 0;
388     AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
389     if (event == nullptr) {
390         TELEPHONY_LOGE("event is nullptr!");
391         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
392     }
393     event->SetOwner(shared_from_this());
394     return event;
395 }
396 
FindLoadRequest(int serial)397 std::shared_ptr<DiallingNumberLoadRequest> IccDiallingNumbersHandler::FindLoadRequest(int serial)
398 {
399     std::lock_guard<std::mutex> lock(requestLock_);
400     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = nullptr;
401     auto iter = IccDiallingNumbersHandler::requestMap_.find(serial);
402     if (iter == IccDiallingNumbersHandler::requestMap_.end()) {
403         TELEPHONY_LOGI("FindLoadRequest not found serial:%{public}d", serial);
404     } else {
405         loadRequest = iter->second;
406     }
407     TELEPHONY_LOGI("FindLoadRequest : %{public}d", serial);
408     return loadRequest;
409 }
410 
ClearLoadRequest(int serial)411 void IccDiallingNumbersHandler::ClearLoadRequest(int serial)
412 {
413     std::lock_guard<std::mutex> lock(requestLock_);
414     IccDiallingNumbersHandler::requestMap_.erase(serial);
415 }
416 
FetchDiallingNumberContent(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,const std::string & recordData)417 void IccDiallingNumbersHandler::FetchDiallingNumberContent(
418     const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, const std::string &recordData)
419 {
420     TELEPHONY_LOGD("FetchDiallingNumberContent start");
421     int recordLen = 0;
422     std::shared_ptr<unsigned char> data = SIMUtils::HexStringConvertToBytes(recordData, recordLen);
423     if (diallingNumber == nullptr || data == nullptr) {
424         TELEPHONY_LOGE("FetchDiallingNumberContent null data");
425         return;
426     }
427     /* parse name */
428     int offset = 0;
429     int length = recordLen - PRE_BYTES_NUM;
430     unsigned char *record = data.get();
431     std::string tempStrTag = SIMUtils::DiallingNumberStringFieldConvertToString(data, offset, length, NAME_CHAR_POS);
432     diallingNumber->name_ = Str8ToStr16(tempStrTag);
433     /* parse length */
434     offset += length;
435     length = static_cast<int>(record[offset]);
436     if (length > MAX_NUMBER_SIZE_BYTES) {
437         length = MAX_NUMBER_SIZE_BYTES;
438         TELEPHONY_LOGE("FetchDiallingNumberContent number error");
439     }
440     /* parse number */
441     ++offset;
442     std::string tempStrNumber =
443     SimNumberDecode::BCDConvertToString(data, offset, length, SimNumberDecode::BCD_TYPE_ADN);
444     diallingNumber->number_ = Str8ToStr16(tempStrNumber);
445     TELEPHONY_LOGD("FetchDiallingNumberContent result end");
446 }
447 
CreateSavingSequence(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,int dataLength)448 std::shared_ptr<unsigned char> IccDiallingNumbersHandler::CreateSavingSequence(
449     const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, int dataLength)
450 {
451     std::shared_ptr<unsigned char> byteTagPac = nullptr;
452     std::shared_ptr<unsigned char> diallingNumberStringPac = nullptr;
453     unsigned char *byteTag = nullptr;
454     unsigned char *diallingNumberString = nullptr;
455     int offset = dataLength - PRE_BYTES_NUM;
456     int byteTagLen = 0;
457     if (dataLength < 0) {
458         return nullptr;
459     }
460     unsigned char *cache = (unsigned char *)calloc(dataLength, sizeof(unsigned char));
461     if (cache == nullptr) {
462         return nullptr;
463     }
464     diallingNumberStringPac = std::shared_ptr<unsigned char>(cache, [](unsigned char *ptr) {
465         if (ptr != nullptr) {
466             free(ptr);
467             ptr = nullptr;
468         }
469     });
470     diallingNumberString = diallingNumberStringPac.get();
471     for (int i = 0; i < dataLength; i++) {
472         diallingNumberString[i] = (unsigned char)BYTE_VALUE;
473     }
474     TELEPHONY_LOGI("CreateSavingSequence contents start");
475 
476     uint maxNumberSize = (DIALING_NUMBERS_END - DIALING_NUMBERS_BEGIN + 1) * LENGTH_RATE;
477     if (diallingNumber->number_.empty()) {
478         TELEPHONY_LOGE("CreateSavingSequence number should not be empty");
479         return diallingNumberStringPac;
480     } else if (diallingNumber->number_.size() > maxNumberSize) {
481         TELEPHONY_LOGE("CreateSavingSequence number length exceed the maximum");
482         return nullptr;
483     }
484     byteTagPac = CreateNameSequence(diallingNumber->name_, byteTagLen);
485     byteTag = byteTagPac.get();
486 
487     if (byteTagLen <= offset) {
488         std::string tempNum = Str16ToStr8(diallingNumber->number_);
489         FillNumberFiledForDiallingNumber(diallingNumberStringPac, tempNum, dataLength);
490         if (byteTagLen > 0) {
491             SIMUtils::ArrayCopy(byteTag, 0, diallingNumberString, 0, byteTagLen);
492         }
493         TELEPHONY_LOGI("CreateSavingSequence result: %{public}d", byteTagLen);
494         return diallingNumberStringPac;
495     } else {
496         TELEPHONY_LOGE("CreateSavingSequence max data length is %{public}d", offset);
497         return nullptr;
498     }
499 }
500 
FillNumberFiledForDiallingNumber(std::shared_ptr<unsigned char> diallingNumber,const std::string & number,int dataLength)501 void IccDiallingNumbersHandler::FillNumberFiledForDiallingNumber(
502     std::shared_ptr<unsigned char> diallingNumber, const std::string &number, int dataLength)
503 {
504     if (diallingNumber == nullptr) {
505         return;
506     }
507     unsigned char *diallingNumberString = diallingNumber.get();
508     int offSet = dataLength - PRE_BYTES_NUM;
509     std::vector<uint8_t> bcdCodes;
510     if (!SimNumberDecode::NumberConvertToBCD(number, bcdCodes, false, SimNumberDecode::BCD_TYPE_ADN)) {
511         TELEPHONY_LOGE("FillNumberFiledForDiallingNumber fail at to SimNumberDecode::NumberConvertToBCD");
512         return;
513     }
514     TELEPHONY_LOGI(" get result from SimNumberDecode::NumberConvertToBCD !! size:%{public}zu", bcdCodes.size());
515     for (size_t i = 0; i < bcdCodes.size(); ++i) {
516         diallingNumberString[offSet + TON_NPI_NUMBER + i] = bcdCodes.at(i);
517     }
518     int index = offSet + BCD_NUMBER_BYTES;
519     unsigned char value = (unsigned char)(bcdCodes.size());
520     diallingNumberString[index] = value;
521     index = offSet + MORE_FILE_ID;
522     value = (unsigned char)(BYTE_VALUE);
523     diallingNumberString[index] = value;
524     index = offSet + EXTRA_FILE_ID;
525     diallingNumberString[index] = value;
526 }
527 
CreateNameSequence(const std::u16string & name,int & seqLength)528 std::shared_ptr<unsigned char> IccDiallingNumbersHandler::CreateNameSequence(
529     const std::u16string &name, int &seqLength)
530 {
531     std::string tempTag = Str16ToStr8(name);
532     std::shared_ptr<unsigned char> seqResult = nullptr;
533     if (SimCharDecode::IsChineseString(tempTag)) {
534         std::string sq = SimCharDecode::CharCodeToSequence(name, true);
535         seqResult = SIMUtils::HexStringConvertToBytes(sq, seqLength);
536         TELEPHONY_LOGI("chinese alphabet encode len:%{public}d", seqLength);
537     } else {
538         std::string sq = SimCharDecode::CharCodeToSequence(tempTag, false);
539         seqResult = SIMUtils::HexStringConvertToBytes(sq, seqLength);
540         TELEPHONY_LOGI("english alphabet encode len:%{public}d", seqLength);
541     }
542     return seqResult;
543 }
544 
FormatNameAndNumber(std::shared_ptr<DiallingNumbersInfo> & diallingNumber,bool isDel)545 bool IccDiallingNumbersHandler::FormatNameAndNumber(
546     std::shared_ptr<DiallingNumbersInfo> &diallingNumber, bool isDel)
547 {
548     if (diallingNumber == nullptr) {
549         TELEPHONY_LOGE("diallingNumber is nullptr!");
550         return false;
551     }
552     if (isDel) {
553         diallingNumber->number_ = u"";
554         diallingNumber->name_ = u"";
555         return true;
556     }
557     std::string nameTemp = Str16ToStr8(diallingNumber->name_);
558     std::string numberTemp = Str16ToStr8(diallingNumber->number_);
559     std::string &&name = SIMUtils::Trim(nameTemp);
560     std::string &&number = SIMUtils::Trim(numberTemp);
561 
562     std::u16string &&nameWide = Str8ToStr16(name);
563     std::u16string &&numberWide = Str8ToStr16(number);
564 
565     uint nameMaxNum = SimCharDecode::IsChineseString(name) ? MAX_CHINESE_NAME : MAX_ENGLISH_NAME;
566     if (nameWide.size() > nameMaxNum) {
567         diallingNumber->name_ = nameWide.substr(0, nameMaxNum);
568     }
569 
570     uint numberMaxNum = MAX_NUMBER_CHAR;
571     if (numberWide.size() > numberMaxNum) {
572         std::string tempNum = number.substr(0, numberMaxNum);
573         if (SimNumberDecode::IsValidNumberString(tempNum)) {
574             diallingNumber->number_ = Str8ToStr16(tempNum);
575         } else {
576             TELEPHONY_LOGE("invalid number full string");
577             return false;
578         }
579     } else {
580         if (!SimNumberDecode::IsValidNumberString(number)) {
581             TELEPHONY_LOGE("invalid number string");
582             return false;
583         }
584     }
585     return true;
586 }
587 
MakeExceptionResult(int code)588 std::shared_ptr<RadioResponseInfo> IccDiallingNumbersHandler::MakeExceptionResult(int code)
589 {
590     std::shared_ptr<RadioResponseInfo> responseInfo = std::make_shared<RadioResponseInfo>();
591     responseInfo->error = static_cast<Telephony::ErrType>(code);
592     return responseInfo;
593 }
594 
InitFuncMap()595 void IccDiallingNumbersHandler::InitFuncMap()
596 {
597     memberFuncMap_[MSG_SIM_OBTAIN_ADN_DONE] =
598         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessDiallingNumberLoadDone(event, id); };
599     memberFuncMap_[MSG_SIM_OBTAIN_ALL_ADN_DONE] =
600         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessDiallingNumberAllLoadDone(event, id); };
601     memberFuncMap_[MSG_SIM_OBTAIN_LINEAR_FILE_SIZE_DONE] =
602         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessLinearSizeDone(event, id); };
603     memberFuncMap_[MSG_SIM_RENEW_ADN_DONE] =
604         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessUpdateRecordDone(event, id); };
605 }
606 
UpdateFileController(const std::shared_ptr<IccFileController> & fileController)607 void IccDiallingNumbersHandler::UpdateFileController(const std::shared_ptr<IccFileController> &fileController)
608 {
609     fileController_ = fileController;
610 }
~IccDiallingNumbersHandler()611 IccDiallingNumbersHandler::~IccDiallingNumbersHandler() {}
612 } // namespace Telephony
613 } // namespace OHOS
614