1 /*
2  * Copyright (C) 2021-2023 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 "gsm_sms_sender.h"
17 
18 #include <cinttypes>
19 
20 #include "core_manager_inner.h"
21 #include "radio_event.h"
22 #include "satellite_sms_client.h"
23 #include "securec.h"
24 #include "sms_hisysevent.h"
25 #include "telephony_log_wrapper.h"
26 
27 namespace OHOS {
28 namespace Telephony {
29 using namespace std;
GsmSmsSender(int32_t slotId,function<void (std::shared_ptr<SmsSendIndexer>)> sendRetryFun)30 GsmSmsSender::GsmSmsSender(int32_t slotId, function<void(std::shared_ptr<SmsSendIndexer>)> sendRetryFun)
31     : SmsSender(slotId, sendRetryFun)
32 {}
33 
~GsmSmsSender()34 GsmSmsSender::~GsmSmsSender() {}
35 
Init()36 void GsmSmsSender::Init()
37 {
38     if (!RegisterHandler()) {
39         TELEPHONY_LOGI("GsmSmsSender::Init Register RADIO_SMS_STATUS fail.");
40     }
41 }
42 
TextBasedSmsDelivery(const string & desAddr,const string & scAddr,const string & text,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)43 void GsmSmsSender::TextBasedSmsDelivery(const string &desAddr, const string &scAddr, const string &text,
44     const sptr<ISendShortMessageCallback> &sendCallback,
45     const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
46 {
47     DataCodingScheme codingType;
48     GsmSmsMessage gsmSmsMessage;
49     std::vector<struct SplitInfo> cellsInfos;
50     gsmSmsMessage.SetSmsCodingNationalType(GetSmsCodingNationalType(slotId_));
51     std::string addr;
52     gsmSmsMessage.SplitMessage(cellsInfos, text, CheckForce7BitEncodeType(), codingType, false, addr);
53     bool isStatusReport = (deliveryCallback == nullptr) ? false : true;
54     std::shared_ptr<struct SmsTpdu> tpdu =
55         gsmSmsMessage.CreateDefaultSubmitSmsTpdu(desAddr, scAddr, text, isStatusReport, codingType);
56     if (tpdu == nullptr) {
57         SendCallbackExceptionCase(sendCallback, "TextBasedSmsDelivery");
58         return;
59     }
60     int cellsInfosSize = static_cast<int>(cellsInfos.size());
61     if (cellsInfosSize > MAX_SEGMENT_NUM) {
62         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
63         TELEPHONY_LOGE("message exceed the limit.");
64         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
65             SmsMmsErrorCode::SMS_ERROR_EXCEED_MAX_SEGMENT_NUM, "text sms gsm message cellsInfosSize exceed the limit");
66         return;
67     }
68     isStatusReport = tpdu->data.submit.bStatusReport;
69 
70     TELEPHONY_LOGI("TextBasedSmsDelivery isStatusReport= %{public}d", isStatusReport);
71     std::unique_lock<std::mutex> lock(mutex_);
72     TextBasedSmsSplitDelivery(
73         desAddr, scAddr, cellsInfos, codingType, isStatusReport, tpdu, gsmSmsMessage, sendCallback, deliveryCallback);
74 }
75 
TextBasedSmsSplitDelivery(const std::string & desAddr,const std::string & scAddr,std::vector<struct SplitInfo> cellsInfos,DataCodingScheme codingType,bool isStatusReport,std::shared_ptr<struct SmsTpdu> tpdu,GsmSmsMessage & gsmSmsMessage,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)76 void GsmSmsSender::TextBasedSmsSplitDelivery(const std::string &desAddr, const std::string &scAddr,
77     std::vector<struct SplitInfo> cellsInfos, DataCodingScheme codingType, bool isStatusReport,
78     std::shared_ptr<struct SmsTpdu> tpdu, GsmSmsMessage &gsmSmsMessage,
79     const sptr<ISendShortMessageCallback> &sendCallback, const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
80 {
81     int cellsInfosSize = static_cast<int>(cellsInfos.size());
82     unsigned char msgRef8bit = GetMsgRef8Bit();
83     shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(cellsInfosSize);
84     shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
85     if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
86         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
87         return;
88     }
89     for (int i = 0; i < cellsInfosSize; i++) {
90         std::shared_ptr<SmsSendIndexer> indexer = nullptr;
91         std::string segmentText;
92         segmentText.append((char *)(cellsInfos[i].encodeData.data()), cellsInfos[i].encodeData.size());
93         indexer = make_shared<SmsSendIndexer>(desAddr, scAddr, segmentText, sendCallback, deliveryCallback);
94         if (indexer == nullptr) {
95             SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
96             return;
97         }
98         indexer->SetDcs(cellsInfos[i].encodeType);
99         (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
100         if (cellsInfos[i].encodeData.size() > MAX_USER_DATA_LEN + 1) {
101             TELEPHONY_LOGE("TextBasedSmsDelivery data length invalid.");
102             return;
103         }
104         int ret = memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, &cellsInfos[i].encodeData[0],
105             cellsInfos[i].encodeData.size());
106         if (ret != EOK) {
107             SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
108             return;
109         }
110         tpdu->data.submit.userData.length = cellsInfos[i].encodeData.size();
111         tpdu->data.submit.userData.data[cellsInfos[i].encodeData.size()] = 0;
112         tpdu->data.submit.msgRef = msgRef8bit;
113         int headerCnt = 0;
114         if (cellsInfosSize > 1) {
115             indexer->SetIsConcat(true);
116             SmsConcat concat;
117             concat.msgRef = msgRef8bit;
118             concat.totalSeg = static_cast<uint16_t>(cellsInfosSize);
119             concat.seqNum = static_cast<uint16_t>(i + 1);
120             indexer->SetSmsConcat(concat);
121             headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, concat);
122             concat.is8Bits = true;
123         }
124         /* Set User Data Header for Alternate Reply Address */
125         headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
126         /* Set User Data Header for National Language Single Shift */
127         headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, codingType, cellsInfos[i].langId);
128         indexer->SetLangId(cellsInfos[i].langId);
129         tpdu->data.submit.userData.headerCnt = headerCnt;
130         tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
131         bool isMore = false;
132         if (cellsInfosSize > 1 && i < (cellsInfosSize - 1)) {
133             isMore = true;
134             tpdu->data.submit.bStatusReport = false;
135         } else {
136             tpdu->data.submit.bStatusReport = isStatusReport;
137             isMore = false;
138         }
139         std::shared_ptr<struct EncodeInfo> encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(scAddr, isMore);
140         if (encodeInfo == nullptr) {
141             SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
142             TELEPHONY_LOGE("create encodeInfo encodeInfo nullptr error.");
143             continue;
144         }
145         SetSendIndexerInfo(indexer, encodeInfo, msgRef8bit);
146         indexer->SetUnSentCellCount(*unSentCellCount);
147         indexer->SetHasCellFailed(hasCellFailed);
148         SendSmsToRil(indexer);
149     }
150 }
151 
DataBasedSmsDelivery(const std::string & desAddr,const std::string & scAddr,int32_t port,const uint8_t * data,uint32_t dataLen,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)152 void GsmSmsSender::DataBasedSmsDelivery(const std::string &desAddr, const std::string &scAddr, int32_t port,
153     const uint8_t *data, uint32_t dataLen, const sptr<ISendShortMessageCallback> &sendCallback,
154     const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
155 {
156     GsmSmsMessage gsmSmsMessage;
157     std::vector<struct SplitInfo> cellsInfos;
158     DataCodingScheme codingType;
159     std::string dataStr;
160     CharArrayToString(data, dataLen, dataStr);
161     gsmSmsMessage.SetSmsCodingNationalType(GetSmsCodingNationalType(slotId_));
162     gsmSmsMessage.SplitMessage(cellsInfos, dataStr, CheckForce7BitEncodeType(), codingType, true, desAddr);
163     uint8_t msgRef8bit = GetMsgRef8Bit();
164     TELEPHONY_LOGI("gsm data msgRef8bit = %{public}d", msgRef8bit);
165     std::shared_ptr<struct SmsTpdu> tpdu = gsmSmsMessage.CreateDataSubmitSmsTpdu(
166         desAddr, scAddr, port, data, dataLen, msgRef8bit, codingType, (deliveryCallback == nullptr) ? false : true);
167     if (tpdu == nullptr) {
168         SendCallbackExceptionCase(sendCallback, "DataBasedSmsDelivery");
169         return;
170     }
171     DataBasedSmsDeliverySplitPage(
172         gsmSmsMessage, cellsInfos, tpdu, msgRef8bit, desAddr, scAddr, port, sendCallback, deliveryCallback);
173 }
174 
SendSmsToRil(const shared_ptr<SmsSendIndexer> & smsIndexer)175 void GsmSmsSender::SendSmsToRil(const shared_ptr<SmsSendIndexer> &smsIndexer)
176 {
177     if (smsIndexer == nullptr) {
178         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
179         TELEPHONY_LOGE("gsm_sms_sender: SendSms smsIndexer nullptr");
180         return;
181     }
182     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
183     if (!satelliteSmsClient.IsSatelliteEnabled()) {
184         if (!isImsNetDomain_ && (voiceServiceState_ != static_cast<int32_t>(RegServiceState::REG_STATE_IN_SERVICE))) {
185             SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
186             TELEPHONY_LOGE("gsm_sms_sender: SendSms not in service");
187             SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
188                 SmsMmsErrorCode::SMS_ERROR_SENDSMS_NOT_IN_SERVICE, "gsm send sms not in service");
189             return;
190         }
191     }
192 
193     int64_t refId = GetMsgRef64Bit();
194     TELEPHONY_LOGI("gsm refId = %{public}" PRId64 "", refId);
195     if (!SendCacheMapAddItem(refId, smsIndexer)) {
196         TELEPHONY_LOGE("SendCacheMapAddItem Error!!");
197         return;
198     }
199 
200     GsmSimMessageParam smsData;
201     smsData.refId = refId;
202     smsData.smscPdu = StringUtils::StringToHex(smsIndexer->GetEncodeSmca());
203     smsData.pdu = StringUtils::StringToHex(smsIndexer->GetEncodePdu());
204 
205     if (satelliteSmsClient.IsSatelliteEnabled()) {
206         TELEPHONY_LOGI("send sms through satellite");
207         SendSatelliteSms(smsIndexer, smsData);
208         return;
209     }
210 
211     bool sendCsSMS = false;
212     if ((!isImsNetDomain_ || !imsSmsCfg_) || (smsIndexer->GetPsResendCount() == MAX_SEND_RETRIES)) {
213         sendCsSMS = true;
214     }
215     if (sendCsSMS) {
216         SendCsSms(smsIndexer, smsData);
217     } else {
218         SendImsSms(smsIndexer, smsData);
219     }
220 }
221 
SendCsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)222 void GsmSmsSender::SendCsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
223 {
224     uint8_t tryCount = smsIndexer->GetCsResendCount();
225     lastSmsDomain_ = CS_DOMAIN;
226     if (tryCount > 0) {
227         smsIndexer->UpdatePduForResend();
228     }
229     if (tryCount == 0 && smsIndexer->GetHasMore()) {
230         TELEPHONY_LOGI("SendSmsMoreMode pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
231         CoreManagerInner::GetInstance().SendSmsMoreMode(
232             slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, smsData, shared_from_this());
233     } else {
234         TELEPHONY_LOGI("SendSms pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
235         CoreManagerInner::GetInstance().SendGsmSms(slotId_, RadioEvent::RADIO_SEND_SMS, smsData, shared_from_this());
236     }
237 }
238 
SendSatelliteSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)239 void GsmSmsSender::SendSatelliteSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
240 {
241     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
242     uint8_t tryCount = smsIndexer->GetCsResendCount();
243     lastSmsDomain_ = CS_DOMAIN;
244     if (tryCount > 0) {
245         smsIndexer->UpdatePduForResend();
246     }
247     TELEPHONY_LOGI("satellite SendSms tryCount = %{public}d", tryCount);
248     if (tryCount == 0 && smsIndexer->GetHasMore()) {
249         TELEPHONY_LOGI("satellite SendSmsMoreMode pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
250         satelliteSmsClient.SendSmsMoreMode(slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, smsData);
251     } else {
252         TELEPHONY_LOGI("satellite SendSms pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
253         satelliteSmsClient.SendSms(slotId_, RadioEvent::RADIO_SEND_SMS, smsData);
254     }
255 }
256 
SendImsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)257 void GsmSmsSender::SendImsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
258 {
259     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
260     TELEPHONY_LOGI("ims network domain send sms interface.!");
261     if (smsClient == nullptr) {
262         TELEPHONY_LOGE("SendSmsToRil return, ImsSmsClient is nullptr.");
263         return;
264     }
265     lastSmsDomain_ = IMS_DOMAIN;
266     ImsMessageInfo imsMessageInfo;
267     imsMessageInfo.refId = smsData.refId;
268     imsMessageInfo.smscPdu = smsData.smscPdu;
269     imsMessageInfo.pdu = smsData.pdu;
270     imsMessageInfo.tech = SMS_RADIO_TECH_3GPP;
271     int32_t reply = smsClient->ImsSendMessage(slotId_, imsMessageInfo);
272     TELEPHONY_LOGI("SendImsSms reply = %{public}d", reply);
273 }
274 
IsImsSmsSupported(int32_t slotId,bool & isSupported)275 int32_t GsmSmsSender::IsImsSmsSupported(int32_t slotId, bool &isSupported)
276 {
277     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
278     if (smsClient == nullptr) {
279         TELEPHONY_LOGE("GetImsSmsConfig return, ImsSmsClient is nullptr.");
280         return TELEPHONY_ERR_LOCAL_PTR_NULL;
281     }
282     std::unique_lock<std::mutex> lck(ctx_);
283     resIsSmsReady_ = false;
284     int32_t reply = smsClient->ImsGetSmsConfig(slotId);
285     TELEPHONY_LOGI("GetImsSms reply = %{public}d", reply);
286     while (resIsSmsReady_) {
287         TELEPHONY_LOGI("GetImsSmsConfig::wait(), resIsSmsReady_ = false");
288         if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
289             break;
290         }
291     }
292     TELEPHONY_LOGI("GsmSmsSender::IsImsSmsSupported() imsSmsCfg_:%{public}d", imsSmsCfg_);
293     isSupported = (imsSmsCfg_ == IMS_SMS_ENABLE);
294     return TELEPHONY_ERR_SUCCESS;
295 }
296 
StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer & event)297 void GsmSmsSender::StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer &event)
298 {
299     if (event == nullptr) {
300         TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis event nullptr error.");
301         return;
302     }
303 
304     std::shared_ptr<SmsMessageInfo> statusInfo = event->GetSharedObject<SmsMessageInfo>();
305     if (statusInfo == nullptr) {
306         TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis statusInfo nullptr error.");
307         return;
308     }
309 
310     std::string pdu = StringUtils::StringToHex(statusInfo->pdu);
311     TELEPHONY_LOGI("StatusReport pdu size == %{public}zu", pdu.length());
312     std::shared_ptr<GsmSmsMessage> message = GsmSmsMessage::CreateMessage(pdu);
313     if (message == nullptr) {
314         TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis message nullptr error.");
315         return;
316     }
317     sptr<IDeliveryShortMessageCallback> deliveryCallback = nullptr;
318     auto oldIndexer = reportList_.begin();
319     while (oldIndexer != reportList_.end()) {
320         auto iter = oldIndexer++;
321         if (*iter != nullptr && (message->GetMsgRef() == (*iter)->GetMsgRefId())) {
322             // save the message to db, or updata to db msg state(success or failed)
323             TELEPHONY_LOGI("StatusReport %{public}d", message->GetMsgRef());
324             deliveryCallback = (*iter)->GetDeliveryCallback();
325             reportList_.erase(iter);
326         }
327     }
328     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
329     if (satelliteSmsClient.GetSatelliteCapability() > 0 && satelliteSmsClient.IsSatelliteEnabled()) {
330         TELEPHONY_LOGI("send sms ack through satellite");
331         satelliteSmsClient.SendSmsAck(slotId_, 0, AckIncomeCause::SMS_ACK_PROCESSED, true);
332     } else {
333         CoreManagerInner::GetInstance().SendSmsAck(slotId_, 0, AckIncomeCause::SMS_ACK_PROCESSED, true, nullptr);
334     }
335     if (deliveryCallback != nullptr) {
336         std::string ackpdu = StringUtils::StringToHex(message->GetRawPdu());
337         deliveryCallback->OnSmsDeliveryResult(StringUtils::ToUtf16(ackpdu));
338     }
339 }
340 
StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer & event)341 void GsmSmsSender::StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
342 {
343     if (event == nullptr) {
344         TELEPHONY_LOGE("GsmSmsSender: StatusReportSetImsSms event nullptr error.");
345         return;
346     }
347     std::shared_ptr<RadioResponseInfo> imsResponseInfo = event->GetSharedObject<RadioResponseInfo>();
348 
349     if (imsResponseInfo == nullptr) {
350         return;
351     }
352 
353     if (imsResponseInfo->error != ErrType::NONE) {
354         imsSmsCfg_ = IMS_SMS_DISABLE;
355     }
356 }
357 
StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer & event)358 void GsmSmsSender::StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
359 {
360     if (event == nullptr) {
361         TELEPHONY_LOGE("GsmSmsSender: StatusReportGetImsSms event nullptr error.");
362         return;
363     }
364     std::shared_ptr<int32_t> imsSmsInfo = event->GetSharedObject<int32_t>();
365     if (imsSmsInfo == nullptr) {
366         TELEPHONY_LOGE("GsmSmsSender: StatusReportGetImsSms imsSmsInfo nullptr error.");
367         return;
368     }
369     imsSmsCfg_ = *imsSmsInfo;
370 }
371 
SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> & indexer,const std::shared_ptr<struct EncodeInfo> & encodeInfo,unsigned char msgRef8bit)372 void GsmSmsSender::SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> &indexer,
373     const std::shared_ptr<struct EncodeInfo> &encodeInfo, unsigned char msgRef8bit)
374 {
375     if (encodeInfo == nullptr || indexer == nullptr) {
376         TELEPHONY_LOGE("CreateSendIndexer encodeInfo nullptr");
377         return;
378     }
379 
380     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
381     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
382     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
383     int64_t timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
384     indexer->SetTimeStamp(timeStamp);
385     indexer->SetEncodeSmca(std::move(smca));
386     indexer->SetEncodePdu(std::move(pdu));
387     indexer->SetHasMore(encodeInfo->isMore_);
388     TELEPHONY_LOGI("gsm text msgRef8bit = %{public}d", msgRef8bit);
389     indexer->SetMsgRefId(msgRef8bit);
390     indexer->SetNetWorkType(NET_TYPE_GSM);
391 }
392 
RegisterHandler()393 bool GsmSmsSender::RegisterHandler()
394 {
395     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
396     if (satelliteSmsClient.GetSatelliteSupported()) {
397         satelliteSmsClient.AddSendHandler(slotId_, std::static_pointer_cast<TelEventHandler>(shared_from_this()));
398     }
399     CoreManagerInner::GetInstance().RegisterCoreNotify(
400         slotId_, shared_from_this(), RadioEvent::RADIO_SMS_STATUS, nullptr);
401 
402     return true;
403 }
404 
RegisterSatelliteCallback()405 void GsmSmsSender::RegisterSatelliteCallback()
406 {
407     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
408     if (satelliteSmsClient.GetSatelliteSupported()) {
409         TELEPHONY_LOGI("gsm sender register satellite notify");
410         satelliteCallback_ =
411             std::make_unique<SatelliteSmsCallback>(std::static_pointer_cast<TelEventHandler>(shared_from_this()))
412                 .release();
413         satelliteSmsClient.RegisterSmsNotify(slotId_, RadioEvent::RADIO_SMS_STATUS, satelliteCallback_);
414         satelliteSmsClient.RegisterSmsNotify(slotId_, RadioEvent::RADIO_SEND_SMS, satelliteCallback_);
415         satelliteSmsClient.RegisterSmsNotify(slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, satelliteCallback_);
416     }
417 }
418 
UnregisterSatelliteCallback()419 void GsmSmsSender::UnregisterSatelliteCallback()
420 {
421     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
422     if (satelliteSmsClient.GetSatelliteSupported()) {
423         TELEPHONY_LOGI("gsm sender unregister satellite notify");
424         satelliteCallback_ = nullptr;
425     }
426 }
427 
RegisterImsHandler()428 void GsmSmsSender::RegisterImsHandler()
429 {
430     if (isImsGsmHandlerRegistered) {
431         return;
432     }
433     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
434     if (smsClient == nullptr) {
435         TELEPHONY_LOGE("RegisterHandler return, ImsSmsClient is nullptr.");
436         return;
437     }
438 
439     smsClient->RegisterImsSmsCallbackHandler(slotId_, shared_from_this());
440     TELEPHONY_LOGE("RegisterHandler  gsm ImsSmsClient successs");
441     isImsGsmHandlerRegistered = true;
442 }
443 
ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)444 void GsmSmsSender::ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
445 {
446     if (smsIndexer == nullptr) {
447         TELEPHONY_LOGE("ResendTextDelivery smsIndexer == nullptr");
448         return;
449     }
450     GsmSmsMessage gsmSmsMessage;
451     bool isMore = false;
452     if (!SetPduInfo(smsIndexer, gsmSmsMessage, isMore)) {
453         TELEPHONY_LOGE("SetPduInfo fail.");
454         return;
455     }
456 
457     std::shared_ptr<struct EncodeInfo> encodeInfo = nullptr;
458     encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(smsIndexer->GetSmcaAddr(), isMore);
459     if (encodeInfo == nullptr) {
460         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
461         TELEPHONY_LOGE("create encodeInfo indexer == nullptr\r\n");
462         return;
463     }
464     SetSendIndexerInfo(smsIndexer, encodeInfo, smsIndexer->GetMsgRefId());
465     std::unique_lock<std::mutex> lock(mutex_);
466     SendSmsToRil(smsIndexer);
467 }
468 
ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)469 void GsmSmsSender::ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
470 {
471     if (smsIndexer == nullptr) {
472         TELEPHONY_LOGE("DataBasedSmsDelivery ResendDataDelivery smsIndexer nullptr");
473         return;
474     }
475 
476     bool isStatusReport = false;
477     unsigned char msgRef8bit = 0;
478     msgRef8bit = smsIndexer->GetMsgRefId();
479     isStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
480 
481     GsmSmsMessage gsmSmsMessage;
482     std::shared_ptr<struct SmsTpdu> tpdu = nullptr;
483     tpdu = gsmSmsMessage.CreateDataSubmitSmsTpdu(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
484         smsIndexer->GetDestPort(), smsIndexer->GetData().data(), smsIndexer->GetData().size(), msgRef8bit,
485         smsIndexer->GetDcs(), isStatusReport);
486 
487     std::shared_ptr<struct EncodeInfo> encodeInfo = nullptr;
488     encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(smsIndexer->GetSmcaAddr(), false);
489     if (encodeInfo == nullptr || tpdu == nullptr) {
490         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
491         TELEPHONY_LOGE("DataBasedSmsDelivery encodeInfo or tpdu nullptr");
492         return;
493     }
494     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
495     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
496     std::shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(1);
497     if (unSentCellCount == nullptr) {
498         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
499         TELEPHONY_LOGE("DataBasedSmsDelivery unSentCellCount nullptr");
500         return;
501     }
502     std::shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
503     if (hasCellFailed == nullptr) {
504         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
505         TELEPHONY_LOGE("DataBasedSmsDelivery hasCellFailed nullptr");
506         return;
507     }
508     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
509     int64_t timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
510 
511     smsIndexer->SetUnSentCellCount(*unSentCellCount);
512     smsIndexer->SetHasCellFailed(hasCellFailed);
513     smsIndexer->SetEncodeSmca(std::move(smca));
514     smsIndexer->SetEncodePdu(std::move(pdu));
515     smsIndexer->SetHasMore(encodeInfo->isMore_);
516     smsIndexer->SetMsgRefId(msgRef8bit);
517     smsIndexer->SetNetWorkType(NET_TYPE_GSM);
518     smsIndexer->SetTimeStamp(timeStamp);
519     std::unique_lock<std::mutex> lock(mutex_);
520     SendSmsToRil(smsIndexer);
521 }
522 
SetPduInfo(const std::shared_ptr<SmsSendIndexer> & smsIndexer,GsmSmsMessage & gsmSmsMessage,bool & isMore)523 bool GsmSmsSender::SetPduInfo(
524     const std::shared_ptr<SmsSendIndexer> &smsIndexer, GsmSmsMessage &gsmSmsMessage, bool &isMore)
525 {
526     bool ret = false;
527     if (smsIndexer == nullptr) {
528         TELEPHONY_LOGE("Indexer is nullptr");
529         return ret;
530     }
531     DataCodingScheme codingType = smsIndexer->GetDcs();
532     std::shared_ptr<struct SmsTpdu> tpdu = nullptr;
533     tpdu = gsmSmsMessage.CreateDefaultSubmitSmsTpdu(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
534         smsIndexer->GetText(), (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true, codingType);
535     if (tpdu == nullptr) {
536         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
537         TELEPHONY_LOGE("ResendTextDelivery CreateDefaultSubmitSmsTpdu err.");
538         return ret;
539     }
540     (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
541     if (smsIndexer->GetText().length() > MAX_USER_DATA_LEN + 1) {
542         TELEPHONY_LOGE("SetPduInfo data length invalid.");
543         return ret;
544     }
545     if (memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, smsIndexer->GetText().c_str(),
546         smsIndexer->GetText().length()) != EOK) {
547         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
548         TELEPHONY_LOGE("TextBasedSmsDelivery memcpy_s error.");
549         return ret;
550     }
551     int headerCnt = 0;
552     tpdu->data.submit.userData.length = static_cast<int>(smsIndexer->GetText().length());
553     tpdu->data.submit.userData.data[smsIndexer->GetText().length()] = 0;
554     tpdu->data.submit.msgRef = smsIndexer->GetMsgRefId();
555     if (smsIndexer->GetIsConcat()) {
556         headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, smsIndexer->GetSmsConcat());
557     }
558     /* Set User Data Header for Alternate Reply Address */
559     headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
560     /* Set User Data Header for National Language Single Shift */
561     headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, codingType, smsIndexer->GetLangId());
562     tpdu->data.submit.userData.headerCnt = headerCnt;
563     tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
564 
565     unsigned char totalSeg = smsIndexer->GetSmsConcat().totalSeg;
566     if ((totalSeg > 1) && (smsIndexer->GetSmsConcat().seqNum < totalSeg)) {
567         tpdu->data.submit.bStatusReport = false;
568         isMore = true;
569     } else {
570         tpdu->data.submit.bStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
571         isMore = false;
572     }
573     return true;
574 }
575 } // namespace Telephony
576 } // namespace OHOS
577