• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "cdma_sms_sender.h"
17 
18 #include "cdma_sms_message.h"
19 #include "core_manager_inner.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;
CdmaSmsSender(const shared_ptr<AppExecFwk::EventRunner> & runner,int32_t slotId,function<void (shared_ptr<SmsSendIndexer>)> sendRetryFun)29 CdmaSmsSender::CdmaSmsSender(const shared_ptr<AppExecFwk::EventRunner> &runner, int32_t slotId,
30     function<void(shared_ptr<SmsSendIndexer>)> sendRetryFun)
31     : SmsSender(runner, slotId, sendRetryFun)
32 {}
33 
~CdmaSmsSender()34 CdmaSmsSender::~CdmaSmsSender() {}
35 
TextBasedSmsDelivery(const string & desAddr,const string & scAddr,const string & text,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)36 void CdmaSmsSender::TextBasedSmsDelivery(const string &desAddr, const string &scAddr, const string &text,
37     const sptr<ISendShortMessageCallback> &sendCallback,
38     const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
39 {
40     if (isImsNetDomain_ && imsSmsCfg_) {
41         TextBasedSmsDeliveryViaIms(desAddr, scAddr, text, sendCallback, deliveryCallback);
42         return;
43     }
44     CdmaSmsMessage message;
45     SmsCodingScheme codingType;
46     std::vector<struct SplitInfo> splits;
47     message.SplitMessage(splits, text, CheckForce7BitEncodeType(), codingType, false);
48     if (splits.size() > MAX_SEGMENT_NUM) {
49         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
50         TELEPHONY_LOGE("message exceed the limit.");
51         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
52             SmsMmsErrorCode::SMS_ERROR_EXCEED_MAX_SEGMENT_NUM, "text sms cdma message exceed the limit");
53         return;
54     }
55     bool bStatusReport = (deliveryCallback == nullptr) ? false : true;
56     std::unique_ptr<SmsTransMsg> transMsg =
57         message.CreateSubmitTransMsg(desAddr, scAddr, text, bStatusReport, codingType);
58     if (transMsg == nullptr) {
59         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
60         TELEPHONY_LOGE("CreateSubmitTransMsg nullptr fail.");
61         return;
62     }
63     /* 1. Set Reply sequence number. */
64     uint8_t msgRef8bit = GetSeqNum();
65     transMsg->data.p2pMsg.transReplySeq = msgRef8bit;
66     /* 2. Set msg ID. */
67     uint16_t msgId = GetSubmitMsgId();
68     transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.msgId = msgId;
69     shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(splits.size());
70     shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
71     if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
72         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
73         return;
74     }
75     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
76     long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
77 
78     for (std::size_t i = 0; i < splits.size(); i++) {
79         (void)memset_s(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data,
80             sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data), 0x00,
81             sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data));
82         if (splits[i].encodeData.size() > sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data)) {
83             TELEPHONY_LOGE("data length invalid");
84             return;
85         }
86         if (memcpy_s(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data,
87             sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data),
88             splits[i].encodeData.data(), splits[i].encodeData.size()) != EOK) {
89             SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
90             return;
91         }
92         std::string segmentText;
93         segmentText.append((char *)(splits[i].encodeData.data()), splits[i].encodeData.size());
94         std::shared_ptr<SmsSendIndexer> indexer = nullptr;
95         indexer = make_shared<SmsSendIndexer>(desAddr, scAddr, segmentText, sendCallback, deliveryCallback);
96         if (indexer == nullptr) {
97             SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
98             return;
99         }
100         indexer->SetDcs(splits[i].encodeType);
101         SetPduSeqInfo(indexer, splits.size(), transMsg, i, msgRef8bit);
102         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.length =
103             static_cast<int>(splits[i].encodeData.size());
104         /* encode msg data */
105         uint8_t pduStr[TAPI_NETTEXT_SMDATA_SIZE_MAX + 1] = { 0 };
106         int len = CdmaSmsPduCodec::EncodeMsg(*transMsg.get(), pduStr, TAPI_NETTEXT_SMDATA_SIZE_MAX + 1);
107         std::vector<uint8_t> pdu(pduStr, pduStr + len);
108         indexer->SetEncodePdu(std::move(pdu));
109         indexer->SetMsgRefId(msgRef8bit);
110         indexer->SetNetWorkType(NET_TYPE_CDMA);
111         indexer->SetUnSentCellCount(unSentCellCount);
112         indexer->SetHasCellFailed(hasCellFailed);
113         indexer->SetTimeStamp(timeStamp);
114         indexer->SetMsgId(msgId);
115         SendSmsToRil(indexer);
116     }
117 }
118 
TextBasedSmsDeliveryViaIms(const string & desAddr,const string & scAddr,const string & text,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)119 void CdmaSmsSender::TextBasedSmsDeliveryViaIms(const string &desAddr, const string &scAddr, const string &text,
120     const sptr<ISendShortMessageCallback> &sendCallback, const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
121 {
122     SmsCodingScheme codingType;
123     GsmSmsMessage gsmSmsMessage;
124     std::vector<struct SplitInfo> cellsInfos;
125     gsmSmsMessage.SplitMessage(cellsInfos, text, CheckForce7BitEncodeType(), codingType, false);
126     bool isStatusReport = (deliveryCallback == nullptr) ? false : true;
127     std::shared_ptr<struct SmsTpdu> tpdu =
128         gsmSmsMessage.CreateDefaultSubmitSmsTpdu(desAddr, scAddr, text, isStatusReport, codingType);
129     int cellsInfosSize = static_cast<int>(cellsInfos.size());
130     shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(cellsInfosSize);
131     shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
132     if (TpduNullOrSmsPageOverNormalOrSmsEncodeFail(cellsInfos, tpdu, unSentCellCount, hasCellFailed, sendCallback)) {
133         return;
134     }
135 
136     std::unique_lock<std::mutex> lock(mutex_);
137     uint8_t msgRef8bit = GetMsgRef8Bit();
138     for (int i = 0; i < cellsInfosSize; i++) {
139         SendSmsForEveryIndexer(i, cellsInfos, desAddr, scAddr, tpdu, gsmSmsMessage, unSentCellCount, hasCellFailed,
140             codingType, msgRef8bit, sendCallback, deliveryCallback);
141     }
142     return;
143 }
144 
SendSmsForEveryIndexer(int & i,std::vector<struct SplitInfo> cellsInfos,const string & desAddr,const string & scAddr,std::shared_ptr<struct SmsTpdu> tpdu,GsmSmsMessage gsmSmsMessage,shared_ptr<uint8_t> unSentCellCount,shared_ptr<bool> hasCellFailed,SmsCodingScheme codingType,uint8_t msgRef8bit,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)145 void CdmaSmsSender::SendSmsForEveryIndexer(int &i, std::vector<struct SplitInfo> cellsInfos, const string &desAddr,
146     const string &scAddr, std::shared_ptr<struct SmsTpdu> tpdu, GsmSmsMessage gsmSmsMessage,
147     shared_ptr<uint8_t> unSentCellCount, shared_ptr<bool> hasCellFailed, SmsCodingScheme codingType, uint8_t msgRef8bit,
148     const sptr<ISendShortMessageCallback> &sendCallback, const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
149 {
150     std::string segmentText;
151     segmentText.append((char *)(cellsInfos[i].encodeData.data()), cellsInfos[i].encodeData.size());
152     std::shared_ptr<SmsSendIndexer> indexer =
153         make_shared<SmsSendIndexer>(desAddr, scAddr, segmentText, sendCallback, deliveryCallback);
154     if (indexer == nullptr) {
155         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
156         return;
157     }
158     indexer->SetDcs(cellsInfos[i].encodeType);
159     (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
160 
161     if (cellsInfos[i].encodeData.size() > MAX_USER_DATA_LEN + 1) {
162         return;
163     }
164     if (memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, &cellsInfos[i].encodeData[0],
165         cellsInfos[i].encodeData.size()) != EOK) {
166         SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
167         return;
168     }
169 
170     tpdu->data.submit.userData.length = cellsInfos[i].encodeData.size();
171     tpdu->data.submit.userData.data[cellsInfos[i].encodeData.size()] = 0;
172     tpdu->data.submit.msgRef = msgRef8bit;
173     int headerCnt = 0;
174     bool isMore = false;
175     bool isStatusReport = false;
176     isStatusReport = (deliveryCallback == nullptr) ? false : true;
177 
178     int cellsInfosSize = static_cast<int>(cellsInfos.size());
179     if (cellsInfosSize > 1) {
180         indexer->SetIsConcat(true);
181         SmsConcat concat;
182         concat.is8Bits = true;
183         concat.msgRef = msgRef8bit;
184         concat.totalSeg = static_cast<uint16_t>(cellsInfosSize);
185         concat.seqNum = static_cast<uint16_t>(i + 1);
186         indexer->SetSmsConcat(concat);
187         headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, concat);
188     }
189 
190     /* Set User Data Header for Alternate Reply Address */
191     headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
192     /* Set User Data Header for National Language Single Shift */
193     headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, codingType, cellsInfos[i].langId);
194     indexer->SetLangId(cellsInfos[i].langId);
195     tpdu->data.submit.userData.headerCnt = headerCnt;
196     tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
197 
198     if (cellsInfosSize > 1 && i < (cellsInfosSize - 1)) {
199         tpdu->data.submit.bStatusReport = false;
200         isMore = true;
201     } else {
202         tpdu->data.submit.bStatusReport = isStatusReport;
203     }
204     ReadySendSms(gsmSmsMessage, scAddr, isMore, indexer, msgRef8bit, unSentCellCount, hasCellFailed);
205 }
206 
ReadySendSms(GsmSmsMessage gsmSmsMessage,const string & scAddr,bool isMore,std::shared_ptr<SmsSendIndexer> indexer,uint8_t msgRef8bit,shared_ptr<uint8_t> unSentCellCount,shared_ptr<bool> hasCellFailed)207 void CdmaSmsSender::ReadySendSms(GsmSmsMessage gsmSmsMessage, const string &scAddr, bool isMore,
208     std::shared_ptr<SmsSendIndexer> indexer, uint8_t msgRef8bit, shared_ptr<uint8_t> unSentCellCount,
209     shared_ptr<bool> hasCellFailed)
210 {
211     std::shared_ptr<struct EncodeInfo> encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(scAddr, isMore);
212     if (encodeInfo == nullptr) {
213         SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
214         TELEPHONY_LOGE("create encodeInfo encodeInfo nullptr error.");
215         return;
216     }
217 
218     SetSendIndexerInfo(indexer, encodeInfo, msgRef8bit);
219     indexer->SetUnSentCellCount(unSentCellCount);
220     indexer->SetHasCellFailed(hasCellFailed);
221     indexer->SetImsSmsForCdma(true);
222     SendSmsToRil(indexer);
223 }
224 
TpduNullOrSmsPageOverNormalOrSmsEncodeFail(std::vector<struct SplitInfo> cellsInfos,std::shared_ptr<struct SmsTpdu> tpdu,shared_ptr<uint8_t> unSentCellCount,shared_ptr<bool> hasCellFailed,const sptr<ISendShortMessageCallback> & sendCallback)225 bool CdmaSmsSender::TpduNullOrSmsPageOverNormalOrSmsEncodeFail(std::vector<struct SplitInfo> cellsInfos,
226     std::shared_ptr<struct SmsTpdu> tpdu, shared_ptr<uint8_t> unSentCellCount, shared_ptr<bool> hasCellFailed,
227     const sptr<ISendShortMessageCallback> &sendCallback)
228 {
229     if (tpdu == nullptr) {
230         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
231         TELEPHONY_LOGE("TextBasedSmsDelivery tpdu nullptr error.");
232         return true;
233     }
234 
235     int cellsInfosSize = static_cast<int>(cellsInfos.size());
236     if (cellsInfosSize > MAX_SEGMENT_NUM) {
237         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
238         TELEPHONY_LOGE("message exceed the limit.");
239         return true;
240     }
241 
242     bool isStatusReport = tpdu->data.submit.bStatusReport;
243     TELEPHONY_LOGI("TextBasedSmsDelivery isStatusReport= %{public}d", isStatusReport);
244     if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
245         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
246         return true;
247     }
248     return false;
249 }
250 
SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> & indexer,const std::shared_ptr<struct EncodeInfo> & encodeInfo,uint8_t msgRef8bit)251 void CdmaSmsSender::SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> &indexer,
252     const std::shared_ptr<struct EncodeInfo> &encodeInfo, uint8_t msgRef8bit)
253 {
254     if (encodeInfo == nullptr || indexer == nullptr) {
255         TELEPHONY_LOGE("CdmaSmsSender::SetSendIndexerInfo encodeInfo nullptr");
256         return;
257     }
258 
259     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
260     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
261     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
262     long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
263     indexer->SetTimeStamp(timeStamp);
264     indexer->SetEncodeSmca(std::move(smca));
265     indexer->SetEncodePdu(std::move(pdu));
266     indexer->SetHasMore(encodeInfo->isMore_);
267     indexer->SetMsgRefId(msgRef8bit);
268     indexer->SetNetWorkType(NET_TYPE_CDMA);
269 }
270 
SetPduSeqInfo(const std::shared_ptr<SmsSendIndexer> & smsIndexer,const std::size_t size,const std::unique_ptr<SmsTransMsg> & transMsg,const std::size_t index,const uint8_t msgRef8bit)271 void CdmaSmsSender::SetPduSeqInfo(const std::shared_ptr<SmsSendIndexer> &smsIndexer, const std::size_t size,
272     const std::unique_ptr<SmsTransMsg> &transMsg, const std::size_t index, const uint8_t msgRef8bit)
273 {
274     if (size > 1) {
275         smsIndexer->SetIsConcat(true);
276         SmsConcat smsConcat;
277         transMsg->data.p2pMsg.transTelesvcId = SMS_TRANS_TELESVC_WEMT;
278         transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.headerInd = true;
279         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.headerCnt = 1;
280         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udhType = SMS_UDH_CONCAT_8BIT;
281         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.msgRef = msgRef8bit;
282         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.totalSeg =
283             static_cast<uint8_t>(size);
284         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.seqNum = index + 1;
285         smsConcat.msgRef = msgRef8bit;
286         smsConcat.seqNum = index + 1;
287         smsConcat.totalSeg = static_cast<uint8_t>(size);
288         smsConcat.is8Bits = true;
289         smsIndexer->SetSmsConcat(smsConcat);
290     }
291 }
292 
DataBasedSmsDelivery(const string & desAddr,const string & scAddr,int32_t port,const uint8_t * data,uint32_t dataLen,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)293 void CdmaSmsSender::DataBasedSmsDelivery(const string &desAddr, const string &scAddr, int32_t port,
294     const uint8_t *data, uint32_t dataLen, const sptr<ISendShortMessageCallback> &sendCallback,
295     const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
296 {
297     if (isImsNetDomain_ && imsSmsCfg_) {
298         DataBasedSmsDeliveryViaIms(desAddr, scAddr, port, data, dataLen, sendCallback, deliveryCallback);
299         return;
300     }
301     CdmaSmsMessage message;
302     SmsCodingScheme codingType;
303     std::vector<struct SplitInfo> splits;
304     std::string text((char *)data, dataLen);
305     message.SplitMessage(splits, text, false, codingType, true);
306     if (splits.size() == 0) {
307         TELEPHONY_LOGE("splits fail.");
308         return;
309     }
310     std::unique_ptr<SmsTransMsg> transMsg = nullptr;
311     bool bStatusReport = (deliveryCallback == nullptr) ? false : true;
312     transMsg = message.CreateSubmitTransMsg(desAddr, scAddr, port, data, dataLen, bStatusReport);
313     if (transMsg == nullptr) {
314         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
315         TELEPHONY_LOGE("CreateSubmitTransMsg nullptr fail.");
316         return;
317     }
318     /* Set Reply sequence number. */
319     uint8_t msgRef8bit = GetSeqNum();
320     transMsg->data.p2pMsg.transReplySeq = msgRef8bit;
321     /* Set msg ID. */
322     uint16_t msgId = GetSubmitMsgId();
323     transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.msgId = msgId;
324     /* while user data header isn't exist, headerInd must be set false. */
325     transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.headerInd = true;
326 
327     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
328     long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
329     transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.length =
330         static_cast<int>(splits[0].encodeData.size());
331     if (splits[0].encodeData.size() > sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data)) {
332         TELEPHONY_LOGE("DataBasedSmsDelivery data length invalid.");
333         return;
334     }
335     if (memcpy_s(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data,
336         sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data),
337         splits[0].encodeData.data(), splits[0].encodeData.size()) != EOK) {
338         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
339         TELEPHONY_LOGE("memcpy_s return error.");
340         return;
341     }
342     /* encode msg data */
343     uint8_t pduStr[TAPI_NETTEXT_SMDATA_SIZE_MAX + 1] = { 0 };
344     int len = CdmaSmsPduCodec::EncodeMsg(*transMsg.get(), pduStr, TAPI_NETTEXT_SMDATA_SIZE_MAX + 1);
345     if (len <= 0) {
346         TELEPHONY_LOGE("EncodeMsg Error len = %{public}d", len);
347         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
348         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
349             SmsMmsErrorCode::SMS_ERROR_PDU_ENCODEING_FAIL, "cdma encode msg data len error");
350         return;
351     }
352 
353     const uint8_t segmentCount = 1;
354     std::shared_ptr<SmsSendIndexer> indexer = nullptr;
355     shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(segmentCount);
356     shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
357     indexer = make_shared<SmsSendIndexer>(desAddr, scAddr, port, splits[0].encodeData.data(),
358         splits[0].encodeData.size(), sendCallback, deliveryCallback);
359     if (indexer == nullptr || unSentCellCount == nullptr || hasCellFailed == nullptr) {
360         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
361         TELEPHONY_LOGE("Init SmsSend Indexer Error.");
362         return;
363     }
364     std::vector<uint8_t> pdu(pduStr, pduStr + len);
365     indexer->SetEncodePdu(std::move(pdu));
366     indexer->SetMsgRefId(msgRef8bit);
367     indexer->SetNetWorkType(NET_TYPE_CDMA);
368     indexer->SetUnSentCellCount(unSentCellCount);
369     indexer->SetHasCellFailed(hasCellFailed);
370     indexer->SetTimeStamp(timeStamp);
371     indexer->SetMsgId(msgId);
372     SendSmsToRil(indexer);
373 }
374 
DataBasedSmsDeliveryViaIms(const string & desAddr,const string & scAddr,int32_t port,const uint8_t * data,uint32_t dataLen,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)375 void CdmaSmsSender::DataBasedSmsDeliveryViaIms(const string &desAddr, const string &scAddr, int32_t port,
376     const uint8_t *data, uint32_t dataLen, const sptr<ISendShortMessageCallback> &sendCallback,
377     const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
378 {
379     uint8_t msgRef8bit = GetMsgRef8Bit();
380     GsmSmsMessage gsmSmsMessage;
381     std::shared_ptr<struct SmsTpdu> tpdu = gsmSmsMessage.CreateDataSubmitSmsTpdu(
382         desAddr, scAddr, port, data, dataLen, msgRef8bit, (deliveryCallback == nullptr) ? false : true);
383     std::shared_ptr<struct EncodeInfo> encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(scAddr, false);
384     if (encodeInfo == nullptr || tpdu == nullptr) {
385         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
386         TELEPHONY_LOGE("DataBasedSmsDelivery encodeInfo or tpdu nullptr error.");
387         return;
388     }
389     shared_ptr<SmsSendIndexer> indexer = nullptr;
390     indexer = make_shared<SmsSendIndexer>(desAddr, scAddr, port, data, dataLen, sendCallback, deliveryCallback);
391     if (indexer == nullptr) {
392         SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
393         TELEPHONY_LOGE("DataBasedSmsDelivery create SmsSendIndexer nullptr");
394         return;
395     }
396 
397     std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
398     std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
399     std::shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(1);
400     std::shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
401     if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
402         SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
403         return;
404     }
405     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
406     long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
407     indexer->SetUnSentCellCount(unSentCellCount);
408     indexer->SetHasCellFailed(hasCellFailed);
409     indexer->SetEncodeSmca(std::move(smca));
410     indexer->SetEncodePdu(std::move(pdu));
411     indexer->SetHasMore(encodeInfo->isMore_);
412     indexer->SetMsgRefId(msgRef8bit);
413     indexer->SetNetWorkType(NET_TYPE_GSM);
414     indexer->SetTimeStamp(timeStamp);
415     std::unique_lock<std::mutex> lock(mutex_);
416     indexer->SetImsSmsForCdma(true);
417     SendSmsToRil(indexer);
418 }
419 
StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer & event)420 void CdmaSmsSender::StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer &event)
421 {
422     if (event == nullptr) {
423         TELEPHONY_LOGE("cdma_sms_sender: StatusReportAnalysis event nullptr error.");
424         return;
425     }
426     std::shared_ptr<SmsReceiveIndexer> statusInfo = event->GetSharedObject<SmsReceiveIndexer>();
427     if (statusInfo == nullptr) {
428         TELEPHONY_LOGE("cdma_sms_sender: StatusReportAnalysis statusInfo nullptr error.");
429         return;
430     }
431     std::string pdu = StringUtils::StringToHex(statusInfo->GetPdu());
432     std::shared_ptr<CdmaSmsMessage> message = CdmaSmsMessage::CreateMessage(pdu);
433     if (message == nullptr) {
434         TELEPHONY_LOGE("message is nullptr.");
435         return;
436     }
437     sptr<IDeliveryShortMessageCallback> deliveryCallback = nullptr;
438     auto oldIndexer = reportList_.begin();
439     while (oldIndexer != reportList_.end()) {
440         auto iter = oldIndexer++;
441         if (*iter != nullptr) {
442             if (message->GetMsgRef() == (*iter)->GetMsgRefId()) {
443                 // save the message to db, or updata to db msg state(success or fail)
444                 deliveryCallback = (*iter)->GetDeliveryCallback();
445                 reportList_.erase(iter);
446             }
447         }
448     }
449     if (deliveryCallback != nullptr) {
450         std::string ackpdu = StringUtils::StringToHex(message->GetRawPdu());
451         deliveryCallback->OnSmsDeliveryResult(StringUtils::ToUtf16(ackpdu));
452         TELEPHONY_LOGI("gsm_sms_sender: StatusReportAnalysis %{private}s", pdu.c_str());
453     }
454 }
455 
SendSmsToRil(const shared_ptr<SmsSendIndexer> & smsIndexer)456 void CdmaSmsSender::SendSmsToRil(const shared_ptr<SmsSendIndexer> &smsIndexer)
457 {
458     if (smsIndexer == nullptr) {
459         TELEPHONY_LOGE("cdma_sms_sender: SendSms smsIndexer nullptr");
460         return;
461     }
462     if ((!isImsNetDomain_ && voiceServiceState_ != static_cast<int32_t>(RegServiceState::REG_STATE_IN_SERVICE))) {
463         SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
464         TELEPHONY_LOGE("cdma_sms_sender: SendSms not in service");
465         SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
466             SmsMmsErrorCode::SMS_ERROR_SENDSMS_NOT_IN_SERVICE, "cdma send sms not in service");
467         return;
468     }
469     int64_t refId = GetMsgRef64Bit();
470     if (!SendCacheMapAddItem(refId, smsIndexer)) {
471         TELEPHONY_LOGE("SendCacheMapAddItem Error!!");
472     }
473 
474     std::string pdu = StringUtils::StringToHex(smsIndexer->GetEncodePdu());
475     bool sendImsSMS = smsIndexer->IsImsSmsForCdma();
476     if (lastSmsDomain_ == IMS_DOMAIN && smsIndexer->GetPsResendCount() < MAX_SEND_RETRIES) {
477         sendImsSMS = true;
478     }
479 
480     if (sendImsSMS) {
481         SendImsSms(smsIndexer, refId, pdu);
482     } else {
483         SendCsSms(smsIndexer, refId, pdu);
484     }
485 }
486 
SendCsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,int64_t & refId,std::string & pdu)487 void CdmaSmsSender::SendCsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, int64_t &refId, std::string &pdu)
488 {
489     lastSmsDomain_ = CS_DOMAIN;
490     CoreManagerInner::GetInstance().SendCdmaSms(
491         slotId_, RadioEvent::RADIO_SEND_CDMA_SMS, pdu, refId, shared_from_this());
492     TELEPHONY_LOGI("SendCsSms pdu = %{private}s", pdu.c_str());
493 }
494 
SendImsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,int64_t & refId,std::string & pdu)495 void CdmaSmsSender::SendImsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, int64_t &refId, std::string &pdu)
496 {
497     TELEPHONY_LOGI("ims network domain send sms interface.!");
498     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
499     if (smsClient == nullptr) {
500         TELEPHONY_LOGE("SendImsSms return, ImsSmsClient is nullptr.");
501         return;
502     }
503     lastSmsDomain_ = IMS_DOMAIN;
504     ImsMessageInfo imsMessageInfo;
505     imsMessageInfo.refId = refId;
506     imsMessageInfo.smscPdu = "";
507     imsMessageInfo.pdu = pdu;
508     imsMessageInfo.tech = SMS_RADIO_TECH_3GPP;
509     int32_t reply = smsClient->ImsSendMessage(slotId_, imsMessageInfo);
510     TELEPHONY_LOGI("SendImsSms reply = %{public}d", reply);
511 }
512 
IsImsSmsSupported(int32_t slotId,bool & isSupported)513 int32_t CdmaSmsSender::IsImsSmsSupported(int32_t slotId, bool &isSupported)
514 {
515     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
516     if (smsClient == nullptr) {
517         TELEPHONY_LOGE("IsImsSmsSupported return, ImsSmsClient is nullptr.");
518         return TELEPHONY_ERR_LOCAL_PTR_NULL;
519     }
520     std::unique_lock<std::mutex> lck(ctx_);
521     resIsSmsReady_ = false;
522     int32_t reply = smsClient->ImsGetSmsConfig(slotId);
523     TELEPHONY_LOGI("IsImsSmsSupported reply = %{public}d", reply);
524     while (resIsSmsReady_) {
525         TELEPHONY_LOGI("IsImsSmsSupported::wait(), resIsSmsReady_ = false");
526         if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
527             break;
528         }
529     }
530     TELEPHONY_LOGI("CdmaSmsSender::IsImsSmsSupported(), imsSmsCfg_:%{public}d", imsSmsCfg_);
531     isSupported = (imsSmsCfg_ == IMS_SMS_ENABLE);
532     return TELEPHONY_ERR_SUCCESS;
533 }
534 
StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer & event)535 void CdmaSmsSender::StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
536 {
537     if (event == nullptr) {
538         TELEPHONY_LOGE("cdma_sms_sender: StatusReportSetImsSms event nullptr error.");
539         return;
540     }
541     std::shared_ptr<HRilRadioResponseInfo> imsResponseInfo = event->GetSharedObject<HRilRadioResponseInfo>();
542 
543     if (imsResponseInfo->error != HRilErrType::NONE) {
544         imsSmsCfg_ = IMS_SMS_DISABLE;
545     }
546 }
547 
StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer & event)548 void CdmaSmsSender::StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
549 {
550     if (event == nullptr) {
551         TELEPHONY_LOGE("CdmaSmsSender: StatusReportGetImsSms event nullptr error.");
552         return;
553     }
554     std::shared_ptr<int32_t> imsSmsInfo = event->GetSharedObject<int32_t>();
555     if (imsSmsInfo == nullptr) {
556         TELEPHONY_LOGE("CdmaSmsSender: StatusReportGetImsSms imsSmsInfo nullptr error.");
557         return;
558     }
559     imsSmsCfg_ = *imsSmsInfo;
560 }
561 
Init()562 void CdmaSmsSender::Init() {}
563 
ReceiveStatusReport(const std::shared_ptr<SmsReceiveIndexer> & smsIndexer)564 void CdmaSmsSender::ReceiveStatusReport(const std::shared_ptr<SmsReceiveIndexer> &smsIndexer)
565 {
566     SendEvent(RadioEvent::RADIO_SMS_STATUS, smsIndexer);
567 }
568 
RegisterImsHandler()569 void CdmaSmsSender::RegisterImsHandler()
570 {
571     if (isImsCdmaHandlerRegistered) {
572         return;
573     }
574     auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
575     if (smsClient == nullptr) {
576         TELEPHONY_LOGE("RegisterHandler return, ImsSmsClient is nullptr.");
577         return;
578     }
579     smsClient->RegisterImsSmsCallbackHandler(slotId_, shared_from_this());
580     TELEPHONY_LOGE("RegisterHandler  gsm ImsSmsClient successs");
581     isImsCdmaHandlerRegistered = true;
582 }
583 
GetSeqNum()584 uint8_t CdmaSmsSender::GetSeqNum()
585 {
586     msgSeqNum_ = ((msgSeqNum_ + 1) % SMS_SEQ_NUM_MAX);
587     return msgSeqNum_;
588 }
589 
GetSubmitMsgId()590 uint8_t CdmaSmsSender::GetSubmitMsgId()
591 {
592     msgSubmitId_ = ((msgSubmitId_ + 1) % SMS_MAX_MESSAGE_ID);
593     return msgSubmitId_;
594 }
595 
ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)596 void CdmaSmsSender::ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
597 {
598     if (smsIndexer == nullptr) {
599         TELEPHONY_LOGE("smsIndexer is nullptr!!");
600         return;
601     }
602     CdmaSmsMessage message;
603     SmsCodingScheme codingType = smsIndexer->GetDcs();
604     std::unique_ptr<SmsTransMsg> transMsg = nullptr;
605     bool bStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
606     transMsg = message.CreateSubmitTransMsg(
607         smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(), smsIndexer->GetText(), bStatusReport, codingType);
608     if (transMsg == nullptr) {
609         SendResultCallBack(smsIndexer->GetSendCallback(), ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
610         TELEPHONY_LOGE("CreateSubmitTransMsg nullptr fail.");
611         return;
612     }
613     /* 1. Set Reply sequence number. */
614     uint8_t msgRef8bit = smsIndexer->GetMsgRefId();
615     transMsg->data.p2pMsg.transReplySeq = msgRef8bit;
616     /* 2. Set msg ID. */
617     transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.msgId = smsIndexer->GetMsgId();
618     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
619     long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
620     smsIndexer->SetTimeStamp(timeStamp);
621     transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.encodeType = SMS_ENCODE_OCTET;
622     (void)memset_s(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data,
623         sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data), 0x00,
624         sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data));
625     if (smsIndexer->GetText().length() > sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data)) {
626         TELEPHONY_LOGE("ResendTextDelivery data length invalid.");
627         return;
628     }
629     if (memcpy_s(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data,
630         sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data),
631         smsIndexer->GetText().data(), smsIndexer->GetText().length()) != EOK) {
632         SendResultCallBack(smsIndexer->GetSendCallback(), ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
633         return;
634     }
635     SetConcact(smsIndexer, transMsg);
636     /* encode msg data */
637     uint8_t pduStr[TAPI_NETTEXT_SMDATA_SIZE_MAX + 1] = { 0 };
638     int len = CdmaSmsPduCodec::EncodeMsg(*transMsg.get(), pduStr, TAPI_NETTEXT_SMDATA_SIZE_MAX + 1);
639     std::vector<uint8_t> pdu(pduStr, pduStr + len);
640     smsIndexer->SetEncodePdu(std::move(pdu));
641     smsIndexer->SetNetWorkType(NET_TYPE_CDMA);
642     smsIndexer->SetTimeStamp(timeStamp);
643     SendSmsToRil(smsIndexer);
644 }
645 
ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)646 void CdmaSmsSender::ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
647 {
648     if (smsIndexer == nullptr) {
649         TELEPHONY_LOGI("ResendDataDelivery::smsIndexer is nullptr error.");
650         return;
651     }
652 
653     CdmaSmsMessage message;
654     std::unique_ptr<SmsTransMsg> transMsg = nullptr;
655     bool bStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
656     transMsg = message.CreateSubmitTransMsg(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
657         smsIndexer->GetDestPort(), smsIndexer->GetData().data(), smsIndexer->GetData().size(), bStatusReport);
658     if (transMsg == nullptr) {
659         SendResultCallBack(smsIndexer->GetSendCallback(), ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
660         TELEPHONY_LOGE("CreateSubmitTransMsg nullptr fail.");
661         return;
662     }
663     /* Set Reply sequence number. */
664     uint8_t msgRef8bit = smsIndexer->GetMsgRefId();
665     transMsg->data.p2pMsg.transReplySeq = msgRef8bit;
666     /* Set msg ID. */
667     transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.msgId = smsIndexer->GetMsgId();
668     /* while user data header isn't exist, headerInd must be set false. */
669     transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.headerInd = true;
670 
671     chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
672     long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
673     transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.encodeType = SMS_ENCODE_OCTET;
674     if (smsIndexer->GetData().size() > sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data)) {
675         TELEPHONY_LOGE("ResendDataDelivery data length invalid.");
676         return;
677     }
678     if (memcpy_s(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data,
679         sizeof(transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.data),
680         smsIndexer->GetData().data(), smsIndexer->GetData().size()) != EOK) {
681         SendResultCallBack(smsIndexer->GetSendCallback(), ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
682         return;
683     }
684 
685     transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.length =
686         static_cast<int>(smsIndexer->GetData().size());
687     /* encode msg data */
688     uint8_t pduStr[TAPI_NETTEXT_SMDATA_SIZE_MAX + 1] = { 0 };
689     int len = CdmaSmsPduCodec::EncodeMsg(*transMsg.get(), pduStr, TAPI_NETTEXT_SMDATA_SIZE_MAX + 1);
690     std::vector<uint8_t> pdu(pduStr, pduStr + len);
691     smsIndexer->SetEncodePdu(std::move(pdu));
692     smsIndexer->SetNetWorkType(NET_TYPE_CDMA);
693     smsIndexer->SetTimeStamp(timeStamp);
694     SendSmsToRil(smsIndexer);
695 }
696 
SetConcact(const std::shared_ptr<SmsSendIndexer> & smsIndexer,const std::unique_ptr<SmsTransMsg> & transMsg)697 void CdmaSmsSender::SetConcact(
698     const std::shared_ptr<SmsSendIndexer> &smsIndexer, const std::unique_ptr<SmsTransMsg> &transMsg)
699 {
700     if (smsIndexer->GetIsConcat()) {
701         SmsConcat smsConcat = smsIndexer->GetSmsConcat();
702         transMsg->data.p2pMsg.transTelesvcId = SMS_TRANS_TELESVC_WEMT;
703         transMsg->data.p2pMsg.telesvcMsg.data.submit.msgId.headerInd = true;
704         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.headerCnt = 1;
705         if (smsConcat.is8Bits) {
706             transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udhType = SMS_UDH_CONCAT_8BIT;
707         } else {
708             transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udhType = SMS_UDH_CONCAT_16BIT;
709         }
710         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.msgRef =
711             smsConcat.msgRef;
712         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.totalSeg =
713             smsConcat.totalSeg;
714         transMsg->data.p2pMsg.telesvcMsg.data.submit.userData.userData.header[0].udh.concat8bit.seqNum =
715             smsConcat.seqNum;
716     }
717 }
718 } // namespace Telephony
719 } // namespace OHOS