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