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
21 namespace OHOS {
22 namespace Telephony {
23 static constexpr uint16_t PDU_BUFFER_MAX_SIZE = 0xFF;
24 static constexpr uint16_t PDU_BUFFER_MIN_SIZE = 2;
25
~SmsPduBuffer()26 SmsPduBuffer::~SmsPduBuffer()
27 {
28 if (data_ != nullptr) {
29 data_.reset();
30 }
31 }
32
IsEmpty()33 bool SmsPduBuffer::IsEmpty()
34 {
35 return data_ == nullptr;
36 }
37
GetIndex()38 uint16_t SmsPduBuffer::GetIndex()
39 {
40 return index_;
41 }
42
GetSize()43 uint16_t SmsPduBuffer::GetSize()
44 {
45 return length_;
46 }
47
SetIndex(uint16_t index)48 bool 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
MoveForward(uint16_t len)63 uint16_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
MoveBack(uint16_t len)79 uint16_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
SkipBits()95 uint16_t SmsPduBuffer::SkipBits()
96 {
97 if (bitIndex_ > BIT0) {
98 index_++;
99 bitIndex_ = BIT0;
100 }
101 return index_;
102 }
103
GetPduBuffer()104 std::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
SmsReadBuffer(const std::string & hex)129 SmsReadBuffer::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
ReadByte(uint8_t & v)157 bool 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
PickOneByte(uint8_t & v)176 bool 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
PickOneByteFromIndex(uint16_t index,uint8_t & v)186 bool 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
ReadWord(uint16_t & v)196 bool 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
ReadBits(uint8_t & v,uint8_t l)207 bool 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
SmsWriteBuffer()242 SmsWriteBuffer::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
WriteByte(uint8_t v)253 bool 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
WriteWord(uint16_t v)266 bool 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
WriteBits(uint8_t v,uint8_t l)277 bool 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
InsertByte(uint8_t v,uint16_t index)311 bool 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
GetTopValue(uint8_t & oneByte)321 bool 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
GetValueFromIndex(uint16_t index,uint8_t & v)331 bool 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