• 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 
16 #include "mms_encode_buffer.h"
17 
18 #include "mms_decode_buffer.h"
19 #include "securec.h"
20 #include "telephony_log_wrapper.h"
21 
22 namespace OHOS {
23 namespace Telephony {
24 using namespace std;
25 /**
26  * @brief DecodeInteger
27  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
28  * Uintvar-integer = 1*5 OCTET
29  * @param value
30  * @return true
31  * @return false
32  */
EncodeUintvar(uint32_t value)33 bool MmsEncodeBuffer::EncodeUintvar(uint32_t value)
34 {
35     const uint8_t setNotHighestBitZero = 0x80;
36     const uint8_t setHighestBitZero = 0x7f;
37     const uint8_t shiftUintBits = 7;
38     char reversed[8] = {0};
39     int len = 1;
40     reversed[0] = (char)value & setHighestBitZero;
41     value = value >> shiftUintBits;
42     while (value > 0) {
43         reversed[len] = setNotHighestBitZero | (value & setHighestBitZero);
44         len++;
45         value = value >> shiftUintBits;
46     }
47 
48     int j = 0;
49     for (j = 0; j < len; j++) {
50         if (!WriteByte(reversed[len - j - 1])) {
51             TELEPHONY_LOGE("Encode buffer WriteByte fail.");
52             return false;
53         }
54     }
55     return true;
56 }
57 
WriteByte(uint8_t value)58 bool MmsEncodeBuffer::WriteByte(uint8_t value)
59 {
60     if (curPosition_ >= CODE_BUFFER_MAX_SIZE) {
61         TELEPHONY_LOGE("Encode buffer current position invalid.");
62         return false;
63     }
64     pduBuffer_[curPosition_++] = value;
65     return true;
66 }
67 
WriteBuffer(MmsEncodeBuffer & buff)68 bool MmsEncodeBuffer::WriteBuffer(MmsEncodeBuffer &buff)
69 {
70     uint32_t len = buff.GetCurPosition();
71     if (curPosition_ + len >= CODE_BUFFER_MAX_SIZE) {
72         TELEPHONY_LOGE("Encode buffer current position invalid.");
73         return false;
74     }
75     if (memcpy_s(pduBuffer_.get() + curPosition_, len, buff.pduBuffer_.get(), len) != EOK) {
76         TELEPHONY_LOGE("Encode buffer memcpy_s fail.");
77         return false;
78     }
79     curPosition_ += buff.GetCurPosition();
80     return true;
81 }
82 
WriteBuffer(std::unique_ptr<char[]> input,uint32_t length)83 bool MmsEncodeBuffer::WriteBuffer(std::unique_ptr<char[]> input, uint32_t length)
84 {
85     if (input == nullptr) {
86         TELEPHONY_LOGE("Encode buffer input is null.");
87         return false;
88     }
89 
90     if (curPosition_ + length >= CODE_BUFFER_MAX_SIZE) {
91         TELEPHONY_LOGE("Encode buffer current position invalid.");
92         return false;
93     }
94     if (memcpy_s(pduBuffer_.get() + curPosition_, length, input.get(), length) != EOK) {
95         TELEPHONY_LOGE("Encode buffer memcpy_s fail.");
96         return false;
97     }
98     curPosition_ += length;
99     return true;
100 }
101 
102 /**
103  * @brief EncodeShortLength
104  * wap-230-wsp-20010705-a.pdf   section:8.4.2.2 Length
105  * Short-length = <Any octet 0-30>
106  * @param value
107  * @return true
108  * @return false
109  */
EncodeShortLength(uint8_t value)110 bool MmsEncodeBuffer::EncodeShortLength(uint8_t value)
111 {
112     const uint8_t minShortLength = 30;
113     if (value > minShortLength) {
114         TELEPHONY_LOGE("Encode buffer value invalid.");
115         return false;
116     }
117     if (!WriteByte(value)) {
118         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
119         return false;
120     }
121     return true;
122 }
123 
124 /**
125  * @brief EncodeShortInteger
126  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
127  * Short-integer = OCTET
128  * Integers in range 0-127 shall be encoded as a one octet value with
129  * the most significant bit set to one (1xxx xxxx) and with the value
130  * in the remaining least significant bits
131  * @param value
132  * @return true
133  * @return false
134  */
EncodeShortInteger(uint8_t value)135 bool MmsEncodeBuffer::EncodeShortInteger(uint8_t value)
136 {
137     const uint8_t setHighestBitOne = 0x80;
138     if (!WriteByte(value | setHighestBitOne)) {
139         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
140         return false;
141     }
142     return true;
143 }
144 
145 /**
146  * @brief EncodeOctet
147  * wap-230-wsp-20010705-a   section:8.1.2 Variable Length Unsigned Integers
148  * octet 8 bits of opaque data
149  * @param value
150  * @return true
151  * @return false
152  */
EncodeOctet(uint8_t value)153 bool MmsEncodeBuffer::EncodeOctet(uint8_t value)
154 {
155     if (!WriteByte(value)) {
156         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
157         return false;
158     }
159     return true;
160 }
161 
162 /**
163  * @brief EncodeValueLength
164  * wap-230-wsp-20010705-a   section:8.4.2.2 Length
165  * value-length = short-length | (Length-quote Length)
166  * short-length = <Any octet 0-30>
167  * Length-quote = <Octet 31>
168  * (Length-quote Length) = Length-quote + Uintvar-length
169  * @param value
170  * @return true
171  * @return false
172  */
EncodeValueLength(uint32_t value)173 bool MmsEncodeBuffer::EncodeValueLength(uint32_t value)
174 {
175     const uint8_t lengthQuote = 0x1f;
176     const uint32_t maxShortLength = 30;
177 
178     if (value <= maxShortLength) {
179         return EncodeShortLength(value);
180     }
181     if (!WriteByte(lengthQuote)) {
182         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
183         return false;
184     }
185     if (!EncodeUintvar(value)) {
186         TELEPHONY_LOGE("Encode buffer EncodeUintvar fail.");
187         return false;
188     }
189     return true;
190 }
191 
EncodeInteger(uint32_t value)192 bool MmsEncodeBuffer::EncodeInteger(uint32_t value)
193 {
194     const uint32_t maxShortInteger = 127;
195     if (value <= maxShortInteger) {
196         return EncodeShortInteger(value);
197     } else {
198         return EncodeLongInteger(value);
199     }
200     return true;
201 }
202 
203 /**
204  * @brief EncodeLongInteger
205  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
206  * Long-integer = [Short-length] [Multi-octet-integer]
207  * Short-length = 1 byte
208  * Multi-octet-integer = <Short-length> bytes
209  * @param value
210  * @return true
211  * @return false
212  */
EncodeLongInteger(uint64_t value)213 bool MmsEncodeBuffer::EncodeLongInteger(uint64_t value)
214 {
215     const uint64_t getLast8Bit = 0x000000FF;
216     const uint8_t rightMoveBits = 8;
217 
218     uint64_t temp = value;
219     uint8_t count = 0;
220     uint8_t result[8] = {0};
221     while (temp > 0) {
222         result[count] = temp & getLast8Bit;
223         temp = temp >> rightMoveBits;
224         count++;
225     }
226 
227     if (value == 0) {
228         count = 1;
229     }
230     if (!WriteByte(count)) {
231         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
232         return false;
233     }
234 
235     for (int16_t i = static_cast<int16_t>(count) - 1; i >= 0; i--) {
236         if (!WriteByte(result[i])) {
237             TELEPHONY_LOGE("Encode buffer WriteByte fail.");
238             return false;
239         }
240     }
241     return true;
242 }
243 
244 /**
245  * @brief EncodeText
246  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
247  * Text-string = [Quote] *TEXT End-of-string
248  * Quote = <Octet 127>
249  * End-of-string = <Octet 0>
250  * @param value
251  * @return true
252  * @return false
253  */
EncodeText(std::string value)254 bool MmsEncodeBuffer::EncodeText(std::string value)
255 {
256     const uint8_t quoteText = 0x7f;
257     if (value.empty()) {
258         TELEPHONY_LOGI("Encode buffer value is empty string.");
259         return true;
260     }
261 
262     if (value.at(0) > quoteText) {
263         if (!WriteByte(quoteText)) {
264             TELEPHONY_LOGE("Encode buffer WriteByte fail.");
265             return false;
266         }
267     }
268     for (std::size_t i = 0; i < value.length(); i++) {
269         if (!WriteByte(value.at(i))) {
270             TELEPHONY_LOGE("Encode buffer WriteByte fail.");
271             return false;
272         }
273     }
274     if (!WriteByte(0)) {
275         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
276         return false;
277     }
278     return true;
279 }
280 
281 /**
282  * @brief EncodeQuotedText
283  * wap-230-wsp-20010705-a   section:8.4.2.1 Basic rules
284  * Quoted-string = <Octet 34> *TEXT End-of-string
285  * The TEXT encodes an RFC2616 Quoted-string with the enclosing quotation-marks <"> removed
286  * @param value
287  * @return true
288  * @return false
289  */
EncodeQuotedText(std::string value)290 bool MmsEncodeBuffer::EncodeQuotedText(std::string value)
291 {
292     if (value.empty()) {
293         return true;
294     }
295     if (!WriteByte('\"')) {
296         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
297         return false;
298     }
299     for (std::size_t i = 0; i < value.length(); i++) {
300         if (!WriteByte(value.at(i))) {
301             TELEPHONY_LOGE("Encode buffer WriteByte fail.");
302             return false;
303         }
304     }
305     if (!WriteByte(0)) {
306         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
307         return false;
308     }
309     return true;
310 }
311 
312 /**
313  * @brief EncodeTokenText
314  * wap-230-wsp-20010705-a   section:8.4.2.2 Length
315  * Token-text = Token End-of-string
316  * End-of-string = <Octet 0>
317  * @param value
318  * @return true
319  * @return false
320  */
EncodeTokenText(std::string value)321 bool MmsEncodeBuffer::EncodeTokenText(std::string value)
322 {
323     if (value.empty()) {
324         return true;
325     }
326     for (std::size_t i = 0; i < value.length(); i++) {
327         if (!MmsDecodeBuffer::CharIsToken(value.at(i))) {
328             TELEPHONY_LOGE("Encode buffer EncodeTokenText fail.");
329             return false;
330         }
331     }
332     for (std::size_t i = 0; i < value.length(); i++) {
333         if (!WriteByte(value.at(i))) {
334             TELEPHONY_LOGE("Encode buffer WriteByte fail.");
335             return false;
336         }
337     }
338     if (!WriteByte(0)) {
339         TELEPHONY_LOGE("Encode buffer WriteByte fail.");
340         return false;
341     }
342     return true;
343 }
344 } // namespace Telephony
345 } // namespace OHOS
346