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