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