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 "sms_receive_handler.h"
17
18 #include "gsm_sms_message.h"
19 #include "radio_event.h"
20 #include "sms_hisysevent.h"
21 #include "sms_persist_helper.h"
22 #include "telephony_log_wrapper.h"
23
24 namespace OHOS {
25 namespace Telephony {
26 using namespace std;
27 constexpr static uint16_t PDU_POS_OFFSET = 1;
28 constexpr static uint8_t SMS_TYPE_GSM = 1;
29 constexpr static uint8_t SMS_TYPE_CDMA = 2;
30 static const std::string WAP_SEQ_NUMBER_TAG = "0003";
31 constexpr static size_t WAP_SEQ_NUMBER_LEN = 10;
32
SmsReceiveHandler(int32_t slotId)33 SmsReceiveHandler::SmsReceiveHandler(int32_t slotId) : TelEventHandler("SmsReceiveHandler"), slotId_(slotId)
34 {
35 smsWapPushHandler_ = std::make_unique<SmsWapPushHandler>(slotId);
36 if (smsWapPushHandler_ == nullptr) {
37 TELEPHONY_LOGE("make sms wapPush Hander error.");
38 }
39 }
40
~SmsReceiveHandler()41 SmsReceiveHandler::~SmsReceiveHandler() {}
42
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)43 void SmsReceiveHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
44 {
45 if (event == nullptr) {
46 TELEPHONY_LOGE("SmsReceiveHandler::ProcessEvent event == nullptr");
47 return;
48 }
49
50 uint32_t eventId = 0;
51 eventId = event->GetInnerEventId();
52 TELEPHONY_LOGI("SmsReceiveHandler::ProcessEvent eventId = %{public}d", eventId);
53 switch (eventId) {
54 case RadioEvent::RADIO_GSM_SMS:
55 case RadioEvent::RADIO_CDMA_SMS: {
56 std::shared_ptr<SmsBaseMessage> message = nullptr;
57 message = TransformMessageInfo(event->GetSharedObject<SmsMessageInfo>());
58 if (message != nullptr) {
59 TELEPHONY_LOGI("[raw pdu] =%{private}s", StringUtils::StringToHex(message->GetRawPdu()).c_str());
60 }
61 HandleReceivedSms(message);
62 break;
63 }
64 default:
65 TELEPHONY_LOGE("SmsReceiveHandler::ProcessEvent Unknown eventId %{public}d", eventId);
66 break;
67 }
68 }
69
HandleReceivedSms(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)70 void SmsReceiveHandler::HandleReceivedSms(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
71 {
72 if (smsBaseMessage == nullptr) {
73 TELEPHONY_LOGE("smsBaseMessage is nullptr");
74 return;
75 }
76 ReplySmsToSmsc(HandleSmsByType(smsBaseMessage), nullptr);
77 }
78
CombineMessagePart(const std::shared_ptr<SmsReceiveIndexer> & indexer)79 void SmsReceiveHandler::CombineMessagePart(const std::shared_ptr<SmsReceiveIndexer> &indexer)
80 {
81 std::shared_ptr<vector<string>> pdus = make_shared<vector<string>>();
82 if ((indexer == nullptr) || (pdus == nullptr)) {
83 TELEPHONY_LOGE("indexer or pdus is nullptr");
84 return;
85 }
86 auto reliabilityHandler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
87 if ((reliabilityHandler == nullptr)) {
88 TELEPHONY_LOGE("reliabilityHandler is nullptr");
89 return;
90 }
91 if (indexer->IsSingleMsg()) {
92 string pdu = StringUtils::StringToHex(indexer->GetPdu());
93 pdus->push_back(pdu);
94 } else {
95 if (!CombineMultiPageMessage(indexer, pdus, reliabilityHandler)) {
96 TELEPHONY_LOGI("The multi-page text didn't all arrive");
97 return;
98 }
99 }
100
101 if (indexer->GetIsWapPushMsg()) {
102 if (smsWapPushHandler_ != nullptr) {
103 auto rawWapPushUserData = indexer->GetRawWapPushUserData();
104 if (!smsWapPushHandler_->DecodeWapPushPdu(indexer, rawWapPushUserData)) {
105 SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::WAP_PUSH,
106 SmsMmsErrorCode::SMS_ERROR_PDU_DECODE_FAIL, "Wap push decode wap push fail");
107 }
108 }
109 return;
110 }
111 reliabilityHandler->SendBroadcast(indexer, pdus);
112 }
113
CombineMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> & indexer,std::shared_ptr<std::vector<std::string>> pdus,std::shared_ptr<SmsReceiveReliabilityHandler> reliabilityHandler)114 bool SmsReceiveHandler::CombineMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> &indexer,
115 std::shared_ptr<std::vector<std::string>> pdus, std::shared_ptr<SmsReceiveReliabilityHandler> reliabilityHandler)
116 {
117 pdus->assign(MAX_SEGMENT_NUM, "");
118 int msgSeg = static_cast<int>(indexer->GetMsgCount());
119 int8_t notNullPart = msgSeg;
120 std::vector<SmsReceiveIndexer> dbIndexers;
121 DataShare::DataSharePredicates predicates;
122 predicates.EqualTo(SmsSubsection::SENDER_NUMBER, indexer->GetOriginatingAddress())
123 ->And()
124 ->EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(indexer->GetMsgRefId()))
125 ->And()
126 ->EqualTo(SmsSubsection::SIZE, std::to_string(indexer->GetMsgCount()));
127 DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
128 int8_t count = 0;
129 for (const auto &v : dbIndexers) {
130 ++count;
131 string pdu = StringUtils::StringToHex(v.GetPdu());
132 if ((v.GetMsgSeqId() - PDU_POS_OFFSET >= MAX_SEGMENT_NUM) || (v.GetMsgSeqId() - PDU_POS_OFFSET < 0)) {
133 reliabilityHandler->DeleteMessageFormDb(indexer->GetMsgRefId());
134 return false;
135 }
136 pdus->at(v.GetMsgSeqId() - PDU_POS_OFFSET) = pdu;
137 if (v.GetPdu().size() == 0) {
138 --notNullPart;
139 }
140 }
141 if ((count != msgSeg) || (pdus->empty()) || (notNullPart != msgSeg)) {
142 return false;
143 }
144 UpdateMultiPageMessage(indexer, pdus);
145 return true;
146 }
147
UpdateMultiPageMessage(const std::shared_ptr<SmsReceiveIndexer> & indexer,std::shared_ptr<std::vector<std::string>> pdus)148 void SmsReceiveHandler::UpdateMultiPageMessage(
149 const std::shared_ptr<SmsReceiveIndexer> &indexer, std::shared_ptr<std::vector<std::string>> pdus)
150 {
151 if ((indexer == nullptr) || (pdus == nullptr) || (pdus->empty())) {
152 TELEPHONY_LOGE("indexer or pdus is null");
153 return;
154 }
155 std::string messagBody;
156 std::string userDataRaw;
157 std::string rawWapPushUserData;
158 for (const auto &pdu : *pdus) {
159 if (pdu.empty()) {
160 continue;
161 }
162 std::shared_ptr<SmsBaseMessage> baseMessage = GsmSmsMessage::CreateMessage(pdu);
163 if (baseMessage == nullptr) {
164 continue;
165 }
166 messagBody.append(baseMessage->GetVisibleMessageBody());
167 userDataRaw.append(baseMessage->GetRawUserData());
168 if (!indexer->GetIsWapPushMsg()) {
169 continue;
170 }
171 auto wapDataHex = StringUtils::StringToHex(baseMessage->GetRawWapPushUserData());
172 if (wapDataHex.substr(0, WAP_SEQ_NUMBER_TAG.size()) == WAP_SEQ_NUMBER_TAG) {
173 rawWapPushUserData.append(StringUtils::HexToString(wapDataHex.substr(WAP_SEQ_NUMBER_LEN)));
174 } else {
175 rawWapPushUserData.append(StringUtils::HexToString(wapDataHex));
176 }
177 }
178
179 indexer->SetVisibleMessageBody(messagBody);
180 indexer->SetRawUserData(userDataRaw);
181 if (indexer->GetIsWapPushMsg()) {
182 indexer->SetRawWapPushUserData(rawWapPushUserData);
183 }
184 }
185
IsRepeatedMessagePart(const shared_ptr<SmsReceiveIndexer> & smsIndexer)186 bool SmsReceiveHandler::IsRepeatedMessagePart(const shared_ptr<SmsReceiveIndexer> &smsIndexer)
187 {
188 if (smsIndexer != nullptr) {
189 std::vector<SmsReceiveIndexer> dbIndexers;
190 DataShare::DataSharePredicates predicates;
191 predicates.EqualTo(SmsSubsection::SENDER_NUMBER, smsIndexer->GetOriginatingAddress())
192 ->And()
193 ->EqualTo(SmsSubsection::SMS_SUBSECTION_ID, std::to_string(smsIndexer->GetMsgRefId()))
194 ->And()
195 ->EqualTo(SmsSubsection::SIZE, std::to_string(smsIndexer->GetMsgCount()));
196 DelayedSingleton<SmsPersistHelper>::GetInstance()->Query(predicates, dbIndexers);
197
198 for (const auto &it : dbIndexers) {
199 if (it.GetMsgSeqId() == smsIndexer->GetMsgSeqId()) {
200 return true;
201 }
202 }
203 }
204 return false;
205 }
206
AddMsgToDB(const std::shared_ptr<SmsReceiveIndexer> indexer)207 bool SmsReceiveHandler::AddMsgToDB(const std::shared_ptr<SmsReceiveIndexer> indexer)
208 {
209 if (indexer == nullptr) {
210 TELEPHONY_LOGE("indexer is nullptr.");
211 return false;
212 }
213
214 DataShare::DataShareValuesBucket bucket;
215 bucket.Put(SmsSubsection::SLOT_ID, std::to_string(slotId_));
216 bucket.Put(SmsSubsection::RECEIVER_NUMBER, indexer->GetOriginatingAddress());
217 bucket.Put(SmsSubsection::SENDER_NUMBER, indexer->GetOriginatingAddress());
218 bucket.Put(SmsSubsection::START_TIME, std::to_string(indexer->GetTimestamp()));
219 bucket.Put(SmsSubsection::END_TIME, std::to_string(indexer->GetTimestamp()));
220 bucket.Put(SmsSubsection::REW_PUD, StringUtils::StringToHex(indexer->GetPdu()));
221
222 bucket.Put(SmsSubsection::FORMAT, indexer->GetIsCdma() ? SMS_TYPE_CDMA : SMS_TYPE_GSM);
223 bucket.Put(SmsSubsection::DEST_PORT, indexer->GetDestPort());
224 bucket.Put(SmsSubsection::SMS_SUBSECTION_ID, indexer->GetMsgRefId());
225 bucket.Put(SmsSubsection::SIZE, indexer->GetMsgCount());
226 bucket.Put(SmsSubsection::SUBSECTION_INDEX, indexer->GetMsgSeqId());
227 uint16_t dataBaseId = 0;
228 bool ret = DelayedSingleton<SmsPersistHelper>::GetInstance()->Insert(bucket, dataBaseId);
229 indexer->SetDataBaseId(dataBaseId);
230 if (!ret) {
231 SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
232 SmsMmsErrorCode::SMS_ERROR_ADD_TO_DATABASE_FAIL, "add msg to database error");
233 }
234 return ret;
235 }
236 } // namespace Telephony
237 } // namespace OHOS