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_receive_handler.h"
17 
18 #include "cdma_sms_common.h"
19 #include "cdma_sms_message.h"
20 #include "cdma_sms_sender.h"
21 #include "common_event.h"
22 #include "common_event_manager.h"
23 #include "common_event_support.h"
24 #include "core_manager_inner.h"
25 #include "radio_event.h"
26 #include "singleton.h"
27 #include "sms_common.h"
28 #include "sms_hisysevent.h"
29 #include "sms_persist_helper.h"
30 #include "sms_receive_reliability_handler.h"
31 #include "telephony_log_wrapper.h"
32 #include "telephony_permission.h"
33 #include "want.h"
34 
35 namespace OHOS {
36 namespace Telephony {
37 using namespace OHOS::EventFwk;
CdmaSmsReceiveHandler(int32_t slotId)38 CdmaSmsReceiveHandler::CdmaSmsReceiveHandler(int32_t slotId) : SmsReceiveHandler(slotId)
39 {
40     TELEPHONY_LOGI("%{public}d", slotId_);
41 }
42 
HandleSmsByType(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)43 int32_t CdmaSmsReceiveHandler::HandleSmsByType(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
44 {
45     if (smsBaseMessage == nullptr) {
46         TELEPHONY_LOGE("SmsBaseMessage is null!");
47         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
48     }
49     CdmaSmsMessage *message = static_cast<CdmaSmsMessage *>(smsBaseMessage.get());
50     if (message->IsBroadcastMsg()) {
51         SendCBBroadcast(smsBaseMessage);
52         return AckIncomeCause::SMS_ACK_RESULT_OK;
53     }
54     int service = message->GetTransTeleService();
55     if (static_cast<int>(SmsTransTelsvcId::WEMT) != service && static_cast<int>(SmsTransTelsvcId::CMT_95) != service) {
56         return AckIncomeCause::SMS_ACK_RESULT_OK;
57     }
58     if (message->IsStatusReport() && !cdmaSmsSender_.expired()) {
59         std::shared_ptr<SmsSender> smsSender = cdmaSmsSender_.lock();
60         CdmaSmsSender *cdmaSend = static_cast<CdmaSmsSender *>(smsSender.get());
61         std::shared_ptr<SmsReceiveIndexer> statusInfo = std::make_shared<SmsReceiveIndexer>();
62         if (statusInfo == nullptr) {
63             TELEPHONY_LOGE("statusInfo is null!");
64             return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
65         }
66         statusInfo->SetMsgRefId(message->GetMsgRef());
67         statusInfo->SetPdu(message->GetRawPdu());
68         cdmaSend->ReceiveStatusReport(statusInfo);
69         return AckIncomeCause::SMS_ACK_RESULT_OK;
70     }
71     return HandleSmsOtherSvcid(smsBaseMessage);
72 }
73 
HandleAck(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)74 int32_t CdmaSmsReceiveHandler::HandleAck(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
75 {
76     if (smsBaseMessage == nullptr) {
77         TELEPHONY_LOGE("SmsBaseMessage is null!");
78         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
79     }
80     CdmaSmsMessage *message = static_cast<CdmaSmsMessage *>(smsBaseMessage.get());
81     if (message->IsBroadcastMsg()) {
82         SendCBBroadcast(smsBaseMessage);
83         return AckIncomeCause::SMS_ACK_RESULT_OK;
84     }
85     int service = message->GetTransTeleService();
86     if (static_cast<int>(SmsTransTelsvcId::WEMT) != service && static_cast<int>(SmsTransTelsvcId::CMT_95) != service) {
87         return AckIncomeCause::SMS_ACK_RESULT_OK;
88     }
89     if (message->IsStatusReport() && !cdmaSmsSender_.expired()) {
90         std::shared_ptr<SmsSender> smsSender = cdmaSmsSender_.lock();
91         CdmaSmsSender *cdmaSend = static_cast<CdmaSmsSender *>(smsSender.get());
92         std::shared_ptr<SmsReceiveIndexer> statusInfo = std::make_shared<SmsReceiveIndexer>();
93         if (statusInfo == nullptr) {
94             TELEPHONY_LOGE("statusInfo is null!");
95             return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
96         }
97         statusInfo->SetMsgRefId(message->GetMsgRef());
98         statusInfo->SetPdu(message->GetRawPdu());
99         cdmaSend->ReceiveStatusReport(statusInfo);
100         return AckIncomeCause::SMS_ACK_RESULT_OK;
101     }
102     if (message->IsConcatMsg()) {
103         std::shared_ptr<SmsConcat> smsConcat = message->GetConcatMsg();
104         if (smsConcat == nullptr) {
105             TELEPHONY_LOGE("Concat is null.");
106             return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
107         }
108     }
109     return AckIncomeCause::SMS_ACK_RESULT_OK;
110 }
111 
HandleRemainDataShare(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)112 void CdmaSmsReceiveHandler::HandleRemainDataShare(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
113 {
114     if (smsBaseMessage == nullptr) {
115         TELEPHONY_LOGE("SmsBaseMessage is null!");
116         return;
117     }
118     CdmaSmsMessage *message = static_cast<CdmaSmsMessage *>(smsBaseMessage.get());
119     std::shared_ptr<SmsReceiveIndexer> indexer;
120     if (!message->IsConcatMsg()) {
121         indexer = std::make_shared<SmsReceiveIndexer>(message->GetRawPdu(), message->GetScTimestamp(),
122             message->GetDestPort(), true, false, message->GetOriginatingAddress(),
123             message->GetVisibleOriginatingAddress(), message->GetVisibleMessageBody());
124     } else {
125         std::shared_ptr<SmsConcat> smsConcat = message->GetConcatMsg();
126         if (smsConcat == nullptr) {
127             return;
128         }
129         indexer = std::make_shared<SmsReceiveIndexer>(message->GetRawPdu(), message->GetScTimestamp(),
130             message->GetDestPort(), true, message->GetOriginatingAddress(), message->GetVisibleOriginatingAddress(),
131             smsConcat->msgRef, smsConcat->seqNum, smsConcat->totalSeg, false, message->GetVisibleMessageBody());
132     }
133     if (indexer == nullptr) {
134         TELEPHONY_LOGE("indexer is nullptr.");
135         return;
136     }
137     TELEPHONY_LOGI("received a cdma sms, the refid is %{public}d, this is %{public}d, a total of %{public}d",
138         indexer->GetMsgRefId(), indexer->GetMsgSeqId(), indexer->GetMsgCount());
139     if (indexer->GetIsText() && message->IsConcatMsg() && IsRepeatedMessagePart(indexer)) {
140         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
141             SmsMmsErrorCode::SMS_ERROR_REPEATED_ERROR, "cdma message repeated error");
142         return;
143     }
144     if (!AddMsgToDB(indexer)) {
145         TELEPHONY_LOGE("AddMsgToDB failed");
146         return;
147     }
148     auto reliabilityHandler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
149     if (reliabilityHandler == nullptr) {
150         TELEPHONY_LOGE("reliabilityHandler nullptr");
151         return;
152     }
153     if (!reliabilityHandler->DeleteExpireSmsFromDB()) {
154         TELEPHONY_LOGE("DeleteExpireSmsFromDB fail");
155         return;
156     }
157     CombineMessagePart(indexer);
158 }
159 
HandleSmsOtherSvcid(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)160 int32_t CdmaSmsReceiveHandler::HandleSmsOtherSvcid(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
161 {
162     if (smsBaseMessage == nullptr) {
163         TELEPHONY_LOGE("SmsBaseMessage is null!");
164         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
165     }
166     CdmaSmsMessage *message = static_cast<CdmaSmsMessage *>(smsBaseMessage.get());
167     // Encapsulate key information to Tracker
168     std::shared_ptr<SmsReceiveIndexer> indexer;
169     if (!message->IsConcatMsg()) {
170         indexer = std::make_shared<SmsReceiveIndexer>(message->GetRawPdu(), message->GetScTimestamp(),
171             message->GetDestPort(), true, false, message->GetOriginatingAddress(),
172             message->GetVisibleOriginatingAddress(), message->GetVisibleMessageBody());
173     } else {
174         std::shared_ptr<SmsConcat> smsConcat = message->GetConcatMsg();
175         if (smsConcat == nullptr) {
176             return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
177         }
178         indexer = std::make_shared<SmsReceiveIndexer>(message->GetRawPdu(), message->GetScTimestamp(),
179             message->GetDestPort(), true, message->GetOriginatingAddress(), message->GetVisibleOriginatingAddress(),
180             smsConcat->msgRef, smsConcat->seqNum, smsConcat->totalSeg, false, message->GetVisibleMessageBody());
181     }
182     // add messages to the database
183     if (indexer == nullptr) {
184         TELEPHONY_LOGE("indexer is nullptr.");
185         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
186     }
187     TELEPHONY_LOGI("received a cdma sms, the refid is %{public}d, this is %{public}d, a total of %{public}d",
188         indexer->GetMsgRefId(), indexer->GetMsgSeqId(), indexer->GetMsgCount());
189     if (indexer->GetIsText() && message->IsConcatMsg() && IsRepeatedMessagePart(indexer)) {
190         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::SMS_SHORT_MESSAGE,
191             SmsMmsErrorCode::SMS_ERROR_REPEATED_ERROR, "cdma message repeated error");
192         return AckIncomeCause::SMS_ACK_RESULT_OK;
193     }
194     if (!AddMsgToDB(indexer)) {
195         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
196     }
197     auto reliabilityHandler = std::make_shared<SmsReceiveReliabilityHandler>(slotId_);
198     if (reliabilityHandler == nullptr) {
199         TELEPHONY_LOGE("reliabilityHandler nullptr");
200         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
201     }
202     if (!reliabilityHandler->DeleteExpireSmsFromDB()) {
203         TELEPHONY_LOGE("DeleteExpireSmsFromDB fail");
204         return AckIncomeCause::SMS_ACK_UNKNOWN_ERROR;
205     }
206     CombineMessagePart(indexer);
207     return AckIncomeCause::SMS_ACK_RESULT_OK;
208 }
209 
ReplySmsToSmsc(int result)210 bool CdmaSmsReceiveHandler::ReplySmsToSmsc(int result)
211 {
212     TELEPHONY_LOGI("Reply To Smsc ackResult %{public}d", result);
213     CoreManagerInner::GetInstance().SendSmsAck(
214         slotId_, SMS_EVENT_NEW_SMS_REPLY, result == AckIncomeCause::SMS_ACK_RESULT_OK, result, shared_from_this());
215     return result == AckIncomeCause::SMS_ACK_RESULT_OK;
216 }
217 
SetCdmaSender(const std::weak_ptr<SmsSender> & smsSender)218 void CdmaSmsReceiveHandler::SetCdmaSender(const std::weak_ptr<SmsSender> &smsSender)
219 {
220     cdmaSmsSender_ = smsSender;
221 }
222 
TransformMessageInfo(const std::shared_ptr<SmsMessageInfo> info)223 std::shared_ptr<SmsBaseMessage> CdmaSmsReceiveHandler::TransformMessageInfo(const std::shared_ptr<SmsMessageInfo> info)
224 {
225     std::shared_ptr<SmsBaseMessage> baseMessage = nullptr;
226     if (info == nullptr) {
227         TELEPHONY_LOGE("SmsBaseMessage is null!");
228         return baseMessage;
229     }
230     std::string pdu = StringUtils::StringToHex(info->pdu);
231     baseMessage = CdmaSmsMessage::CreateMessage(pdu);
232     return baseMessage;
233 }
234 
Init()235 void CdmaSmsReceiveHandler::Init()
236 {
237     if (!RegisterHandler()) {
238         TELEPHONY_LOGI("GsmSmsSender::Init Register RADIO_SMS_STATUS fail.");
239     }
240 }
241 
RegisterHandler()242 bool CdmaSmsReceiveHandler::RegisterHandler()
243 {
244     TELEPHONY_LOGI("CdmaSmsReceiveHandler::RegisteHandler Register RADIO_CDMA_SMS ok.");
245     CoreManagerInner::GetInstance().RegisterCoreNotify(
246         slotId_, shared_from_this(), RadioEvent::RADIO_CDMA_SMS, nullptr);
247     return true;
248 }
249 
UnRegisterHandler()250 void CdmaSmsReceiveHandler::UnRegisterHandler()
251 {
252     TELEPHONY_LOGI("CdmaSmsReceiveHandler::UnRegisterHandler::slotId= %{public}d", slotId_);
253     CoreManagerInner::GetInstance().UnRegisterCoreNotify(slotId_, shared_from_this(), RadioEvent::RADIO_CDMA_SMS);
254 }
255 
SendCBBroadcast(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)256 bool CdmaSmsReceiveHandler::SendCBBroadcast(const std::shared_ptr<SmsBaseMessage> smsBaseMessage)
257 {
258     if (smsBaseMessage == nullptr) {
259         TELEPHONY_LOGE("smsBaseMessage is nullptr.");
260         return false;
261     }
262 
263     bool isMergency = false;
264     SmsCbData::CbData sendData;
265     GetCBData(smsBaseMessage, sendData, isMergency);
266     EventFwk::Want want;
267     EventFwk::CommonEventData data;
268     if (isMergency) {
269         want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SMS_EMERGENCY_CB_RECEIVE_COMPLETED);
270     } else {
271         want.SetAction(EventFwk::CommonEventSupport::COMMON_EVENT_SMS_CB_RECEIVE_COMPLETED);
272     }
273     SetCBBroadcastParam(want, sendData);
274     data.SetWant(want);
275     EventFwk::CommonEventPublishInfo publishInfo;
276     publishInfo.SetOrdered(true);
277     std::vector<std::string> cdmaCbPermissions;
278     cdmaCbPermissions.emplace_back(Permission::RECEIVE_MESSAGES);
279     publishInfo.SetSubscriberPermissions(cdmaCbPermissions);
280     bool publishResult = EventFwk::CommonEventManager::PublishCommonEvent(data, publishInfo, nullptr);
281     if (!publishResult) {
282         TELEPHONY_LOGE("SendBroadcast PublishBroadcastEvent result fail");
283         SmsHiSysEvent::WriteSmsReceiveFaultEvent(slotId_, SmsMmsMessageType::CELL_BROAD_CAST,
284             SmsMmsErrorCode::SMS_ERROR_PUBLISH_COMMON_EVENT_FAIL, "publish cell broadcast event fail");
285         return false;
286     }
287     DelayedSingleton<SmsHiSysEvent>::GetInstance()->SetCbBroadcastStartTime();
288     return true;
289 }
290 
SetCBBroadcastParam(AppExecFwk::Want & want,SmsCbData::CbData & sendData)291 bool CdmaSmsReceiveHandler::SetCBBroadcastParam(AppExecFwk::Want &want, SmsCbData::CbData &sendData)
292 {
293     const int lac = -1;
294     const int cid = -1;
295     want.SetParam(SmsCbData::GEO_SCOPE, static_cast<char>(sendData.geoScope));
296     want.SetParam(SmsCbData::CMAS_RESPONSE, static_cast<char>(sendData.cmasRes));
297     want.SetParam(SmsCbData::SLOT_ID, static_cast<int>(slotId_));
298     want.SetParam(SmsCbData::FORMAT, static_cast<char>(sendData.format));
299     want.SetParam(SmsCbData::CB_MSG_TYPE, static_cast<char>(sendData.msgType));
300     want.SetParam(SmsCbData::MSG_ID, static_cast<int>(sendData.msgId));
301     want.SetParam(SmsCbData::SERVICE_CATEGORY, static_cast<int>(sendData.category));
302     want.SetParam(SmsCbData::LANG_TYPE, static_cast<char>(sendData.langType));
303     want.SetParam(SmsCbData::PRIORITY, static_cast<char>(sendData.priority));
304     want.SetParam(SmsCbData::MSG_BODY, sendData.msgBody);
305     want.SetParam(SmsCbData::CMAS_CLASS, static_cast<char>(sendData.cmasClass));
306     want.SetParam(SmsCbData::CMAS_CATEGORY, static_cast<char>(sendData.cmasCate));
307     want.SetParam(SmsCbData::SEVERITY, static_cast<char>(sendData.severity));
308     want.SetParam(SmsCbData::URGENCY, static_cast<char>(sendData.urgency));
309     want.SetParam(SmsCbData::CERTAINTY, static_cast<char>(sendData.certainty));
310     want.SetParam(SmsCbData::IS_CMAS_MESSAGE, sendData.isCmas);
311     want.SetParam(SmsCbData::SERIAL_NUM, static_cast<int>(sendData.serial));
312     want.SetParam(SmsCbData::RECV_TIME, std::to_string(sendData.recvTime));
313     want.SetParam(SmsCbData::DCS, static_cast<char>(sendData.dcs));
314     want.SetParam(SmsCbData::IS_ETWS_PRIMARY, sendData.isPrimary);
315     want.SetParam(SmsCbData::IS_ETWS_MESSAGE, sendData.isEtws);
316     want.SetParam(SmsCbData::PLMN, StringUtils::ToUtf8(plmn_));
317     want.SetParam(SmsCbData::LAC, static_cast<int>(lac));
318     want.SetParam(SmsCbData::CID, static_cast<int>(cid));
319     want.SetParam(SmsCbData::WARNING_TYPE, static_cast<int>(sendData.warnType));
320     return true;
321 }
322 
GetCBData(const std::shared_ptr<SmsBaseMessage> smsBaseMessage,SmsCbData::CbData & sendData,bool & isEmergency)323 void CdmaSmsReceiveHandler::GetCBData(
324     const std::shared_ptr<SmsBaseMessage> smsBaseMessage, SmsCbData::CbData &sendData, bool &isEmergency)
325 {
326     if (smsBaseMessage == nullptr) {
327         TELEPHONY_LOGE("smsBaseMessage is nullptr.");
328         return;
329     }
330     CdmaSmsMessage *message = static_cast<CdmaSmsMessage *>(smsBaseMessage.get());
331     if (message == nullptr) {
332         TELEPHONY_LOGE("message is nullptr.");
333         return;
334     }
335 
336     sendData.format = message->GetFormat();
337     sendData.geoScope = message->GetGeoScope();
338     sendData.msgId = message->GetMessageId();
339     sendData.serial = message->GetMessageId();
340     sendData.category = message->GetServiceCategoty();
341     sendData.langType = static_cast<uint8_t>(message->GetLanguage());
342     sendData.msgBody = message->GetVisibleMessageBody();
343     sendData.priority = message->GetPriority();
344     sendData.isCmas = message->IsCMAS();
345     sendData.cmasClass = message->GetCMASMessageClass();
346     sendData.cmasCate = message->GetCMASCategory();
347     sendData.severity = message->GetCMASSeverity();
348     sendData.urgency = message->GetCMASUrgency();
349     sendData.certainty = message->GetCMASCertainty();
350     sendData.recvTime = message->GetReceTime();
351     sendData.langType = static_cast<uint8_t>(message->GetLanguage());
352     isEmergency = message->IsEmergencyMsg();
353     plmn_ = CoreManagerInner::GetInstance().GetOperatorNumeric(slotId_);
354 }
355 } // namespace Telephony
356 } // namespace OHOS
357