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