• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
IsAdnHasExtRecord(int eventId,int loadId)110 bool IccDiallingNumbersHandler::IsAdnHasExtRecord(int eventId, int loadId)
111 {
112     if (eventId == MSG_SIM_OBTAIN_ADN_DONE) {
113         std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
114         if (loadRequest != nullptr && loadRequest->HasExtendedRecord()) {
115             return true;
116         }
117     }
118     return false;
119 }
120 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)121 void IccDiallingNumbersHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
122 {
123     if (event == nullptr) {
124         TELEPHONY_LOGE("event is nullptr!");
125         return;
126     }
127     auto id = event->GetInnerEventId();
128     int loadId = 0;
129     TELEPHONY_LOGD("IccDiallingNumbersHandler::ProcessEvent id %{public}d", id);
130     auto itFunc = memberFuncMap_.find(id);
131     if (itFunc != memberFuncMap_.end()) {
132         auto memberFunc = itFunc->second;
133         if (memberFunc != nullptr) {
134             memberFunc(event, loadId);
135             if (IsAdnHasExtRecord(id, loadId)) {
136                 return;
137             }
138             SendBackResult(loadId);
139         }
140     } else {
141         TELEPHONY_LOGI("IccDiallingNumbersHandler::ProcessEvent unknown id %{public}d", id);
142     }
143 }
144 
ProcessLinearSizeDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)145 void IccDiallingNumbersHandler::ProcessLinearSizeDone(const AppExecFwk::InnerEvent::Pointer &event, int &id)
146 {
147     if (event == nullptr) {
148         TELEPHONY_LOGE("event is nullptr!");
149         return;
150     }
151     std::unique_ptr<ControllerToFileMsg> fdError = event->GetUniqueObject<ControllerToFileMsg>();
152     int loadId = 0;
153     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = nullptr;
154     if (fdError != nullptr) {
155         loadId = fdError->arg1;
156         id = loadId;
157         loadRequest = FindLoadRequest(loadId);
158         if (loadRequest != nullptr) {
159             loadRequest->SetException(fdError->exception);
160         }
161         TELEPHONY_LOGE("ProcessLinearSizeDone error occured");
162         return;
163     }
164     std::shared_ptr<EfLinearResult> object = event->GetSharedObject<EfLinearResult>();
165     if (object == nullptr) {
166         TELEPHONY_LOGE("object is nullptr!");
167         return;
168     }
169     std::shared_ptr<DiallingNumbersInfo> diallingNumberLoad = nullptr;
170     loadId = object->arg1;
171     id = loadId;
172     loadRequest = FindLoadRequest(loadId);
173     if (loadRequest == nullptr) {
174         TELEPHONY_LOGE("loadRequest is nullptr!");
175         return;
176     }
177     if (object->exception == nullptr) {
178         std::shared_ptr<void> baseLoad = object->iccLoader;
179         int *dataSize = object->valueData;
180         if (baseLoad != nullptr) {
181             diallingNumberLoad = std::static_pointer_cast<DiallingNumbersInfo>(baseLoad);
182         }
183         if (!FormatNameAndNumber(diallingNumberLoad, loadRequest->GetIsDelete())) {
184             loadRequest->SetException(static_cast<std::shared_ptr<void>>(MakeExceptionResult(PARAMETER_INCORRECT)));
185             return;
186         }
187         SendUpdateCommand(diallingNumberLoad, dataSize[0], loadRequest, loadId);
188     }
189 }
190 
ProcessUpdateRecordDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)191 void IccDiallingNumbersHandler::ProcessUpdateRecordDone(const AppExecFwk::InnerEvent::Pointer &event, int &id)
192 {
193     if (event == nullptr) {
194         TELEPHONY_LOGE("event is nullptr!");
195         return;
196     }
197     std::unique_ptr<ControllerToFileMsg> object = event->GetUniqueObject<ControllerToFileMsg>();
198     if (object == nullptr) {
199         TELEPHONY_LOGE("object is nullptr!");
200         return;
201     }
202     int loadId = object->arg1;
203     id = loadId;
204     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
205     if (loadRequest != nullptr) {
206         loadRequest->ClearCount();
207         loadRequest->SetException(object->exception);
208         if (loadRequest->GetException() == nullptr) {
209             loadRequest->SetResult(object->iccLoader);
210         }
211     }
212 }
213 
ProcessDiallingNumberAllLoadDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)214 void IccDiallingNumbersHandler::ProcessDiallingNumberAllLoadDone(
215     const AppExecFwk::InnerEvent::Pointer &event, int &id)
216 {
217     if (event == nullptr) {
218         TELEPHONY_LOGE("event is nullptr!");
219         return;
220     }
221     std::unique_ptr<ControllerToFileMsg> fdError = event->GetUniqueObject<ControllerToFileMsg>();
222     int loadId = 0;
223     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = nullptr;
224     if (fdError != nullptr) {
225         loadId = fdError->arg1;
226         id = loadId;
227         loadRequest = FindLoadRequest(loadId);
228         if (loadRequest != nullptr) {
229             loadRequest->SetException(fdError->exception);
230         }
231         TELEPHONY_LOGE("ProcessDiallingNumberAllLoadDone error occured");
232         return;
233     }
234 
235     std::shared_ptr<MultiRecordResult> object = event->GetSharedObject<MultiRecordResult>();
236     if (object == nullptr) {
237         TELEPHONY_LOGE("object is nullptr!");
238         return;
239     }
240     loadId = object->arg1;
241     id = loadId;
242     loadRequest = FindLoadRequest(loadId);
243     if (object->exception != nullptr) {
244         TELEPHONY_LOGE("ProcessDiallingNumberAllLoadDone load failed");
245         if (loadRequest != nullptr) {
246             loadRequest->SetException(object->exception);
247         }
248         return;
249     }
250 
251     ProcessDiallingNumber(loadRequest, object);
252 }
253 
ProcessDiallingNumber(const std::shared_ptr<DiallingNumberLoadRequest> & loadRequest,const std::shared_ptr<MultiRecordResult> & object)254 void IccDiallingNumbersHandler::ProcessDiallingNumber(
255     const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest, const std::shared_ptr<MultiRecordResult> &object)
256 {
257     if (loadRequest == nullptr || object == nullptr) {
258         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessDiallingNumber loadRequest or object is nullptr");
259         return;
260     }
261     loadRequest->ClearCount();
262     std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
263         std::make_shared<std::vector<std::shared_ptr<DiallingNumbersInfo>>>();
264     loadRequest->SetResult(static_cast<std::shared_ptr<void>>(diallingNumberList));
265 
266     std::vector<std::string> &dataList = object->fileResults;
267     TELEPHONY_LOGI("ProcessDiallingNumberAllLoadDone start: %{public}zu", dataList.size());
268     int i = 0;
269     for (std::vector<std::string>::iterator it = dataList.begin(); it != dataList.end(); ++it, i++) {
270         std::string item = *it;
271         std::shared_ptr<DiallingNumbersInfo> diallingNumber =
272             std::make_shared<DiallingNumbersInfo>(loadRequest->GetElementaryFileId(), 1 + i);
273         FetchDiallingNumberContent(diallingNumber, item, nullptr);
274         diallingNumberList->push_back(diallingNumber);
275     }
276 }
277 
ProcessExtensionRecordNumbers(const AppExecFwk::InnerEvent::Pointer & event,int & id)278 void IccDiallingNumbersHandler::ProcessExtensionRecordNumbers(const AppExecFwk::InnerEvent::Pointer &event, int &id)
279 {
280     if (event == nullptr) {
281         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessExtensionRecordNumbers event is nullptr!");
282         return;
283     }
284     std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
285     if (fd == nullptr) {
286         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessExtensionRecordNumbers fd is nullptr");
287         return;
288     }
289     id = fd->arg1;
290     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(id);
291     if (loadRequest == nullptr) {
292         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessExtensionRecordNumbers loadRequest is nullptr");
293         return;
294     }
295     if (fd->exception != nullptr) {
296         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessExtensionRecordNumbers load failed with exception");
297         return;
298     }
299     std::string iccData = fd->resultData;
300     TELEPHONY_LOGI("IccDiallingNumbersHandler::ProcessExtensionRecordNumbers handle start");
301     std::shared_ptr<void> diallingNumber = loadRequest->GetResult();
302     FetchExtensionContent(std::static_pointer_cast<DiallingNumbersInfo>(diallingNumber), iccData);
303     loadRequest->SetResult(static_cast<std::shared_ptr<void>>(diallingNumber));
304 }
305 
ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer & event,int & id)306 void IccDiallingNumbersHandler::ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer &event, int &id)
307 {
308     if (event == nullptr) {
309         TELEPHONY_LOGE("event is nullptr!");
310         return;
311     }
312     std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
313     if (fd == nullptr) {
314         TELEPHONY_LOGE("IccDiallingNumbersHandler::ProcessDiallingNumberLoadDone fd is nullptr");
315         return;
316     }
317     int loadId = fd->arg1;
318     id = loadId;
319     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
320     if (fd->exception != nullptr) {
321         if (loadRequest != nullptr) {
322             loadRequest->SetException(fd->exception);
323         }
324         TELEPHONY_LOGE("ProcessDiallingNumberLoadDone load failed with exception");
325         return;
326     }
327 
328     std::string iccData = fd->resultData;
329     TELEPHONY_LOGI("ProcessDiallingNumberLoadDone handle start");
330     if (loadRequest == nullptr) {
331         TELEPHONY_LOGE("ProcessDiallingNumberLoadDone loadRequest is nullptr");
332         return;
333     }
334     std::shared_ptr<DiallingNumbersInfo> diallingNumber =
335         std::make_shared<DiallingNumbersInfo>(loadRequest->GetElementaryFileId(), loadRequest->GetIndex());
336     FetchDiallingNumberContent(diallingNumber, iccData, loadRequest);
337     loadRequest->SetResult(static_cast<std::shared_ptr<void>>(diallingNumber));
338     if (loadRequest->HasExtendedRecord()) {
339         AppExecFwk::InnerEvent::Pointer ptExtensionRecordRead =
340             BuildCallerInfo(MSG_SIM_EXT_RECORD_LOAD_DONE, loadRequest->GetLoadId());
341         fileController_->ObtainLinearFixedFile(loadRequest->GetExEF(), GetFilePath(loadRequest->GetExEF()),
342             loadRequest->extensionRecord_, ptExtensionRecordRead);
343     }
344 }
345 
SendUpdateCommand(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,int length,const std::shared_ptr<DiallingNumberLoadRequest> & loadRequest,int loadId)346 void IccDiallingNumbersHandler::SendUpdateCommand(const std::shared_ptr<DiallingNumbersInfo> &diallingNumber,
347     int length, const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest, int loadId)
348 {
349     int dataLen = length;
350     if (dataLen == INVALID_LENGTH) {
351         dataLen = RECORD_LENGTH;
352     }
353     TELEPHONY_LOGI("DiallingNumbersHandler::SendUpdateCommand start!! %{public}d %{public}d", dataLen, length);
354     std::shared_ptr<unsigned char> dataDiallingNumber = nullptr;
355     if (dataLen > 0) {
356         dataDiallingNumber = CreateSavingSequence(diallingNumber, dataLen);
357     }
358     if (dataDiallingNumber != nullptr) {
359         std::string data = SIMUtils::BytesConvertToHexString(dataDiallingNumber.get(), dataLen);
360         AppExecFwk::InnerEvent::Pointer event =
361             BuildCallerInfo(MSG_SIM_RENEW_ADN_DONE, diallingNumber, loadId);
362         fileController_->UpdateLinearFixedFile(loadRequest->GetElementaryFileId(),
363             GetFilePath(loadRequest->GetElementaryFileId()), loadRequest->GetIndex(), data, dataLen,
364             loadRequest->GetPin2(), event);
365         loadRequest->InitCount();
366     } else {
367         TELEPHONY_LOGE("invalid adn data");
368         loadRequest->SetException(static_cast<std::shared_ptr<void>>(MakeExceptionResult(
369             PARAMETER_INCORRECT)));
370     }
371 }
372 
SendBackResult(int loadId)373 bool IccDiallingNumbersHandler::SendBackResult(int loadId)
374 {
375     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = FindLoadRequest(loadId);
376     if (loadRequest == nullptr) {
377         return false;
378     }
379     if (loadRequest->GetCaller() == nullptr || loadRequest->HasCount()) {
380         return false;
381     }
382     auto owner = loadRequest->GetCaller()->GetOwner();
383     uint32_t id = loadRequest->GetCaller()->GetInnerEventId();
384     std::unique_ptr<DiallingNumbersHandleHolder> fd =
385         loadRequest->GetCaller()->GetUniqueObject<DiallingNumbersHandleHolder>();
386     if (fd == nullptr) {
387         TELEPHONY_LOGE("fd is nullptr!");
388         return false;
389     }
390     std::unique_ptr<DiallingNumbersHandlerResult> data = make_unique<DiallingNumbersHandlerResult>(fd.get());
391     if (data == nullptr) {
392         TELEPHONY_LOGE("data is nullptr!");
393         return false;
394     }
395     data->result = loadRequest->GetResult();
396     data->exception = loadRequest->GetException();
397     if (owner == nullptr) {
398         TELEPHONY_LOGE("IccDiallingNumbersHandler::SendBackResult owner null pointer");
399         return false;
400     }
401     TelEventHandler::SendTelEvent(owner, id, data);
402     ClearLoadRequest(loadId);
403     TELEPHONY_LOGI("IccDiallingNumbersHandler::SendBackResult send end");
404     return true;
405 }
406 
BuildCallerInfo(int eventId,int loadId)407 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersHandler::BuildCallerInfo(int eventId, int loadId)
408 {
409     std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
410     if (object == nullptr) {
411         TELEPHONY_LOGE("object is nullptr!");
412         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
413     }
414     object->arg1 = loadId;
415     int eventParam = 0;
416     AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
417     if (event == nullptr) {
418         TELEPHONY_LOGE("event is nullptr!");
419         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
420     }
421     event->SetOwner(shared_from_this());
422     return event;
423 }
424 
BuildCallerInfo(int eventId,std::shared_ptr<void> pobj,int loadId)425 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersHandler::BuildCallerInfo(
426     int eventId, std::shared_ptr<void> pobj, int loadId)
427 {
428     std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
429     if (object == nullptr) {
430         TELEPHONY_LOGE("object is nullptr!");
431         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
432     }
433     object->arg1 = loadId;
434     object->iccLoader = pobj;
435     int eventParam = 0;
436     AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
437     if (event == nullptr) {
438         TELEPHONY_LOGE("event is nullptr!");
439         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
440     }
441     event->SetOwner(shared_from_this());
442     return event;
443 }
444 
FindLoadRequest(int serial)445 std::shared_ptr<DiallingNumberLoadRequest> IccDiallingNumbersHandler::FindLoadRequest(int serial)
446 {
447     std::lock_guard<std::mutex> lock(requestLock_);
448     std::shared_ptr<DiallingNumberLoadRequest> loadRequest = nullptr;
449     auto iter = IccDiallingNumbersHandler::requestMap_.find(serial);
450     if (iter == IccDiallingNumbersHandler::requestMap_.end()) {
451         TELEPHONY_LOGI("FindLoadRequest not found serial:%{public}d", serial);
452     } else {
453         loadRequest = iter->second;
454     }
455     TELEPHONY_LOGI("FindLoadRequest : %{public}d", serial);
456     return loadRequest;
457 }
458 
ClearLoadRequest(int serial)459 void IccDiallingNumbersHandler::ClearLoadRequest(int serial)
460 {
461     std::lock_guard<std::mutex> lock(requestLock_);
462     IccDiallingNumbersHandler::requestMap_.erase(serial);
463 }
464 
FetchExtensionContent(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,const std::string & recordData)465 void IccDiallingNumbersHandler::FetchExtensionContent(
466     const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, const std::string &recordData)
467 {
468     TELEPHONY_LOGD("FetchExtensionContent start");
469     int recordLen = 0;
470     std::shared_ptr<unsigned char> data = SIMUtils::HexStringConvertToBytes(recordData, recordLen);
471     if (diallingNumber == nullptr || data == nullptr) {
472         TELEPHONY_LOGE("FetchExtensionContent null data");
473         return;
474     }
475     /* parse record lenth */
476     if (recordLen != MAX_EXT_RECORD_LENGTH_BYTES) {
477         TELEPHONY_LOGE("FetchExtensionContent record length error");
478         return;
479     }
480     unsigned char *record = data.get();
481     int offset = 0;
482     /* parse record type */
483     if (record[offset] != EXT_RECORD_TYPE_ADDITIONAL_DATA) {
484         TELEPHONY_LOGE("FetchExtensionContent invalid or empty record");
485         // invalid or empty record
486         return;
487     }
488     ++offset;
489     /* parse extension data lenth */
490     int length = static_cast<int>(record[offset]);
491     if (length > MAX_EXT_BCD_LENGTH) {
492         length = MAX_EXT_BCD_LENGTH;
493         TELEPHONY_LOGE("FetchExtensionContent number error");
494     }
495     ++offset;
496     /* parse extension data */
497     std::string extensionNumber = SimNumberDecode::ExtensionBCDConvertToString(data, recordLen, offset, length);
498     std::u16string diallingNumberAndExt = diallingNumber->GetNumber().append(Str8ToStr16(extensionNumber));
499     diallingNumber->UpdateNumber(diallingNumberAndExt);
500     TELEPHONY_LOGD("FetchExtensionContent result end");
501 }
502 
FetchDiallingNumberContent(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,const std::string & recordData,const std::shared_ptr<DiallingNumberLoadRequest> & loadRequest)503 void IccDiallingNumbersHandler::FetchDiallingNumberContent(
504     const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, const std::string &recordData,
505     const std::shared_ptr<DiallingNumberLoadRequest> &loadRequest)
506 {
507     TELEPHONY_LOGD("FetchDiallingNumberContent start");
508     int recordLen = 0;
509     std::shared_ptr<unsigned char> data = SIMUtils::HexStringConvertToBytes(recordData, recordLen);
510     if (diallingNumber == nullptr || data == nullptr) {
511         TELEPHONY_LOGE("FetchDiallingNumberContent null data");
512         return;
513     }
514     /* parse name */
515     int offset = 0;
516     int length = recordLen - PRE_BYTES_NUM;
517     unsigned char *record = data.get();
518     std::string tempStrTag = SIMUtils::DiallingNumberStringFieldConvertToString(data, offset, length, NAME_CHAR_POS);
519     diallingNumber->name_ = Str8ToStr16(tempStrTag);
520     /* parse length */
521     offset += length;
522     length = static_cast<int>(record[offset]);
523     if (length > MAX_NUMBER_SIZE_BYTES) {
524         length = MAX_NUMBER_SIZE_BYTES;
525         TELEPHONY_LOGE("FetchDiallingNumberContent number error");
526     }
527     /* parse number */
528     ++offset;
529     std::string tempStrNumber =
530         SimNumberDecode::BCDConvertToString(data, recordLen, offset, length);
531     diallingNumber->number_ = Str8ToStr16(tempStrNumber);
532     if (loadRequest != nullptr) {
533         loadRequest->extensionRecord_ = record[recordLen - 1];
534     }
535     TELEPHONY_LOGD("FetchDiallingNumberContent result end");
536 }
537 
CreateSavingSequence(const std::shared_ptr<DiallingNumbersInfo> & diallingNumber,int dataLength)538 std::shared_ptr<unsigned char> IccDiallingNumbersHandler::CreateSavingSequence(
539     const std::shared_ptr<DiallingNumbersInfo> &diallingNumber, int dataLength)
540 {
541     std::shared_ptr<unsigned char> byteTagPac = nullptr;
542     std::shared_ptr<unsigned char> diallingNumberStringPac = nullptr;
543     unsigned char *byteTag = nullptr;
544     unsigned char *diallingNumberString = nullptr;
545     int offset = dataLength - PRE_BYTES_NUM;
546     int byteTagLen = 0;
547     if (dataLength < 0) {
548         return nullptr;
549     }
550     unsigned char *cache = (unsigned char *)calloc(dataLength, sizeof(unsigned char));
551     if (cache == nullptr) {
552         return nullptr;
553     }
554     diallingNumberStringPac = std::shared_ptr<unsigned char>(cache, [](unsigned char *ptr) {
555         if (ptr != nullptr) {
556             free(ptr);
557             ptr = nullptr;
558         }
559     });
560     diallingNumberString = diallingNumberStringPac.get();
561     for (int i = 0; i < dataLength; i++) {
562         diallingNumberString[i] = (unsigned char)BYTE_VALUE;
563     }
564     TELEPHONY_LOGI("CreateSavingSequence contents start");
565 
566     uint maxNumberSize = (DIALING_NUMBERS_END - DIALING_NUMBERS_BEGIN + 1) * LENGTH_RATE;
567     if (diallingNumber->number_.empty()) {
568         TELEPHONY_LOGE("CreateSavingSequence number should not be empty");
569         return diallingNumberStringPac;
570     } else if (diallingNumber->number_.size() > maxNumberSize) {
571         TELEPHONY_LOGE("CreateSavingSequence number length exceed the maximum");
572         return nullptr;
573     }
574     byteTagPac = CreateNameSequence(diallingNumber->name_, byteTagLen);
575     byteTag = byteTagPac.get();
576 
577     if (byteTagLen <= offset) {
578         std::string tempNum = Str16ToStr8(diallingNumber->number_);
579         FillNumberFiledForDiallingNumber(diallingNumberStringPac, tempNum, dataLength);
580         if (byteTagLen > 0) {
581             SIMUtils::ArrayCopy(byteTag, 0, diallingNumberString, 0, byteTagLen);
582         }
583         TELEPHONY_LOGI("CreateSavingSequence result: %{public}d", byteTagLen);
584         return diallingNumberStringPac;
585     } else {
586         TELEPHONY_LOGE("CreateSavingSequence max data length is %{public}d", offset);
587         return nullptr;
588     }
589 }
590 
FillNumberFiledForDiallingNumber(std::shared_ptr<unsigned char> diallingNumber,const std::string & number,int dataLength)591 void IccDiallingNumbersHandler::FillNumberFiledForDiallingNumber(
592     std::shared_ptr<unsigned char> diallingNumber, const std::string &number, int dataLength)
593 {
594     if (diallingNumber == nullptr) {
595         return;
596     }
597     unsigned char *diallingNumberString = diallingNumber.get();
598     int offSet = dataLength - PRE_BYTES_NUM;
599     std::vector<uint8_t> bcdCodes;
600     if (!SimNumberDecode::NumberConvertToBCD(number, bcdCodes, false, SimNumberDecode::BCD_TYPE_ADN)) {
601         TELEPHONY_LOGE("FillNumberFiledForDiallingNumber fail at to SimNumberDecode::NumberConvertToBCD");
602         return;
603     }
604     TELEPHONY_LOGI(" get result from SimNumberDecode::NumberConvertToBCD !! size:%{public}zu", bcdCodes.size());
605     for (size_t i = 0; i < bcdCodes.size(); ++i) {
606         diallingNumberString[offSet + TON_NPI_NUMBER + i] = bcdCodes.at(i);
607     }
608     int index = offSet + BCD_NUMBER_BYTES;
609     unsigned char value = (unsigned char)(bcdCodes.size());
610     diallingNumberString[index] = value;
611     index = offSet + MORE_FILE_ID;
612     value = (unsigned char)(BYTE_VALUE);
613     diallingNumberString[index] = value;
614     index = offSet + EXTRA_FILE_ID;
615     diallingNumberString[index] = value;
616 }
617 
CreateNameSequence(const std::u16string & name,int & seqLength)618 std::shared_ptr<unsigned char> IccDiallingNumbersHandler::CreateNameSequence(
619     const std::u16string &name, int &seqLength)
620 {
621     std::string tempTag = Str16ToStr8(name);
622     std::shared_ptr<unsigned char> seqResult = nullptr;
623     if (SimCharDecode::IsChineseString(tempTag)) {
624         std::string sq = SimCharDecode::CharCodeToSequence(name, true);
625         seqResult = SIMUtils::HexStringConvertToBytes(sq, seqLength);
626         TELEPHONY_LOGI("chinese alphabet encode len:%{public}d", seqLength);
627     } else {
628         std::string sq = SimCharDecode::CharCodeToSequence(tempTag, false);
629         seqResult = SIMUtils::HexStringConvertToBytes(sq, seqLength);
630         TELEPHONY_LOGI("english alphabet encode len:%{public}d", seqLength);
631     }
632     return seqResult;
633 }
634 
FormatNameAndNumber(std::shared_ptr<DiallingNumbersInfo> & diallingNumber,bool isDel)635 bool IccDiallingNumbersHandler::FormatNameAndNumber(
636     std::shared_ptr<DiallingNumbersInfo> &diallingNumber, bool isDel)
637 {
638     if (diallingNumber == nullptr) {
639         TELEPHONY_LOGE("diallingNumber is nullptr!");
640         return false;
641     }
642     if (isDel) {
643         diallingNumber->number_ = u"";
644         diallingNumber->name_ = u"";
645         return true;
646     }
647     std::string nameTemp = Str16ToStr8(diallingNumber->name_);
648     std::string numberTemp = Str16ToStr8(diallingNumber->number_);
649     std::string &&name = SIMUtils::Trim(nameTemp);
650     std::string &&number = SIMUtils::Trim(numberTemp);
651 
652     std::u16string &&nameWide = Str8ToStr16(name);
653     std::u16string &&numberWide = Str8ToStr16(number);
654 
655     uint nameMaxNum = SimCharDecode::IsChineseString(name) ? MAX_CHINESE_NAME : MAX_ENGLISH_NAME;
656     if (nameWide.size() > nameMaxNum) {
657         diallingNumber->name_ = nameWide.substr(0, nameMaxNum);
658     }
659 
660     uint numberMaxNum = MAX_NUMBER_CHAR;
661     if (numberWide.size() > numberMaxNum) {
662         std::string tempNum = number.substr(0, numberMaxNum);
663         if (SimNumberDecode::IsValidNumberString(tempNum)) {
664             diallingNumber->number_ = Str8ToStr16(tempNum);
665         } else {
666             TELEPHONY_LOGE("invalid number full string");
667             return false;
668         }
669     } else {
670         if (!SimNumberDecode::IsValidNumberString(number)) {
671             TELEPHONY_LOGE("invalid number string");
672             return false;
673         }
674     }
675     return true;
676 }
677 
MakeExceptionResult(int code)678 std::shared_ptr<RadioResponseInfo> IccDiallingNumbersHandler::MakeExceptionResult(int code)
679 {
680     std::shared_ptr<RadioResponseInfo> responseInfo = std::make_shared<RadioResponseInfo>();
681     responseInfo->error = static_cast<Telephony::ErrType>(code);
682     return responseInfo;
683 }
684 
InitFuncMap()685 void IccDiallingNumbersHandler::InitFuncMap()
686 {
687     memberFuncMap_[MSG_SIM_OBTAIN_ADN_DONE] =
688         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessDiallingNumberLoadDone(event, id); };
689     memberFuncMap_[MSG_SIM_OBTAIN_ALL_ADN_DONE] =
690         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessDiallingNumberAllLoadDone(event, id); };
691     memberFuncMap_[MSG_SIM_OBTAIN_LINEAR_FILE_SIZE_DONE] =
692         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessLinearSizeDone(event, id); };
693     memberFuncMap_[MSG_SIM_RENEW_ADN_DONE] =
694         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessUpdateRecordDone(event, id); };
695     memberFuncMap_[MSG_SIM_EXT_RECORD_LOAD_DONE] =
696         [this](const AppExecFwk::InnerEvent::Pointer &event, int &id) { ProcessExtensionRecordNumbers(event, id); };
697 }
698 
UpdateFileController(const std::shared_ptr<IccFileController> & fileController)699 void IccDiallingNumbersHandler::UpdateFileController(const std::shared_ptr<IccFileController> &fileController)
700 {
701     fileController_ = fileController;
702 }
~IccDiallingNumbersHandler()703 IccDiallingNumbersHandler::~IccDiallingNumbersHandler() {}
704 } // namespace Telephony
705 } // namespace OHOS
706