• 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 <cinttypes>
19 
20 #include "core_manager_inner.h"
21 #include "ims_sms_client.h"
22 #include "radio_event.h"
23 #include "securec.h"
24 #include "sms_mms_common.h"
25 #include "sms_hisysevent.h"
26 #include "string_utils.h"
27 #include "telephony_log_wrapper.h"
28 #include "telephony_permission.h"
29 
30 namespace OHOS {
31 namespace Telephony {
32 using namespace std;
33 using namespace std::chrono;
34 int64_t SmsSender::msgRef64bit_ = 0;
35 std::unordered_map<int64_t, std::shared_ptr<SmsSendIndexer>> SmsSender::sendCacheMap_;
36 
SmsSender(int32_t slotId,function<void (shared_ptr<SmsSendIndexer>)> & sendRetryFun)37 SmsSender::SmsSender(int32_t slotId, function<void(shared_ptr<SmsSendIndexer>)> &sendRetryFun)
38     : TelEventHandler("SmsSender"), slotId_(slotId), sendRetryFun_(sendRetryFun)
39 {}
40 
~SmsSender()41 SmsSender::~SmsSender() {}
42 
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)43 void SmsSender::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
44 {
45     if (event == nullptr) {
46         TELEPHONY_LOGE("event is nullptr");
47         return;
48     }
49     shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
50     uint32_t eventId = event->GetInnerEventId();
51     TELEPHONY_LOGI("SmsSender::ProcessEvent eventId %{public}d", eventId);
52     switch (eventId) {
53         case RadioEvent::RADIO_SEND_SMS:
54         case RadioEvent::RADIO_SEND_CDMA_SMS:
55         case RadioEvent::RADIO_SEND_IMS_GSM_SMS:
56         case RadioEvent::RADIO_SEND_SMS_EXPECT_MORE: {
57             smsIndexer = FindCacheMapAndTransform(event);
58             HandleMessageResponse(smsIndexer);
59             break;
60         }
61         case MSG_SMS_RETRY_DELIVERY: {
62             smsIndexer = event->GetSharedObject<SmsSendIndexer>();
63             if (sendRetryFun_ != nullptr) {
64                 sendRetryFun_(smsIndexer);
65             }
66             break;
67         }
68         case RadioEvent::RADIO_SMS_STATUS: {
69             StatusReportAnalysis(event);
70             break;
71         }
72         case RadioEvent::RADIO_SET_IMS_SMS: {
73             StatusReportSetImsSms(event);
74             SyncSwitchISmsResponse();
75             break;
76         }
77         case RadioEvent::RADIO_GET_IMS_SMS: {
78             StatusReportGetImsSms(event);
79             SyncSwitchISmsResponse();
80             break;
81         }
82         default:
83             TELEPHONY_LOGE("SmsSender::ProcessEvent Unknown %{public}d", eventId);
84             break;
85     }
86 }
87 
SyncSwitchISmsResponse()88 void SmsSender::SyncSwitchISmsResponse()
89 {
90     std::unique_lock<std::mutex> lck(ctx_);
91     resIsSmsReady_ = true;
92     TELEPHONY_LOGI("resIsSmsReady_ = %{public}d", resIsSmsReady_);
93     cv_.notify_one();
94 }
95 
HandleMessageResponse(const shared_ptr<SmsSendIndexer> & smsIndexer)96 void SmsSender::HandleMessageResponse(const shared_ptr<SmsSendIndexer> &smsIndexer)
97 {
98     if (smsIndexer == nullptr) {
99         TELEPHONY_LOGE("smsIndexer is nullptr");
100         return;
101     }
102     if (!SendCacheMapEraseItem(smsIndexer->GetMsgRefId64Bit())) {
103         TELEPHONY_LOGE("SendCacheMapEraseItem fail !!!!!");
104     }
105     SendCacheMapTimeoutCheck();
106     if (!smsIndexer->GetIsFailure()) {
107         if (smsIndexer->GetDeliveryCallback() != nullptr) {
108             // Expecting a status report.  Add it to the list.
109             if (reportList_.size() > MAX_REPORT_LIST_LIMIT) {
110                 reportList_.pop_front();
111             }
112             reportList_.push_back(smsIndexer);
113         }
114         SendMessageSucceed(smsIndexer);
115     } else {
116         HandleResend(smsIndexer);
117     }
118 }
119 
SendMessageSucceed(const shared_ptr<SmsSendIndexer> & smsIndexer)120 void SmsSender::SendMessageSucceed(const shared_ptr<SmsSendIndexer> &smsIndexer)
121 {
122     if (smsIndexer == nullptr) {
123         TELEPHONY_LOGE("SendMessageSucceed but smsIndexer drop!");
124         return;
125     }
126 
127     bool isLastPart = false;
128     uint8_t unSentCellCount = smsIndexer->GetUnSentCellCount();
129     if (unSentCellCount == 0) {
130         isLastPart = true;
131     }
132     TELEPHONY_LOGI("isLastPart:%{public}d", isLastPart);
133     if (isLastPart) {
134         smsIndexer->SetPsResendCount(INITIAL_COUNT);
135         smsIndexer->SetCsResendCount(INITIAL_COUNT);
136         ISendShortMessageCallback::SmsSendResult messageType = ISendShortMessageCallback::SEND_SMS_SUCCESS;
137         if (smsIndexer->GetHasCellFailed() != nullptr) {
138             if (*smsIndexer->GetHasCellFailed()) {
139                 messageType = ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN;
140             }
141         }
142         SendResultCallBack(smsIndexer->GetSendCallback(), messageType);
143         if (messageType == ISendShortMessageCallback::SEND_SMS_SUCCESS) {
144             SmsHiSysEvent::WriteSmsSendBehaviorEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE);
145         }
146         if (smsIndexer->GetDataBaseId() == 0) {
147             return;
148         }
149         DataShare::DataShareValuesBucket sessionBucket;
150         sessionBucket.Put(SmsMmsInfo::MSG_STATE, SmsMmsCommonData::SMS_MMS_INFO_MSG_STATE_SUCCEED);
151         DataShare::DataSharePredicates predicates;
152         predicates.EqualTo(SmsMmsInfo::MSG_ID, smsIndexer->GetDataBaseId());
153         if (!DelayedSingleton<SmsPersistHelper>::GetInstance()->UpdateSms(predicates, sessionBucket)) {
154             TELEPHONY_LOGE("modify db fail while SendMessageSucceed. id:%{public}d;", smsIndexer->GetDataBaseId());
155         }
156         std::string  notifyType = SmsMmsCommonData::MESSAGE_STATUS_CHANGE_NOTIFY;
157         if (smsIndexer->GetIsMmsApp()) {
158             notifyType = SmsMmsCommonData::SMS_MMS_SENT_RESULT_NOTIFY;
159         }
160         TELEPHONY_LOGI("before send boradcast. SendMessageSucceed %{public}d", smsIndexer->GetDataBaseId());
161         DelayedSingleton<SmsMmsCommon>::GetInstance()->SendBroadcast(smsIndexer->GetDataBaseId(),
162             notifyType, SmsMmsCommonData::SMS_MMS_INFO_MSG_STATE_SUCCEED,
163             SmsMmsCommonData::SMS_MMS_INFO_SMS_TYPE);
164     }
165 }
166 
SendMessageFailed(const shared_ptr<SmsSendIndexer> & smsIndexer)167 void SmsSender::SendMessageFailed(const shared_ptr<SmsSendIndexer> &smsIndexer)
168 {
169     if (smsIndexer == nullptr) {
170         TELEPHONY_LOGE("smsIndexer is nullptr");
171         return;
172     }
173     shared_ptr<bool> hasCellFailed = smsIndexer->GetHasCellFailed();
174     if (hasCellFailed != nullptr) {
175         *hasCellFailed = true;
176     }
177 
178     bool isLastPart = false;
179     uint8_t unSentCellCount = smsIndexer->GetUnSentCellCount();
180     if (unSentCellCount == 0) {
181         isLastPart = true;
182     }
183     TELEPHONY_LOGI("isLastPart:%{public}d", isLastPart);
184     if (isLastPart) {
185         smsIndexer->SetPsResendCount(INITIAL_COUNT);
186         smsIndexer->SetCsResendCount(INITIAL_COUNT);
187         // save to db and update state
188         sptr<ISendShortMessageCallback> sendCallback = smsIndexer->GetSendCallback();
189         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
190         TELEPHONY_LOGI("send sms result fail from ril response. IsMmsApp:%{public}d;dataBaseId:%{public}d;",
191             smsIndexer->GetIsMmsApp(), smsIndexer->GetDataBaseId());
192         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
193             SmsMmsErrorCode::SMS_ERROR_SEND_RESULT_FAIL, "send sms result fail from ril response");
194         if (smsIndexer->GetDataBaseId() == 0) {
195             return;
196         }
197         DataShare::DataShareValuesBucket sessionBucket;
198         sessionBucket.Put(SmsMmsInfo::MSG_STATE, SmsMmsCommonData::SMS_MMS_INFO_MSG_STATE_FAILED);
199         DataShare::DataSharePredicates predicates;
200         predicates.EqualTo(SmsMmsInfo::MSG_ID, smsIndexer->GetDataBaseId());
201         if (!DelayedSingleton<SmsPersistHelper>::GetInstance()->UpdateSms(predicates, sessionBucket)) {
202             TELEPHONY_LOGE("modify fail while SendMessageFailed. id:%{public}d;", smsIndexer->GetDataBaseId());
203         }
204         std::string  notifyType = SmsMmsCommonData::MESSAGE_STATUS_CHANGE_NOTIFY;
205         if (smsIndexer->GetIsMmsApp()) {
206             notifyType = SmsMmsCommonData::SMS_MMS_SENT_RESULT_NOTIFY;
207         }
208         TELEPHONY_LOGI("before send boradcast. SendMessageSucceed %{public}d", smsIndexer->GetDataBaseId());
209         DelayedSingleton<SmsMmsCommon>::GetInstance()->SendBroadcast(smsIndexer->GetDataBaseId(),
210             notifyType, SmsMmsCommonData::SMS_MMS_INFO_MSG_STATE_FAILED,
211             SmsMmsCommonData::SMS_MMS_INFO_SMS_TYPE);
212         TELEPHONY_LOGI("after send boradcast. SendMessageSucceed %{public}d", smsIndexer->GetDataBaseId());
213     }
214 }
215 
SendResultCallBack(const std::shared_ptr<SmsSendIndexer> & indexer,ISendShortMessageCallback::SmsSendResult result)216 void SmsSender::SendResultCallBack(
217     const std::shared_ptr<SmsSendIndexer> &indexer, ISendShortMessageCallback::SmsSendResult result)
218 {
219     if (indexer != nullptr && indexer->GetSendCallback() != nullptr) {
220         indexer->GetSendCallback()->OnSmsSendResult(result);
221     }
222 }
223 
SendResultCallBack(const sptr<ISendShortMessageCallback> & sendCallback,ISendShortMessageCallback::SmsSendResult result)224 void SmsSender::SendResultCallBack(
225     const sptr<ISendShortMessageCallback> &sendCallback, ISendShortMessageCallback::SmsSendResult result)
226 {
227     if (sendCallback != nullptr) {
228         sendCallback->OnSmsSendResult(result);
229     }
230 }
231 
SendCacheMapTimeoutCheck()232 void SmsSender::SendCacheMapTimeoutCheck()
233 {
234     std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
235     system_clock::duration timePoint = system_clock::now().time_since_epoch();
236     seconds sec = duration_cast<seconds>(timePoint);
237     int64_t timeStamp = sec.count();
238     auto item = sendCacheMap_.begin();
239     while (item != sendCacheMap_.end()) {
240         auto iter = item++;
241         shared_ptr<SmsSendIndexer> &indexer = iter->second;
242         if (indexer == nullptr || (timeStamp - indexer->GetTimeStamp()) > EXPIRED_TIME) {
243             sendCacheMap_.erase(iter);
244         }
245     }
246 }
247 
SendCacheMapLimitCheck(const sptr<ISendShortMessageCallback> & sendCallback)248 bool SmsSender::SendCacheMapLimitCheck(const sptr<ISendShortMessageCallback> &sendCallback)
249 {
250     std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
251     if (sendCacheMap_.size() > MSG_QUEUE_LIMIT) {
252         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
253         return true;
254     }
255     return false;
256 }
257 
SendCacheMapAddItem(int64_t id,const std::shared_ptr<SmsSendIndexer> & smsIndexer)258 bool SmsSender::SendCacheMapAddItem(int64_t id, const std::shared_ptr<SmsSendIndexer> &smsIndexer)
259 {
260     std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
261     if (smsIndexer != nullptr) {
262         auto result = sendCacheMap_.emplace(id, smsIndexer);
263         return result.second;
264     }
265     return false;
266 }
267 
SendCacheMapEraseItem(int64_t id)268 bool SmsSender::SendCacheMapEraseItem(int64_t id)
269 {
270     std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
271     return (sendCacheMap_.erase(id) != 0);
272 }
273 
FindCacheMapAndTransform(const AppExecFwk::InnerEvent::Pointer & event)274 std::shared_ptr<SmsSendIndexer> SmsSender::FindCacheMapAndTransform(const AppExecFwk::InnerEvent::Pointer &event)
275 {
276     if (event == nullptr) {
277         TELEPHONY_LOGE("event is nullptr");
278         return nullptr;
279     }
280     for (auto const &pair : sendCacheMap_) {
281         TELEPHONY_LOGI("Key = %{public}" PRId64 "", pair.first);
282     }
283     std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
284     std::lock_guard<std::mutex> guard(sendCacheMapMutex_);
285     std::shared_ptr<RadioResponseInfo> res = event->GetSharedObject<RadioResponseInfo>();
286     if (res != nullptr) {
287         TELEPHONY_LOGI("flag = %{public}d", res->flag);
288         auto iter = sendCacheMap_.find(res->flag);
289         if (iter != sendCacheMap_.end()) {
290             smsIndexer = iter->second;
291             if (smsIndexer == nullptr) {
292                 TELEPHONY_LOGE("smsIndexer is nullptr");
293                 return nullptr;
294             }
295             smsIndexer->SetErrorCode(ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
296             smsIndexer->SetMsgRefId64Bit(res->flag);
297             smsIndexer->SetIsFailure(true);
298             UpdateUnSentCellCount(smsIndexer->GetMsgRefId());
299         }
300         return smsIndexer;
301     }
302     std::shared_ptr<SendSmsResultInfo> info = event->GetSharedObject<SendSmsResultInfo>();
303     if (info != nullptr) {
304         TELEPHONY_LOGI("flag = %{public}" PRId64 "", info->flag);
305         auto iter = sendCacheMap_.find(info->flag);
306         if (iter != sendCacheMap_.end()) {
307             TELEPHONY_LOGI("msgRef = %{public}d", info->msgRef);
308             smsIndexer = iter->second;
309             if (smsIndexer == nullptr) {
310                 TELEPHONY_LOGE("smsIndexer is nullptr");
311                 return nullptr;
312             }
313             smsIndexer->SetAckPdu(std::move(StringUtils::HexToByteVector(info->pdu)));
314             info->errCode != 0? smsIndexer->SetIsFailure(true) : smsIndexer->SetIsFailure(false);
315             smsIndexer->SetErrorCode(info->errCode);
316             smsIndexer->SetMsgRefId64Bit(info->flag);
317             UpdateUnSentCellCount(smsIndexer->GetMsgRefId());
318         }
319     }
320     return smsIndexer;
321 }
322 
UpdateUnSentCellCount(uint8_t refId)323 void SmsSender::UpdateUnSentCellCount(uint8_t refId)
324 {
325     std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
326     for (auto it = sendCacheMap_.begin(); it != sendCacheMap_.end(); ++it) {
327         smsIndexer = it->second;
328         if (smsIndexer == nullptr) {
329             continue;
330         }
331         uint8_t unSentCount = smsIndexer->GetUnSentCellCount();
332         if (smsIndexer->GetMsgRefId() == refId && unSentCount > 0) {
333             smsIndexer->SetUnSentCellCount(unSentCount - 1);
334         }
335     }
336 }
337 
SetImsSmsConfig(int32_t slotId,int32_t enable)338 bool SmsSender::SetImsSmsConfig(int32_t slotId, int32_t enable)
339 {
340     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
341     if (smsClient == nullptr) {
342         TELEPHONY_LOGE("SetImsSmsConfig return, ImsSmsClient is nullptr.");
343         return false;
344     }
345     imsSmsCfg_ = enable;
346     std::unique_lock<std::mutex> lck(ctx_);
347     resIsSmsReady_ = false;
348 
349     int32_t reply = smsClient->ImsSetSmsConfig(slotId, enable);
350     TELEPHONY_LOGI("SetImsSmsConfig reply = %{public}d", reply);
351     while (resIsSmsReady_) {
352         TELEPHONY_LOGI("SetImsSmsConfig::wait(), resIsSmsReady_ = false");
353         if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
354             break;
355         }
356     }
357     TELEPHONY_LOGI("SmsSender::SetImsSmsConfig(), %{public}d:", imsSmsCfg_);
358     return true;
359 }
360 
HandleResend(const std::shared_ptr<SmsSendIndexer> & smsIndexer)361 void SmsSender::HandleResend(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
362 {
363     if (smsIndexer == nullptr) {
364         TELEPHONY_LOGE("smsIndexer is nullptr");
365         return;
366     }
367     // resending mechanism
368     bool errorCode = false;
369     if (smsIndexer->GetErrorCode() == static_cast<int32_t>(ErrType::ERR_CMD_SEND_FAILURE)) {
370         errorCode = true;
371     }
372     bool csResend = false;
373     if (!lastSmsDomain_ && smsIndexer->GetCsResendCount() < MAX_SEND_RETRIES) {
374         csResend = true;
375     }
376     bool psResend = false;
377     if (lastSmsDomain_ && smsIndexer->GetPsResendCount() <= MAX_SEND_RETRIES) {
378         psResend = true;
379     }
380     if (errorCode && (csResend || psResend)) {
381         if (lastSmsDomain_ && psResend) {
382             smsIndexer->SetPsResendCount(smsIndexer->GetPsResendCount() + 1);
383             SendEvent(MSG_SMS_RETRY_DELIVERY, smsIndexer, DELAY_MAX_TIME_MSCE);
384         } else if (csResend) {
385             smsIndexer->SetCsResendCount(smsIndexer->GetCsResendCount() + 1);
386             SendEvent(MSG_SMS_RETRY_DELIVERY, smsIndexer, DELAY_MAX_TIME_MSCE);
387         }
388     } else {
389         SendMessageFailed(smsIndexer);
390     }
391 }
392 
GetMsgRef8Bit()393 uint8_t SmsSender::GetMsgRef8Bit()
394 {
395     return ++msgRef8bit_;
396 }
397 
GetMsgRef64Bit()398 int64_t SmsSender::GetMsgRef64Bit()
399 {
400     return ++msgRef64bit_;
401 }
402 
SetNetworkState(bool isImsNetDomain,int32_t voiceServiceState)403 void SmsSender::SetNetworkState(bool isImsNetDomain, int32_t voiceServiceState)
404 {
405     isImsNetDomain_ = isImsNetDomain;
406     voiceServiceState_ = voiceServiceState;
407     TELEPHONY_LOGD("isImsNetDomain = %{public}s voiceServiceState = %{public}d",
408         isImsNetDomain_ ? "true" : "false", voiceServiceState_);
409 }
410 
CheckForce7BitEncodeType()411 bool SmsSender::CheckForce7BitEncodeType()
412 {
413     auto helperPtr = DelayedSingleton<SmsPersistHelper>::GetInstance();
414     if (helperPtr == nullptr) {
415         TELEPHONY_LOGE("Check User Force 7Bit Encode Type helperPtr nullptr error.");
416         return false;
417     }
418     return helperPtr->QueryParamBoolean(SmsPersistHelper::SMS_ENCODING_PARAM_KEY, false);
419 }
420 
GetSmsCodingNationalType(int slotId)421 SmsCodingNationalType SmsSender::GetSmsCodingNationalType(int slotId)
422 {
423     SmsCodingNationalType smsCodingNational = SMS_CODING_NATIONAL_TYPE_DEFAULT;
424     OperatorConfig operatorConfig;
425     CoreManagerInner::GetInstance().GetOperatorConfigs(slotId, operatorConfig);
426     if (operatorConfig.intValue.find(KEY_SMS_CODING_NATIONAL_INT) != operatorConfig.intValue.end()) {
427         smsCodingNational = (SmsCodingNationalType)operatorConfig.intValue[KEY_SMS_CODING_NATIONAL_INT];
428     }
429     return smsCodingNational;
430 }
431 
GetNetworkId()432 std::optional<int32_t> SmsSender::GetNetworkId()
433 {
434     return networkId_;
435 }
436 
SetNetworkId(std::optional<int32_t> & id)437 void SmsSender::SetNetworkId(std::optional<int32_t> &id)
438 {
439     networkId_ = id;
440 }
441 
OnRilAdapterHostDied()442 void SmsSender::OnRilAdapterHostDied()
443 {
444     std::shared_ptr<SmsSendIndexer> smsIndexer = nullptr;
445     for (auto it = sendCacheMap_.begin(); it != sendCacheMap_.end(); ++it) {
446         smsIndexer = it->second;
447         if (smsIndexer == nullptr || smsIndexer->GetIsFailure()) {
448             TELEPHONY_LOGE("smsIndexer is nullptr");
449             continue;
450         }
451         if (!SendCacheMapEraseItem(smsIndexer->GetMsgRefId64Bit())) {
452             TELEPHONY_LOGE("SendCacheMapEraseItem fail !!!!!");
453         }
454         smsIndexer->SetIsFailure(true);
455         smsIndexer->SetPsResendCount(INITIAL_COUNT);
456         smsIndexer->SetCsResendCount(INITIAL_COUNT);
457         sptr<ISendShortMessageCallback> sendCallback = smsIndexer->GetSendCallback();
458         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
459         TELEPHONY_LOGI("Message(s) failed to send due to RIL died.");
460     }
461 }
462 
CharArrayToString(const uint8_t * data,uint32_t dataLen,std::string & dataStr)463 void SmsSender::CharArrayToString(const uint8_t *data, uint32_t dataLen, std::string &dataStr)
464 {
465     uint32_t indexData = 0;
466     while (indexData < dataLen) {
467         dataStr += data[indexData];
468         indexData++;
469     }
470 }
471 
DataBasedSmsDeliverySplitPage(GsmSmsMessage & gsmSmsMessage,std::vector<struct SplitInfo> cellsInfos,std::shared_ptr<struct SmsTpdu> tpdu,uint8_t msgRef8bit,const std::string & desAddr,const std::string & scAddr,int32_t port,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)472 void SmsSender::DataBasedSmsDeliverySplitPage(GsmSmsMessage &gsmSmsMessage, std::vector<struct SplitInfo> cellsInfos,
473     std::shared_ptr<struct SmsTpdu> tpdu, uint8_t msgRef8bit, const std::string &desAddr, const std::string &scAddr,
474     int32_t port, const sptr<ISendShortMessageCallback> &sendCallback,
475     const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
476 {
477     uint32_t cellsInfosSize = static_cast<uint32_t>(cellsInfos.size());
478     for (uint32_t indexData = 0; indexData < cellsInfosSize; indexData++) {
479         const uint8_t *dataItem = reinterpret_cast<uint8_t *>(cellsInfos[indexData].text.data());
480         uint32_t dataItemLen = static_cast<uint32_t>(cellsInfos[indexData].text.size());
481 
482         std::shared_ptr<SmsSendIndexer> indexer =
483             make_shared<SmsSendIndexer>(desAddr, scAddr, port, dataItem, dataItemLen, sendCallback, deliveryCallback);
484         if (indexer == nullptr) {
485             SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
486             TELEPHONY_LOGE("create SmsSendIndexer nullptr");
487             return;
488         }
489 
490         (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
491         if (cellsInfos[indexData].encodeData.size() > MAX_USER_DATA_LEN + 1) {
492             TELEPHONY_LOGE("data length invalid.");
493             return;
494         }
495         int ret = memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, &cellsInfos[indexData].encodeData[0],
496             cellsInfos[indexData].encodeData.size());
497         if (ret != EOK) {
498             SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
499             TELEPHONY_LOGE("ret:%{public}d", ret);
500             return;
501         }
502         DataBasedSmsDeliveryPacketSplitPage(gsmSmsMessage, tpdu, msgRef8bit, indexData, port, scAddr, sendCallback,
503             deliveryCallback, indexer, cellsInfos);
504     }
505 }
506 
DataBasedSmsDeliveryPacketSplitPage(GsmSmsMessage & gsmSmsMessage,std::shared_ptr<struct SmsTpdu> tpdu,uint8_t msgRef8bit,uint32_t indexData,int32_t port,const std::string & scAddr,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback,std::shared_ptr<SmsSendIndexer> indexer,std::vector<struct SplitInfo> cellsInfos)507 void SmsSender::DataBasedSmsDeliveryPacketSplitPage(GsmSmsMessage &gsmSmsMessage, std::shared_ptr<struct SmsTpdu> tpdu,
508     uint8_t msgRef8bit, uint32_t indexData, int32_t port, const std::string &scAddr,
509     const sptr<ISendShortMessageCallback> &sendCallback, const sptr<IDeliveryShortMessageCallback> &deliveryCallback,
510     std::shared_ptr<SmsSendIndexer> indexer, std::vector<struct SplitInfo> cellsInfos)
511 {
512     tpdu->data.submit.userData.length = static_cast<int>(cellsInfos[indexData].encodeData.size());
513     tpdu->data.submit.userData.data[cellsInfos[indexData].encodeData.size()] = 0;
514     tpdu->data.submit.msgRef = msgRef8bit;
515     int headerCnt = 0;
516     uint32_t cellsInfosSize = static_cast<uint32_t>(cellsInfos.size());
517     if (cellsInfosSize > 1) {
518         indexer->SetIsConcat(true);
519         SmsConcat concat;
520         concat.is8Bits = true;
521         concat.msgRef = msgRef8bit;
522         concat.totalSeg = static_cast<uint16_t>(cellsInfosSize);
523         concat.seqNum = static_cast<uint16_t>(indexData + 1);
524         indexer->SetSmsConcat(concat);
525         headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, concat);
526     }
527     if (headerCnt >= MAX_UD_HEADER_NUM) {
528         TELEPHONY_LOGE("PDU header Array out of bounds");
529         return;
530     }
531 
532     tpdu->data.submit.userData.header[headerCnt].udhType = UDH_APP_PORT_16BIT;
533     tpdu->data.submit.userData.header[headerCnt].udh.appPort16bit.destPort = ((unsigned short)port & 0xFFFF);
534     tpdu->data.submit.userData.header[headerCnt].udh.appPort16bit.originPort = 0;
535     headerCnt++;
536     tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
537     /* Set User Data Header for Alternate Reply Address */
538     headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
539     /* Set User Data Header for National Language Single Shift */
540     DataCodingScheme pCodingType = DATA_CODING_7BIT;
541     MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG;
542     headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, pCodingType, langId);
543     tpdu->data.submit.userData.headerCnt = headerCnt;
544 
545     std::shared_ptr<struct EncodeInfo> encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(scAddr, false);
546     if (encodeInfo == nullptr) {
547         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
548         TELEPHONY_LOGE("encodeInfo nullptr error.");
549         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
550             SmsMmsErrorCode::SMS_ERROR_PDU_ENCODEING_FAIL, "data sms gsm encodeInfo nullptr error");
551         return;
552     }
553 
554     if (cellsInfosSize > 1 && indexData < (cellsInfosSize - 1)) {
555         tpdu->data.submit.bStatusReport = false;
556     } else {
557         tpdu->data.submit.bStatusReport = (deliveryCallback == nullptr) ? false : true;
558     }
559     encodeInfo->isMore_ = (cellsInfosSize > 1) ? true : false;
560     DataBasedSmsDeliverySendSplitPage(encodeInfo, sendCallback, indexer, msgRef8bit, cellsInfosSize);
561 }
562 
SendCallbackExceptionCase(const sptr<ISendShortMessageCallback> & sendCallback,std::string str)563 void SmsSender::SendCallbackExceptionCase(const sptr<ISendShortMessageCallback> &sendCallback, std::string str)
564 {
565     SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
566     TELEPHONY_LOGE("%{public}s tpdu nullptr error.", str.c_str());
567     SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
568         SmsMmsErrorCode::SMS_ERROR_PDU_ENCODEING_FAIL, "data sms gsm encodeInfo nullptr error");
569 }
570 
DataBasedSmsDeliverySendSplitPage(std::shared_ptr<struct EncodeInfo> encodeInfo,const sptr<ISendShortMessageCallback> & sendCallback,shared_ptr<SmsSendIndexer> indexer,uint8_t msgRef8bit,uint32_t cellsInfosSize)571 void SmsSender::DataBasedSmsDeliverySendSplitPage(std::shared_ptr<struct EncodeInfo> encodeInfo,
572     const sptr<ISendShortMessageCallback> &sendCallback, shared_ptr<SmsSendIndexer> indexer, uint8_t msgRef8bit,
573     uint32_t cellsInfosSize)
574 {
575     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
576     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
577     TELEPHONY_LOGE("cellsInfosSize:%{public}d", cellsInfosSize);
578     std::shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(cellsInfosSize);
579     std::shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
580     if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
581         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
582         return;
583     }
584 
585     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
586     int64_t timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
587     indexer->SetUnSentCellCount(*unSentCellCount);
588     indexer->SetHasCellFailed(hasCellFailed);
589     indexer->SetEncodeSmca(std::move(smca));
590     indexer->SetEncodePdu(std::move(pdu));
591     indexer->SetHasMore(encodeInfo->isMore_);
592     indexer->SetMsgRefId(msgRef8bit);
593     indexer->SetNetWorkType(NET_TYPE_GSM);
594     indexer->SetTimeStamp(timeStamp);
595     SendSmsToRil(indexer);
596 }
597 } // namespace Telephony
598 } // namespace OHOS
599