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