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