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