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 "sms_sender.h"
17
18 #include "core_manager_inner.h"
19 #include "ims_sms_client.h"
20 #include "radio_event.h"
21 #include "sms_hisysevent.h"
22 #include "string_utils.h"
23 #include "telephony_log_wrapper.h"
24
25 namespace OHOS {
26 namespace Telephony {
27 using namespace std;
28 using namespace std::chrono;
SmsSender(const shared_ptr<AppExecFwk::EventRunner> & runner,int32_t slotId,function<void (shared_ptr<SmsSendIndexer>)> & sendRetryFun)29 SmsSender::SmsSender(const shared_ptr<AppExecFwk::EventRunner> &runner, int32_t slotId,
30 function<void(shared_ptr<SmsSendIndexer>)> &sendRetryFun)
31 : AppExecFwk::EventHandler(runner), slotId_(slotId), sendRetryFun_(sendRetryFun)
32 {}
33
~SmsSender()34 SmsSender::~SmsSender() {}
35
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)36 void SmsSender::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
37 {
38 if (event == nullptr) {
39 TELEPHONY_LOGE("event is nullptr");
40 return;
41 }
42 shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
43 uint32_t eventId = event->GetInnerEventId();
44 TELEPHONY_LOGI("SmsSender::ProcessEvent eventId %{public}d", eventId);
45 switch (eventId) {
46 case RadioEvent::RADIO_SEND_SMS:
47 case RadioEvent::RADIO_SEND_CDMA_SMS:
48 case RadioEvent::RADIO_SEND_IMS_GSM_SMS:
49 case RadioEvent::RADIO_SEND_SMS_EXPECT_MORE: {
50 smsIndexer = FindCacheMapAndTransform(event);
51 HandleMessageResponse(smsIndexer);
52 break;
53 }
54 case MSG_SMS_RETRY_DELIVERY: {
55 smsIndexer = event->GetSharedObject<SmsSendIndexer>();
56 if (sendRetryFun_ != nullptr) {
57 sendRetryFun_(smsIndexer);
58 }
59 break;
60 }
61 case RadioEvent::RADIO_SMS_STATUS: {
62 StatusReportAnalysis(event);
63 break;
64 }
65 case RadioEvent::RADIO_SET_IMS_SMS: {
66 StatusReportSetImsSms(event);
67 SyncSwitchISmsResponse();
68 break;
69 }
70 case RadioEvent::RADIO_GET_IMS_SMS: {
71 StatusReportGetImsSms(event);
72 SyncSwitchISmsResponse();
73 break;
74 }
75 default:
76 TELEPHONY_LOGE("SmsSender::ProcessEvent Unknown %{public}d", eventId);
77 break;
78 }
79 }
80
SyncSwitchISmsResponse()81 void SmsSender::SyncSwitchISmsResponse()
82 {
83 std::unique_lock<std::mutex> lck(ctx_);
84 resIsSmsReady_ = true;
85 TELEPHONY_LOGI("resIsSmsReady_ = %{public}d", resIsSmsReady_);
86 cv_.notify_one();
87 }
88
HandleMessageResponse(const shared_ptr<SmsSendIndexer> & smsIndexer)89 void SmsSender::HandleMessageResponse(const shared_ptr<SmsSendIndexer> &smsIndexer)
90 {
91 if (smsIndexer == nullptr) {
92 TELEPHONY_LOGE("smsIndexer is nullptr");
93 return;
94 }
95 if (!SendCacheMapEraseItem(smsIndexer->GetMsgRefId64Bit())) {
96 TELEPHONY_LOGE("SendCacheMapEraseItem fail !!!!!");
97 }
98 SendCacheMapTimeoutCheck();
99 if (!smsIndexer->GetIsFailure()) {
100 if (smsIndexer->GetDeliveryCallback() != nullptr) {
101 // Expecting a status report. Add it to the list.
102 if (reportList_.size() > MAX_REPORT_LIST_LIMIT) {
103 reportList_.pop_front();
104 }
105 reportList_.push_back(smsIndexer);
106 }
107 SendMessageSucceed(smsIndexer);
108 } else {
109 HandleResend(smsIndexer);
110 }
111 }
112
SendMessageSucceed(const shared_ptr<SmsSendIndexer> & smsIndexer)113 void SmsSender::SendMessageSucceed(const shared_ptr<SmsSendIndexer> &smsIndexer)
114 {
115 if (smsIndexer == nullptr) {
116 TELEPHONY_LOGE("SendMessageSucceed but smsIndexer drop!");
117 return;
118 }
119
120 bool isLastPart = false;
121 uint8_t unSentCellCount = smsIndexer->GetUnSentCellCount();
122 if (unSentCellCount == 0) {
123 isLastPart = true;
124 }
125 TELEPHONY_LOGI("isLastPart:%{public}d", isLastPart);
126 if (isLastPart) {
127 smsIndexer->SetPsResendCount(INITIAL_COUNT);
128 smsIndexer->SetCsResendCount(INITIAL_COUNT);
129 ISendShortMessageCallback::SmsSendResult messageType = ISendShortMessageCallback::SEND_SMS_SUCCESS;
130 if (smsIndexer->GetHasCellFailed() != nullptr) {
131 if (*smsIndexer->GetHasCellFailed()) {
132 messageType = ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN;
133 }
134 }
135 SendResultCallBack(smsIndexer->GetSendCallback(), messageType);
136 if (messageType == ISendShortMessageCallback::SEND_SMS_SUCCESS) {
137 SmsHiSysEvent::WriteSmsSendBehaviorEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE);
138 }
139 }
140 }
141
SendMessageFailed(const shared_ptr<SmsSendIndexer> & smsIndexer)142 void SmsSender::SendMessageFailed(const shared_ptr<SmsSendIndexer> &smsIndexer)
143 {
144 if (smsIndexer == nullptr) {
145 TELEPHONY_LOGE("smsIndexer is nullptr");
146 return;
147 }
148 shared_ptr<bool> hasCellFailed = smsIndexer->GetHasCellFailed();
149 if (hasCellFailed != nullptr) {
150 *hasCellFailed = true;
151 }
152
153 bool isLastPart = false;
154 uint8_t unSentCellCount = smsIndexer->GetUnSentCellCount();
155 if (unSentCellCount == 0) {
156 isLastPart = true;
157 }
158 TELEPHONY_LOGI("isLastPart:%{public}d", isLastPart);
159 if (isLastPart) {
160 smsIndexer->SetPsResendCount(INITIAL_COUNT);
161 smsIndexer->SetCsResendCount(INITIAL_COUNT);
162 // save to db and update state
163 sptr<ISendShortMessageCallback> sendCallback = smsIndexer->GetSendCallback();
164 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
165 }
166 }
167
SendResultCallBack(const std::shared_ptr<SmsSendIndexer> & indexer,ISendShortMessageCallback::SmsSendResult result)168 void SmsSender::SendResultCallBack(
169 const std::shared_ptr<SmsSendIndexer> &indexer, ISendShortMessageCallback::SmsSendResult result)
170 {
171 if (indexer != nullptr && indexer->GetSendCallback() != nullptr) {
172 indexer->GetSendCallback()->OnSmsSendResult(result);
173 }
174 }
175
SendResultCallBack(const sptr<ISendShortMessageCallback> & sendCallback,ISendShortMessageCallback::SmsSendResult result)176 void SmsSender::SendResultCallBack(
177 const sptr<ISendShortMessageCallback> &sendCallback, ISendShortMessageCallback::SmsSendResult result)
178 {
179 if (sendCallback != nullptr) {
180 sendCallback->OnSmsSendResult(result);
181 }
182 }
183
SendCacheMapTimeoutCheck()184 void SmsSender::SendCacheMapTimeoutCheck()
185 {
186 std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
187 system_clock::duration timePoint = system_clock::now().time_since_epoch();
188 seconds sec = duration_cast<seconds>(timePoint);
189 int64_t timeStamp = sec.count();
190 auto item = sendCacheMap_.begin();
191 while (item != sendCacheMap_.end()) {
192 auto iter = item++;
193 shared_ptr<SmsSendIndexer> &indexer = iter->second;
194 if (indexer == nullptr || (timeStamp - indexer->GetTimeStamp()) > EXPIRED_TIME) {
195 sendCacheMap_.erase(iter);
196 }
197 }
198 }
199
SendCacheMapLimitCheck(const sptr<ISendShortMessageCallback> & sendCallback)200 bool SmsSender::SendCacheMapLimitCheck(const sptr<ISendShortMessageCallback> &sendCallback)
201 {
202 std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
203 if (sendCacheMap_.size() > MSG_QUEUE_LIMIT) {
204 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
205 return true;
206 }
207 return false;
208 }
209
SendCacheMapAddItem(int64_t id,const std::shared_ptr<SmsSendIndexer> & smsIndexer)210 bool SmsSender::SendCacheMapAddItem(int64_t id, const std::shared_ptr<SmsSendIndexer> &smsIndexer)
211 {
212 std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
213 if (smsIndexer != nullptr) {
214 auto result = sendCacheMap_.emplace(id, smsIndexer);
215 return result.second;
216 }
217 return false;
218 }
219
SendCacheMapEraseItem(int64_t id)220 bool SmsSender::SendCacheMapEraseItem(int64_t id)
221 {
222 std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
223 return (sendCacheMap_.erase(id) != 0);
224 }
225
FindCacheMapAndTransform(const AppExecFwk::InnerEvent::Pointer & event)226 std::shared_ptr<SmsSendIndexer> SmsSender::FindCacheMapAndTransform(const AppExecFwk::InnerEvent::Pointer &event)
227 {
228 if (event == nullptr) {
229 TELEPHONY_LOGE("event is nullptr");
230 return nullptr;
231 }
232 for (auto const &pair : sendCacheMap_) {
233 TELEPHONY_LOGI("Key = %{public}" PRId64 "", pair.first);
234 }
235 std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
236 std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
237 std::shared_ptr<HRilRadioResponseInfo> res = event->GetSharedObject<HRilRadioResponseInfo>();
238 if (res != nullptr) {
239 TELEPHONY_LOGI("flag = %{public}d", res->flag);
240 auto iter = sendCacheMap_.find(res->flag);
241 if (iter != sendCacheMap_.end()) {
242 smsIndexer = iter->second;
243 if (smsIndexer == nullptr) {
244 TELEPHONY_LOGE("smsIndexer is nullptr");
245 return nullptr;
246 }
247 smsIndexer->SetErrorCode(ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
248 smsIndexer->SetMsgRefId64Bit(res->flag);
249 smsIndexer->SetIsFailure(true);
250 UpdateUnSentCellCount(smsIndexer->GetMsgRefId());
251 }
252 return smsIndexer;
253 }
254
255 std::shared_ptr<SendSmsResultInfo> info = event->GetSharedObject<SendSmsResultInfo>();
256 if (info != nullptr) {
257 TELEPHONY_LOGI("flag = %{public}" PRId64 "", info->flag);
258 auto iter = sendCacheMap_.find(info->flag);
259 if (iter != sendCacheMap_.end()) {
260 TELEPHONY_LOGI("msgRef = %{public}d", info->msgRef);
261 smsIndexer = iter->second;
262 if (smsIndexer == nullptr) {
263 TELEPHONY_LOGE("smsIndexer is nullptr");
264 return nullptr;
265 }
266 smsIndexer->SetAckPdu(std::move(StringUtils::HexToByteVector(info->pdu)));
267 if (info->errCode != 0) {
268 smsIndexer->SetIsFailure(true);
269 }
270 smsIndexer->SetErrorCode(info->errCode);
271 smsIndexer->SetMsgRefId64Bit(info->flag);
272 UpdateUnSentCellCount(smsIndexer->GetMsgRefId());
273 }
274 }
275 return smsIndexer;
276 }
277
UpdateUnSentCellCount(uint8_t refId)278 void SmsSender::UpdateUnSentCellCount(uint8_t refId)
279 {
280 std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
281 for (auto it = sendCacheMap_.begin(); it != sendCacheMap_.end(); ++it) {
282 smsIndexer = it->second;
283 if (smsIndexer == nullptr) {
284 continue;
285 }
286 uint8_t unSentCount = smsIndexer->GetUnSentCellCount();
287 if (smsIndexer->GetMsgRefId() == refId && unSentCount > 0) {
288 smsIndexer->SetUnSentCellCount(unSentCount - 1);
289 }
290 }
291 }
292
SetImsSmsConfig(int32_t slotId,int32_t enable)293 bool SmsSender::SetImsSmsConfig(int32_t slotId, int32_t enable)
294 {
295 auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
296 if (smsClient == nullptr) {
297 TELEPHONY_LOGE("SetImsSmsConfig return, ImsSmsClient is nullptr.");
298 return false;
299 }
300 imsSmsCfg_ = enable;
301 std::unique_lock<std::mutex> lck(ctx_);
302 resIsSmsReady_ = false;
303
304 int32_t reply = smsClient->ImsSetSmsConfig(slotId, enable);
305 TELEPHONY_LOGI("SetImsSmsConfig reply = %{public}d", reply);
306 while (resIsSmsReady_) {
307 TELEPHONY_LOGI("SetImsSmsConfig::wait(), resIsSmsReady_ = false");
308 if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
309 break;
310 }
311 }
312 TELEPHONY_LOGI("SmsSender::SetImsSmsConfig(), %{public}d:", imsSmsCfg_);
313 return true;
314 }
315
HandleResend(const std::shared_ptr<SmsSendIndexer> & smsIndexer)316 void SmsSender::HandleResend(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
317 {
318 if (smsIndexer == nullptr) {
319 TELEPHONY_LOGE("smsIndexer is nullptr");
320 return;
321 }
322 // resending mechanism
323 bool errorCode = false;
324 if ((smsIndexer->GetErrorCode() == HRIL_ERR_GENERIC_FAILURE) ||
325 (smsIndexer->GetErrorCode() == HRIL_ERR_CMD_SEND_FAILURE)) {
326 errorCode = true;
327 }
328 bool csResend = false;
329 if (!lastSmsDomain_ && smsIndexer->GetCsResendCount() < MAX_SEND_RETRIES) {
330 csResend = true;
331 }
332 bool psResend = false;
333 if (lastSmsDomain_ && smsIndexer->GetPsResendCount() <= MAX_SEND_RETRIES) {
334 psResend = true;
335 }
336 if (errorCode && (csResend || psResend)) {
337 if (lastSmsDomain_ && psResend) {
338 smsIndexer->SetPsResendCount(smsIndexer->GetPsResendCount() + 1);
339 SendEvent(MSG_SMS_RETRY_DELIVERY, smsIndexer, DELAY_MAX_TIME_MSCE);
340 } else if (csResend) {
341 smsIndexer->SetCsResendCount(smsIndexer->GetCsResendCount() + 1);
342 SendEvent(MSG_SMS_RETRY_DELIVERY, smsIndexer, DELAY_MAX_TIME_MSCE);
343 }
344 } else {
345 SendMessageFailed(smsIndexer);
346 }
347 }
348
GetMsgRef8Bit()349 uint8_t SmsSender::GetMsgRef8Bit()
350 {
351 return ++msgRef8bit_;
352 }
353
GetMsgRef64Bit()354 int64_t SmsSender::GetMsgRef64Bit()
355 {
356 return ++msgRef64bit_;
357 }
358
SetNetworkState(bool isImsNetDomain,int32_t voiceServiceState)359 void SmsSender::SetNetworkState(bool isImsNetDomain, int32_t voiceServiceState)
360 {
361 isImsNetDomain_ = isImsNetDomain;
362 voiceServiceState_ = voiceServiceState;
363 if (enableImsSmsOnceWhenImsReg_ && isImsNetDomain) {
364 SetImsSmsConfig(slotId_, IMS_SMS_ENABLE);
365 enableImsSmsOnceWhenImsReg_ = false;
366 }
367 TELEPHONY_LOGD("isImsNetDomain = %{public}s voiceServiceState = %{public}d",
368 isImsNetDomain_ ? "true" : "false", voiceServiceState_);
369 }
370
CheckForce7BitEncodeType()371 bool SmsSender::CheckForce7BitEncodeType()
372 {
373 auto helperPtr = DelayedSingleton<SmsPersistHelper>::GetInstance();
374 if (helperPtr == nullptr) {
375 TELEPHONY_LOGE("Check User Force 7Bit Encode Type helperPtr nullptr error.");
376 return false;
377 }
378 return helperPtr->QueryParamBoolean(SmsPersistHelper::SMS_ENCODING_PARAM_KEY, false);
379 }
380
GetNetworkId()381 std::optional<int32_t> SmsSender::GetNetworkId()
382 {
383 return networkId_;
384 }
385
SetNetworkId(std::optional<int32_t> & id)386 void SmsSender::SetNetworkId(std::optional<int32_t> &id)
387 {
388 networkId_ = id;
389 }
390 } // namespace Telephony
391 } // namespace OHOS