1 /*
2 * Copyright (C) 2021-2022 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 "gsm_sms_sender.h"
17
18 #include "core_manager_inner.h"
19 #include "msg_text_convert.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;
GsmSmsSender(const std::shared_ptr<AppExecFwk::EventRunner> & runner,int32_t slotId,function<void (std::shared_ptr<SmsSendIndexer>)> sendRetryFun)29 GsmSmsSender::GsmSmsSender(const std::shared_ptr<AppExecFwk::EventRunner> &runner, int32_t slotId,
30 function<void(std::shared_ptr<SmsSendIndexer>)> sendRetryFun)
31 : SmsSender(runner, slotId, sendRetryFun)
32 {}
33
~GsmSmsSender()34 GsmSmsSender::~GsmSmsSender() {}
35
Init()36 void GsmSmsSender::Init()
37 {
38 if (!RegisterHandler()) {
39 TELEPHONY_LOGI("GsmSmsSender::Init Register RADIO_SMS_STATUS fail.");
40 }
41 }
42
TextBasedSmsDelivery(const string & desAddr,const string & scAddr,const string & text,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)43 void GsmSmsSender::TextBasedSmsDelivery(const string &desAddr, const string &scAddr, const string &text,
44 const sptr<ISendShortMessageCallback> &sendCallback,
45 const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
46 {
47 bool isMore = false;
48 int ret = 0;
49 int headerCnt;
50 unsigned char msgRef8bit;
51 SmsCodingScheme codingType;
52 GsmSmsMessage gsmSmsMessage;
53 std::vector<struct SplitInfo> cellsInfos;
54 gsmSmsMessage.SplitMessage(cellsInfos, text, CheckForce7BitEncodeType(), codingType, false);
55 bool isStatusReport = (deliveryCallback == nullptr) ? false : true;
56 std::shared_ptr<struct SmsTpdu> tpdu =
57 gsmSmsMessage.CreateDefaultSubmitSmsTpdu(desAddr, scAddr, text, isStatusReport, codingType);
58 if (tpdu == nullptr) {
59 SendCallbackBecauseTpduNull(sendCallback, "TextBasedSmsDelivery");
60 return;
61 }
62 int cellsInfosSize = static_cast<int>(cellsInfos.size());
63 if (cellsInfosSize > MAX_SEGMENT_NUM) {
64 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
65 TELEPHONY_LOGE("message exceed the limit.");
66 SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
67 SmsMmsErrorCode::SMS_ERROR_EXCEED_MAX_SEGMENT_NUM, "text sms gsm message cellsInfosSize exceed the limit");
68 return;
69 }
70 msgRef8bit = GetMsgRef8Bit();
71 isStatusReport = tpdu->data.submit.bStatusReport;
72
73 TELEPHONY_LOGI("TextBasedSmsDelivery isStatusReport= %{public}d", isStatusReport);
74 shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(cellsInfosSize);
75 shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
76 if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
77 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
78 return;
79 }
80 std::unique_lock<std::mutex> lock(mutex_);
81 for (int i = 0; i < cellsInfosSize; i++) {
82 std::shared_ptr<SmsSendIndexer> indexer = nullptr;
83 std::string segmentText;
84 segmentText.append((char *)(cellsInfos[i].encodeData.data()), cellsInfos[i].encodeData.size());
85 indexer = make_shared<SmsSendIndexer>(desAddr, scAddr, segmentText, sendCallback, deliveryCallback);
86 if (indexer == nullptr) {
87 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
88 return;
89 }
90 indexer->SetDcs(cellsInfos[i].encodeType);
91 headerCnt = 0;
92 (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
93 if (cellsInfos[i].encodeData.size() > MAX_USER_DATA_LEN + 1) {
94 TELEPHONY_LOGE("TextBasedSmsDelivery data length invalid.");
95 return;
96 }
97 ret = memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, &cellsInfos[i].encodeData[0],
98 cellsInfos[i].encodeData.size());
99 if (ret != EOK) {
100 SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
101 return;
102 }
103 tpdu->data.submit.userData.length = cellsInfos[i].encodeData.size();
104 tpdu->data.submit.userData.data[cellsInfos[i].encodeData.size()] = 0;
105 tpdu->data.submit.msgRef = msgRef8bit;
106 if (cellsInfosSize > 1) {
107 indexer->SetIsConcat(true);
108 SmsConcat concat;
109 concat.is8Bits = true;
110 concat.msgRef = msgRef8bit;
111 concat.totalSeg = static_cast<uint16_t>(cellsInfosSize);
112 concat.seqNum = static_cast<uint16_t>(i + 1);
113 indexer->SetSmsConcat(concat);
114 headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, concat);
115 }
116 /* Set User Data Header for Alternate Reply Address */
117 headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
118 /* Set User Data Header for National Language Single Shift */
119 headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, codingType, cellsInfos[i].langId);
120 indexer->SetLangId(cellsInfos[i].langId);
121 tpdu->data.submit.userData.headerCnt = headerCnt;
122 tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
123
124 if (cellsInfosSize > 1 && i < (cellsInfosSize - 1)) {
125 tpdu->data.submit.bStatusReport = false;
126 isMore = true;
127 } else {
128 tpdu->data.submit.bStatusReport = isStatusReport;
129 isMore = false;
130 }
131 std::shared_ptr<struct EncodeInfo> encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(scAddr, isMore);
132 if (encodeInfo == nullptr) {
133 SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
134 TELEPHONY_LOGE("create encodeInfo encodeInfo nullptr error.");
135 continue;
136 }
137 SetSendIndexerInfo(indexer, encodeInfo, msgRef8bit);
138 indexer->SetUnSentCellCount(unSentCellCount);
139 indexer->SetHasCellFailed(hasCellFailed);
140 SendSmsToRil(indexer);
141 }
142 }
143
DataBasedSmsDelivery(const std::string & desAddr,const std::string & scAddr,int32_t port,const uint8_t * data,uint32_t dataLen,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)144 void GsmSmsSender::DataBasedSmsDelivery(const std::string &desAddr, const std::string &scAddr, int32_t port,
145 const uint8_t *data, uint32_t dataLen, const sptr<ISendShortMessageCallback> &sendCallback,
146 const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
147 {
148 GsmSmsMessage gsmSmsMessage;
149 std::vector<struct SplitInfo> cellsInfos;
150 SmsCodingScheme codingType;
151 std::string dataStr;
152 CharArrayToString(data, dataLen, dataStr);
153
154 gsmSmsMessage.SplitMessage(cellsInfos, dataStr, CheckForce7BitEncodeType(), codingType, true);
155 uint8_t msgRef8bit = GetMsgRef8Bit();
156 std::shared_ptr<struct SmsTpdu> tpdu = gsmSmsMessage.CreateDataSubmitSmsTpdu(
157 desAddr, scAddr, port, data, dataLen, msgRef8bit, (deliveryCallback == nullptr) ? false : true);
158 if (tpdu == nullptr) {
159 SendCallbackBecauseTpduNull(sendCallback, "DataBasedSmsDelivery");
160 return;
161 }
162
163 DataBasedSmsDeliverySplitPage(
164 gsmSmsMessage, cellsInfos, tpdu, msgRef8bit, desAddr, scAddr, port, sendCallback, deliveryCallback);
165 }
166
DataBasedSmsDeliverySplitPage(GsmSmsMessage & gsmSmsMessage,std::vector<struct SplitInfo> cellsInfos,std::shared_ptr<struct SmsTpdu> tpdu,uint8_t msgRef8bit,const std::string & desAddr,const std::string & scAddr,int32_t port,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback)167 void GsmSmsSender::DataBasedSmsDeliverySplitPage(GsmSmsMessage &gsmSmsMessage, std::vector<struct SplitInfo> cellsInfos,
168 std::shared_ptr<struct SmsTpdu> tpdu, uint8_t msgRef8bit, const std::string &desAddr, const std::string &scAddr,
169 int32_t port, const sptr<ISendShortMessageCallback> &sendCallback,
170 const sptr<IDeliveryShortMessageCallback> &deliveryCallback)
171 {
172 uint32_t cellsInfosSize = static_cast<uint32_t>(cellsInfos.size());
173 for (uint32_t indexData = 0; indexData < cellsInfosSize; indexData++) {
174 const uint8_t *dataItem = reinterpret_cast<uint8_t *>(cellsInfos[indexData].text.data());
175 uint32_t dataItemLen = static_cast<uint32_t>(cellsInfos[indexData].text.size());
176
177 std::shared_ptr<SmsSendIndexer> indexer =
178 make_shared<SmsSendIndexer>(desAddr, scAddr, port, dataItem, dataItemLen, sendCallback, deliveryCallback);
179 if (indexer == nullptr) {
180 SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
181 TELEPHONY_LOGE("DataBasedSmsDeliverySplitPage create SmsSendIndexer nullptr");
182 return;
183 }
184
185 (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
186 if (cellsInfos[indexData].encodeData.size() > MAX_USER_DATA_LEN + 1) {
187 TELEPHONY_LOGE("DataBasedSmsDeliverySplitPage data length invalid.");
188 return;
189 }
190 int ret = memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, &cellsInfos[indexData].encodeData[0],
191 cellsInfos[indexData].encodeData.size());
192 if (ret != EOK) {
193 SendResultCallBack(indexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
194 TELEPHONY_LOGE("DataBasedSmsDeliverySplitPage ret:%{public}d", ret);
195 return;
196 }
197 DataBasedSmsDeliveryPacketSplitPage(gsmSmsMessage, tpdu, msgRef8bit, indexData, port, scAddr, sendCallback,
198 deliveryCallback, indexer, cellsInfos);
199 }
200 }
201
DataBasedSmsDeliveryPacketSplitPage(GsmSmsMessage & gsmSmsMessage,std::shared_ptr<struct SmsTpdu> tpdu,uint8_t msgRef8bit,uint32_t indexData,int32_t port,const std::string & scAddr,const sptr<ISendShortMessageCallback> & sendCallback,const sptr<IDeliveryShortMessageCallback> & deliveryCallback,std::shared_ptr<SmsSendIndexer> indexer,std::vector<struct SplitInfo> cellsInfos)202 void GsmSmsSender::DataBasedSmsDeliveryPacketSplitPage(GsmSmsMessage &gsmSmsMessage,
203 std::shared_ptr<struct SmsTpdu> tpdu, uint8_t msgRef8bit, uint32_t indexData, int32_t port,
204 const std::string &scAddr, const sptr<ISendShortMessageCallback> &sendCallback,
205 const sptr<IDeliveryShortMessageCallback> &deliveryCallback, std::shared_ptr<SmsSendIndexer> indexer,
206 std::vector<struct SplitInfo> cellsInfos)
207 {
208 tpdu->data.submit.userData.length = static_cast<int>(cellsInfos[indexData].encodeData.size());
209 tpdu->data.submit.userData.data[cellsInfos[indexData].encodeData.size()] = 0;
210 tpdu->data.submit.msgRef = msgRef8bit;
211
212 int headerCnt = 0;
213 uint32_t cellsInfosSize = static_cast<uint32_t>(cellsInfos.size());
214 if (cellsInfosSize > 1) {
215 indexer->SetIsConcat(true);
216 SmsConcat concat;
217 concat.is8Bits = true;
218 concat.msgRef = msgRef8bit;
219 concat.totalSeg = static_cast<uint16_t>(cellsInfosSize);
220 concat.seqNum = static_cast<uint16_t>(indexData + 1);
221 indexer->SetSmsConcat(concat);
222 headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, concat);
223 }
224
225 if (headerCnt >= MAX_UD_HEADER_NUM) {
226 TELEPHONY_LOGE("PDU header Array out of bounds");
227 return;
228 }
229
230 tpdu->data.submit.userData.header[headerCnt].udhType = SMS_UDH_APP_PORT_16BIT;
231 tpdu->data.submit.userData.header[headerCnt].udh.appPort16bit.destPort = ((unsigned short)port & 0xFFFF);
232 tpdu->data.submit.userData.header[headerCnt].udh.appPort16bit.originPort = 0;
233 headerCnt++;
234
235 tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
236 /* Set User Data Header for Alternate Reply Address */
237 headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
238 /* Set User Data Header for National Language Single Shift */
239 SmsCodingScheme pCodingType = SMS_CODING_7BIT;
240 MSG_LANGUAGE_ID_T langId = MSG_ID_RESERVED_LANG;
241 headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, pCodingType, langId);
242 tpdu->data.submit.userData.headerCnt = headerCnt;
243
244 std::shared_ptr<struct EncodeInfo> encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(scAddr, false);
245 if (encodeInfo == nullptr) {
246 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
247 TELEPHONY_LOGE("DataBasedSmsDeliveryPacketSplitPage encodeInfo nullptr error.");
248 SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
249 SmsMmsErrorCode::SMS_ERROR_PDU_ENCODEING_FAIL, "data sms gsm encodeInfo nullptr error");
250 return;
251 }
252
253 if (cellsInfosSize > 1 && indexData < (cellsInfosSize - 1)) {
254 tpdu->data.submit.bStatusReport = false;
255 } else {
256 tpdu->data.submit.bStatusReport = (deliveryCallback == nullptr) ? false : true;
257 }
258 encodeInfo->isMore_ = (cellsInfosSize > 1) ? true : false;
259 DataBasedSmsDeliverySendSplitPage(encodeInfo, sendCallback, indexer, msgRef8bit, cellsInfosSize);
260 }
261
CharArrayToString(const uint8_t * data,uint32_t dataLen,std::string & dataStr)262 void GsmSmsSender::CharArrayToString(const uint8_t *data, uint32_t dataLen, std::string &dataStr)
263 {
264 uint32_t indexData = 0;
265 while (indexData < dataLen) {
266 dataStr += data[indexData];
267 indexData++;
268 }
269 }
270
SendCallbackBecauseTpduNull(const sptr<ISendShortMessageCallback> & sendCallback,std::string str)271 void GsmSmsSender::SendCallbackBecauseTpduNull(const sptr<ISendShortMessageCallback> &sendCallback, std::string str)
272 {
273 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
274 TELEPHONY_LOGE("%{public}s tpdu nullptr error.", str.c_str());
275 SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
276 SmsMmsErrorCode::SMS_ERROR_PDU_ENCODEING_FAIL, "data sms gsm encodeInfo nullptr error");
277 }
278
DataBasedSmsDeliverySendSplitPage(std::shared_ptr<struct EncodeInfo> encodeInfo,const sptr<ISendShortMessageCallback> & sendCallback,shared_ptr<SmsSendIndexer> indexer,uint8_t msgRef8bit,uint32_t cellsInfosSize)279 void GsmSmsSender::DataBasedSmsDeliverySendSplitPage(std::shared_ptr<struct EncodeInfo> encodeInfo,
280 const sptr<ISendShortMessageCallback> &sendCallback, shared_ptr<SmsSendIndexer> indexer, uint8_t msgRef8bit,
281 uint32_t cellsInfosSize)
282 {
283 std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
284 std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
285 TELEPHONY_LOGE("DataBasedSmsDeliverySendSplitPage cellsInfosSize:%{public}d", cellsInfosSize);
286 std::shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(cellsInfosSize);
287 std::shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
288 if (unSentCellCount == nullptr || hasCellFailed == nullptr) {
289 SendResultCallBack(sendCallback, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
290 return;
291 }
292
293 chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
294 long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
295 indexer->SetUnSentCellCount(unSentCellCount);
296 indexer->SetHasCellFailed(hasCellFailed);
297 indexer->SetEncodeSmca(std::move(smca));
298 indexer->SetEncodePdu(std::move(pdu));
299 indexer->SetHasMore(encodeInfo->isMore_);
300 indexer->SetMsgRefId(msgRef8bit);
301 indexer->SetNetWorkType(NET_TYPE_GSM);
302 indexer->SetTimeStamp(timeStamp);
303 std::unique_lock<std::mutex> lock(mutex_);
304 SendSmsToRil(indexer);
305 }
306
SendSmsToRil(const shared_ptr<SmsSendIndexer> & smsIndexer)307 void GsmSmsSender::SendSmsToRil(const shared_ptr<SmsSendIndexer> &smsIndexer)
308 {
309 if (smsIndexer == nullptr) {
310 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
311 TELEPHONY_LOGE("gsm_sms_sender: SendSms smsIndexer nullptr");
312 return;
313 }
314 if (!isImsNetDomain_ && (voiceServiceState_ != static_cast<int32_t>(RegServiceState::REG_STATE_IN_SERVICE))) {
315 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_SERVICE_UNAVAILABLE);
316 TELEPHONY_LOGE("gsm_sms_sender: SendSms not in service");
317 SmsHiSysEvent::WriteSmsSendFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
318 SmsMmsErrorCode::SMS_ERROR_SENDSMS_NOT_IN_SERVICE, "gsm send sms not in service");
319 return;
320 }
321 int64_t refId = GetMsgRef64Bit();
322 if (!SendCacheMapAddItem(refId, smsIndexer)) {
323 TELEPHONY_LOGE("SendCacheMapAddItem Error!!");
324 return;
325 }
326
327 GsmSimMessageParam smsData;
328 smsData.refId = refId;
329 smsData.smscPdu = StringUtils::StringToHex(smsIndexer->GetEncodeSmca());
330 smsData.pdu = StringUtils::StringToHex(smsIndexer->GetEncodePdu());
331 bool sendCsSMS = false;
332 if ((!isImsNetDomain_ || !imsSmsCfg_) || (smsIndexer->GetPsResendCount() == MAX_SEND_RETRIES)) {
333 sendCsSMS = true;
334 }
335 if (sendCsSMS) {
336 SendCsSms(smsIndexer, smsData);
337 } else {
338 SendImsSms(smsIndexer, smsData);
339 }
340 }
341
SendCsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)342 void GsmSmsSender::SendCsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
343 {
344 uint8_t tryCount = smsIndexer->GetCsResendCount();
345 lastSmsDomain_ = CS_DOMAIN;
346 if (tryCount > 0) {
347 smsIndexer->UpdatePduForResend();
348 }
349 if (tryCount == 0 && smsIndexer->GetHasMore()) {
350 TELEPHONY_LOGI("SendSmsMoreMode pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
351 CoreManagerInner::GetInstance().SendSmsMoreMode(
352 slotId_, RadioEvent::RADIO_SEND_SMS_EXPECT_MORE, smsData, shared_from_this());
353 } else {
354 TELEPHONY_LOGI("SendSms pdu len = %{public}zu", smsIndexer->GetEncodePdu().size());
355 CoreManagerInner::GetInstance().SendGsmSms(slotId_, RadioEvent::RADIO_SEND_SMS, smsData, shared_from_this());
356 }
357 }
358
SendImsSms(const shared_ptr<SmsSendIndexer> & smsIndexer,GsmSimMessageParam smsData)359 void GsmSmsSender::SendImsSms(const shared_ptr<SmsSendIndexer> &smsIndexer, GsmSimMessageParam smsData)
360 {
361 auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
362 TELEPHONY_LOGI("ims network domain send sms interface.!");
363 if (smsClient == nullptr) {
364 TELEPHONY_LOGE("SendSmsToRil return, ImsSmsClient is nullptr.");
365 return;
366 }
367 lastSmsDomain_ = IMS_DOMAIN;
368 ImsMessageInfo imsMessageInfo;
369 imsMessageInfo.refId = smsData.refId;
370 imsMessageInfo.smscPdu = smsData.smscPdu;
371 imsMessageInfo.pdu = smsData.pdu;
372 imsMessageInfo.tech = SMS_RADIO_TECH_3GPP;
373 int32_t reply = smsClient->ImsSendMessage(slotId_, imsMessageInfo);
374 TELEPHONY_LOGI("SendImsSms reply = %{public}d", reply);
375 }
376
IsImsSmsSupported(int32_t slotId,bool & isSupported)377 int32_t GsmSmsSender::IsImsSmsSupported(int32_t slotId, bool &isSupported)
378 {
379 auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
380 if (smsClient == nullptr) {
381 TELEPHONY_LOGE("GetImsSmsConfig return, ImsSmsClient is nullptr.");
382 return TELEPHONY_ERR_LOCAL_PTR_NULL;
383 }
384 std::unique_lock<std::mutex> lck(ctx_);
385 resIsSmsReady_ = false;
386 int32_t reply = smsClient->ImsGetSmsConfig(slotId);
387 TELEPHONY_LOGI("GetImsSms reply = %{public}d", reply);
388 while (resIsSmsReady_) {
389 TELEPHONY_LOGI("GetImsSmsConfig::wait(), resIsSmsReady_ = false");
390 if (cv_.wait_for(lck, std::chrono::seconds(WAIT_TIME_SECOND)) == std::cv_status::timeout) {
391 break;
392 }
393 }
394 TELEPHONY_LOGI("GsmSmsSender::IsImsSmsSupported() imsSmsCfg_:%{public}d", imsSmsCfg_);
395 isSupported = (imsSmsCfg_ == IMS_SMS_ENABLE);
396 return TELEPHONY_ERR_SUCCESS;
397 }
398
StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer & event)399 void GsmSmsSender::StatusReportAnalysis(const AppExecFwk::InnerEvent::Pointer &event)
400 {
401 if (event == nullptr) {
402 TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis event nullptr error.");
403 return;
404 }
405
406 std::shared_ptr<SmsMessageInfo> statusInfo = event->GetSharedObject<SmsMessageInfo>();
407 if (statusInfo == nullptr) {
408 TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis statusInfo nullptr error.");
409 return;
410 }
411
412 std::string pdu = StringUtils::StringToHex(statusInfo->pdu);
413 TELEPHONY_LOGI("StatusReport pdu size == %{public}zu", pdu.length());
414 std::shared_ptr<GsmSmsMessage> message = GsmSmsMessage::CreateMessage(pdu);
415 if (message == nullptr) {
416 TELEPHONY_LOGE("GsmSmsSender: StatusReportAnalysis message nullptr error.");
417 return;
418 }
419 sptr<IDeliveryShortMessageCallback> deliveryCallback = nullptr;
420 auto oldIndexer = reportList_.begin();
421 while (oldIndexer != reportList_.end()) {
422 auto iter = oldIndexer++;
423 if (*iter != nullptr && (message->GetMsgRef() == (*iter)->GetMsgRefId())) {
424 // save the message to db, or updata to db msg state(success or failed)
425 TELEPHONY_LOGI("StatusReport %{public}d %{public}d", message->GetMsgRef(), (*iter)->GetMsgRefId());
426 deliveryCallback = (*iter)->GetDeliveryCallback();
427 reportList_.erase(iter);
428 }
429 }
430 CoreManagerInner::GetInstance().SendSmsAck(slotId_, 0, AckIncomeCause::SMS_ACK_PROCESSED, true, nullptr);
431 if (deliveryCallback != nullptr) {
432 std::string ackpdu = StringUtils::StringToHex(message->GetRawPdu());
433 deliveryCallback->OnSmsDeliveryResult(StringUtils::ToUtf16(ackpdu));
434 }
435 }
436
StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer & event)437 void GsmSmsSender::StatusReportSetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
438 {
439 if (event == nullptr) {
440 TELEPHONY_LOGE("GsmSmsSender: StatusReportSetImsSms event nullptr error.");
441 return;
442 }
443 std::shared_ptr<HRilRadioResponseInfo> imsResponseInfo = event->GetSharedObject<HRilRadioResponseInfo>();
444
445 if (imsResponseInfo->error != HRilErrType::NONE) {
446 imsSmsCfg_ = IMS_SMS_DISABLE;
447 }
448 }
449
StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer & event)450 void GsmSmsSender::StatusReportGetImsSms(const AppExecFwk::InnerEvent::Pointer &event)
451 {
452 if (event == nullptr) {
453 TELEPHONY_LOGE("GsmSmsSender: StatusReportGetImsSms event nullptr error.");
454 return;
455 }
456 std::shared_ptr<int32_t> imsSmsInfo = event->GetSharedObject<int32_t>();
457 if (imsSmsInfo == nullptr) {
458 TELEPHONY_LOGE("GsmSmsSender: StatusReportGetImsSms imsSmsInfo nullptr error.");
459 return;
460 }
461 imsSmsCfg_ = *imsSmsInfo;
462 }
463
SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> & indexer,const std::shared_ptr<struct EncodeInfo> & encodeInfo,unsigned char msgRef8bit)464 void GsmSmsSender::SetSendIndexerInfo(const std::shared_ptr<SmsSendIndexer> &indexer,
465 const std::shared_ptr<struct EncodeInfo> &encodeInfo, unsigned char msgRef8bit)
466 {
467 if (encodeInfo == nullptr || indexer == nullptr) {
468 TELEPHONY_LOGE("CreateSendIndexer encodeInfo nullptr");
469 return;
470 }
471
472 std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
473 std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
474 chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
475 long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
476 indexer->SetTimeStamp(timeStamp);
477 indexer->SetEncodeSmca(std::move(smca));
478 indexer->SetEncodePdu(std::move(pdu));
479 indexer->SetHasMore(encodeInfo->isMore_);
480 indexer->SetMsgRefId(msgRef8bit);
481 indexer->SetNetWorkType(NET_TYPE_GSM);
482 }
483
RegisterHandler()484 bool GsmSmsSender::RegisterHandler()
485 {
486 CoreManagerInner::GetInstance().RegisterCoreNotify(
487 slotId_, shared_from_this(), RadioEvent::RADIO_SMS_STATUS, nullptr);
488 return true;
489 }
490
RegisterImsHandler()491 void GsmSmsSender::RegisterImsHandler()
492 {
493 if (isImsGsmHandlerRegistered) {
494 return;
495 }
496 auto smsClient = DelayedSingleton<ImsSmsClient>::GetInstance();
497 if (smsClient == nullptr) {
498 TELEPHONY_LOGE("RegisterHandler return, ImsSmsClient is nullptr.");
499 return;
500 }
501
502 smsClient->RegisterImsSmsCallbackHandler(slotId_, shared_from_this());
503 TELEPHONY_LOGE("RegisterHandler gsm ImsSmsClient successs");
504 isImsGsmHandlerRegistered = true;
505 }
506
ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)507 void GsmSmsSender::ResendTextDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
508 {
509 if (smsIndexer == nullptr) {
510 TELEPHONY_LOGE("ResendTextDelivery smsIndexer == nullptr");
511 return;
512 }
513 GsmSmsMessage gsmSmsMessage;
514 bool isMore = false;
515 if (!SetPduInfo(smsIndexer, gsmSmsMessage, isMore)) {
516 TELEPHONY_LOGE("SetPduInfo fail.");
517 return;
518 }
519
520 std::shared_ptr<struct EncodeInfo> encodeInfo = nullptr;
521 encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(smsIndexer->GetSmcaAddr(), isMore);
522 if (encodeInfo == nullptr) {
523 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
524 TELEPHONY_LOGE("create encodeInfo indexer == nullptr\r\n");
525 return;
526 }
527 SetSendIndexerInfo(smsIndexer, encodeInfo, smsIndexer->GetMsgRefId());
528 std::unique_lock<std::mutex> lock(mutex_);
529 SendSmsToRil(smsIndexer);
530 }
531
ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> & smsIndexer)532 void GsmSmsSender::ResendDataDelivery(const std::shared_ptr<SmsSendIndexer> &smsIndexer)
533 {
534 if (smsIndexer == nullptr) {
535 TELEPHONY_LOGE("DataBasedSmsDelivery ResendDataDelivery smsIndexer nullptr");
536 return;
537 }
538
539 bool isStatusReport = false;
540 unsigned char msgRef8bit = 0;
541 msgRef8bit = smsIndexer->GetMsgRefId();
542 isStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
543
544 GsmSmsMessage gsmSmsMessage;
545 std::shared_ptr<struct SmsTpdu> tpdu = nullptr;
546 tpdu = gsmSmsMessage.CreateDataSubmitSmsTpdu(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
547 smsIndexer->GetDestPort(), smsIndexer->GetData().data(), smsIndexer->GetData().size(), msgRef8bit,
548 isStatusReport);
549
550 std::shared_ptr<struct EncodeInfo> encodeInfo = nullptr;
551 encodeInfo = gsmSmsMessage.GetSubmitEncodeInfo(smsIndexer->GetSmcaAddr(), false);
552 if (encodeInfo == nullptr || tpdu == nullptr) {
553 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
554 TELEPHONY_LOGE("DataBasedSmsDelivery encodeInfo or tpdu nullptr");
555 return;
556 }
557 std::vector<uint8_t> smca(encodeInfo->smcaData_, encodeInfo->smcaData_ + encodeInfo->smcaLen);
558 std::vector<uint8_t> pdu(encodeInfo->tpduData_, encodeInfo->tpduData_ + encodeInfo->tpduLen);
559 std::shared_ptr<uint8_t> unSentCellCount = make_shared<uint8_t>(1);
560 if (unSentCellCount == nullptr) {
561 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
562 TELEPHONY_LOGE("DataBasedSmsDelivery unSentCellCount nullptr");
563 return;
564 }
565 std::shared_ptr<bool> hasCellFailed = make_shared<bool>(false);
566 if (hasCellFailed == nullptr) {
567 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
568 TELEPHONY_LOGE("DataBasedSmsDelivery hasCellFailed nullptr");
569 return;
570 }
571 chrono::system_clock::duration timePoint = chrono::system_clock::now().time_since_epoch();
572 long timeStamp = chrono::duration_cast<chrono::seconds>(timePoint).count();
573
574 smsIndexer->SetUnSentCellCount(unSentCellCount);
575 smsIndexer->SetHasCellFailed(hasCellFailed);
576 smsIndexer->SetEncodeSmca(std::move(smca));
577 smsIndexer->SetEncodePdu(std::move(pdu));
578 smsIndexer->SetHasMore(encodeInfo->isMore_);
579 smsIndexer->SetMsgRefId(msgRef8bit);
580 smsIndexer->SetNetWorkType(NET_TYPE_GSM);
581 smsIndexer->SetTimeStamp(timeStamp);
582 std::unique_lock<std::mutex> lock(mutex_);
583 SendSmsToRil(smsIndexer);
584 }
585
SetPduInfo(const std::shared_ptr<SmsSendIndexer> & smsIndexer,GsmSmsMessage & gsmSmsMessage,bool & isMore)586 bool GsmSmsSender::SetPduInfo(
587 const std::shared_ptr<SmsSendIndexer> &smsIndexer, GsmSmsMessage &gsmSmsMessage, bool &isMore)
588 {
589 bool ret = false;
590 if (smsIndexer == nullptr) {
591 TELEPHONY_LOGE("Indexer is nullptr");
592 return ret;
593 }
594 SmsCodingScheme codingType = smsIndexer->GetDcs();
595 std::shared_ptr<struct SmsTpdu> tpdu = nullptr;
596 tpdu = gsmSmsMessage.CreateDefaultSubmitSmsTpdu(smsIndexer->GetDestAddr(), smsIndexer->GetSmcaAddr(),
597 smsIndexer->GetText(), (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true, codingType);
598 if (tpdu == nullptr) {
599 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
600 TELEPHONY_LOGE("ResendTextDelivery CreateDefaultSubmitSmsTpdu err.");
601 return ret;
602 }
603 (void)memset_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, 0x00, MAX_USER_DATA_LEN + 1);
604 if (smsIndexer->GetText().length() > MAX_USER_DATA_LEN + 1) {
605 TELEPHONY_LOGE("SetPduInfo data length invalid.");
606 return ret;
607 }
608 if (memcpy_s(tpdu->data.submit.userData.data, MAX_USER_DATA_LEN + 1, smsIndexer->GetText().c_str(),
609 smsIndexer->GetText().length()) != EOK) {
610 SendResultCallBack(smsIndexer, ISendShortMessageCallback::SEND_SMS_FAILURE_UNKNOWN);
611 TELEPHONY_LOGE("TextBasedSmsDelivery memcpy_s error.");
612 return ret;
613 }
614 int headerCnt = 0;
615 tpdu->data.submit.userData.length = static_cast<int>(smsIndexer->GetText().length());
616 tpdu->data.submit.userData.data[smsIndexer->GetText().length()] = 0;
617 tpdu->data.submit.msgRef = smsIndexer->GetMsgRefId();
618 if (smsIndexer->GetIsConcat()) {
619 headerCnt += gsmSmsMessage.SetHeaderConcat(headerCnt, smsIndexer->GetSmsConcat());
620 }
621 /* Set User Data Header for Alternate Reply Address */
622 headerCnt += gsmSmsMessage.SetHeaderReply(headerCnt);
623 /* Set User Data Header for National Language Single Shift */
624 headerCnt += gsmSmsMessage.SetHeaderLang(headerCnt, codingType, smsIndexer->GetLangId());
625 tpdu->data.submit.userData.headerCnt = headerCnt;
626 tpdu->data.submit.bHeaderInd = (headerCnt > 0) ? true : false;
627
628 unsigned char totalSeg = smsIndexer->GetSmsConcat().totalSeg;
629 if ((totalSeg > 1) && (smsIndexer->GetSmsConcat().seqNum < totalSeg)) {
630 tpdu->data.submit.bStatusReport = false;
631 isMore = true;
632 } else {
633 tpdu->data.submit.bStatusReport = (smsIndexer->GetDeliveryCallback() == nullptr) ? false : true;
634 isMore = false;
635 }
636 return true;
637 }
638 } // namespace Telephony
639 } // namespace OHOS