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