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_manager.h"
17 
18 #include "core_service_errors.h"
19 #include "radio_event.h"
20 #include "telephony_errors.h"
21 
22 namespace OHOS {
23 namespace Telephony {
24 constexpr static const int32_t WAIT_TIME_SECOND = 1;
25 constexpr static const int32_t WAIT_QUERY_TIME_SECOND = 30;
26 
IccDiallingNumbersManager(std::weak_ptr<SimFileManager> simFileManager,std::shared_ptr<SimStateManager> simState)27 IccDiallingNumbersManager::IccDiallingNumbersManager(
28     std::weak_ptr<SimFileManager> simFileManager, std::shared_ptr<SimStateManager> simState)
29     : TelEventHandler("IccDiallingNumbersManager"), simFileManager_(simFileManager), simStateManager_(simState)
30 {}
31 
Init()32 void IccDiallingNumbersManager::Init()
33 {
34     TELEPHONY_LOGI("IccDiallingNumbersManager::Init() started ");
35     if (stateDiallingNumbers_ == HandleRunningState::STATE_RUNNING) {
36         TELEPHONY_LOGI("IccDiallingNumbersManager::Init eventLoopDiallingNumbers_ started.");
37         return;
38     }
39 
40     auto simFileManager = simFileManager_.lock();
41     if (simFileManager == nullptr) {
42         TELEPHONY_LOGE("SimFileManager null pointer");
43         return;
44     }
45 
46     diallingNumbersCache_ = std::make_shared<IccDiallingNumbersCache>(simFileManager);
47     if (diallingNumbersCache_ == nullptr) {
48         TELEPHONY_LOGE("simFile create nullptr.");
49         return;
50     }
51 
52     stateDiallingNumbers_ = HandleRunningState::STATE_RUNNING;
53 
54     diallingNumbersCache_->Init();
55     simFileManager->RegisterCoreNotify(shared_from_this(), RadioEvent::RADIO_SIM_RECORDS_LOADED);
56     TELEPHONY_LOGI("Init() end");
57 }
58 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)59 void IccDiallingNumbersManager::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
60 {
61     if (event == nullptr) {
62         TELEPHONY_LOGE("event is nullptr!");
63         return;
64     }
65     uint32_t id = event->GetInnerEventId();
66     TELEPHONY_LOGD("IccDiallingNumbersManager ProcessEvent Id is %{public}d", id);
67     switch (id) {
68         case MSG_SIM_DIALLING_NUMBERS_GET_DONE:
69             ProcessLoadDone(event);
70             break;
71         case MSG_SIM_DIALLING_NUMBERS_UPDATE_DONE:
72             ProcessUpdateDone(event);
73             break;
74         case MSG_SIM_DIALLING_NUMBERS_WRITE_DONE:
75             ProcessWriteDone(event);
76             break;
77         case MSG_SIM_DIALLING_NUMBERS_DELETE_DONE:
78             ProcessDeleteDone(event);
79             break;
80         default:
81             break;
82     }
83 }
84 
ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer & event)85 void IccDiallingNumbersManager::ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer &event)
86 {
87     TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessLoadDone: start");
88     std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
89     if (object != nullptr) {
90         if (object->exception == nullptr) {
91             std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> diallingNumberList =
92                 std::static_pointer_cast<std::vector<std::shared_ptr<DiallingNumbersInfo>>>(object->result);
93             if (diallingNumberList != nullptr) {
94                 FillResults(diallingNumberList);
95             } else {
96                 TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: get null vectors!!!");
97             }
98         } else {
99             TELEPHONY_LOGE("ProcessLoadDone: icc diallingnumbers get exception result");
100         }
101     } else {
102         TELEPHONY_LOGE("ProcessDiallingNumberLoadDone: get null pointer!!!");
103     }
104     TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessLoadDone: end");
105     hasQueryEventDone_ = true;
106     processWait_.notify_all();
107 }
108 
ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer & event)109 void IccDiallingNumbersManager::ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer &event)
110 {
111     std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
112     if (object != nullptr && object->exception != nullptr) {
113         std::shared_ptr<RadioResponseInfo> responseInfo =
114             std::static_pointer_cast<RadioResponseInfo>(object->exception);
115         TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessUpdateDone error %{public}d", responseInfo->error);
116         hasEventDone_ = (responseInfo->error == ErrType::NONE);
117     } else {
118         hasEventDone_ = true;
119     }
120     TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessUpdateDone: end");
121     processWait_.notify_all();
122 }
123 
ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer & event)124 void IccDiallingNumbersManager::ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer &event)
125 {
126     std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
127     if (object != nullptr && object->exception != nullptr) {
128         std::shared_ptr<RadioResponseInfo> responseInfo =
129             std::static_pointer_cast<RadioResponseInfo>(object->exception);
130         TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessWriteDone error %{public}d", responseInfo->error);
131         hasEventDone_ = (responseInfo->error == ErrType::NONE);
132     } else {
133         hasEventDone_ = true;
134     }
135     TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessWriteDone: end");
136     processWait_.notify_all();
137 }
138 
ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer & event)139 void IccDiallingNumbersManager::ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer &event)
140 {
141     std::unique_ptr<ResponseResult> object = event->GetUniqueObject<ResponseResult>();
142     if (object != nullptr && object->exception != nullptr) {
143         std::shared_ptr<RadioResponseInfo> responseInfo =
144             std::static_pointer_cast<RadioResponseInfo>(object->exception);
145         TELEPHONY_LOGE("IccDiallingNumbersManager::ProcessDeleteDone error %{public}d", responseInfo->error);
146         hasEventDone_ = (responseInfo->error == ErrType::NONE);
147     } else {
148         hasEventDone_ = true;
149     }
150     TELEPHONY_LOGI("IccDiallingNumbersManager::ProcessDeleteDone: end");
151     processWait_.notify_all();
152 }
153 
UpdateIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)154 int32_t IccDiallingNumbersManager::UpdateIccDiallingNumbers(
155     int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
156 {
157     std::unique_lock<std::mutex> lock(mtx_);
158     if (diallingNumber == nullptr) {
159         return TELEPHONY_ERR_LOCAL_PTR_NULL;
160     }
161     if (!HasSimCard()) {
162         return TELEPHONY_ERR_NO_SIM_CARD;
163     }
164     if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
165         return TELEPHONY_ERR_ARGUMENT_INVALID;
166     }
167     int index = diallingNumber->GetIndex();
168     TELEPHONY_LOGI("UpdateIccDiallingNumbers start: %{public}d %{public}d", type, index);
169     int fileId = GetFileIdForType(type);
170     AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_UPDATE_DONE);
171     hasEventDone_ = false;
172     diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, index, false, response);
173     while (!hasEventDone_) {
174         TELEPHONY_LOGI("UpdateIccDiallingNumbers::wait(), response = false");
175         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
176             break;
177         }
178     }
179     TELEPHONY_LOGI("IccDiallingNumbersManager::UpdateIccDiallingNumbers OK return %{public}d", hasEventDone_);
180     return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
181 }
182 
DelIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)183 int32_t IccDiallingNumbersManager::DelIccDiallingNumbers(
184     int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
185 {
186     std::unique_lock<std::mutex> lock(mtx_);
187     if (diallingNumber == nullptr) {
188         return TELEPHONY_ERR_LOCAL_PTR_NULL;
189     }
190     if (!HasSimCard()) {
191         return TELEPHONY_ERR_NO_SIM_CARD;
192     }
193     if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
194         return TELEPHONY_ERR_ARGUMENT_INVALID;
195     }
196     int index = diallingNumber->GetIndex();
197     TELEPHONY_LOGI("DelIccDiallingNumbers start: %{public}d %{public}d", type, index);
198     int fileId = GetFileIdForType(type);
199     AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_DELETE_DONE);
200     hasEventDone_ = false;
201     diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, index, true, response);
202     while (!hasEventDone_) {
203         TELEPHONY_LOGI("DelIccDiallingNumbers::wait(), response = false");
204         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
205             break;
206         }
207     }
208     TELEPHONY_LOGI("IccDiallingNumbersManager::DelIccDiallingNumbers OK return %{public}d", hasEventDone_);
209     return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
210 }
211 
AddIccDiallingNumbers(int type,const std::shared_ptr<DiallingNumbersInfo> & diallingNumber)212 int32_t IccDiallingNumbersManager::AddIccDiallingNumbers(
213     int type, const std::shared_ptr<DiallingNumbersInfo> &diallingNumber)
214 {
215     std::unique_lock<std::mutex> lock(mtx_);
216     TELEPHONY_LOGI("AddIccDiallingNumbers start:%{public}d", type);
217     if (diallingNumber == nullptr) {
218         return TELEPHONY_ERR_LOCAL_PTR_NULL;
219     }
220     if (!HasSimCard()) {
221         return TELEPHONY_ERR_NO_SIM_CARD;
222     }
223     if (!IsValidType(type) || !IsValidParam(type, diallingNumber)) {
224         return TELEPHONY_ERR_ARGUMENT_INVALID;
225     }
226     AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_WRITE_DONE);
227     int fileId = GetFileIdForType(type);
228     hasEventDone_ = false;
229     diallingNumbersCache_->UpdateDiallingNumberToIcc(fileId, diallingNumber, ADD_FLAG, false, response);
230     while (!hasEventDone_) {
231         TELEPHONY_LOGI("AddIccDiallingNumbers::wait(), response = false");
232         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
233             break;
234         }
235     }
236     TELEPHONY_LOGI("IccDiallingNumbersManager::AddIccDiallingNumbers OK return %{public}d", hasEventDone_);
237     return hasEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_UPDATE_FAILED;
238 }
239 
QueryIccDiallingNumbers(int type,std::vector<std::shared_ptr<DiallingNumbersInfo>> & result)240 int32_t IccDiallingNumbersManager::QueryIccDiallingNumbers(
241     int type, std::vector<std::shared_ptr<DiallingNumbersInfo>> &result)
242 {
243     std::unique_lock<std::mutex> lock(mtx_);
244     if (diallingNumbersCache_ == nullptr) {
245         return TELEPHONY_ERR_LOCAL_PTR_NULL;
246     }
247     if (!HasSimCard()) {
248         return TELEPHONY_ERR_NO_SIM_CARD;
249     }
250     if (!IsValidType(type)) {
251         return TELEPHONY_ERR_ARGUMENT_INVALID;
252     }
253     TELEPHONY_LOGI("QueryIccDiallingNumbers start:%{public}d", type);
254     if (hasQueryEventDone_) {
255         ClearRecords();
256         int fileId = GetFileIdForType(type);
257         int extensionEf = diallingNumbersCache_->ExtendedElementFile(fileId);
258         AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(MSG_SIM_DIALLING_NUMBERS_GET_DONE);
259         hasQueryEventDone_ = false;
260         diallingNumbersCache_->ObtainAllDiallingNumberFiles(fileId, extensionEf, event);
261     }
262     processWait_.wait_for(
263         lock, std::chrono::seconds(WAIT_QUERY_TIME_SECOND), [this] { return hasQueryEventDone_ == true; });
264     TELEPHONY_LOGI("QueryIccDiallingNumbers: end");
265     if (!diallingNumbersList_.empty()) {
266         result = diallingNumbersList_;
267     }
268     return hasQueryEventDone_ ? TELEPHONY_SUCCESS : CORE_ERR_SIM_CARD_LOAD_FAILED;
269 }
270 
BuildCallerInfo(int eventId)271 AppExecFwk::InnerEvent::Pointer IccDiallingNumbersManager::BuildCallerInfo(int eventId)
272 {
273     std::unique_ptr<ResultObtain> object = std::make_unique<ResultObtain>();
274     int eventParam = 0;
275     AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
276     if (event == nullptr) {
277         TELEPHONY_LOGE("event is nullptr!");
278         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
279     }
280     event->SetOwner(shared_from_this());
281     return event;
282 }
283 
ClearRecords()284 void IccDiallingNumbersManager::ClearRecords()
285 {
286     std::vector<std::shared_ptr<DiallingNumbersInfo>> nullVector;
287     diallingNumbersList_.swap(nullVector);
288 }
289 
GetFileIdForType(int fileType)290 int IccDiallingNumbersManager::GetFileIdForType(int fileType)
291 {
292     int fileId = 0;
293     if (fileType == DiallingNumbersInfo::SIM_ADN) {
294         fileId = ELEMENTARY_FILE_ADN; //  ELEMENTARY_FILE_PBR  for usim
295     } else if (fileType == DiallingNumbersInfo::SIM_FDN) {
296         fileId = ELEMENTARY_FILE_FDN;
297     }
298     return fileId;
299 }
300 
FillResults(const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> & listInfo)301 void IccDiallingNumbersManager::FillResults(
302     const std::shared_ptr<std::vector<std::shared_ptr<DiallingNumbersInfo>>> &listInfo)
303 {
304     TELEPHONY_LOGI("IccDiallingNumbersManager::FillResults  %{public}zu", listInfo->size());
305     for (auto it = listInfo->begin(); it != listInfo->end(); it++) {
306         std::shared_ptr<DiallingNumbersInfo> item = *it;
307         if (!item->IsEmpty()) {
308             diallingNumbersList_.push_back(item);
309         }
310     }
311     TELEPHONY_LOGI("IccDiallingNumbersManager::FillResults end");
312 }
313 
IsValidType(int type)314 bool IccDiallingNumbersManager::IsValidType(int type)
315 {
316     switch (type) {
317         case DiallingNumbersInfo::SIM_ADN:
318         case DiallingNumbersInfo::SIM_FDN:
319             return true;
320         default:
321             return false;
322     }
323 }
324 
CreateInstance(std::weak_ptr<SimFileManager> simFile,std::shared_ptr<SimStateManager> simState)325 std::shared_ptr<IccDiallingNumbersManager> IccDiallingNumbersManager::CreateInstance(
326     std::weak_ptr<SimFileManager> simFile, std::shared_ptr<SimStateManager> simState)
327 {
328     if (simFile.lock() == nullptr) {
329         TELEPHONY_LOGE("IccDiallingNumbersManager::Init SimFileManager null pointer");
330         return nullptr;
331     }
332     std::shared_ptr<IccDiallingNumbersManager> manager = std::make_shared<IccDiallingNumbersManager>(simFile, simState);
333     if (manager == nullptr) {
334         TELEPHONY_LOGE("IccDiallingNumbersManager::Init manager create nullptr.");
335         return nullptr;
336     }
337     return manager;
338 }
339 
HasSimCard()340 bool IccDiallingNumbersManager::HasSimCard()
341 {
342     return (simStateManager_ != nullptr) ? simStateManager_->HasSimCard() : false;
343 }
344 
IsValidParam(int type,const std::shared_ptr<DiallingNumbersInfo> & info)345 bool IccDiallingNumbersManager::IsValidParam(int type, const std::shared_ptr<DiallingNumbersInfo> &info)
346 {
347     if (type == DiallingNumbersInfo::SIM_FDN) {
348         return !(info->pin2_.empty());
349     } else {
350         return true;
351     }
352 }
353 
~IccDiallingNumbersManager()354 IccDiallingNumbersManager::~IccDiallingNumbersManager() {}
355 } // namespace Telephony
356 } // namespace OHOS
357