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