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 "usim_dialling_numbers_service.h"
17
18 namespace OHOS {
19 namespace Telephony {
20 std::mutex UsimDiallingNumbersService::mtx_;
21
UsimDiallingNumbersService()22 UsimDiallingNumbersService::UsimDiallingNumbersService() : TelEventHandler("UsimDiallingNumbersService")
23 {
24 InitFuncMap();
25 }
26
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)27 void UsimDiallingNumbersService::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
28 {
29 if (event == nullptr) {
30 TELEPHONY_LOGI("UsimDiallingNumbersService::ProcessEvent event is null");
31 return;
32 }
33 uint32_t id = event->GetInnerEventId();
34 TELEPHONY_LOGD("UsimDiallingNumbersService::ProcessEvent Id is %{public}d", id);
35 std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
36 if (fd != nullptr) {
37 if (fd->exception != nullptr) {
38 TELEPHONY_LOGE("UsimDiallingNumbersService::ProcessEvent: get error result");
39 SendLocalBack();
40 return;
41 }
42 }
43 auto itFunc = memberFuncMap_.find(id);
44 if (itFunc != memberFuncMap_.end()) {
45 auto memberFunc = itFunc->second;
46 if (memberFunc != nullptr) {
47 memberFunc(event);
48 }
49 }
50 }
51
InitFuncMap()52 void UsimDiallingNumbersService::InitFuncMap()
53 {
54 memberFuncMap_[MSG_USIM_PBR_LOAD_DONE] =
55 [this](const AppExecFwk::InnerEvent::Pointer &event) { ProcessPbrLoadDone(event); };
56 memberFuncMap_[MSG_USIM_USIM_ADN_LOAD_DONE] =
57 [this](const AppExecFwk::InnerEvent::Pointer &event) { ProcessDiallingNumberLoadDone(event); };
58 }
59
ProcessPbrLoadDone(const AppExecFwk::InnerEvent::Pointer & event)60 void UsimDiallingNumbersService::ProcessPbrLoadDone(const AppExecFwk::InnerEvent::Pointer &event)
61 {
62 if (event == nullptr) {
63 TELEPHONY_LOGE("event is nullptr!");
64 return;
65 }
66 std::shared_ptr<MultiRecordResult> object = event->GetSharedObject<MultiRecordResult>();
67 if (object != nullptr) {
68 TELEPHONY_LOGI("UsimDiallingNumbersService::ProcessPbrLoadDone: %{public}d", object->resultLength);
69 if (object->exception == nullptr) {
70 std::vector<std::string> &files = object->fileResults;
71 GeneratePbrFile(files);
72 }
73 } else {
74 TELEPHONY_LOGE("ProcessPbrLoadDone: get null pointer!!!");
75 }
76 TELEPHONY_LOGI("ProcessPbrLoadDone start load %{public}zu", pbrFiles_.size());
77 if (pbrFiles_.empty()) {
78 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> list =
79 std::make_shared<std::vector<std::shared_ptr<DiallingNumbersInfo>>>();
80 SendBackResult(list);
81 TELEPHONY_LOGI("ProcessPbrLoadDone empty pbr");
82 } else {
83 pbrIndex_ = 0;
84 LoadDiallingNumberFiles(pbrIndex_);
85 }
86 }
87
ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer & event)88 void UsimDiallingNumbersService::ProcessDiallingNumberLoadDone(const AppExecFwk::InnerEvent::Pointer &event)
89 {
90 if (event == nullptr) {
91 return;
92 }
93 std::unique_ptr<DiallingNumbersHandlerResult> object = event->GetUniqueObject<DiallingNumbersHandlerResult>();
94
95 if (object != nullptr) {
96 if (object->exception == nullptr) {
97 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
98 std::static_pointer_cast<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(object->result);
99 FillDiallingNumbersRecords(diallingNumberList);
100 } else {
101 TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: exception occured");
102 }
103 }
104
105 if (pbrIndex_ < pbrFiles_.size()) {
106 TELEPHONY_LOGI(
107 "ProcessDiallingNumberLoadDone to Tap: %{public}d %{public}zu", pbrIndex_, pbrFiles_.size());
108 LoadDiallingNumberFiles(++pbrIndex_);
109 } else {
110 TELEPHONY_LOGI("loadEfFilesFromUsim: finished");
111 SendLocalBack();
112 }
113 }
114
FillDiallingNumbersRecords(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & list)115 void UsimDiallingNumbersService::FillDiallingNumbersRecords(
116 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &list)
117 {
118 if (list != nullptr) {
119 for (std::vector<std::shared_ptr<DiallingNumbersInfo>>::iterator it = list->begin(); it != list->end(); ++it) {
120 diallingNumbersFiles_.push_back(*it);
121 }
122 TELEPHONY_LOGI(
123 "UsimDiallingNumbersService::FillDiallingNumbersRecords %{public}zu", diallingNumbersFiles_.size());
124 } else {
125 TELEPHONY_LOGE("FillDiallingNumbersRecords: get null vectors!!!");
126 }
127 }
128
ObtainUsimElementaryFiles(const AppExecFwk::InnerEvent::Pointer & pointer)129 void UsimDiallingNumbersService::ObtainUsimElementaryFiles(const AppExecFwk::InnerEvent::Pointer &pointer)
130 {
131 callerPointer_ = std::move(const_cast<AppExecFwk::InnerEvent::Pointer &>(pointer));
132 if (diallingNumbersFiles_.empty()) {
133 if (pbrFiles_.empty()) {
134 LoadPbrFiles();
135 }
136 }
137 }
138
LoadPbrFiles()139 void UsimDiallingNumbersService::LoadPbrFiles()
140 {
141 std::unique_lock<std::mutex> lock(mtx_);
142 AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(MSG_USIM_PBR_LOAD_DONE);
143 if (fileController_ == nullptr) {
144 TELEPHONY_LOGE("LoadPbrFiles fileController_ is nullptr");
145 return;
146 }
147 fileController_->ObtainAllLinearFixedFile(ELEMENTARY_FILE_PBR, event);
148 }
149
LoadDiallingNumberFiles(int recId)150 bool UsimDiallingNumbersService::LoadDiallingNumberFiles(int recId)
151 {
152 if (recId >= static_cast<int>(pbrFiles_.size())) {
153 TELEPHONY_LOGI("LoadDiallingNumberFiles finish %{public}d", recId);
154 NextStep(MSG_USIM_USIM_ADN_LOAD_DONE);
155 return false;
156 }
157
158 std::unique_lock<std::mutex> lock(mtx_);
159 std::map<int, std::shared_ptr<TagData>> files = pbrFiles_.at(recId)->fileIds_;
160 if (files.empty() || !files.size()) {
161 TELEPHONY_LOGI("LoadDiallingNumberFiles empty file %{public}d", recId);
162 NextStep(MSG_USIM_USIM_ADN_LOAD_DONE);
163 return false;
164 }
165
166 int extEf = files.at(TAG_SIM_USIM_EXT1) != nullptr ? files.at(TAG_SIM_USIM_EXT1)->fileId : 0;
167 if (extEf >= 0 && files.at(TAG_SIM_USIM_ADN) != nullptr) {
168 TELEPHONY_LOGI("UsimDiallingNumbersService::LoadDiallingNumberFiles start %{public}d", recId);
169 int efId = files.at(TAG_SIM_USIM_ADN)->fileId;
170 AppExecFwk::InnerEvent::Pointer event = CreateHandlerPointer(MSG_USIM_USIM_ADN_LOAD_DONE, efId, 0, nullptr);
171 if (diallingNumbersHandler_ == nullptr) {
172 TELEPHONY_LOGE("LoadDiallingNumberFiles diallingNumbersHandler_ is nullptr");
173 return false;
174 }
175 diallingNumbersHandler_->GetAllDiallingNumbers(efId, extEf, event);
176 return true;
177 } else {
178 bool fileNull = files.at(TAG_SIM_USIM_ADN) == nullptr;
179 TELEPHONY_LOGE("LoadDiallingNumberFiles error params %{public}d, nullfile %{public}d", extEf, fileNull);
180 NextStep(MSG_USIM_USIM_ADN_LOAD_DONE);
181 return false;
182 }
183 }
184
GeneratePbrFile(std::vector<std::string> & records)185 void UsimDiallingNumbersService::GeneratePbrFile(std::vector<std::string> &records)
186 {
187 pbrFileLoaded_ = !records.empty() && pbrFileLoaded_;
188 pbrFiles_.clear();
189 constexpr size_t FstByteChrLen = 2;
190 for (const auto &dataPac : records) {
191 TELEPHONY_LOGI("GeneratePbrFile: %{public}s", dataPac.c_str());
192 if (dataPac.size() < FstByteChrLen) {
193 continue;
194 }
195 auto subStr = dataPac.substr(0, FstByteChrLen);
196 if (subStr == "FF" || subStr == "ff") {
197 continue;
198 }
199 auto pbrFile = BuildNumberFileByRecord(dataPac);
200 if (pbrFile != nullptr) {
201 pbrFiles_.push_back(pbrFile);
202 auto fileIt = pbrFile->fileIds_.find(TAG_SIM_USIM_ADN);
203 if (fileIt == pbrFile->fileIds_.end()) {
204 continue;
205 }
206 std::shared_ptr<TagData> file = fileIt->second;
207 if (file == nullptr || file->shortFileId == INVALID_SFI) {
208 continue;
209 }
210 efIdOfSfi_.insert(std::pair<int, int>(file->shortFileId, file->fileId));
211 }
212 }
213 }
214
BuildCallerInfo(int eventId)215 AppExecFwk::InnerEvent::Pointer UsimDiallingNumbersService::BuildCallerInfo(int eventId)
216 {
217 std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
218 int eventParam = 0;
219 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
220 if (event == nullptr) {
221 TELEPHONY_LOGE("event is nullptr!");
222 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
223 }
224 event->SetOwner(shared_from_this());
225 return event;
226 }
227
CreateHandlerPointer(int eventid,int efId,int index,std::shared_ptr<void> pobj)228 AppExecFwk::InnerEvent::Pointer UsimDiallingNumbersService::CreateHandlerPointer(
229 int eventid, int efId, int index, std::shared_ptr<void> pobj)
230 {
231 std::unique_ptr<DiallingNumbersHandleHolder> holder = std::make_unique<DiallingNumbersHandleHolder>();
232 if (holder == nullptr) {
233 TELEPHONY_LOGE("holder is nullptr!");
234 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
235 }
236 holder->fileID = efId;
237 holder->index = index;
238 holder->diallingNumber = pobj;
239 int eventParam = 0;
240 AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventid, holder, eventParam);
241 if (event == nullptr) {
242 TELEPHONY_LOGE("event is nullptr!");
243 return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
244 }
245 event->SetOwner(shared_from_this());
246 return event;
247 }
248
SetFileControllerAndDiallingNumberHandler(std::shared_ptr<IccFileController> & ctrl,std::shared_ptr<IccDiallingNumbersHandler> handler)249 void UsimDiallingNumbersService::SetFileControllerAndDiallingNumberHandler(
250 std::shared_ptr<IccFileController> &ctrl, std::shared_ptr<IccDiallingNumbersHandler> handler)
251 {
252 fileController_ = ctrl;
253 diallingNumbersHandler_ = handler;
254 }
255
BuildNumberFileByRecord(const std::string & record)256 std::shared_ptr<UsimDiallingNumberFile> UsimDiallingNumbersService::BuildNumberFileByRecord(
257 const std::string &record)
258 {
259 std::shared_ptr<TagService> recTlv = std::make_shared<TagService>(record);
260 if (recTlv == nullptr) {
261 TELEPHONY_LOGI("BuildNumberFileByRecord: recTlv is nullptr!");
262 return nullptr;
263 }
264 std::shared_ptr<UsimDiallingNumberFile> file = std::make_shared<UsimDiallingNumberFile>();
265 int tag = 0;
266 TELEPHONY_LOGI("BuildNumberFileByRecord: start get tag");
267 while (recTlv->Next()) {
268 tag = recTlv->GetTagCode();
269 TELEPHONY_LOGI("front tag type: %{public}d", tag);
270 if ((tag != TYPE1_FLAG) && (tag != TYPE2_FLAG) && (tag != TYPE3_FLAG)) {
271 TELEPHONY_LOGE("the tag:'%{public}d' need in {%{public}d,%{public}d,%{public}d}", tag, TYPE1_FLAG,
272 TYPE2_FLAG, TYPE3_FLAG);
273 continue;
274 }
275 std::vector<uint8_t> datav;
276 recTlv->GetValue(datav);
277 auto tlvEfSfi = std::make_shared<TagService>(datav);
278 StorePbrDetailInfo(file, tlvEfSfi, tag);
279 }
280 return file;
281 }
282
StorePbrDetailInfo(std::shared_ptr<UsimDiallingNumberFile> file,std::shared_ptr<TagService> tlv,int parentTag)283 void UsimDiallingNumbersService::StorePbrDetailInfo(
284 std::shared_ptr<UsimDiallingNumberFile> file, std::shared_ptr<TagService> tlv, int parentTag)
285 {
286 if (tlv == nullptr) {
287 TELEPHONY_LOGI("StorePbrDetailInfo: tlv is nullptr!");
288 return;
289 }
290 for (int count = 0; tlv->Next(); ++count) {
291 const int tag = tlv->GetTagCode();
292 TELEPHONY_LOGI("make file tag type: %{public}d", tag);
293 if ((tag < TAG_SIM_USIM_ADN) || (tag > TAG_SIM_USIM_CCP1)) {
294 TELEPHONY_LOGE("the tag:'%{public}d' need in range [%{public}d,%{public}d]", tag, TAG_SIM_USIM_ADN,
295 TAG_SIM_USIM_CCP1);
296 continue;
297 }
298 // 3GPP TS 31.102, 4.4.2.1 EF_PBR
299 std::vector<uint8_t> data;
300 tlv->GetValue(data);
301 auto dataIt = data.begin();
302 if (dataIt == data.end()) {
303 TELEPHONY_LOGE("the length of data == 0 ?!");
304 continue;
305 }
306 uint32_t efid = *dataIt;
307 ++dataIt;
308 if (dataIt == data.end()) {
309 TELEPHONY_LOGE("the length of data only one ?!");
310 continue;
311 }
312 efid <<= BIT_OF_BYTE;
313 efid |= *dataIt;
314 ++dataIt;
315 int sfi = (dataIt == data.end()) ? 0 : static_cast<int>((*dataIt));
316 std::shared_ptr<TagData> deltaFile = std::make_shared<TagData>(parentTag, efid, sfi, count);
317 TELEPHONY_LOGI(
318 "MakeFiles result[ parentTag:%{public}d, efid:%{public}d, sfi:%{public}d, count:%{public}d ]",
319 parentTag, efid, sfi, count);
320 file->fileIds_.insert(std::pair<int, std::shared_ptr<TagData>>(tag, deltaFile));
321 }
322 }
323
SendBackResult(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & diallingnumbers)324 void UsimDiallingNumbersService::SendBackResult(
325 const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &diallingnumbers)
326 {
327 if (callerPointer_ == nullptr) {
328 TELEPHONY_LOGE("callerPointer_ is nullptr");
329 return;
330 }
331 auto owner = callerPointer_->GetOwner();
332 if (owner == nullptr) {
333 TELEPHONY_LOGE("owner is nullptr");
334 return;
335 }
336 uint32_t id = callerPointer_->GetInnerEventId();
337 std::unique_ptr<UsimFetcher> fd = callerPointer_->GetUniqueObject<UsimFetcher>();
338 std::unique_ptr<UsimResult> data = std::make_unique<UsimResult>(fd.get());
339 if (data == nullptr) {
340 TELEPHONY_LOGE("data is nullptr");
341 return;
342 }
343 data->result = static_cast<std::shared_ptr<void>>(diallingnumbers);
344 TelEventHandler::SendTelEvent(owner, id, data);
345 TELEPHONY_LOGI("UsimDiallingNumbersService::SendBackResult send end");
346 }
347
SendLocalBack()348 void UsimDiallingNumbersService::UsimDiallingNumbersService::SendLocalBack()
349 {
350 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingnumbers =
351 std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(&diallingNumbersFiles_);
352 SendBackResult(diallingnumbers);
353 }
354
NextStep(int msgId)355 void UsimDiallingNumbersService::NextStep(int msgId)
356 {
357 std::unique_ptr<int> step = std::make_unique<int>(NEXT);
358 SendEvent(msgId, step);
359 }
360
~UsimDiallingNumbersService()361 UsimDiallingNumbersService::~UsimDiallingNumbersService() {}
362 } // namespace Telephony
363 } // namespace OHOS
364