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 "sms_pdu_buffer.h" 17 18#include "securec.h" 19#include "telephony_log_wrapper.h" 20 21namespace OHOS { 22namespace Telephony { 23static constexpr uint16_t PDU_BUFFER_MAX_SIZE = 0xFF; 24static constexpr uint16_t PDU_BUFFER_MIN_SIZE = 2; 25 26SmsPduBuffer::~SmsPduBuffer() 27{ 28 if (data_ != nullptr) { 29 data_.reset(); 30 } 31} 32 33bool SmsPduBuffer::IsEmpty() 34{ 35 return data_ == nullptr; 36} 37 38uint16_t SmsPduBuffer::GetIndex() 39{ 40 return index_; 41} 42 43uint16_t SmsPduBuffer::GetSize() 44{ 45 return length_; 46} 47 48bool SmsPduBuffer::SetIndex(uint16_t index) 49{ 50 if (bitIndex_ != BIT0) { 51 TELEPHONY_LOGE("buffer in bit mode"); 52 return false; 53 } 54 if (index > length_) { 55 TELEPHONY_LOGE("index over buffer"); 56 return false; 57 } 58 59 index_ = index; 60 return true; 61} 62 63uint16_t SmsPduBuffer::MoveForward(uint16_t len) 64{ 65 if (bitIndex_ != BIT0) { 66 TELEPHONY_LOGE("buffer in bit mode"); 67 return index_; 68 } 69 if (index_ + len > length_) { 70 TELEPHONY_LOGE("move over buffer"); 71 return index_; 72 } 73 74 uint16_t pos = index_; 75 index_ += len; 76 return pos; 77} 78 79uint16_t SmsPduBuffer::MoveBack(uint16_t len) 80{ 81 if (bitIndex_ != BIT0) { 82 TELEPHONY_LOGE("buffer in bit mode"); 83 return index_; 84 } 85 if (index_ < len) { 86 TELEPHONY_LOGE("back over buffer"); 87 return index_; 88 } 89 90 uint16_t pos = index_; 91 index_ -= len; 92 return pos; 93} 94 95uint16_t SmsPduBuffer::SkipBits() 96{ 97 if (bitIndex_ > BIT0) { 98 index_++; 99 bitIndex_ = BIT0; 100 } 101 return index_; 102} 103 104std::unique_ptr<std::vector<uint8_t>> SmsPduBuffer::GetPduBuffer() 105{ 106 if (data_ == nullptr || index_ == 0) { 107 TELEPHONY_LOGE("data is null"); 108 return nullptr; 109 } 110 if (bitIndex_ != BIT0) { 111 TELEPHONY_LOGE("buffer in bit mode"); 112 return nullptr; 113 } 114 115 if (index_ >= length_) { 116 TELEPHONY_LOGE("data error."); 117 return nullptr; 118 } 119 120 std::unique_ptr<std::vector<uint8_t>> data = 121 std::make_unique<std::vector<uint8_t>>(data_.get(), data_.get() + index_); 122 if (data == nullptr) { 123 TELEPHONY_LOGE("make unique error"); 124 return nullptr; 125 } 126 return data; 127} 128 129SmsReadBuffer::SmsReadBuffer(const std::string &hex) 130{ 131 size_t len = hex.length(); 132 if (len < PDU_BUFFER_MIN_SIZE || len > PDU_BUFFER_MAX_SIZE + 1) { 133 TELEPHONY_LOGE("invalid PDU"); 134 return; 135 } 136 137 data_ = std::make_unique<uint8_t[]>(len); 138 if (data_ == nullptr) { 139 TELEPHONY_LOGE("make_unique error"); 140 return; 141 } 142 if (memset_s(data_.get(), len, 0x00, len) != EOK) { 143 TELEPHONY_LOGE("memset_s error"); 144 data_.reset(); 145 data_ = nullptr; 146 return; 147 } 148 if (memcpy_s(data_.get(), len, hex.c_str(), len) != EOK) { 149 TELEPHONY_LOGE("memcpy_s error"); 150 data_.reset(); 151 data_ = nullptr; 152 return; 153 } 154 length_ = len; 155} 156 157bool SmsReadBuffer::ReadByte(uint8_t &v) 158{ 159 if (data_ == nullptr) { 160 TELEPHONY_LOGE("data is null"); 161 return false; 162 } 163 if (bitIndex_ != BIT0) { 164 return ReadBits(v, BIT8); 165 } 166 167 if (index_ == length_) { 168 TELEPHONY_LOGW("read over buffer"); 169 return false; 170 } 171 172 v = data_[index_++]; 173 return true; 174} 175 176bool SmsReadBuffer::PickOneByte(uint8_t &v) 177{ 178 if (data_ == nullptr || index_ >= length_) { 179 TELEPHONY_LOGE("peek one byte fail."); 180 return false; 181 } 182 v = data_[index_]; 183 return true; 184} 185 186bool SmsReadBuffer::PickOneByteFromIndex(uint16_t index, uint8_t &v) 187{ 188 if (data_ == nullptr || length_ == 0 || index >= length_) { 189 TELEPHONY_LOGE("peek index byte fail."); 190 return false; 191 } 192 v = data_[index]; 193 return true; 194} 195 196bool SmsReadBuffer::ReadWord(uint16_t &v) 197{ 198 if (data_ != nullptr && index_ < (length_ - 1) && bitIndex_ == BIT0) { 199 v = data_[index_++]; 200 v = (v << BIT8) | data_[index_++]; 201 return true; 202 } 203 TELEPHONY_LOGE("read word error"); 204 return false; 205} 206 207bool SmsReadBuffer::ReadBits(uint8_t &v, uint8_t l) 208{ 209 if (data_ == nullptr) { 210 TELEPHONY_LOGE("data is null"); 211 return false; 212 } 213 if (l == BIT0 || l > BIT8) { 214 TELEPHONY_LOGE("read bits : invalid length"); 215 return false; 216 } 217 218 if (bitIndex_ + l <= BIT8) { 219 if (index_ == length_) { 220 TELEPHONY_LOGE("read bits over buffer"); 221 return false; 222 } 223 v = data_[index_] << bitIndex_; 224 v = v >> (BIT8 - l); 225 bitIndex_ += l; 226 if (bitIndex_ == BIT8) { 227 bitIndex_ = BIT0; 228 index_++; 229 } 230 } else { 231 if (index_ == length_ - 1) { 232 TELEPHONY_LOGE("read bits over buffer"); 233 return false; 234 } 235 v = data_[index_++] << bitIndex_; 236 bitIndex_ = l + bitIndex_ - BIT8; 237 v = (v >> (BIT8 - l)) | (data_[index_] >> (BIT8 - bitIndex_)); 238 } 239 return true; 240} 241 242SmsWriteBuffer::SmsWriteBuffer() 243{ 244 length_ = PDU_BUFFER_MAX_SIZE + 1; 245 data_ = std::make_unique<uint8_t[]>(length_); 246 if (data_ == nullptr) { 247 TELEPHONY_LOGE("make_unique create data error"); 248 length_ = 0; 249 return; 250 } 251} 252 253bool SmsWriteBuffer::WriteByte(uint8_t v) 254{ 255 if (bitIndex_ != BIT0) { 256 return WriteBits(v, BIT8); 257 } 258 if (data_ != nullptr && index_ < length_) { 259 data_[index_++] = v; 260 return true; 261 } 262 TELEPHONY_LOGE("write byte error"); 263 return false; 264} 265 266bool SmsWriteBuffer::WriteWord(uint16_t v) 267{ 268 if (data_ != nullptr && index_ < (length_ - 1) && bitIndex_ == BIT0) { 269 data_[index_++] = (0xff00 & v) >> BIT8; 270 data_[index_++] = (0x00ff & v); 271 return true; 272 } 273 TELEPHONY_LOGE("write word error"); 274 return false; 275} 276 277bool SmsWriteBuffer::WriteBits(uint8_t v, uint8_t l) 278{ 279 if (data_ == nullptr) { 280 TELEPHONY_LOGE("data is null"); 281 return false; 282 } 283 if (l == BIT0 || l > BIT8) { 284 TELEPHONY_LOGE("write bits : invalid length"); 285 return false; 286 } 287 288 if (bitIndex_ + l <= BIT8) { 289 if (index_ == length_) { 290 TELEPHONY_LOGE("write bits over buffer[%d]", l); 291 return false; 292 } 293 data_[index_] |= v << (BIT8 - bitIndex_ - l); 294 bitIndex_ += l; 295 if (bitIndex_ == BIT8) { 296 bitIndex_ = BIT0; 297 index_++; 298 } 299 } else { 300 if (index_ == length_ - 1) { 301 TELEPHONY_LOGE("write bits over buffer[%d]", l); 302 return false; 303 } 304 data_[index_++] |= v >> (l + bitIndex_ - BIT8); 305 bitIndex_ = l + bitIndex_ - BIT8; 306 data_[index_] |= v << (BIT8 - bitIndex_); 307 } 308 return true; 309} 310 311bool SmsWriteBuffer::InsertByte(uint8_t v, uint16_t index) 312{ 313 if (data_ != nullptr && index < length_ && bitIndex_ == BIT0) { 314 data_[index] = v; 315 return true; 316 } 317 TELEPHONY_LOGE("insert byte error"); 318 return false; 319} 320 321bool SmsWriteBuffer::GetTopValue(uint8_t &oneByte) 322{ 323 if (data_ == nullptr || length_ == 0 || index_ >= length_) { 324 TELEPHONY_LOGE("buffer error"); 325 return false; 326 } 327 oneByte = data_[index_]; 328 return true; 329} 330 331bool SmsWriteBuffer::GetValueFromIndex(uint16_t index, uint8_t &v) 332{ 333 if (data_ == nullptr || length_ == 0 || index >= length_) { 334 TELEPHONY_LOGE("buffer error"); 335 return false; 336 } 337 v = data_[index]; 338 return true; 339} 340} // namespace Telephony 341} // namespace OHOS 342