• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 "cdma_sms_teleservice_message.h"
17 
18 #include "telephony_log_wrapper.h"
19 
20 namespace OHOS {
21 namespace Telephony {
22 static constexpr uint8_t SUB_PARAMETER_SIZE_MAX = 24;
23 
~CdmaSmsTeleserviceMessage()24 CdmaSmsTeleserviceMessage::~CdmaSmsTeleserviceMessage()
25 {
26     parameter_.clear();
27     parameter_.shrink_to_fit();
28 }
29 
Encode(SmsWriteBuffer & pdu)30 bool CdmaSmsTeleserviceMessage::Encode(SmsWriteBuffer &pdu)
31 {
32     if (pdu.IsEmpty()) {
33         TELEPHONY_LOGE("pdu is empty");
34         return false;
35     }
36     if (parameter_.size() == 0) {
37         TELEPHONY_LOGE("parameter is empty");
38         return false;
39     }
40 
41     for (uint8_t i = 0; i < parameter_.size(); i++) {
42         if (parameter_[i] == nullptr || !parameter_[i]->Encode(pdu)) {
43             TELEPHONY_LOGE("parameter encode error");
44             return false;
45         }
46     }
47     return true;
48 }
49 
Decode(SmsReadBuffer & pdu)50 bool CdmaSmsTeleserviceMessage::Decode(SmsReadBuffer &pdu)
51 {
52     if (pdu.IsEmpty()) {
53         TELEPHONY_LOGE("pdu is empty");
54         return false;
55     }
56     if (parameter_.size() == 0) {
57         TELEPHONY_LOGE("parameter is empty");
58         return false;
59     }
60 
61     for (uint8_t i = 0; i < parameter_.size(); i++) {
62         if (parameter_[i] == nullptr || !parameter_[i]->Decode(pdu)) {
63             TELEPHONY_LOGE("parameter decode error");
64             return false;
65         }
66     }
67     return true;
68 }
69 
GetMessageType(SmsReadBuffer & pdu)70 uint8_t CdmaSmsTeleserviceMessage::GetMessageType(SmsReadBuffer &pdu)
71 {
72     if (pdu.IsEmpty()) {
73         TELEPHONY_LOGE("pdu is empty");
74         return RESERVED;
75     }
76 
77     uint8_t id = CdmaSmsSubParameter::RESERVED;
78     uint8_t type = RESERVED;
79     uint8_t len = 0;
80     while (pdu.ReadByte(id)) {
81         if (id == CdmaSmsSubParameter::MESSAGE_IDENTIFIER) {
82             SmsTeleSvcMsgId msgId;
83             CdmaSmsMessageId messageId(msgId, type);
84             pdu.MoveBack();
85             if (messageId.Decode(pdu)) {
86                 type = messageId.GetMessageType();
87             }
88             return type;
89         }
90         if (!pdu.ReadByte(len)) {
91             TELEPHONY_LOGE("len read error");
92             return type;
93         }
94         pdu.MoveForward(len);
95     }
96     return type;
97 }
98 
CdmaSmsSubmitMessage(TeleserviceSubmit & msg)99 CdmaSmsSubmitMessage::CdmaSmsSubmitMessage(TeleserviceSubmit &msg)
100 {
101     type_ = SUBMIT;
102     // Message Identifier
103     parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
104     // User Data
105     parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
106     // Deferred Delivery Time
107     if (msg.deferValPeriod.format == SMS_TIME_RELATIVE) {
108         parameter_.push_back(std::make_unique<CdmaSmsBaseParameter>(
109             CdmaSmsSubParameter::DEFERRED_DELIVERY_TIME_RELATIVE, msg.deferValPeriod.time.relTime.time));
110     } else if (msg.deferValPeriod.format == SMS_TIME_ABSOLUTE) {
111         parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(
112             CdmaSmsSubParameter::DEFERRED_DELIVERY_TIME_ABSOLUTE, msg.deferValPeriod.time.absTime));
113     }
114     // Priority Indicator
115     if (msg.priority <= SmsPriorityIndicator::EMERGENCY) {
116         parameter_.push_back(std::make_unique<CdmaSmsPriorityInd>(msg.priority));
117     }
118     // Reply Option
119     if (msg.replyOpt.userAck || msg.replyOpt.dak || msg.replyOpt.readAck || msg.replyOpt.report) {
120         parameter_.push_back(std::make_unique<CdmaSmsReplyOption>(msg.replyOpt));
121     }
122     // Call-Back Number
123     if (msg.callbackNumber.addrLen > 0) {
124         parameter_.push_back(std::make_unique<CdmaSmsCallbackNumber>(msg.callbackNumber));
125     }
126 }
127 
CdmaSmsSubmitMessage(TeleserviceSubmit & msg,SmsReadBuffer & pdu)128 CdmaSmsSubmitMessage::CdmaSmsSubmitMessage(TeleserviceSubmit &msg, SmsReadBuffer &pdu)
129 {
130     if (pdu.IsEmpty()) {
131         TELEPHONY_LOGE("pdu is empty");
132         return;
133     }
134 
135     type_ = SUBMIT;
136     msg.priority = SmsPriorityIndicator::RESERVED;
137     uint8_t id = 0;
138     uint8_t len = 0;
139     while ((parameter_.size() < SUB_PARAMETER_SIZE_MAX) && pdu.ReadByte(id) && pdu.ReadByte(len)) {
140         if (id == CdmaSmsSubParameter::MESSAGE_IDENTIFIER) {
141             parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
142         } else if (id == CdmaSmsSubParameter::USER_DATA) {
143             parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
144         } else if (id == CdmaSmsSubParameter::VALIDITY_PERIOD_ABSOLUTE) {
145             msg.valPeriod.format = SMS_TIME_ABSOLUTE;
146             parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.valPeriod.time.absTime));
147         } else if (id == CdmaSmsSubParameter::VALIDITY_PERIOD_RELATIVE) {
148             msg.valPeriod.format = SMS_TIME_RELATIVE;
149             parameter_.push_back(std::make_unique<CdmaSmsBaseParameter>(id, msg.valPeriod.time.relTime.time));
150         } else if (id == CdmaSmsSubParameter::DEFERRED_DELIVERY_TIME_ABSOLUTE) {
151             msg.deferValPeriod.format = SMS_TIME_ABSOLUTE;
152             parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.deferValPeriod.time.absTime));
153         } else if (id == CdmaSmsSubParameter::DEFERRED_DELIVERY_TIME_RELATIVE) {
154             msg.deferValPeriod.format = SMS_TIME_RELATIVE;
155             parameter_.push_back(std::make_unique<CdmaSmsBaseParameter>(id, msg.deferValPeriod.time.relTime.time));
156         } else if (id == CdmaSmsSubParameter::PRIORITY_INDICATOR) {
157             parameter_.push_back(std::make_unique<CdmaSmsPriorityInd>(msg.priority));
158         } else if (id == CdmaSmsSubParameter::PRIVACY_INDICATOR) {
159             parameter_.push_back(std::make_unique<CdmaSmsPrivacyInd>(msg.privacy));
160         } else if (id == CdmaSmsSubParameter::REPLY_OPTION) {
161             parameter_.push_back(std::make_unique<CdmaSmsReplyOption>(msg.replyOpt));
162         } else if (id == CdmaSmsSubParameter::ALERT_ON_MSG_DELIVERY) {
163             parameter_.push_back(std::make_unique<CdmaSmsAlertPriority>(msg.alertPriority));
164         } else if (id == CdmaSmsSubParameter::LANGUAGE_INDICATOR) {
165             parameter_.push_back(std::make_unique<CdmaSmsLanguageInd>(msg.language));
166         } else if (id == CdmaSmsSubParameter::CALLBACK_NUMBER) {
167             parameter_.push_back(std::make_unique<CdmaSmsCallbackNumber>(msg.callbackNumber));
168         } else if (id == CdmaSmsSubParameter::MESSAGE_DEPOSIT_INDEX) {
169             parameter_.push_back(std::make_unique<CdmaSmsDepositIndex>(msg.depositId));
170         } else {
171             TELEPHONY_LOGW("sub parameter [%{public}d] not support", id);
172             parameter_.push_back(std::make_unique<CdmaSmsReservedParameter>(id));
173         }
174         pdu.MoveForward(len);
175     }
176 }
177 
CdmaSmsCancelMessage(TeleserviceCancel & msg)178 CdmaSmsCancelMessage::CdmaSmsCancelMessage(TeleserviceCancel &msg)
179 {
180     type_ = CANCELLATION;
181     // Message Identifier
182     parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
183 }
184 
CdmaSmsDeliverReport(TeleserviceDeliverReport & msg)185 CdmaSmsDeliverReport::CdmaSmsDeliverReport(TeleserviceDeliverReport &msg)
186 {
187     type_ = DELIVER_REPORT;
188     // Message Identifier
189     parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
190     // TP-Failure Cause
191     if (msg.tpFailCause >= 0x80) {
192         parameter_.push_back(
193             std::make_unique<CdmaSmsBaseParameter>(CdmaSmsSubParameter::TP_FAILURE_CAUSE, msg.tpFailCause));
194     }
195     // User Data
196     parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
197 }
198 
CdmaSmsDeliverMessage(TeleserviceDeliver & msg,SmsReadBuffer & pdu,bool isCMAS)199 CdmaSmsDeliverMessage::CdmaSmsDeliverMessage(TeleserviceDeliver &msg, SmsReadBuffer &pdu, bool isCMAS)
200 {
201     if (pdu.IsEmpty()) {
202         TELEPHONY_LOGE("pdu is empty");
203         return;
204     }
205     type_ = DELIVER;
206     uint8_t id = 0;
207     uint8_t len = 0;
208     while ((parameter_.size() < SUB_PARAMETER_SIZE_MAX) && pdu.ReadByte(id) && pdu.ReadByte(len)) {
209         if (isCMAS && id == CdmaSmsSubParameter::USER_DATA) {
210             parameter_.push_back(std::make_unique<CdmaSmsCmasData>(msg.cmasData));
211         } else {
212             PushParameter(id, msg);
213         }
214         pdu.MoveForward(len);
215     }
216 }
217 
PushParameter(uint8_t id,TeleserviceDeliver & msg)218 void CdmaSmsDeliverMessage::PushParameter(uint8_t id, TeleserviceDeliver &msg)
219 {
220     if (id == CdmaSmsSubParameter::MESSAGE_IDENTIFIER) {
221         parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
222     } else if (id == CdmaSmsSubParameter::USER_DATA) {
223         parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
224     } else if (id == CdmaSmsSubParameter::MESSAGE_CENTER_TIME_STAMP) {
225         parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.timeStamp));
226     } else if (id == CdmaSmsSubParameter::VALIDITY_PERIOD_ABSOLUTE) {
227         msg.valPeriod.format = SMS_TIME_ABSOLUTE;
228         parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.valPeriod.time.absTime));
229     } else if (id == CdmaSmsSubParameter::VALIDITY_PERIOD_RELATIVE) {
230         msg.valPeriod.format = SMS_TIME_RELATIVE;
231         parameter_.push_back(std::make_unique<CdmaSmsBaseParameter>(id, msg.valPeriod.time.relTime.time));
232     } else if (id == CdmaSmsSubParameter::PRIORITY_INDICATOR) {
233         parameter_.push_back(std::make_unique<CdmaSmsPriorityInd>(msg.priority));
234     } else if (id == CdmaSmsSubParameter::PRIVACY_INDICATOR) {
235         parameter_.push_back(std::make_unique<CdmaSmsPrivacyInd>(msg.privacy));
236     } else if (id == CdmaSmsSubParameter::REPLY_OPTION) {
237         parameter_.push_back(std::make_unique<CdmaSmsReplyOption>(msg.replyOpt));
238     } else if (id == CdmaSmsSubParameter::NUMBER_OF_MESSAGES) {
239         parameter_.push_back(std::make_unique<CdmaSmsNumberMessages>(msg.numMsg));
240     } else if (id == CdmaSmsSubParameter::ALERT_ON_MSG_DELIVERY) {
241         parameter_.push_back(std::make_unique<CdmaSmsAlertPriority>(msg.alertPriority));
242     } else if (id == CdmaSmsSubParameter::LANGUAGE_INDICATOR) {
243         parameter_.push_back(std::make_unique<CdmaSmsLanguageInd>(msg.language));
244     } else if (id == CdmaSmsSubParameter::CALLBACK_NUMBER) {
245         parameter_.push_back(std::make_unique<CdmaSmsCallbackNumber>(msg.callbackNumber));
246     } else if (id == CdmaSmsSubParameter::MESSAGE_DISPLAY_MODE) {
247         parameter_.push_back(std::make_unique<CdmaSmsDisplayMode>(msg.displayMode));
248     } else if (id == CdmaSmsSubParameter::MESSAGE_DEPOSIT_INDEX) {
249         parameter_.push_back(std::make_unique<CdmaSmsDepositIndex>(msg.depositId));
250     } else if (id == CdmaSmsSubParameter::ENHANCED_VMN) {
251         parameter_.push_back(std::make_unique<CdmaSmsEnhancedVmn>(msg.vmn));
252     } else if (id == CdmaSmsSubParameter::ENHANCED_VMN_ACK) {
253         parameter_.push_back(std::make_unique<CdmaSmsEnhancedVmnAck>(msg.vmnAck));
254     } else {
255         parameter_.push_back(std::make_unique<CdmaSmsReservedParameter>(id));
256     }
257 }
258 
CdmaSmsDeliveryAck(TeleserviceDeliverAck & msg,SmsReadBuffer & pdu)259 CdmaSmsDeliveryAck::CdmaSmsDeliveryAck(TeleserviceDeliverAck &msg, SmsReadBuffer &pdu)
260 {
261     if (pdu.IsEmpty()) {
262         TELEPHONY_LOGE("pdu is empty");
263         return;
264     }
265 
266     type_ = DELIVERY_ACK;
267     uint8_t id = 0;
268     uint8_t len = 0;
269     while ((parameter_.size() < SUB_PARAMETER_SIZE_MAX) && pdu.ReadByte(id) && pdu.ReadByte(len)) {
270         if (id == CdmaSmsSubParameter::MESSAGE_IDENTIFIER) {
271             parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
272         } else if (id == CdmaSmsSubParameter::USER_DATA) {
273             parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
274         } else if (id == CdmaSmsSubParameter::MESSAGE_CENTER_TIME_STAMP) {
275             parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.timeStamp));
276         } else if (id == CdmaSmsSubParameter::MESSAGE_STATUS) {
277             parameter_.push_back(std::make_unique<CdmaSmsMessageStatus>(msg.msgStatus));
278         } else {
279             TELEPHONY_LOGW("sub parameter [%{public}d] not support", id);
280             parameter_.push_back(std::make_unique<CdmaSmsReservedParameter>(id));
281         }
282         pdu.MoveForward(len);
283     }
284 }
285 
CdmaSmsUserAck(TeleserviceUserAck & msg,SmsReadBuffer & pdu)286 CdmaSmsUserAck::CdmaSmsUserAck(TeleserviceUserAck &msg, SmsReadBuffer &pdu)
287 {
288     if (pdu.IsEmpty()) {
289         TELEPHONY_LOGE("pdu is empty");
290         return;
291     }
292 
293     type_ = USER_ACK;
294     uint8_t id = 0;
295     uint8_t len = 0;
296     while ((parameter_.size() < SUB_PARAMETER_SIZE_MAX) && pdu.ReadByte(id) && pdu.ReadByte(len)) {
297         if (id == CdmaSmsSubParameter::MESSAGE_IDENTIFIER) {
298             parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
299         } else if (id == CdmaSmsSubParameter::USER_DATA) {
300             parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
301         } else if (id == CdmaSmsSubParameter::USER_RESPONSE_CODE) {
302             parameter_.push_back(std::make_unique<CdmaSmsBaseParameter>(id, msg.respCode));
303         } else if (id == CdmaSmsSubParameter::MESSAGE_CENTER_TIME_STAMP) {
304             parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.timeStamp));
305         } else if (id == CdmaSmsSubParameter::MESSAGE_DEPOSIT_INDEX) {
306             parameter_.push_back(std::make_unique<CdmaSmsDepositIndex>(msg.depositId));
307         } else {
308             TELEPHONY_LOGW("sub parameter [%{public}d] not support", id);
309             parameter_.push_back(std::make_unique<CdmaSmsReservedParameter>(id));
310         }
311         pdu.MoveForward(len);
312     }
313 }
314 
CdmaSmsReadAck(TeleserviceReadAck & msg,SmsReadBuffer & pdu)315 CdmaSmsReadAck::CdmaSmsReadAck(TeleserviceReadAck &msg, SmsReadBuffer &pdu)
316 {
317     if (pdu.IsEmpty()) {
318         TELEPHONY_LOGE("pdu is empty");
319         return;
320     }
321 
322     type_ = READ_ACK;
323     uint8_t id = 0;
324     uint8_t len = 0;
325     while ((parameter_.size() < SUB_PARAMETER_SIZE_MAX) && pdu.ReadByte(id) && pdu.ReadByte(len)) {
326         if (id == CdmaSmsSubParameter::MESSAGE_IDENTIFIER) {
327             parameter_.push_back(std::make_unique<CdmaSmsMessageId>(msg.msgId, type_));
328         } else if (id == CdmaSmsSubParameter::USER_DATA) {
329             parameter_.push_back(std::make_unique<CdmaSmsUserData>(msg.userData, msg.msgId.headerInd));
330         } else if (id == CdmaSmsSubParameter::MESSAGE_CENTER_TIME_STAMP) {
331             parameter_.push_back(std::make_unique<CdmaSmsAbsoluteTime>(id, msg.timeStamp));
332         } else if (id == CdmaSmsSubParameter::MESSAGE_DEPOSIT_INDEX) {
333             parameter_.push_back(std::make_unique<CdmaSmsDepositIndex>(msg.depositId));
334         } else {
335             TELEPHONY_LOGW("Sub Parameter ID[%{public}d] not support", id);
336             parameter_.push_back(std::make_unique<CdmaSmsReservedParameter>(id));
337         }
338         pdu.MoveForward(len);
339     }
340 }
341 
342 } // namespace Telephony
343 } // namespace OHOS
344