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