• 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 #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     uint8_t oneByte = 0;
195     uint8_t paramCode = 0;
196     while (valueLength > 0) {
197         if (!decodeBuffer.GetOneByte(oneByte)) {
198             TELEPHONY_LOGE("Wap push DecodeParameter GetOneByte fail.");
199             return false;
200         }
201         paramCode = oneByte;
202         valueLength--;
203         switch (static_cast<WapContentParam>(paramCode)) {
204             case WapContentParam::CT_P_CHARSET: {
205                 if (!DecodeCharsetField(decodeBuffer, valueLength)) {
206                     TELEPHONY_LOGE("Wap push DecodeParameter DecodeCharsetField fail.");
207                     return false;
208                 }
209                 break;
210             }
211             case WapContentParam::CT_P_FILENAME:
212             case WapContentParam::CT_P_FILENAME_VALUE:
213             case WapContentParam::CT_P_START_VALUE:
214             case WapContentParam::CT_P_START:
215             case WapContentParam::CT_P_NAME:
216             case WapContentParam::CT_P_NAME_VALUE:
217             case WapContentParam::CT_P_START_INFO:
218             case WapContentParam::CT_P_START_INFO_VALUE: {
219                 if (!DecodeTextField(decodeBuffer, paramCode, valueLength)) {
220                     TELEPHONY_LOGE("Wap push DecodeParameter DecodeTextField fail.");
221                     return false;
222                 }
223                 break;
224             }
225             case WapContentParam::CT_P_TYPE:
226             case WapContentParam::CT_P_TYPE_STRING: {
227                 if (!DecodeTypeField(decodeBuffer, valueLength)) {
228                     TELEPHONY_LOGE("Wap push DecodeParameter DecodeTypeField fail.");
229                     return false;
230                 }
231                 break;
232             }
233             default: {
234                 if (!decodeBuffer.IncreasePointer(valueLength)) {
235                     TELEPHONY_LOGE("Wap push DecodeParameter IncreasePointer fail.");
236                     return false;
237                 }
238                 valueLength = 0;
239             }
240         }
241     }
242     return true;
243 }
244 
GetContentType()245 std::string SmsWapPushContentType::GetContentType()
246 {
247     return contentType_;
248 }
249 
SetContentType(std::string str)250 bool SmsWapPushContentType::SetContentType(std::string str)
251 {
252     contentType_ = str;
253     return true;
254 }
255 
256 /**
257  * @brief DecodeTextField
258  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
259  * Text-string = [Quote] *TEXT End-of-string
260  * Quote = <Octet 127>
261  * End-of-string = <Octet 0>
262  * @param decodeBuffer
263  * @param field
264  * @param valueLength
265  * @return true
266  * @return false
267  */
DecodeTextField(SmsWapPushBuffer & decodeBuffer,uint8_t field,int32_t & valueLength)268 bool SmsWapPushContentType::DecodeTextField(SmsWapPushBuffer &decodeBuffer, uint8_t field, int32_t &valueLength)
269 {
270     std::string str = "";
271     uint32_t len = 0;
272     if (!decodeBuffer.DecodeText(str, len)) {
273         TELEPHONY_LOGE("Wap push DecodeTextField DecodeText fail.");
274         return false;
275     }
276     textParameterMap_.insert(std::make_pair(field, str));
277     valueLength -= static_cast<int32_t>(len);
278     valueLength -= 1;
279     return true;
280 }
281 
282 /**
283  * @brief DecodeCharsetField
284  * wap-230-wsp-20010705-a   section:8.4.2.8 Accept charset field
285  * Well-known-charset = Any-charset | Integer-value
286  * Any-charset = <Octet 128>
287  * @param decodeBuffer
288  * @param valueLength
289  * @return true
290  * @return false
291  */
DecodeCharsetField(SmsWapPushBuffer & decodeBuffer,int32_t & valueLength)292 bool SmsWapPushContentType::DecodeCharsetField(SmsWapPushBuffer &decodeBuffer, int32_t &valueLength)
293 {
294     const uint8_t TEXT_MAX = 0x7F;
295     const uint8_t TEXT_MIN = 0x20;
296     int32_t charset = 0;
297     uint8_t oneByte = 0;
298     if (decodeBuffer.PeekOneByte(oneByte) == false) {
299         TELEPHONY_LOGE("Wap push DecodeCharsetField PeekOneByte fail.");
300         return false;
301     }
302     if (((oneByte > TEXT_MIN) && (oneByte < TEXT_MAX)) || (oneByte == 0)) {
303         std::string sCharset = "";
304         uint32_t len = 0;
305 
306         if (!decodeBuffer.DecodeText(sCharset, len)) {
307             TELEPHONY_LOGE("Wap push DecodeCharsetField DecodeText fail.");
308             return false;
309         }
310         valueLength -= static_cast<int32_t>(len + 1);
311         uint32_t tmpCharSet = 0;
312         if (!GetCharSetIntFromString(tmpCharSet, sCharset)) {
313             TELEPHONY_LOGE("Wap push DecodeCharsetField GetCharSetIntFromString fail.");
314             return false;
315         }
316         charset = static_cast<int32_t>(tmpCharSet);
317     } else {
318         uint32_t startPosition = decodeBuffer.GetCurPosition();
319         uint64_t temp = 0;
320         if (!decodeBuffer.DecodeInteger(temp)) {
321             TELEPHONY_LOGE("Wap push DecodeCharsetField DecodeInteger fail.");
322             return false;
323         }
324         charset = static_cast<int32_t>(temp);
325         uint32_t endPosition = decodeBuffer.GetCurPosition();
326         valueLength -= static_cast<int32_t>(endPosition - startPosition);
327     }
328     charset_ = static_cast<uint32_t>(charset);
329     return true;
330 }
331 
332 /**
333  * @brief DecodeTypeField
334  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
335  * Constrained-encoding = Extension-Media | Short-integer
336  * Extension-media = *TEXT End-of-string
337  * @param decodeBuffer
338  * @param valueLength
339  * @return true
340  * @return false
341  */
DecodeTypeField(SmsWapPushBuffer & decodeBuffer,int32_t & valueLength)342 bool SmsWapPushContentType::DecodeTypeField(SmsWapPushBuffer &decodeBuffer, int32_t &valueLength)
343 {
344     const uint8_t TEXT_MAX = 0x7F;
345     uint8_t oneByte = 0;
346     if (decodeBuffer.GetOneByte(oneByte) == false) {
347         TELEPHONY_LOGE("Wap push DecodeTypeField GetOneByte fail.");
348         return false;
349     }
350 
351     if (oneByte > TEXT_MAX) {
352         type_ = GetContentTypeFromInt(oneByte & TEXT_MAX);
353         valueLength -= 1;
354     } else {
355         if (!decodeBuffer.DecreasePointer(1)) {
356             TELEPHONY_LOGE("Wap push DecodeTypeField DecreasePointer fail.");
357             return false;
358         }
359         std::string sType = "";
360         uint32_t len = 0;
361         if (!decodeBuffer.DecodeText(sType, len)) {
362             TELEPHONY_LOGE("Wap push DecodeTypeField DecodeText fail.");
363             return false;
364         }
365         valueLength -= static_cast<int32_t>(len);
366         valueLength -= 1;
367         type_ = sType;
368     }
369     return true;
370 }
371 
GetCharSetIntFromString(uint32_t & charSet,const std::string & strCharSet)372 bool SmsWapPushContentType::GetCharSetIntFromString(uint32_t &charSet, const std::string &strCharSet)
373 {
374     auto iterMap = mapCharSet_.find(strCharSet);
375     if (iterMap != mapCharSet_.end()) {
376         charSet = iterMap->second;
377         return true;
378     }
379     return false;
380 }
381 
GetContentTypeFromInt(uint8_t type)382 std::string SmsWapPushContentType::GetContentTypeFromInt(uint8_t type)
383 {
384     for (unsigned int i = 0; i < sizeof(wapContentNames) / sizeof(wapContentNames[0]); i++) {
385         if (type == static_cast<uint8_t>(wapContentNames[i].key)) {
386             return wapContentNames[i].value;
387         }
388     }
389     return "*/*";
390 }
391 } // namespace Telephony
392 } // namespace OHOS
393