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