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