• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (!isImsNetDomain_ && (voiceServiceState_ != static_cast<int32_t>(RegServiceState::REG_STATE_IN_SERVICE))) {
183         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
184         TELEPHONY_LOGE("gsm_sms_sender: SendSms not in service");
185         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
186             SmsMmsErrorCode::SMS_ERROR_SENDSMS_NOT_IN_SERVICE, "gsm send sms not in service");
187         return;
188     }
189     int64_t refId = GetMsgRef64Bit();
190     TELEPHONY_LOGI("gsm refId = %{public}" PRId64 "", refId);
191     if (!SendCacheMapAddItem(refId, smsIndexer)) {
192         TELEPHONY_LOGE("SendCacheMapAddItem Error!!");
193         return;
194     }
195 
196     GsmSimMessageParam smsData;
197     smsData.refId = refId;
198     smsData.smscPdu = StringUtils::StringToHex(smsIndexer->GetEncodeSmca());
199     smsData.pdu = StringUtils::StringToHex(smsIndexer->GetEncodePdu());
200 
201     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
202     if (satelliteSmsClient.GetSatelliteCapability() > 0 && satelliteSmsClient.IsSatelliteEnabled()) {
203         TELEPHONY_LOGI("send sms through satellite");
204         SendSatelliteSms(smsIndexer, smsData);
205         return;
206     }
207 
208     bool sendCsSMS = false;
209     if ((!isImsNetDomain_ || !imsSmsCfg_) || (smsIndexer->GetPsResendCount() == MAX_SEND_RETRIES)) {
210         sendCsSMS = true;
211     }
212     if (sendCsSMS) {
213         SendCsSms(smsIndexer, smsData);
214     } else {
215         SendImsSms(smsIndexer, smsData);
216     }
217 }
218 
SendCsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)219 void GsmSmsSender::SendCsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
220 {
221     uint8_t tryCount = smsIndexer->GetCsResendCount();
222     lastSmsDomain_ = CS_DOMAIN;
223     if (tryCount > 0) {
224         smsIndexer->UpdatePduForResend();
225     }
226     if (tryCount == 0 && smsIndexer->GetHasMore()) {
227         TELEPHONY_LOGI("SendSmsMoreMode pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
228         CoreManagerInner::GetInstance().SendSmsMoreMode(
229             slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, smsData, shared_from_this());
230     } else {
231         TELEPHONY_LOGI("SendSms pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
232         CoreManagerInner::GetInstance().SendGsmSms(slotId_, RadioEvent::RADIO_SEND_SMS, smsData, shared_from_this());
233     }
234 }
235 
SendSatelliteSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)236 void GsmSmsSender::SendSatelliteSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
237 {
238     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
239     uint8_t tryCount = smsIndexer->GetCsResendCount();
240     lastSmsDomain_ = CS_DOMAIN;
241     if (tryCount > 0) {
242         smsIndexer->UpdatePduForResend();
243     }
244     TELEPHONY_LOGI("satellite SendSms tryCount = %{public}d", tryCount);
245     if (tryCount == 0 && smsIndexer->GetHasMore()) {
246         TELEPHONY_LOGI("satellite SendSmsMoreMode pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
247         satelliteSmsClient.SendSmsMoreMode(slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, smsData);
248     } else {
249         TELEPHONY_LOGI("satellite SendSms pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
250         satelliteSmsClient.SendSms(slotId_, RadioEvent::RADIO_SEND_SMS, smsData);
251     }
252 }
253 
SendImsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)254 void GsmSmsSender::SendImsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
255 {
256     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
257     TELEPHONY_LOGI("ims network domain send sms interface.!");
258     if (smsClient == nullptr) {
259         TELEPHONY_LOGE("SendSmsToRil return, ImsSmsClient is nullptr.");
260         return;
261     }
262     lastSmsDomain_ = IMS_DOMAIN;
263     ImsMessageInfo imsMessageInfo;
264     imsMessageInfo.refId = smsData.refId;
265     imsMessageInfo.smscPdu = smsData.smscPdu;
266     imsMessageInfo.pdu = smsData.pdu;
267     imsMessageInfo.tech = SMS_RADIO_TECH_3GPP;
268     int32_t reply = smsClient->ImsSendMessage(slotId_, imsMessageInfo);
269     TELEPHONY_LOGI("SendImsSms reply = %{public}d", reply);
270 }
271 
IsImsSmsSupported(int32_t slotId,bool & isSupported)272 int32_t GsmSmsSender::IsImsSmsSupported(int32_t slotId, bool &isSupported)
273 {
274     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
275     if (smsClient == nullptr) {
276         TELEPHONY_LOGE("GetImsSmsConfig return, ImsSmsClient is nullptr.");
277         return TELEPHONY_ERR_LOCAL_PTR_NULL;
278     }
279     std::unique_lock<std::mutex> lck(ctx_);
280     resIsSmsReady_ = false;
281     int32_t reply = smsClient->ImsGetSmsConfig(slotId);
282     TELEPHONY_LOGI("GetImsSms reply = %{public}d", reply);
283     while (resIsSmsReady_) {
284         TELEPHONY_LOGI("GetImsSmsConfig::wait(), resIsSmsReady_ = false");
285         if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
286             break;
287         }
288     }
289     TELEPHONY_LOGI("GsmSmsSender::IsImsSmsSupported() imsSmsCfg_:%{public}d", imsSmsCfg_);
290     isSupported = (imsSmsCfg_ == IMS_SMS_ENABLE);
291     return TELEPHONY_ERR_SUCCESS;
292 }
293 
StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer & event)294 void GsmSmsSender::StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer &event)
295 {
296     if (event == nullptr) {
297         TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis event nullptr error.");
298         return;
299     }
300 
301     std::shared_ptr<SmsMessageInfo> statusInfo = event->GetSharedObject<SmsMessageInfo>();
302     if (statusInfo == nullptr) {
303         TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis statusInfo nullptr error.");
304         return;
305     }
306 
307     std::string pdu = StringUtils::StringToHex(statusInfo->pdu);
308     TELEPHONY_LOGI("StatusReport pdu size == %{public}zu", pdu.length());
309     std::shared_ptr<GsmSmsMessage> message = GsmSmsMessage::CreateMessage(pdu);
310     if (message == nullptr) {
311         TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis message nullptr error.");
312         return;
313     }
314     sptr<IDeliveryShortMessageCallback> deliveryCallback = nullptr;
315     auto oldIndexer = reportList_.begin();
316     while (oldIndexer != reportList_.end()) {
317         auto iter = oldIndexer++;
318         if (*iter != nullptr && (message->GetMsgRef() == (*iter)->GetMsgRefId())) {
319             // save the message to db, or updata to db msg state(success or failed)
320             TELEPHONY_LOGI("StatusReport %{public}d", message->GetMsgRef());
321             deliveryCallback = (*iter)->GetDeliveryCallback();
322             reportList_.erase(iter);
323         }
324     }
325     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
326     if (satelliteSmsClient.GetSatelliteCapability() > 0 && satelliteSmsClient.IsSatelliteEnabled()) {
327         TELEPHONY_LOGI("send sms ack through satellite");
328         satelliteSmsClient.SendSmsAck(slotId_, 0, AckIncomeCause::SMS_ACK_PROCESSED, true);
329     } else {
330         CoreManagerInner::GetInstance().SendSmsAck(slotId_, 0, AckIncomeCause::SMS_ACK_PROCESSED, true, nullptr);
331     }
332     if (deliveryCallback != nullptr) {
333         std::string ackpdu = StringUtils::StringToHex(message->GetRawPdu());
334         deliveryCallback->OnSmsDeliveryResult(StringUtils::ToUtf16(ackpdu));
335     }
336 }
337 
StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer & event)338 void GsmSmsSender::StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
339 {
340     if (event == nullptr) {
341         TELEPHONY_LOGE("GsmSmsSender: StatusReportSetImsSms event nullptr error.");
342         return;
343     }
344     std::shared_ptr<RadioResponseInfo> imsResponseInfo = event->GetSharedObject<RadioResponseInfo>();
345 
346     if (imsResponseInfo->error != ErrType::NONE) {
347         imsSmsCfg_ = IMS_SMS_DISABLE;
348     }
349 }
350 
StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer & event)351 void GsmSmsSender::StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
352 {
353     if (event == nullptr) {
354         TELEPHONY_LOGE("GsmSmsSender: StatusReportGetImsSms event nullptr error.");
355         return;
356     }
357     std::shared_ptr<int32_t> imsSmsInfo = event->GetSharedObject<int32_t>();
358     if (imsSmsInfo == nullptr) {
359         TELEPHONY_LOGE("GsmSmsSender: StatusReportGetImsSms imsSmsInfo nullptr error.");
360         return;
361     }
362     imsSmsCfg_ = *imsSmsInfo;
363 }
364 
SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> & indexer,const std::shared_ptr<struct EncodeInfo> & encodeInfo,unsigned char msgRef8bit)365 void GsmSmsSender::SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> &indexer,
366     const std::shared_ptr<struct EncodeInfo> &encodeInfo, unsigned char msgRef8bit)
367 {
368     if (encodeInfo == nullptr || indexer == nullptr) {
369         TELEPHONY_LOGE("CreateSendIndexer encodeInfo nullptr");
370         return;
371     }
372 
373     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
374     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
375     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
376     int64_t timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
377     indexer->SetTimeStamp(timeStamp);
378     indexer->SetEncodeSmca(std::move(smca));
379     indexer->SetEncodePdu(std::move(pdu));
380     indexer->SetHasMore(encodeInfo->isMore_);
381     TELEPHONY_LOGI("gsm text msgRef8bit = %{public}d", msgRef8bit);
382     indexer->SetMsgRefId(msgRef8bit);
383     indexer->SetNetWorkType(NET_TYPE_GSM);
384 }
385 
RegisterHandler()386 bool GsmSmsSender::RegisterHandler()
387 {
388     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
389     if (satelliteSmsClient.GetSatelliteSupported()) {
390         satelliteSmsClient.AddSendHandler(slotId_, std::static_pointer_cast<TelEventHandler>(shared_from_this()));
391     }
392     CoreManagerInner::GetInstance().RegisterCoreNotify(
393         slotId_, shared_from_this(), RadioEvent::RADIO_SMS_STATUS, nullptr);
394 
395     return true;
396 }
397 
RegisterSatelliteCallback()398 void GsmSmsSender::RegisterSatelliteCallback()
399 {
400     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
401     if (satelliteSmsClient.GetSatelliteSupported()) {
402         TELEPHONY_LOGI("gsm sender register satellite notify");
403         satelliteCallback_ =
404             std::make_unique<SatelliteSmsCallback>(std::static_pointer_cast<TelEventHandler>(shared_from_this()))
405                 .release();
406         satelliteSmsClient.RegisterSmsNotify(slotId_, RadioEvent::RADIO_SMS_STATUS, satelliteCallback_);
407         satelliteSmsClient.RegisterSmsNotify(slotId_, RadioEvent::RADIO_SEND_SMS, satelliteCallback_);
408         satelliteSmsClient.RegisterSmsNotify(slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, satelliteCallback_);
409     }
410 }
411 
UnregisterSatelliteCallback()412 void GsmSmsSender::UnregisterSatelliteCallback()
413 {
414     auto &satelliteSmsClient = SatelliteSmsClient::GetInstance();
415     if (satelliteSmsClient.GetSatelliteSupported()) {
416         TELEPHONY_LOGI("gsm sender unregister satellite notify");
417         satelliteCallback_ = nullptr;
418     }
419 }
420 
RegisterImsHandler()421 void GsmSmsSender::RegisterImsHandler()
422 {
423     if (isImsGsmHandlerRegistered) {
424         return;
425     }
426     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
427     if (smsClient == nullptr) {
428         TELEPHONY_LOGE("RegisterHandler return, ImsSmsClient is nullptr.");
429         return;
430     }
431 
432     smsClient->RegisterImsSmsCallbackHandler(slotId_, shared_from_this());
433     TELEPHONY_LOGE("RegisterHandler  gsm ImsSmsClient successs");
434     isImsGsmHandlerRegistered = true;
435 }
436 
ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)437 void GsmSmsSender::ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
438 {
439     if (smsIndexer == nullptr) {
440         TELEPHONY_LOGE("ResendTextDelivery smsIndexer == nullptr");
441         return;
442     }
443     GsmSmsMessage gsmSmsMessage;
444     bool isMore = false;
445     if (!SetPduInfo(smsIndexer, gsmSmsMessage, isMore)) {
446         TELEPHONY_LOGE("SetPduInfo fail.");
447         return;
448     }
449 
450     std::shared_ptr<struct EncodeInfo> encodeInfo = nullptr;
451     encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(smsIndexer->GetSmcaAddr(), isMore);
452     if (encodeInfo == nullptr) {
453         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
454         TELEPHONY_LOGE("create encodeInfo indexer == nullptr\r\n");
455         return;
456     }
457     SetSendIndexerInfo(smsIndexer, encodeInfo, smsIndexer->GetMsgRefId());
458     std::unique_lock<std::mutex> lock(mutex_);
459     SendSmsToRil(smsIndexer);
460 }
461 
ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)462 void GsmSmsSender::ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
463 {
464     if (smsIndexer == nullptr) {
465         TELEPHONY_LOGE("DataBasedSmsDelivery ResendDataDelivery smsIndexer nullptr");
466         return;
467     }
468 
469     bool isStatusReport = false;
470     unsigned char msgRef8bit = 0;
471     msgRef8bit = smsIndexer->GetMsgRefId();
472     isStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
473 
474     GsmSmsMessage gsmSmsMessage;
475     std::shared_ptr<struct SmsTpdu> tpdu = nullptr;
476     tpdu = gsmSmsMessage.CreateDataSubmitSmsTpdu(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
477         smsIndexer->GetDestPort(), smsIndexer->GetData().data(), smsIndexer->GetData().size(), msgRef8bit,
478         smsIndexer->GetDcs(), isStatusReport);
479 
480     std::shared_ptr<struct EncodeInfo> encodeInfo = nullptr;
481     encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(smsIndexer->GetSmcaAddr(), false);
482     if (encodeInfo == nullptr || tpdu == nullptr) {
483         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
484         TELEPHONY_LOGE("DataBasedSmsDelivery encodeInfo or tpdu nullptr");
485         return;
486     }
487     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
488     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
489     std::shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(1);
490     if (unSentCellCount == nullptr) {
491         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
492         TELEPHONY_LOGE("DataBasedSmsDelivery unSentCellCount nullptr");
493         return;
494     }
495     std::shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
496     if (hasCellFailed == nullptr) {
497         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
498         TELEPHONY_LOGE("DataBasedSmsDelivery hasCellFailed nullptr");
499         return;
500     }
501     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
502     int64_t timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
503 
504     smsIndexer->SetUnSentCellCount(*unSentCellCount);
505     smsIndexer->SetHasCellFailed(hasCellFailed);
506     smsIndexer->SetEncodeSmca(std::move(smca));
507     smsIndexer->SetEncodePdu(std::move(pdu));
508     smsIndexer->SetHasMore(encodeInfo->isMore_);
509     smsIndexer->SetMsgRefId(msgRef8bit);
510     smsIndexer->SetNetWorkType(NET_TYPE_GSM);
511     smsIndexer->SetTimeStamp(timeStamp);
512     std::unique_lock<std::mutex> lock(mutex_);
513     SendSmsToRil(smsIndexer);
514 }
515 
SetPduInfo(const std::shared_ptr<SmsSendIndexer> & smsIndexer,GsmSmsMessage & gsmSmsMessage,bool & isMore)516 bool GsmSmsSender::SetPduInfo(
517     const std::shared_ptr<SmsSendIndexer> &smsIndexer, GsmSmsMessage &gsmSmsMessage, bool &isMore)
518 {
519     bool ret = false;
520     if (smsIndexer == nullptr) {
521         TELEPHONY_LOGE("Indexer is nullptr");
522         return ret;
523     }
524     DataCodingScheme codingType = smsIndexer->GetDcs();
525     std::shared_ptr<struct SmsTpdu> tpdu = nullptr;
526     tpdu = gsmSmsMessage.CreateDefaultSubmitSmsTpdu(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
527         smsIndexer->GetText(), (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true, codingType);
528     if (tpdu == nullptr) {
529         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
530         TELEPHONY_LOGE("ResendTextDelivery CreateDefaultSubmitSmsTpdu err.");
531         return ret;
532     }
533     (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
534     if (smsIndexer->GetText().length() > MAX_USER_DATA_LEN + 1) {
535         TELEPHONY_LOGE("SetPduInfo data length invalid.");
536         return ret;
537     }
538     if (memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, smsIndexer->GetText().c_str(),
539         smsIndexer->GetText().length()) != EOK) {
540         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
541         TELEPHONY_LOGE("TextBasedSmsDelivery memcpy_s error.");
542         return ret;
543     }
544     int headerCnt = 0;
545     tpdu->data.submit.userData.length = static_cast<int>(smsIndexer->GetText().length());
546     tpdu->data.submit.userData.data[smsIndexer->GetText().length()] = 0;
547     tpdu->data.submit.msgRef = smsIndexer->GetMsgRefId();
548     if (smsIndexer->GetIsConcat()) {
549         headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, smsIndexer->GetSmsConcat());
550     }
551     /* Set User Data Header for Alternate Reply Address */
552     headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
553     /* Set User Data Header for National Language Single Shift */
554     headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, codingType, smsIndexer->GetLangId());
555     tpdu->data.submit.userData.headerCnt = headerCnt;
556     tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
557 
558     unsigned char totalSeg = smsIndexer->GetSmsConcat().totalSeg;
559     if ((totalSeg > 1) && (smsIndexer->GetSmsConcat().seqNum < totalSeg)) {
560         tpdu->data.submit.bStatusReport = false;
561         isMore = true;
562     } else {
563         tpdu->data.submit.bStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
564         isMore = false;
565     }
566     return true;
567 }
568 } // namespace Telephony
569 } // namespace OHOS
570