• 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 "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     std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
233     std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
234     std::shared_ptr<HRilRadioResponseInfo> res = event->GetSharedObject<HRilRadioResponseInfo>();
235     if (res != nullptr) {
236         auto iter = sendCacheMap_.find(res->flag);
237         if (iter != sendCacheMap_.end()) {
238             smsIndexer = iter->second;
239             if (smsIndexer == nullptr) {
240                 TELEPHONY_LOGE("smsIndexer is nullptr");
241                 return nullptr;
242             }
243             smsIndexer->SetErrorCode(ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
244             smsIndexer->SetMsgRefId64Bit(res->flag);
245             smsIndexer->SetIsFailure(true);
246             UpdateUnSentCellCount(smsIndexer->GetMsgRefId());
247         }
248         return smsIndexer;
249     }
250 
251     std::shared_ptr<SendSmsResultInfo> info = event->GetSharedObject<SendSmsResultInfo>();
252     if (info != nullptr) {
253         auto iter = sendCacheMap_.find(info->flag);
254         if (iter != sendCacheMap_.end()) {
255             TELEPHONY_LOGI("msgRef = %{public}d", info->msgRef);
256             smsIndexer = iter->second;
257             if (smsIndexer == nullptr) {
258                 TELEPHONY_LOGE("smsIndexer is nullptr");
259                 return nullptr;
260             }
261             smsIndexer->SetMsgRefId((uint8_t)info->msgRef);
262             smsIndexer->SetAckPdu(std::move(StringUtils::HexToByteVector(info->pdu)));
263             if (info->errCode != 0) {
264                 smsIndexer->SetIsFailure(true);
265             }
266             smsIndexer->SetErrorCode(info->errCode);
267             smsIndexer->SetMsgRefId64Bit(info->flag);
268             UpdateUnSentCellCount(smsIndexer->GetMsgRefId());
269         }
270     }
271     return smsIndexer;
272 }
273 
UpdateUnSentCellCount(uint8_t refId)274 void SmsSender::UpdateUnSentCellCount(uint8_t refId)
275 {
276     std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
277     for (auto it = sendCacheMap_.begin(); it != sendCacheMap_.end(); ++it) {
278         smsIndexer = it->second;
279         if (smsIndexer == nullptr) {
280             continue;
281         }
282         uint8_t unSentCount = smsIndexer->GetUnSentCellCount();
283         if (smsIndexer->GetMsgRefId() == refId && unSentCount > 0) {
284             smsIndexer->SetUnSentCellCount(unSentCount - 1);
285         }
286     }
287 }
288 
SetImsSmsConfig(int32_t slotId,int32_t enable)289 bool SmsSender::SetImsSmsConfig(int32_t slotId, int32_t enable)
290 {
291     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
292     if (smsClient == nullptr) {
293         TELEPHONY_LOGE("SetImsSmsConfig return, ImsSmsClient is nullptr.");
294         return false;
295     }
296     imsSmsCfg_ = enable;
297     std::unique_lock<std::mutex> lck(ctx_);
298     resIsSmsReady_ = false;
299 
300     int32_t reply = smsClient->ImsSetSmsConfig(slotId, enable);
301     TELEPHONY_LOGI("SetImsSmsConfig reply = %{public}d", reply);
302     while (resIsSmsReady_) {
303         TELEPHONY_LOGI("SetImsSmsConfig::wait(), resIsSmsReady_ = false");
304         if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
305             break;
306         }
307     }
308     TELEPHONY_LOGI("SmsSender::SetImsSmsConfig(), %{public}d:", imsSmsCfg_);
309     return true;
310 }
311 
HandleResend(const std::shared_ptr<SmsSendIndexer> & smsIndexer)312 void SmsSender::HandleResend(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
313 {
314     if (smsIndexer == nullptr) {
315         TELEPHONY_LOGE("smsIndexer is nullptr");
316         return;
317     }
318     // resending mechanism
319     bool errorCode = false;
320     if ((smsIndexer->GetErrorCode() == HRIL_ERR_GENERIC_FAILURE) ||
321         (smsIndexer->GetErrorCode() == HRIL_ERR_CMD_SEND_FAILURE)) {
322         errorCode = true;
323     }
324     bool csResend = false;
325     if (!lastSmsDomain_ && smsIndexer->GetCsResendCount() < MAX_SEND_RETRIES) {
326         csResend = true;
327     }
328     bool psResend = false;
329     if (lastSmsDomain_ && smsIndexer->GetPsResendCount() <= MAX_SEND_RETRIES) {
330         psResend = true;
331     }
332     if (errorCode && (csResend || psResend)) {
333         if (lastSmsDomain_ && psResend) {
334             smsIndexer->SetPsResendCount(smsIndexer->GetPsResendCount() + 1);
335             SendEvent(MSG_SMS_RETRY_DELIVERY, smsIndexer, DELAY_MAX_TIME_MSCE);
336         } else if (csResend) {
337             smsIndexer->SetCsResendCount(smsIndexer->GetCsResendCount() + 1);
338             SendEvent(MSG_SMS_RETRY_DELIVERY, smsIndexer, DELAY_MAX_TIME_MSCE);
339         }
340     } else {
341         SendMessageFailed(smsIndexer);
342     }
343 }
344 
GetMsgRef8Bit()345 uint8_t SmsSender::GetMsgRef8Bit()
346 {
347     return ++msgRef8bit_;
348 }
349 
GetMsgRef64Bit()350 int64_t SmsSender::GetMsgRef64Bit()
351 {
352     return ++msgRef64bit_;
353 }
354 
SetNetworkState(bool isImsNetDomain,int32_t voiceServiceState)355 void SmsSender::SetNetworkState(bool isImsNetDomain, int32_t voiceServiceState)
356 {
357     isImsNetDomain_ = isImsNetDomain;
358     voiceServiceState_ = voiceServiceState;
359     if (enableImsSmsOnceWhenImsReg_ && isImsNetDomain) {
360         SetImsSmsConfig(slotId_, IMS_SMS_ENABLE);
361         enableImsSmsOnceWhenImsReg_ = false;
362     }
363     TELEPHONY_LOGD("isImsNetDomain = %{public}s voiceServiceState = %{public}d",
364         isImsNetDomain_ ? "true" : "false", voiceServiceState_);
365 }
366 
CheckForce7BitEncodeType()367 bool SmsSender::CheckForce7BitEncodeType()
368 {
369     auto helperPtr = DelayedSingleton<SmsPersistHelper>::GetInstance();
370     if (helperPtr == nullptr) {
371         TELEPHONY_LOGE("Check User Force 7Bit Encode Type helperPtr nullptr error.");
372         return false;
373     }
374     return helperPtr->QueryParamBoolean(SmsPersistHelper::SMS_ENCODING_PARAM_KEY, false);
375 }
376 
GetNetworkId()377 std::optional<int32_t> SmsSender::GetNetworkId()
378 {
379     return networkId_;
380 }
381 
SetNetworkId(std::optional<int32_t> & id)382 void SmsSender::SetNetworkId(std::optional<int32_t> &id)
383 {
384     networkId_ = id;
385 }
386 } // namespace Telephony
387 } // namespace OHOS