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 #include "sms_wap_push_content_type.h"
16
17 #include "telephony_log_wrapper.h"
18 #include "sms_wap_push_buffer.h"
19
20 namespace OHOS {
21 namespace Telephony {
22 /**
23 * @brief Construct a new Sms Wap Push Content Type:: Sms Wap Push Content Type
24 * wap-230-wsp-20010705-a
25 * Table 42. Character Set Assignment Examples
26 */
SmsWapPushContentType()27 SmsWapPushContentType::SmsWapPushContentType()
28 {
29 mapCharSet_.emplace("US-ASCII", 0x03);
30 mapCharSet_.emplace("UTF-16", 0x03F7);
31 mapCharSet_.emplace("CSUNICODE", 0x03E8);
32 mapCharSet_.emplace("UTF-8", 0x6A);
33 mapCharSet_.emplace("ISO-2022-KR", 0x25);
34 mapCharSet_.emplace("KS_C_5601-1987", 0x24);
35 mapCharSet_.emplace("EUC-KR", 0x26);
36 mapCharSet_.emplace("ISO-2022-JP", 0x27);
37 mapCharSet_.emplace("ISO-2022-JP-2", 0x28);
38 mapCharSet_.emplace("ISO_8859-1", 0x04);
39 mapCharSet_.emplace("ISO_8859-2", 0x05);
40 mapCharSet_.emplace("ISO-8859-3", 0x06);
41 mapCharSet_.emplace("ISO-8859-4", 0x07);
42 mapCharSet_.emplace("ISO-8859-5", 0x08);
43 mapCharSet_.emplace("ISO-8859-6", 0x09);
44 mapCharSet_.emplace("ISO-8859-7", 0x0A);
45 mapCharSet_.emplace("ISO-8859-8", 0x0B);
46 mapCharSet_.emplace("ISO-8859-9", 0x0C);
47 mapCharSet_.emplace("ISO-8859-10", 0x0D);
48 mapCharSet_.emplace("ISO-8859-15", 0x6F);
49 mapCharSet_.emplace("SHIFT_JIS", 0x11);
50 mapCharSet_.emplace("EUC-JP", 0x13);
51 mapCharSet_.emplace("GB2312", 0x07E9);
52 mapCharSet_.emplace("BIG5", 0x0d);
53 mapCharSet_.emplace("WINDOWS-1251", 0x08CB);
54 mapCharSet_.emplace("KOI8-R", 0x0824);
55 mapCharSet_.emplace("KOI8-U", 0x0828);
56 }
57
58 /**
59 * @brief DecodeContentType
60 * wap-230-wsp-20010705-a section:8.4.2.24 Content type field section:8.4.2.1 Basic rules
61 * Content-type-value = Constrained-media | Content-general-form
62 * Constrained-media = Constrained-encoding
63 * Constrained-encoding = Extension-Media | Short-integer
64 * Extension-media = *TEXT End-of-string
65 * Content-general-form = Value-length Media-type
66 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
67 * Well-known-media = Integer-value
68 * Parameter = Typed-parameter | Untyped-parameter
69 * @param decodeBuffer
70 * @param contentLength
71 * @return true
72 * @return false
73 */
DecodeContentType(SmsWapPushBuffer & decodeBuffer,int32_t & contentLength)74 bool SmsWapPushContentType::DecodeContentType(SmsWapPushBuffer &decodeBuffer, int32_t &contentLength)
75 {
76 const uint8_t setHighestBitZero = 0x7f;
77
78 if (decodeBuffer.DecodeIsShortInt()) {
79 uint8_t oneByte = 0;
80 if (!decodeBuffer.GetOneByte(oneByte)) {
81 TELEPHONY_LOGE("Wap push decode contentType GetOneByte fail.");
82 return false;
83 }
84 contentType_ = GetContentTypeFromInt(oneByte & setHighestBitZero);
85 contentLength = 1;
86 return true;
87 }
88
89 if (decodeBuffer.DecodeIsString()) {
90 std::string sType = "";
91 uint32_t len = 0;
92 decodeBuffer.DecodeText(sType, len);
93 contentLength = static_cast<int32_t>(len + 1);
94 contentType_ = sType;
95 return true; // 2
96 }
97
98 if (!DecodeCTGeneralForm(decodeBuffer, contentLength)) {
99 TELEPHONY_LOGE("Decode contentType DecodeMmsCTGeneralForm fail.");
100 return false;
101 }
102 return true;
103 }
104
105 /**
106 * @brief DecodeCTGeneralForm
107 * wap-230-wsp-20010705-a section:8.4.2.24 Content type field section:8.4.2.1 Basic rules
108 * Content-type-value = Constrained-media | Content-general-form
109 * Constrained-media = Constrained-encoding
110 * Constrained-encoding = Extension-Media | Short-integer
111 * Extension-media = *TEXT End-of-string
112 * Content-general-form = Value-length Media-type
113 * Media-type = (Well-known-media | Extension-Media) *(Parameter)
114 * Well-known-media = Integer-value
115 * Parameter = Typed-parameter | Untyped-parameter
116 * @param decodeBuffer
117 * @param contentLength
118 * @return true
119 * @return false
120 */
DecodeCTGeneralForm(SmsWapPushBuffer & decodeBuffer,int32_t & contentLength)121 bool SmsWapPushContentType::DecodeCTGeneralForm(SmsWapPushBuffer &decodeBuffer, int32_t &contentLength)
122 {
123 const uint8_t setHighestBitZero = 0x7f;
124
125 /** false indicated no more data */
126 if (!decodeBuffer.DecodeIsValueLength()) {
127 TELEPHONY_LOGE("Wap push decode contentType DecodeIsValueLength fail.");
128 return false;
129 }
130
131 uint32_t valueLength = 0;
132 uint32_t returnLength = 0;
133 if (!decodeBuffer.DecodeValueLengthReturnLen(valueLength, returnLength)) {
134 TELEPHONY_LOGE("Wap push decode contentType DecodeValueLengthReturnLen fail.");
135 return false;
136 }
137 contentLength = static_cast<int32_t>(valueLength + returnLength);
138
139 uint8_t oneByte = 0;
140 if (!decodeBuffer.PeekOneByte(oneByte)) {
141 TELEPHONY_LOGE("Wap push decode contentType PeekOneByte fail.");
142 return false;
143 }
144 if (decodeBuffer.DecodeIsShortInt()) {
145 contentType_ = GetContentTypeFromInt(oneByte & setHighestBitZero);
146 if (!decodeBuffer.IncreasePointer(1)) {
147 TELEPHONY_LOGE("Wap push decode contentType IncreasePointer fail.");
148 return false;
149 }
150 if (valueLength == 0) {
151 TELEPHONY_LOGI("Wap push decode contentType empty.");
152 return false;
153 }
154 valueLength--;
155 } else if (decodeBuffer.DecodeIsString()) {
156 std::string sType = "";
157 uint32_t len = 0;
158 decodeBuffer.DecodeText(sType, len);
159 valueLength -= len + 1;
160 contentType_ = sType;
161 } else {
162 TELEPHONY_LOGI("Wap push decode contentType empty.");
163 return false;
164 }
165
166 if (!DecodeParameter(decodeBuffer, valueLength)) {
167 TELEPHONY_LOGE("Wap push decode contentType DecodeParameter fail.");
168 return false;
169 }
170 return true;
171 }
172
173 /**
174 * @brief DecodeParameter
175 * wap-230-wsp-20010705-a section:8.4.2.4 Parameter
176 * Parameter = Typed-parameter | Untyped-parameter
177 * Typed-parameter = Well-known-parameter-token Typed-value
178 * Well-known-parameter-token = Integer-value
179 * Typed-value = Compact-value | Text-value
180 * Compact-value = Integer-value |
181 * Date-value | Delta-seconds-value | Q-value | Version-value |
182 * Uri-value
183 * Untyped-parameter = Token-text Untyped-value
184 * Untyped-value = Integer-value | Text-value
185 * Delta-seconds-value = Long-integer
186 * Q-value = 1*2 OCTET
187 * @param decodeBuffer
188 * @param valueLength
189 * @return true
190 * @return false
191 */
DecodeParameter(SmsWapPushBuffer & decodeBuffer,int32_t valueLength)192 bool SmsWapPushContentType::DecodeParameter(SmsWapPushBuffer &decodeBuffer, int32_t valueLength)
193 {
194 while (valueLength > 0) {
195 uint8_t oneByte = 0;
196 if (!decodeBuffer.GetOneByte(oneByte)) {
197 TELEPHONY_LOGE("Wap push DecodeParameter GetOneByte fail.");
198 return false;
199 }
200 uint8_t paramCode = oneByte;
201 valueLength--;
202 switch (static_cast<WapContentParam>(paramCode)) {
203 case WapContentParam::CT_P_CHARSET: {
204 if (!DecodeCharsetField(decodeBuffer, valueLength)) {
205 TELEPHONY_LOGE("Wap push DecodeParameter DecodeCharsetField fail.");
206 return false;
207 }
208 break;
209 }
210 case WapContentParam::CT_P_FILENAME:
211 case WapContentParam::CT_P_FILENAME_VALUE:
212 case WapContentParam::CT_P_START_VALUE:
213 case WapContentParam::CT_P_START:
214 case WapContentParam::CT_P_NAME:
215 case WapContentParam::CT_P_NAME_VALUE:
216 case WapContentParam::CT_P_START_INFO:
217 case WapContentParam::CT_P_START_INFO_VALUE: {
218 if (!DecodeTextField(decodeBuffer, paramCode, valueLength)) {
219 TELEPHONY_LOGE("Wap push DecodeParameter DecodeTextField fail.");
220 return false;
221 }
222 break;
223 }
224 case WapContentParam::CT_P_TYPE:
225 case WapContentParam::CT_P_TYPE_STRING: {
226 if (!DecodeTypeField(decodeBuffer, valueLength)) {
227 TELEPHONY_LOGE("Wap push DecodeParameter DecodeTypeField fail.");
228 return false;
229 }
230 break;
231 }
232 default: {
233 if (!decodeBuffer.IncreasePointer(valueLength)) {
234 TELEPHONY_LOGE("Wap push DecodeParameter IncreasePointer fail.");
235 return false;
236 }
237 valueLength = 0;
238 }
239 }
240 }
241 return true;
242 }
243
GetContentType()244 std::string SmsWapPushContentType::GetContentType()
245 {
246 return contentType_;
247 }
248
SetContentType(std::string str)249 bool SmsWapPushContentType::SetContentType(std::string str)
250 {
251 contentType_ = str;
252 return true;
253 }
254
255 /**
256 * @brief DecodeTextField
257 * wap-230-wsp-20010705-a section:8.4.2.1 Basic rules
258 * Text-string = [Quote] *TEXT End-of-string
259 * Quote = <Octet 127>
260 * End-of-string = <Octet 0>
261 * @param decodeBuffer
262 * @param field
263 * @param valueLength
264 * @return true
265 * @return false
266 */
DecodeTextField(SmsWapPushBuffer & decodeBuffer,uint8_t field,int32_t & valueLength)267 bool SmsWapPushContentType::DecodeTextField(SmsWapPushBuffer &decodeBuffer, uint8_t field, int32_t &valueLength)
268 {
269 std::string str = "";
270 uint32_t len = 0;
271 if (!decodeBuffer.DecodeText(str, len)) {
272 TELEPHONY_LOGE("Wap push DecodeTextField DecodeText fail.");
273 return false;
274 }
275 textParameterMap_.insert(std::make_pair(field, str));
276 valueLength -= static_cast<int32_t>(len);
277 valueLength -= 1;
278 return true;
279 }
280
281 /**
282 * @brief DecodeCharsetField
283 * wap-230-wsp-20010705-a section:8.4.2.8 Accept charset field
284 * Well-known-charset = Any-charset | Integer-value
285 * Any-charset = <Octet 128>
286 * @param decodeBuffer
287 * @param valueLength
288 * @return true
289 * @return false
290 */
DecodeCharsetField(SmsWapPushBuffer & decodeBuffer,int32_t & valueLength)291 bool SmsWapPushContentType::DecodeCharsetField(SmsWapPushBuffer &decodeBuffer, int32_t &valueLength)
292 {
293 const uint8_t TEXT_MAX = 0x7F;
294 const uint8_t TEXT_MIN = 0x20;
295 int32_t charset = 0;
296 uint8_t oneByte = 0;
297 if (decodeBuffer.PeekOneByte(oneByte) == false) {
298 TELEPHONY_LOGE("Wap push DecodeCharsetField PeekOneByte fail.");
299 return false;
300 }
301 if (((oneByte > TEXT_MIN) && (oneByte < TEXT_MAX)) || (oneByte == 0)) {
302 std::string sCharset = "";
303 uint32_t len = 0;
304
305 if (!decodeBuffer.DecodeText(sCharset, len)) {
306 TELEPHONY_LOGE("Wap push DecodeCharsetField DecodeText fail.");
307 return false;
308 }
309 valueLength -= static_cast<int32_t>(len + 1);
310 uint32_t tmpCharSet = 0;
311 if (!GetCharSetIntFromString(tmpCharSet, sCharset)) {
312 TELEPHONY_LOGE("Wap push DecodeCharsetField GetCharSetIntFromString fail.");
313 return false;
314 }
315 charset = static_cast<int32_t>(tmpCharSet);
316 } else {
317 uint32_t startPosition = decodeBuffer.GetCurPosition();
318 uint64_t temp = 0;
319 if (!decodeBuffer.DecodeInteger(temp)) {
320 TELEPHONY_LOGE("Wap push DecodeCharsetField DecodeInteger fail.");
321 return false;
322 }
323 charset = static_cast<int32_t>(temp);
324 uint32_t endPosition = decodeBuffer.GetCurPosition();
325 if (endPosition >= startPosition) {
326 valueLength -= static_cast<int32_t>(endPosition - startPosition);
327 }
328 }
329 charset_ = static_cast<uint32_t>(charset);
330 return true;
331 }
332
333 /**
334 * @brief DecodeTypeField
335 * wap-230-wsp-20010705-a section:8.4.2.1 Basic rules
336 * Constrained-encoding = Extension-Media | Short-integer
337 * Extension-media = *TEXT End-of-string
338 * @param decodeBuffer
339 * @param valueLength
340 * @return true
341 * @return false
342 */
DecodeTypeField(SmsWapPushBuffer & decodeBuffer,int32_t & valueLength)343 bool SmsWapPushContentType::DecodeTypeField(SmsWapPushBuffer &decodeBuffer, int32_t &valueLength)
344 {
345 const uint8_t TEXT_MAX = 0x7F;
346 uint8_t oneByte = 0;
347 if (decodeBuffer.GetOneByte(oneByte) == false) {
348 TELEPHONY_LOGE("Wap push DecodeTypeField GetOneByte fail.");
349 return false;
350 }
351
352 if (oneByte > TEXT_MAX) {
353 type_ = GetContentTypeFromInt(oneByte & TEXT_MAX);
354 valueLength -= 1;
355 } else {
356 if (!decodeBuffer.DecreasePointer(1)) {
357 TELEPHONY_LOGE("Wap push DecodeTypeField DecreasePointer fail.");
358 return false;
359 }
360 std::string sType = "";
361 uint32_t len = 0;
362 if (!decodeBuffer.DecodeText(sType, len)) {
363 TELEPHONY_LOGE("Wap push DecodeTypeField DecodeText fail.");
364 return false;
365 }
366 valueLength -= static_cast<int32_t>(len);
367 valueLength -= 1;
368 type_ = sType;
369 }
370 return true;
371 }
372
GetCharSetIntFromString(uint32_t & charSet,const std::string & strCharSet)373 bool SmsWapPushContentType::GetCharSetIntFromString(uint32_t &charSet, const std::string &strCharSet)
374 {
375 auto iterMap = mapCharSet_.find(strCharSet);
376 if (iterMap != mapCharSet_.end()) {
377 charSet = iterMap->second;
378 return true;
379 }
380 return false;
381 }
382
GetContentTypeFromInt(uint8_t type)383 std::string SmsWapPushContentType::GetContentTypeFromInt(uint8_t type)
384 {
385 for (unsigned int i = 0; i < sizeof(wapContentNames) / sizeof(wapContentNames[0]); i++) {
386 if (type == static_cast<uint8_t>(wapContentNames[i].key)) {
387 return wapContentNames[i].value;
388 }
389 }
390 return "*/*";
391 }
392 } // namespace Telephony
393 } // namespace OHOS
394