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