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 "sim_sms_controller.h"
17 
18 #include "core_service_errors.h"
19 
20 namespace OHOS {
21 namespace Telephony {
22 std::mutex SimSmsController::mtx_;
23 constexpr static const int32_t WAIT_TIME_SECOND = 1;
24 constexpr static const int32_t WAIT_TIME_TEN_SECOND = 10;
25 
SimSmsController(std::shared_ptr<SimStateManager> simStateManager)26 SimSmsController::SimSmsController(std::shared_ptr<SimStateManager> simStateManager)
27     : TelEventHandler("SimSmsController"), stateManager_(simStateManager)
28 {}
29 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)30 void SimSmsController::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
31 {
32     if (event == nullptr) {
33         TELEPHONY_LOGE("SimSmsController ProcessEvent event is nullptr");
34         return;
35     }
36     uint32_t id = event->GetInnerEventId();
37     TELEPHONY_LOGD("SimSmsController ProcessEvent Id is %{public}d", id);
38     switch (id) {
39         case SIM_SMS_GET_COMPLETED:
40             ProcessLoadDone(event);
41             break;
42         case SIM_SMS_UPDATE_COMPLETED:
43             TELEPHONY_LOGI("ProcessEvent update");
44             ProcessUpdateDone(event);
45             break;
46         case SIM_SMS_WRITE_COMPLETED:
47             TELEPHONY_LOGI("ProcessEvent write");
48             ProcessWriteDone(event);
49             break;
50         case SIM_SMS_DELETE_COMPLETED:
51             ProcessDeleteDone(event);
52             break;
53         default:
54             break;
55     }
56 }
57 
ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer & event)58 void SimSmsController::ProcessLoadDone(const AppExecFwk::InnerEvent::Pointer &event)
59 {
60     TELEPHONY_LOGI("SimSmsController::ProcessLoadDone: start");
61     if (event == nullptr) {
62         TELEPHONY_LOGE("SimSmsController ProcessLoadDone event is nullptr");
63         return;
64     }
65     std::unique_ptr<ControllerToFileMsg> fd = event->GetUniqueObject<ControllerToFileMsg>();
66     if (fd != nullptr) {
67         if (fd->exception != nullptr) {
68             TELEPHONY_LOGE("ProcessLoadDone: get error result");
69             std::vector<std::string> nullVector;
70             smsList_.swap(nullVector);
71         }
72     } else {
73         std::shared_ptr<MultiRecordResult> object = event->GetSharedObject<MultiRecordResult>();
74         if (object != nullptr) {
75             TELEPHONY_LOGI("SimSmsController::ProcessLoadDone: %{public}d", object->resultLength);
76             if (object->exception == nullptr) {
77                 smsList_.assign(object->fileResults.begin(), object->fileResults.end());
78             }
79         } else {
80             TELEPHONY_LOGE("ProcessLoadDone: get null pointer!!!");
81         }
82     }
83     loadDone_ = true;
84     processWait_.notify_all();
85 }
86 
ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer & event)87 void SimSmsController::ProcessUpdateDone(const AppExecFwk::InnerEvent::Pointer &event)
88 {
89     if (event == nullptr) {
90         TELEPHONY_LOGE("SimSmsController ProcessUpdateDone event is nullptr");
91         return;
92     }
93     responseReady_ = true;
94     std::shared_ptr<RadioResponseInfo> responseInfo = event->GetSharedObject<RadioResponseInfo>();
95     if (responseInfo != nullptr) {
96         TELEPHONY_LOGE("SimSmsController::ProcessUpdateDone error %{public}d", responseInfo->error);
97         responseReady_ = (responseInfo->error == ErrType::NONE);
98     }
99     TELEPHONY_LOGI("SimSmsController::ProcessUpdateDone: end");
100     processWait_.notify_all();
101 }
102 
ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer & event)103 void SimSmsController::ProcessWriteDone(const AppExecFwk::InnerEvent::Pointer &event)
104 {
105     if (event == nullptr) {
106         TELEPHONY_LOGE("SimSmsController ProcessWriteDone event is nullptr");
107         return;
108     }
109     responseReady_ = true;
110     std::shared_ptr<RadioResponseInfo> responseInfo = event->GetSharedObject<RadioResponseInfo>();
111     if (responseInfo != nullptr) {
112         TELEPHONY_LOGE("SimSmsController::ProcessWriteDone error %{public}d", responseInfo->error);
113         responseReady_ = (responseInfo->error == ErrType::NONE);
114     }
115     TELEPHONY_LOGI("SimSmsController::ProcessWriteDone: end");
116     processWait_.notify_all();
117 }
118 
ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer & event)119 void SimSmsController::ProcessDeleteDone(const AppExecFwk::InnerEvent::Pointer &event)
120 {
121     if (event == nullptr) {
122         TELEPHONY_LOGE("SimSmsController ProcessDeleteDone event is nullptr");
123         return;
124     }
125     responseReady_ = true;
126     std::shared_ptr<RadioResponseInfo> responseInfo = event->GetSharedObject<RadioResponseInfo>();
127     if (responseInfo != nullptr) {
128         TELEPHONY_LOGE("SimSmsController::ProcessDeleteDone error %{public}d", responseInfo->error);
129         responseReady_ = (responseInfo->error == ErrType::NONE);
130     }
131     TELEPHONY_LOGI("SimSmsController::ProcessDeleteDone: end");
132     processWait_.notify_all();
133 }
134 
UpdateSmsIcc(int index,int status,std::string & pduData,std::string & smsc)135 int32_t SimSmsController::UpdateSmsIcc(int index, int status, std::string &pduData, std::string &smsc)
136 {
137     std::unique_lock<std::mutex> lock(mtx_);
138     bool isCDMA = IsCdmaCardType();
139     TELEPHONY_LOGI("UpdateSmsIcc start: %{public}d, %{public}d", index, isCDMA);
140     responseReady_ = false;
141     if (!isCDMA) {
142         AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(SIM_SMS_UPDATE_COMPLETED);
143         SimMessageParam param { index, status, smsc, pduData };
144         telRilManager_->UpdateSimMessage(slotId_, param, response);
145     } else {
146         AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(SIM_SMS_UPDATE_COMPLETED);
147         CdmaSimMessageParam param { index, status, pduData };
148         telRilManager_->UpdateCdmaSimMessage(slotId_, param, response);
149     }
150     while (!responseReady_) {
151         TELEPHONY_LOGI("UpdateSmsIcc::wait(), response = false");
152         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
153             break;
154         }
155     }
156     TELEPHONY_LOGI("SimSmsController::UpdateSmsIcc OK return %{public}d", responseReady_);
157     if (responseReady_) {
158         return TELEPHONY_ERR_SUCCESS;
159     } else {
160         return CORE_ERR_SIM_CARD_UPDATE_FAILED;
161     }
162 }
163 
DelSmsIcc(int index)164 int32_t SimSmsController::DelSmsIcc(int index)
165 {
166     std::unique_lock<std::mutex> lock(mtx_);
167     bool isCDMA = IsCdmaCardType();
168     TELEPHONY_LOGI("DelSmsIcc start: %{public}d, %{public}d", index, isCDMA);
169     responseReady_ = false;
170     if (!isCDMA) {
171         AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(SIM_SMS_DELETE_COMPLETED);
172         telRilManager_->DelSimMessage(slotId_, index, response);
173         TELEPHONY_LOGI("SimSmsController::DelSmsIcc OK return %{public}d", responseReady_);
174     } else {
175         AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(SIM_SMS_DELETE_COMPLETED);
176         telRilManager_->DelCdmaSimMessage(slotId_, index, response);
177         TELEPHONY_LOGI("SimSmsController::DelCdmaSimMessage OK return %{public}d", responseReady_);
178     }
179     while (!responseReady_) {
180         TELEPHONY_LOGI("DelSmsIcc::wait(), response = false");
181         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
182             break;
183         }
184     }
185     if (responseReady_) {
186         return TELEPHONY_ERR_SUCCESS;
187     } else {
188         return CORE_ERR_SIM_CARD_UPDATE_FAILED;
189     }
190 }
191 
AddSmsToIcc(int status,std::string & pdu,std::string & smsc)192 int32_t SimSmsController::AddSmsToIcc(int status, std::string &pdu, std::string &smsc)
193 {
194     std::unique_lock<std::mutex> lock(mtx_);
195     bool isCDMA = IsCdmaCardType();
196     TELEPHONY_LOGI("AddSmsToIcc start: %{public}d, %{public}d", status, isCDMA);
197     responseReady_ = false;
198     if (!isCDMA) {
199         AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(SIM_SMS_WRITE_COMPLETED);
200         SimMessageParam param { 0, status, smsc, pdu };
201         telRilManager_->AddSimMessage(slotId_, param, response);
202     } else {
203         AppExecFwk::InnerEvent::Pointer response = BuildCallerInfo(SIM_SMS_WRITE_COMPLETED);
204         telRilManager_->AddCdmaSimMessage(slotId_, status, pdu, response);
205     }
206     while (!responseReady_) {
207         TELEPHONY_LOGI("AddSmsToIcc::wait(), response = false");
208         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
209             break;
210         }
211     }
212     TELEPHONY_LOGI("SimSmsController::AddSmsToIcc OK return %{public}d", responseReady_);
213     if (responseReady_) {
214         return TELEPHONY_ERR_SUCCESS;
215     } else {
216         return CORE_ERR_SIM_CARD_UPDATE_FAILED;
217     }
218 }
219 
Init(int slodId)220 void SimSmsController::Init(int slodId)
221 {
222     slotId_ = slodId;
223 }
224 
ObtainAllSmsOfIcc()225 std::vector<std::string> SimSmsController::ObtainAllSmsOfIcc()
226 {
227     std::unique_lock<std::mutex> lock(mtx_);
228     std::shared_ptr<IccFileController> fileController = fileManager_->GetIccFileController();
229     loadDone_ = false;
230     if (fileController == nullptr) {
231         TELEPHONY_LOGE("Cannot load Sms records. No icc card?");
232         std::vector<std::string> nullVector;
233         smsList_.swap(nullVector);
234         return smsList_;
235     }
236     TELEPHONY_LOGI("ObtainAllSmsOfIcc start!!");
237     AppExecFwk::InnerEvent::Pointer event = BuildCallerInfo(SIM_SMS_GET_COMPLETED);
238     fileController->ObtainAllLinearFixedFile(ELEMENTARY_FILE_SMS, event);
239     while (!loadDone_) {
240         TELEPHONY_LOGI("ObtainAllSmsOfIcc::wait(), response = false");
241         if (processWait_.wait_for(lock, std::chrono::seconds(WAIT_TIME_TEN_SECOND)) == std::cv_status::timeout) {
242             break;
243         }
244     }
245     TELEPHONY_LOGI("SimSmsController::ObtainAllSmsOfIcc: end");
246     return smsList_;
247 }
248 
SetRilAndFileManager(std::shared_ptr<Telephony::ITelRilManager> ril,std::shared_ptr<SimFileManager> fileMgr)249 void SimSmsController::SetRilAndFileManager(
250     std::shared_ptr<Telephony::ITelRilManager> ril, std::shared_ptr<SimFileManager> fileMgr)
251 {
252     telRilManager_ = ril;
253     if (telRilManager_ == nullptr) {
254         TELEPHONY_LOGE("SimSmsController rilmanager get null pointer");
255     }
256     fileManager_ = fileMgr;
257     if (fileManager_ == nullptr) {
258         TELEPHONY_LOGE("SimSmsController fileManager get null pointer");
259     }
260 }
261 
BuildCallerInfo(int eventId)262 AppExecFwk::InnerEvent::Pointer SimSmsController::BuildCallerInfo(int eventId)
263 {
264     std::unique_ptr<FileToControllerMsg> object = std::make_unique<FileToControllerMsg>();
265     int eventParam = 0;
266     AppExecFwk::InnerEvent::Pointer event = AppExecFwk::InnerEvent::Get(eventId, object, eventParam);
267     if (event == nullptr) {
268         TELEPHONY_LOGE("event is nullptr!");
269         return AppExecFwk::InnerEvent::Pointer(nullptr, nullptr);
270     }
271     event->SetOwner(shared_from_this());
272     return event;
273 }
274 
IsCdmaCardType() const275 bool SimSmsController::IsCdmaCardType() const
276 {
277     bool isCdmaType = false;
278     if (stateManager_ != nullptr) {
279         CardType type = stateManager_->GetCardType();
280         TELEPHONY_LOGI("IsCdmaCardType card type id %{public}d", type);
281         if (type == CardType::SINGLE_MODE_RUIM_CARD) {
282             isCdmaType = true; // cdma
283         }
284     }
285     TELEPHONY_LOGI("IsCdmaCardType result %{public}d", isCdmaType);
286     return isCdmaType;
287 }
288 
~SimSmsController()289 SimSmsController::~SimSmsController() {}
290 } // namespace Telephony
291 } // namespace OHOS
292