• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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