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 "obex_headers.h"
17 #include <algorithm>
18 #include <cstring>
19 #include <iostream>
20 #include <sstream>
21 #include <unordered_map>
22 #include "log.h"
23 #include "obex_utils.h"
24 #include "securec.h"
25
26 namespace OHOS {
27 namespace bluetooth {
28 /************************* OBEX ObexHdrType *******************************/
29 const uint8_t ObexHdrType::UNICODE_TEXT;
30 const uint8_t ObexHdrType::BYTES;
31 const uint8_t ObexHdrType::BYTE;
32 const uint8_t ObexHdrType::WORD;
33 const uint8_t ObexHdrType::MASK;
34 /************************* OBEX ObexHdrSrmMode *******************************/
35 const uint8_t ObexHdrSrmMode::NORMAL;
36 const uint8_t ObexHdrSrmMode::SINGLE;
37 /************************* OBEX ObexHdrSrmpMode *******************************/
38 const uint8_t ObexHdrSrmpMode::WAIT;
39
40 const uint8_t ObexHeader::MIN_PACKET_LENGTH;
41 const uint8_t ObexHeader::TARGET_LENGTH;
42 const uint8_t ObexHeader::U16STRING_NULL_LENGTH;
43 const uint8_t ObexHeader::U16STRING_LENGTH;
44 const uint8_t ObexHeader::UINT16_LENGTH;
45 const uint8_t ObexHeader::UINT32_LENGTH;
46 const uint8_t ObexHeader::UINT64_LENGTH;
47 const uint8_t ObexHeader::HDR_UNICODE_PREFIX_LENGTH;
48 const uint8_t ObexHeader::HDR_BYTES_PREFIX_LENGTH;
49
50 const std::unordered_map<uint8_t, std::string> ObexHeader::HEADER_ID_NAME_MAP = {
51 {0x00, "UNKNOWN"},
52 {0xC0, "COUNT"},
53 {0x01, "NAME"},
54 {0x42, "TYPE"},
55 {0xC3, "LENGTH"},
56 {0x44, "TIME_ISO8601"},
57 {0xC4, "TIME_4BYTE_VERSION"},
58 {0x05, "DESCRIPTION"},
59 {0x46, "TARGET"},
60 {0x47, "HTTP"},
61 {0x48, "BODY"},
62 {0x49, "END_OF_BODY"},
63 {0x4A, "WHO"},
64 {0xCB, "CONNECTION_ID"},
65 {0x4C, "APP_PARAMETERS"},
66 {0x4D, "AUTH_CHALLENGE"},
67 {0x4E, "AUTH_RESPONSE"},
68 {0xCF, "CREATOR_ID"},
69 {0x50, "WAN_UUID"},
70 {0x51, "OBJECT_CLASS"},
71 {0x52, "SESSION_PARAMETERS"},
72 {0x93, "SESSION_SEQUENCE_NUMBER"},
73 {0x94, "ACTION_ID"},
74 {0x15, "DEST_NAME"},
75 {0xD6, "PERMISSIONS"},
76 {0x97, "SRM"},
77 {0x98, "SRMP"}
78 };
79
ObexHeader()80 ObexHeader::ObexHeader()
81 : code_(0x00),
82 packetLength_(0x00),
83 obexVersionNum_(nullptr),
84 flags_(nullptr),
85 maxPacketLength_(nullptr),
86 constants_(nullptr)
87 {}
88
GetHeaderName(uint8_t headerId)89 const std::string &ObexHeader::GetHeaderName(uint8_t headerId)
90 {
91 if (HEADER_ID_NAME_MAP.find(headerId) != HEADER_ID_NAME_MAP.end()) {
92 return HEADER_ID_NAME_MAP.at(headerId);
93 }
94 return HEADER_ID_NAME_MAP.at(0x00);
95 }
96
ParseFields(const uint8_t * buf,const uint8_t & code,uint16_t & pos,bool isRequest,bool isConnect)97 void ObexHeader::ParseFields(const uint8_t *buf, const uint8_t &code, uint16_t &pos, bool isRequest, bool isConnect)
98 {
99 if (isRequest) {
100 if (code == static_cast<uint8_t>(ObexOpeId::CONNECT)) {
101 uint8_t version = buf[pos++];
102 uint8_t flags = buf[pos++];
103 uint16_t maxPacketLength = ObexUtils::GetBufData16(buf, pos);
104 pos += UINT16_LENGTH;
105 SetFieldObexVersionNum(version);
106 SetFieldFlags(flags);
107 SetFieldMaxPacketLength(maxPacketLength);
108 } else if (code == static_cast<uint8_t>(ObexOpeId::SETPATH)) {
109 uint8_t flags = buf[pos++];
110 uint8_t constants = buf[pos++];
111 SetFieldFlags(flags);
112 SetFieldConstants(constants);
113 }
114 } else if (isConnect) {
115 // Connect response
116 uint8_t version = buf[pos++];
117 uint8_t flags = buf[pos++];
118 uint16_t maxPacketLength = ObexUtils::GetBufData16(buf, pos);
119 pos += UINT16_LENGTH;
120 SetFieldObexVersionNum(version);
121 SetFieldFlags(flags);
122 SetFieldMaxPacketLength(maxPacketLength);
123 }
124 }
125
ParseOptionalHeaders(const uint8_t * buf,const uint16_t & size,uint16_t & pos)126 bool ObexHeader::ParseOptionalHeaders(const uint8_t *buf, const uint16_t &size, uint16_t &pos)
127 {
128 while (pos < size) {
129 uint8_t headerId = buf[pos++];
130 uint8_t headerDataType = headerId & ObexHdrType::MASK;
131 OBEX_LOG_DEBUG(
132 "ObexHeader Parse headerId=%02X(%{public}s), type=%02X",
133 headerId, GetHeaderName(headerId).c_str(), headerDataType);
134 switch (headerDataType) {
135 case ObexHdrType::BYTE:
136 AppendByte(headerId, buf[pos++]);
137 break;
138 case ObexHdrType::BYTES:
139 ParseBytes(headerId, buf, pos);
140 break;
141 case ObexHdrType::UNICODE_TEXT:
142 ParseUnicodeText(headerId, buf, pos);
143 break;
144 case ObexHdrType::WORD:
145 AppendWord(headerId, ObexUtils::GetBufData32(buf, pos));
146 pos += UINT32_LENGTH;
147 break;
148 default:
149 OBEX_LOG_ERROR("parse error");
150 return false;
151 }
152 }
153 return true;
154 }
155
Parse(const uint8_t * buf,const uint16_t size,bool isRequest,bool isConnect)156 bool ObexHeader::Parse(const uint8_t *buf, const uint16_t size, bool isRequest, bool isConnect)
157 {
158 OBEX_LOG_DEBUG("ObexHeader Parse: isRequest[%{public}d],isConnect:[%{public}d], buf size=[%{public}d]", isRequest, isConnect, size);
159 isRequest_ = isRequest;
160 uint16_t pos = 0;
161 uint8_t code = buf[pos++];
162 uint16_t packetLengthForCheck = ObexUtils::GetBufData16(buf, pos);
163 OBEX_LOG_DEBUG("ObexHeader Parse: packetLength=%{public}d", int(packetLengthForCheck));
164 pos += UINT16_LENGTH;
165 if (packetLengthForCheck != size) {
166 OBEX_LOG_ERROR("packetLength size is wrong packetSize=%{public}d, actualSize=%{public}d",
167 int(packetLengthForCheck), int(size));
168 return false;
169 }
170 code_ = code;
171 packetLength_ = MIN_PACKET_LENGTH;
172
173 ParseFields(buf, code, pos, isRequest, isConnect);
174
175 if (!ParseOptionalHeaders(buf, size, pos)) {
176 return false;
177 }
178
179 if (packetLength_ != packetLengthForCheck) {
180 OBEX_LOG_ERROR(
181 "parse error packetLength_[%{public}d] != packetLengthForCheck[%{public}d]", packetLength_, packetLengthForCheck);
182 ObexUtils::ObexHeaderDebug(*this);
183 return false;
184 }
185 return true;
186 }
187
ParseBytes(const uint8_t & headerId,const uint8_t * buf,uint16_t & pos)188 void ObexHeader::ParseBytes(const uint8_t &headerId, const uint8_t *buf, uint16_t &pos)
189 {
190 uint16_t dataLen = ObexUtils::GetBufData16(buf, pos) - HDR_BYTES_PREFIX_LENGTH;
191 pos += UINT16_LENGTH;
192 std::unique_ptr<ObexOptionalHeader> header = nullptr;
193 switch (headerId) {
194 case ObexHeader::TYPE:
195 header = std::make_unique<ObexOptionalStringHeader>(headerId, &buf[pos], dataLen);
196 Append(header);
197 break;
198 case ObexHeader::APP_PARAMETERS:
199 case ObexHeader::SESSION_PARAMETERS:
200 case ObexHeader::AUTH_CHALLENGE:
201 case ObexHeader::AUTH_RESPONSE:
202 header = std::make_unique<ObexOptionalTlvHeader>(headerId, &buf[pos], dataLen);
203 Append(header);
204 break;
205 default:
206 header = std::make_unique<ObexOptionalBytesHeader>(headerId, &buf[pos], dataLen);
207 Append(header);
208 break;
209 }
210 pos += dataLen;
211 }
212
ParseUnicodeText(const uint8_t & headerId,const uint8_t * buf,uint16_t & pos)213 void ObexHeader::ParseUnicodeText(const uint8_t &headerId, const uint8_t *buf, uint16_t &pos)
214 {
215 uint16_t bytesLen = ObexUtils::GetBufData16(buf, pos) - HDR_UNICODE_PREFIX_LENGTH;
216 pos += UINT16_LENGTH;
217 if (bytesLen > 0) {
218 auto tmpBuf = std::make_unique<uint8_t[]>(bytesLen);
219 if (memcpy_s(tmpBuf.get(), bytesLen, &buf[pos], bytesLen) != EOK) {
220 OBEX_LOG_ERROR("ParseUnicodeText, memcpy_s fail");
221 return;
222 }
223 if (!ObexUtils::SysIsBigEndian()) {
224 ObexUtils::DataReverse(tmpBuf.get(), bytesLen, UINT16_LENGTH);
225 }
226 std::u16string str((char16_t *)tmpBuf.get());
227 AppendUnicode(headerId, str);
228 } else {
229 AppendUnicode(headerId, u"");
230 }
231 pos += bytesLen;
232 }
233
ObexHeader(const ObexHeader & header,bool fieldOnly)234 ObexHeader::ObexHeader(const ObexHeader &header, bool fieldOnly)
235 {
236 code_ = header.GetFieldCode();
237 isRequest_ = header.isRequest_;
238 uint16_t filedPacketLength = MIN_PACKET_LENGTH;
239 if (header.GetFieldObexVersionNum() != nullptr) {
240 obexVersionNum_ = std::make_unique<uint8_t>();
241 *obexVersionNum_ = *header.GetFieldObexVersionNum();
242 filedPacketLength += 1;
243 }
244 if (header.GetFieldFlags() != nullptr) {
245 flags_ = std::make_unique<uint8_t>();
246 *flags_ = *header.GetFieldFlags();
247 filedPacketLength += 1;
248 }
249 if (header.GetFieldMaxPacketLength() != nullptr) {
250 maxPacketLength_ = std::make_unique<uint16_t>();
251 *maxPacketLength_ = *header.GetFieldMaxPacketLength();
252 filedPacketLength += UINT16_LENGTH;
253 }
254 if (header.GetFieldConstants() != nullptr) {
255 constants_ = std::make_unique<uint8_t>();
256 *constants_ = *header.GetFieldConstants();
257 filedPacketLength += 1;
258 }
259 if (fieldOnly) {
260 packetLength_ = filedPacketLength;
261 } else {
262 packetLength_ = header.GetFieldPacketLength();
263 for (auto &optHeader : header.GetOptionalHeaders()) {
264 headerIndexMap_.insert(std::pair<uint8_t, size_t>(optHeader->GetHeaderId(), optionalHeaders_.size()));
265 optionalHeaders_.push_back(optHeader->Clone());
266 }
267 SetExtendBodyObject(header.GetExtendBodyObject());
268 }
269 }
270
CreateRequest(ObexOpeId opcode)271 std::unique_ptr<ObexHeader> ObexHeader::CreateRequest(ObexOpeId opcode)
272 {
273 auto header = std::make_unique<ObexHeader>();
274 header->isRequest_ = true;
275 header->code_ = static_cast<uint8_t>(opcode);
276 // code + pack length
277 header->packetLength_ = MIN_PACKET_LENGTH;
278 if (opcode == ObexOpeId::CONNECT) {
279 header->SetFieldObexVersionNum(OBEX_VERSION);
280 header->SetFieldFlags(0x00);
281 header->SetFieldMaxPacketLength(OBEX_DEFAULT_MTU);
282 } else if (opcode == ObexOpeId::SETPATH) {
283 // 0bit backup a level before applying name (equivalent to ../ on many systems)
284 // 1bit Don’t create folder if it does not exist, return an error instead.
285 header->SetFieldFlags(0x00);
286 header->SetFieldConstants(0x00);
287 }
288 return header;
289 }
290
CreateResponse(ObexRspCode rspCode,bool isConnectResp)291 std::unique_ptr<ObexHeader> ObexHeader::CreateResponse(ObexRspCode rspCode, bool isConnectResp)
292 {
293 auto header = std::make_unique<ObexHeader>();
294 header->isRequest_ = false;
295 header->code_ = static_cast<uint8_t>(rspCode);
296 // code + pack length
297 header->packetLength_ = MIN_PACKET_LENGTH;
298 if (isConnectResp) {
299 header->SetFieldObexVersionNum(OBEX_VERSION);
300 header->SetFieldFlags(0x00);
301 header->SetFieldMaxPacketLength(OBEX_DEFAULT_MTU);
302 }
303 return header;
304 }
305
ParseRequest(const uint8_t * buf,const uint16_t size)306 std::unique_ptr<ObexHeader> ObexHeader::ParseRequest(const uint8_t *buf, const uint16_t size)
307 {
308 auto header = std::make_unique<ObexHeader>();
309 if (header->Parse(buf, size, true, false)) {
310 return header;
311 }
312 return nullptr;
313 }
314
ParseResponse(const uint8_t * buf,const uint16_t size,bool isConnect)315 std::unique_ptr<ObexHeader> ObexHeader::ParseResponse(const uint8_t *buf, const uint16_t size, bool isConnect)
316 {
317 auto header = std::make_unique<ObexHeader>();
318 if (header->Parse(buf, size, false, isConnect)) {
319 return header;
320 }
321 return nullptr;
322 }
323
GetFieldCode() const324 uint8_t ObexHeader::GetFieldCode() const
325 {
326 return code_;
327 }
328
GetFieldPacketLength() const329 uint16_t ObexHeader::GetFieldPacketLength() const
330 {
331 return packetLength_;
332 }
333
GetFieldObexVersionNum() const334 const uint8_t *ObexHeader::GetFieldObexVersionNum() const
335 {
336 if (obexVersionNum_ == nullptr) {
337 return nullptr;
338 }
339 return obexVersionNum_.get();
340 }
341
GetFieldFlags() const342 const uint8_t *ObexHeader::GetFieldFlags() const
343 {
344 if (flags_ == nullptr) {
345 return nullptr;
346 }
347 return flags_.get();
348 }
349
GetFieldMaxPacketLength() const350 const uint16_t *ObexHeader::GetFieldMaxPacketLength() const
351 {
352 if (maxPacketLength_ == nullptr) {
353 return nullptr;
354 }
355 return maxPacketLength_.get();
356 }
357
GetFieldConstants() const358 const uint8_t *ObexHeader::GetFieldConstants() const
359 {
360 if (constants_ == nullptr) {
361 return nullptr;
362 }
363 return constants_.get();
364 }
365
SetRespCode(uint8_t code)366 void ObexHeader::SetRespCode(uint8_t code)
367 {
368 if (!isRequest_) {
369 code_ = code;
370 }
371 }
372
SetFinalBit(bool finalBit)373 void ObexHeader::SetFinalBit(bool finalBit)
374 {
375 if (finalBit) {
376 code_ = code_ | OBEX_FINAL_BIT_MASK;
377 } else {
378 code_ = code_ & ~OBEX_FINAL_BIT_MASK;
379 }
380 }
381
SetFieldObexVersionNum(const uint8_t obexVersionNum)382 void ObexHeader::SetFieldObexVersionNum(const uint8_t obexVersionNum)
383 {
384 if (obexVersionNum_ == nullptr) {
385 obexVersionNum_ = std::make_unique<uint8_t>();
386 packetLength_ += 1;
387 }
388 *obexVersionNum_ = obexVersionNum;
389 }
390
SetFieldFlags(const uint8_t flags)391 void ObexHeader::SetFieldFlags(const uint8_t flags)
392 {
393 if (flags_ == nullptr) {
394 flags_ = std::make_unique<uint8_t>();
395 packetLength_ += 1;
396 }
397 *flags_ = flags;
398 }
399
SetFieldMaxPacketLength(const uint16_t maxPacketLength)400 void ObexHeader::SetFieldMaxPacketLength(const uint16_t maxPacketLength)
401 {
402 if (maxPacketLength_ == nullptr) {
403 maxPacketLength_ = std::make_unique<uint16_t>();
404 packetLength_ += UINT16_LENGTH;
405 }
406 *maxPacketLength_ = maxPacketLength;
407 }
408
SetFieldConstants(uint8_t constants)409 void ObexHeader::SetFieldConstants(uint8_t constants)
410 {
411 if (constants_ == nullptr) {
412 constants_ = std::make_unique<uint8_t>();
413 packetLength_ += 1;
414 }
415 *constants_ = constants;
416 }
417
Append(std::unique_ptr<ObexOptionalHeader> & header)418 void ObexHeader::Append(std::unique_ptr<ObexOptionalHeader> &header)
419 {
420 uint8_t headerId = header->GetHeaderId();
421 if (HasHeader(headerId)) {
422 OBEX_LOG_ERROR("duplicate headerId: 0x%02X", headerId);
423 return;
424 }
425 headerIndexMap_[headerId] = optionalHeaders_.size();
426 packetLength_ += header->GetHeaderTotalSize();
427 optionalHeaders_.push_back(std::move(header));
428 }
429
430 template<typename T>
GetItem(uint8_t headerId) const431 const T ObexHeader::GetItem(uint8_t headerId) const
432 {
433 const ObexOptionalHeader *headerItem = Get(headerId);
434 if (headerItem == nullptr) {
435 return nullptr;
436 }
437 return static_cast<T>(const_cast<ObexOptionalHeader *>(headerItem));
438 }
439
AppendUnicode(const uint8_t headerId,const std::u16string & text)440 void ObexHeader::AppendUnicode(const uint8_t headerId, const std::u16string &text)
441 {
442 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalUnicodeHeader>(headerId, text);
443 Append(header);
444 }
445
AppendByte(const uint8_t headerId,const uint8_t byte)446 void ObexHeader::AppendByte(const uint8_t headerId, const uint8_t byte)
447 {
448 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalByteHeader>(headerId, byte);
449 Append(header);
450 }
451
AppendBytes(const uint8_t headerId,const uint8_t * byteBuf,const uint32_t size)452 void ObexHeader::AppendBytes(const uint8_t headerId, const uint8_t *byteBuf, const uint32_t size)
453 {
454 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalBytesHeader>(headerId, byteBuf, size);
455 Append(header);
456 }
457
AppendWord(const uint8_t headerId,const uint32_t word)458 void ObexHeader::AppendWord(const uint8_t headerId, const uint32_t word)
459 {
460 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalWordHeader>(headerId, word);
461 Append(header);
462 }
463
AppendString(const uint8_t headerId,const std::string & str)464 void ObexHeader::AppendString(const uint8_t headerId, const std::string &str)
465 {
466 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalStringHeader>(headerId, str);
467 Append(header);
468 }
469
AppendTlvTriplets(const uint8_t headerId,ObexTlvParamters & tlvParamters)470 void ObexHeader::AppendTlvTriplets(const uint8_t headerId, ObexTlvParamters &tlvParamters)
471 {
472 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalTlvHeader>(headerId, tlvParamters);
473 Append(header);
474 }
475
GetOptionalHeaders() const476 std::vector<std::unique_ptr<ObexOptionalHeader>> const &ObexHeader::GetOptionalHeaders() const
477 {
478 return optionalHeaders_;
479 }
480
481 // Header add methods
482 // bytes
AppendItemTarget(const uint8_t * target,const uint16_t length)483 bool ObexHeader::AppendItemTarget(const uint8_t *target, const uint16_t length)
484 {
485 if (optionalHeaders_.size() != 0) {
486 bool error = true;
487 if (optionalHeaders_.size() == 1) {
488 if (optionalHeaders_.at(0)->GetHeaderId() == ObexHeader::SESSION_SEQUENCE_NUMBER) {
489 error = false;
490 }
491 }
492 if (error) {
493 OBEX_LOG_ERROR("Target must the first header in the request");
494 return false;
495 }
496 }
497 if (length != TARGET_LENGTH) {
498 OBEX_LOG_ERROR("AppendItemTarget length is wrong!");
499 return false;
500 }
501 AppendBytes(ObexHeader::TARGET, target, length);
502 return true;
503 }
504
AppendItemTimeIso8601(const uint8_t * time,const uint16_t length)505 void ObexHeader::AppendItemTimeIso8601(const uint8_t *time, const uint16_t length)
506 {
507 AppendBytes(ObexHeader::TIME_ISO8601, time, length);
508 }
509
AppendItemHttp(const uint8_t * http,const uint16_t length)510 void ObexHeader::AppendItemHttp(const uint8_t *http, const uint16_t length)
511 {
512 AppendBytes(ObexHeader::HTTP, http, length);
513 }
514
AppendItemBody(const uint8_t * body,const uint16_t length)515 void ObexHeader::AppendItemBody(const uint8_t *body, const uint16_t length)
516 {
517 AppendBytes(ObexHeader::BODY, body, length);
518 }
519
AppendItemEndBody(const uint8_t * endBody,const uint16_t length)520 void ObexHeader::AppendItemEndBody(const uint8_t *endBody, const uint16_t length)
521 {
522 AppendBytes(ObexHeader::END_OF_BODY, endBody, length);
523 }
524
AppendItemWho(const uint8_t * who,const uint16_t length)525 void ObexHeader::AppendItemWho(const uint8_t *who, const uint16_t length)
526 {
527 AppendBytes(ObexHeader::WHO, who, length);
528 }
529
AppendItemObjectClass(const uint8_t * objectClass,const uint16_t length)530 void ObexHeader::AppendItemObjectClass(const uint8_t *objectClass, const uint16_t length)
531 {
532 AppendBytes(ObexHeader::OBJECT_CLASS, objectClass, length);
533 }
534
535 // tlv
AppendItemAppParams(ObexTlvParamters & params)536 void ObexHeader::AppendItemAppParams(ObexTlvParamters ¶ms)
537 {
538 AppendTlvTriplets(ObexHeader::APP_PARAMETERS, params);
539 }
540
AppendItemAuthChallenges(ObexDigestChallenge & challenges)541 void ObexHeader::AppendItemAuthChallenges(ObexDigestChallenge &challenges)
542 {
543 AppendTlvTriplets(ObexHeader::AUTH_CHALLENGE, challenges);
544 }
545
AppendItemAuthResponse(ObexDigestResponse & responses)546 void ObexHeader::AppendItemAuthResponse(ObexDigestResponse &responses)
547 {
548 AppendTlvTriplets(ObexHeader::AUTH_RESPONSE, responses);
549 }
550
AppendItemSessionParams(ObexSessionParameters & params)551 bool ObexHeader::AppendItemSessionParams(ObexSessionParameters ¶ms)
552 {
553 if (optionalHeaders_.size() != 0) {
554 OBEX_LOG_ERROR("SessionParams must the first header in the request");
555 return false;
556 }
557 AppendTlvTriplets(ObexHeader::SESSION_PARAMETERS, params);
558 return true;
559 }
560
561 // String
AppendItemType(const std::string & type)562 void ObexHeader::AppendItemType(const std::string &type)
563 {
564 AppendString(ObexHeader::TYPE, type);
565 }
566
567 // Word
AppendItemConnectionId(const uint32_t connectionId)568 bool ObexHeader::AppendItemConnectionId(const uint32_t connectionId)
569 {
570 if (optionalHeaders_.size() != 0) {
571 bool error = true;
572 if (optionalHeaders_.size() == 1) {
573 if (optionalHeaders_.at(0)->GetHeaderId() == ObexHeader::SESSION_SEQUENCE_NUMBER) {
574 error = false;
575 }
576 }
577 if (error) {
578 OBEX_LOG_ERROR("ConnectionId must the first header in the request");
579 return false;
580 }
581 }
582 AppendWord(ObexHeader::CONNECTION_ID, connectionId);
583 return true;
584 }
585
AppendItemCount(const uint32_t count)586 void ObexHeader::AppendItemCount(const uint32_t count)
587 {
588 AppendWord(ObexHeader::COUNT, count);
589 }
590
AppendItemLength(const uint32_t length)591 void ObexHeader::AppendItemLength(const uint32_t length)
592 {
593 AppendWord(ObexHeader::LENGTH, length);
594 }
595
AppendItemTime4byte(const uint32_t time)596 void ObexHeader::AppendItemTime4byte(const uint32_t time)
597 {
598 AppendWord(ObexHeader::TIME_4BYTE_VERSION, time);
599 }
600
AppendItemPermissions(const uint32_t permissions)601 void ObexHeader::AppendItemPermissions(const uint32_t permissions)
602 {
603 AppendWord(ObexHeader::PERMISSIONS, permissions);
604 }
605
606 // Unicode
AppendItemName(const std::u16string & name)607 void ObexHeader::AppendItemName(const std::u16string &name)
608 {
609 AppendUnicode(ObexHeader::NAME, name);
610 }
611
AppendItemDescription(const std::u16string & description)612 void ObexHeader::AppendItemDescription(const std::u16string &description)
613 {
614 AppendUnicode(ObexHeader::DESCRIPTION, description);
615 }
616
AppendItemDestName(const std::u16string & destName)617 void ObexHeader::AppendItemDestName(const std::u16string &destName)
618 {
619 AppendUnicode(ObexHeader::DEST_NAME, destName);
620 }
621
622 // byte
AppendItemSessionSeqNum(const uint8_t num)623 bool ObexHeader::AppendItemSessionSeqNum(const uint8_t num)
624 {
625 if (optionalHeaders_.size() != 0) {
626 OBEX_LOG_ERROR("SessionSeqNum must the first header in the request");
627 return false;
628 }
629 AppendByte(ObexHeader::SESSION_SEQUENCE_NUMBER, num);
630 return true;
631 }
632
AppendItemActionId(const ObexActionType actionId)633 void ObexHeader::AppendItemActionId(const ObexActionType actionId)
634 {
635 AppendByte(ObexHeader::ACTION_ID, static_cast<uint8_t>(actionId));
636 }
637
AppendItemSrm(const bool srm)638 void ObexHeader::AppendItemSrm(const bool srm)
639 {
640 AppendByte(ObexHeader::SRM, srm ? ObexHdrSrmMode::SINGLE : ObexHdrSrmMode::NORMAL);
641 }
642
AppendItemSrmp()643 void ObexHeader::AppendItemSrmp()
644 {
645 AppendByte(ObexHeader::SRMP, ObexHdrSrmpMode::WAIT);
646 }
647
648 // obex header get methods
Get(uint8_t headerId) const649 const ObexOptionalHeader *ObexHeader::Get(uint8_t headerId) const
650 {
651 if (!HasHeader(headerId)) {
652 return nullptr;
653 }
654 size_t index = headerIndexMap_.at(headerId);
655 return optionalHeaders_.at(index).get();
656 }
657
658 // ObexOptionalHeader
GetItemTarget() const659 const ObexOptionalHeader *ObexHeader::GetItemTarget() const
660 {
661 return Get(ObexHeader::TARGET);
662 }
663
GetItemTimeIso8601() const664 const ObexOptionalHeader *ObexHeader::GetItemTimeIso8601() const
665 {
666 return Get(ObexHeader::TIME_ISO8601);
667 }
668
GetItemHttp() const669 const ObexOptionalHeader *ObexHeader::GetItemHttp() const
670 {
671 return Get(ObexHeader::HTTP);
672 }
673
GetItemBody() const674 const ObexOptionalHeader *ObexHeader::GetItemBody() const
675 {
676 return Get(ObexHeader::BODY);
677 }
678
GetItemEndBody() const679 const ObexOptionalHeader *ObexHeader::GetItemEndBody() const
680 {
681 return Get(ObexHeader::END_OF_BODY);
682 }
683
GetItemWho() const684 const ObexOptionalHeader *ObexHeader::GetItemWho() const
685 {
686 return Get(ObexHeader::WHO);
687 }
688
GetItemObjectClass() const689 const ObexOptionalHeader *ObexHeader::GetItemObjectClass() const
690 {
691 return Get(ObexHeader::OBJECT_CLASS);
692 }
693
694 // ObexOptionalTlvHeader
GetItemAuthChallenges() const695 const ObexOptionalTlvHeader *ObexHeader::GetItemAuthChallenges() const
696 {
697 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::AUTH_CHALLENGE);
698 }
699
GetItemSessionParams() const700 const ObexOptionalTlvHeader *ObexHeader::GetItemSessionParams() const
701 {
702 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::SESSION_PARAMETERS);
703 }
704
GetItemAppParams() const705 const ObexOptionalTlvHeader *ObexHeader::GetItemAppParams() const
706 {
707 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::APP_PARAMETERS);
708 }
709
GetItemAuthResponse() const710 const ObexOptionalTlvHeader *ObexHeader::GetItemAuthResponse() const
711 {
712 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::AUTH_RESPONSE);
713 }
714
715 // ObexOptionalStringHeader
GetItemType() const716 const ObexOptionalStringHeader *ObexHeader::GetItemType() const
717 {
718 return GetItem<ObexOptionalStringHeader *>(ObexHeader::TYPE);
719 }
720
721 // ObexOptionalWordHeader
GetItemCount() const722 const ObexOptionalWordHeader *ObexHeader::GetItemCount() const
723 {
724 return GetItem<ObexOptionalWordHeader *>(ObexHeader::COUNT);
725 }
726
GetItemLength() const727 const ObexOptionalWordHeader *ObexHeader::GetItemLength() const
728 {
729 return GetItem<ObexOptionalWordHeader *>(ObexHeader::LENGTH);
730 }
731
GetItemTime4byte() const732 const ObexOptionalWordHeader *ObexHeader::GetItemTime4byte() const
733 {
734 return GetItem<ObexOptionalWordHeader *>(ObexHeader::TIME_4BYTE_VERSION);
735 }
736
GetItemConnectionId() const737 const ObexOptionalWordHeader *ObexHeader::GetItemConnectionId() const
738 {
739 return GetItem<ObexOptionalWordHeader *>(ObexHeader::CONNECTION_ID);
740 }
741
GetItemPermissions() const742 const ObexOptionalWordHeader *ObexHeader::GetItemPermissions() const
743 {
744 return GetItem<ObexOptionalWordHeader *>(ObexHeader::PERMISSIONS);
745 }
746
747 // ObexOptionalUnicodeHeader
GetItemName() const748 const ObexOptionalUnicodeHeader *ObexHeader::GetItemName() const
749 {
750 return GetItem<ObexOptionalUnicodeHeader *>(ObexHeader::NAME);
751 }
752
GetItemDescription() const753 const ObexOptionalUnicodeHeader *ObexHeader::GetItemDescription() const
754 {
755 return GetItem<ObexOptionalUnicodeHeader *>(ObexHeader::DESCRIPTION);
756 }
757
GetItemDestName() const758 const ObexOptionalUnicodeHeader *ObexHeader::GetItemDestName() const
759 {
760 return GetItem<ObexOptionalUnicodeHeader *>(ObexHeader::DEST_NAME);
761 }
762
763 // ObexOptionalByteHeader
GetItemSessionSeqNum() const764 const ObexOptionalByteHeader *ObexHeader::GetItemSessionSeqNum() const
765 {
766 return GetItem<ObexOptionalByteHeader *>(ObexHeader::SESSION_SEQUENCE_NUMBER);
767 }
768
GetItemActionId() const769 const ObexOptionalByteHeader *ObexHeader::GetItemActionId() const
770 {
771 return GetItem<ObexOptionalByteHeader *>(ObexHeader::ACTION_ID);
772 }
773
HasHeader(const uint8_t headerId) const774 bool ObexHeader::HasHeader(const uint8_t headerId) const
775 {
776 return headerIndexMap_.find(headerId) != headerIndexMap_.end();
777 }
778
RemoveItem(const uint8_t headerId)779 void ObexHeader::RemoveItem(const uint8_t headerId)
780 {
781 if (!HasHeader(headerId)) {
782 return;
783 }
784 size_t index = headerIndexMap_.at(headerId);
785 auto &header = optionalHeaders_.at(index);
786 packetLength_ -= header->GetHeaderTotalSize();
787 optionalHeaders_.erase(optionalHeaders_.begin() + index);
788 headerIndexMap_.clear();
789 for (size_t i = 0; i < optionalHeaders_.size(); i++) {
790 auto &item = optionalHeaders_.at(i);
791 headerIndexMap_[item->GetHeaderId()] = i;
792 }
793 }
794
GetItemSrm() const795 bool ObexHeader::GetItemSrm() const
796 {
797 auto headerItem = GetItem<ObexOptionalByteHeader *>(ObexHeader::SRM);
798 if (headerItem == nullptr) {
799 return false;
800 }
801 return headerItem->GetByte() == ObexHdrSrmMode::SINGLE;
802 }
803
GetItemSrmp() const804 bool ObexHeader::GetItemSrmp() const
805 {
806 auto headerItem = GetItem<ObexOptionalByteHeader *>(ObexHeader::SRMP);
807 if (headerItem == nullptr) {
808 return false;
809 }
810 return headerItem->GetByte() == ObexHdrSrmpMode::WAIT;
811 }
812
Build() const813 std::unique_ptr<ObexPacket> ObexHeader::Build() const
814 {
815 auto obexPacket = std::make_unique<ObexPacket>(packetLength_);
816 uint8_t *packetBuf = obexPacket->GetBuffer();
817 uint16_t pos = 0;
818 packetBuf[pos++] = code_;
819 bool isBigEndian = ObexUtils::SysIsBigEndian();
820 ObexUtils::SetBufData16(packetBuf, pos, packetLength_);
821 pos += UINT16_LENGTH;
822 if (obexVersionNum_ != nullptr) {
823 packetBuf[pos++] = obexVersionNum_.get()[0];
824 }
825 if (flags_ != nullptr) {
826 packetBuf[pos++] = flags_.get()[0];
827 }
828 if (constants_ != nullptr) {
829 packetBuf[pos++] = constants_.get()[0];
830 }
831 if (maxPacketLength_ != nullptr) {
832 ObexUtils::SetBufData16(packetBuf, pos, maxPacketLength_.get()[0]);
833 pos += UINT16_LENGTH;
834 }
835 for (auto &headerItem : optionalHeaders_) {
836 packetBuf[pos++] = headerItem->GetHeaderId();
837 if (headerItem->HasLengthField()) {
838 ObexUtils::SetBufData16(packetBuf, pos, headerItem->GetHeaderTotalSize());
839 pos += UINT16_LENGTH;
840 }
841 (void)memcpy_s(
842 &packetBuf[pos], packetLength_ - pos, headerItem->GetBytes().get(), headerItem->GetHeaderDataSize());
843 if (!isBigEndian && headerItem->GetHeaderUnitLen() > 1) {
844 ObexUtils::DataReverse(&packetBuf[pos], headerItem->GetHeaderDataSize(), headerItem->GetHeaderUnitLen());
845 }
846 pos += headerItem->GetHeaderDataSize();
847 }
848 return obexPacket;
849 }
850
GetExtendBodyObject() const851 const std::shared_ptr<ObexBodyObject> &ObexHeader::GetExtendBodyObject() const
852 {
853 return extendBodyObject_;
854 }
855
SetExtendBodyObject(const std::shared_ptr<ObexBodyObject> & extendBodyObject)856 void ObexHeader::SetExtendBodyObject(const std::shared_ptr<ObexBodyObject> &extendBodyObject)
857 {
858 extendBodyObject_ = extendBodyObject;
859 }
860
TlvTriplet()861 TlvTriplet::TlvTriplet()
862 {
863 tagId_ = 0x00;
864 len_ = 0x00;
865 unitLen_ = 1;
866 }
867
TlvTriplet(const uint8_t tagId,const uint8_t len,const uint8_t * val,const uint8_t unitLen)868 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint8_t len, const uint8_t *val, const uint8_t unitLen)
869 {
870 tagId_ = tagId;
871 len_ = len;
872 unitLen_ = unitLen;
873 val_.insert(val_.end(), val, val + len);
874 }
875
TlvTriplet(const TlvTriplet & tlvTriplet)876 TlvTriplet::TlvTriplet(const TlvTriplet &tlvTriplet)
877 : TlvTriplet(tlvTriplet.tagId_, tlvTriplet.len_, tlvTriplet.val_.data(), tlvTriplet.unitLen_)
878 {}
879
TlvTriplet(const uint8_t tagId,const uint8_t val)880 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint8_t val)
881 : TlvTriplet(tagId, static_cast<uint8_t>(1), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(1))
882 {}
883
TlvTriplet(const uint8_t tagId,const uint16_t val)884 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint16_t val)
885 : TlvTriplet(tagId, static_cast<uint8_t>(2), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(2))
886 {}
887
TlvTriplet(const uint8_t tagId,const uint32_t val)888 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint32_t val)
889 : TlvTriplet(tagId, static_cast<uint8_t>(4), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(4))
890 {}
891
TlvTriplet(const uint8_t tagId,const uint64_t val)892 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint64_t val)
893 : TlvTriplet(tagId, static_cast<uint8_t>(8), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(8))
894 {}
895
GetTagId() const896 uint8_t TlvTriplet::GetTagId() const
897 {
898 return tagId_;
899 }
900
GetLen() const901 uint8_t TlvTriplet::GetLen() const
902 {
903 return len_;
904 }
905
GetUnitLen() const906 uint8_t TlvTriplet::GetUnitLen() const
907 {
908 return unitLen_;
909 }
910
GetVal() const911 const uint8_t *TlvTriplet::GetVal() const
912 {
913 return val_.data();
914 }
915
GetUint16() const916 uint16_t TlvTriplet::GetUint16() const
917 {
918 if (len_ == ObexHeader::UINT16_LENGTH) {
919 if (unitLen_ > 1) {
920 return *(reinterpret_cast<const uint16_t *>(GetVal()));
921 }
922 return ObexUtils::GetBufData16(GetVal());
923 }
924 return 0;
925 }
926
GetUint32() const927 uint32_t TlvTriplet::GetUint32() const
928 {
929 if (len_ == ObexHeader::UINT32_LENGTH) {
930 if (unitLen_ > 1) {
931 return *(reinterpret_cast<const uint32_t *>(GetVal()));
932 }
933 return ObexUtils::GetBufData32(GetVal());
934 }
935 return 0;
936 }
937
GetUint64() const938 uint64_t TlvTriplet::GetUint64() const
939 {
940 if (len_ == ObexHeader::UINT64_LENGTH) {
941 if (unitLen_ > 1) {
942 return *(reinterpret_cast<const uint64_t *>(GetVal()));
943 }
944 return ObexUtils::GetBufData64(GetVal());
945 }
946 return 0;
947 }
948
ObexOptionalHeader(uint8_t headerId)949 ObexOptionalHeader::ObexOptionalHeader(uint8_t headerId)
950 {
951 headerId_ = headerId;
952 dataSize_ = 0;
953 unitLen_ = 1;
954 }
955
GetHeaderId() const956 uint8_t ObexOptionalHeader::GetHeaderId() const
957 {
958 return headerId_;
959 }
960
GetHeaderTotalSize() const961 uint16_t ObexOptionalHeader::GetHeaderTotalSize() const
962 {
963 uint8_t prefixLen = 1;
964 if (HasLengthField()) {
965 prefixLen += ObexHeader::UINT16_LENGTH;
966 }
967 return prefixLen + GetHeaderDataSize();
968 }
969
GetHeaderDataSize() const970 uint16_t ObexOptionalHeader::GetHeaderDataSize() const
971 {
972 return dataSize_;
973 }
974
GetHeaderUnitLen() const975 uint8_t ObexOptionalHeader::GetHeaderUnitLen() const
976 {
977 return unitLen_;
978 }
979
980 // ObexOptionalBytesHeader
ObexOptionalBytesHeader(const uint8_t headerId,const uint8_t * data,const uint16_t dataSize,const uint16_t unitLen)981 ObexOptionalBytesHeader::ObexOptionalBytesHeader(
982 const uint8_t headerId, const uint8_t *data, const uint16_t dataSize, const uint16_t unitLen)
983 : ObexOptionalHeader(headerId)
984 {
985 dataSize_ = dataSize;
986 data_.insert(data_.end(), data, data + dataSize);
987 unitLen_ = unitLen;
988 }
989
GetBytes() const990 std::unique_ptr<uint8_t[]> ObexOptionalBytesHeader::GetBytes() const
991 {
992 if (dataSize_ < 1) {
993 return nullptr;
994 }
995 if (data_.size() == 0) {
996 return nullptr;
997 }
998 auto buf = std::make_unique<uint8_t[]>(dataSize_);
999 (void)memcpy_s(buf.get(), dataSize_, data_.data(), dataSize_);
1000 return buf;
1001 }
1002
HasLengthField() const1003 bool ObexOptionalBytesHeader::HasLengthField() const
1004 {
1005 return true;
1006 }
1007
GetHeaderClassType() const1008 ObexHeaderDataType ObexOptionalBytesHeader::GetHeaderClassType() const
1009 {
1010 return ObexHeaderDataType::BYTES;
1011 }
1012
GetHeaderClassTypeName() const1013 std::string ObexOptionalBytesHeader::GetHeaderClassTypeName() const
1014 {
1015 return "ObexOptionalBytesHeader";
1016 }
1017
Clone() const1018 std::unique_ptr<ObexOptionalHeader> ObexOptionalBytesHeader::Clone() const
1019 {
1020 return std::make_unique<ObexOptionalBytesHeader>(GetHeaderId(), data_.data(), dataSize_, unitLen_);
1021 }
1022
1023 // ObexOptionalStringHeader
ObexOptionalStringHeader(const uint8_t headerId,const std::string & str)1024 ObexOptionalStringHeader::ObexOptionalStringHeader(const uint8_t headerId, const std::string &str)
1025 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<char *>(str.c_str())),
1026 (str.size() == 0) ? 0 : (str.size() + 1), 1)
1027 {}
1028
ObexOptionalStringHeader(const uint8_t headerId,const uint8_t * data,const uint16_t dataSize)1029 ObexOptionalStringHeader::ObexOptionalStringHeader(const uint8_t headerId,
1030 const uint8_t *data, const uint16_t dataSize)
1031 : ObexOptionalBytesHeader(headerId, data, dataSize)
1032 {}
1033
GetString() const1034 std::string ObexOptionalStringHeader::GetString() const
1035 {
1036 if (dataSize_ == 0) {
1037 return "";
1038 }
1039 std::string str((char *)data_.data(), dataSize_ - 1);
1040 return str;
1041 }
1042
GetHeaderClassType() const1043 ObexHeaderDataType ObexOptionalStringHeader::GetHeaderClassType() const
1044 {
1045 return ObexHeaderDataType::STRING;
1046 }
1047
GetHeaderClassTypeName() const1048 std::string ObexOptionalStringHeader::GetHeaderClassTypeName() const
1049 {
1050 return "ObexOptionalStringHeader";
1051 }
1052
Clone() const1053 std::unique_ptr<ObexOptionalHeader> ObexOptionalStringHeader::Clone() const
1054 {
1055 return std::make_unique<ObexOptionalStringHeader>(GetHeaderId(), GetString());
1056 }
1057
1058 // ObexOptionalUnicodeHeader
ObexOptionalUnicodeHeader(const uint8_t headerId,const std::u16string & unicodeText)1059 ObexOptionalUnicodeHeader::ObexOptionalUnicodeHeader(const uint8_t headerId, const std::u16string &unicodeText)
1060 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<char16_t *>(unicodeText.c_str())),
1061 (unicodeText.size() == 0) ? 0 : ((unicodeText.size() + 1) * ObexHeader::U16STRING_LENGTH),
1062 ObexHeader::U16STRING_LENGTH)
1063 {}
GetUnicodeText() const1064 std::u16string ObexOptionalUnicodeHeader::GetUnicodeText() const
1065 {
1066 if (dataSize_ == 0) {
1067 return u"";
1068 }
1069 std::u16string str(
1070 (char16_t *)data_.data(), (dataSize_ - ObexHeader::U16STRING_NULL_LENGTH) / ObexHeader::U16STRING_LENGTH);
1071 return str;
1072 }
1073
GetHeaderClassType() const1074 ObexHeaderDataType ObexOptionalUnicodeHeader::GetHeaderClassType() const
1075 {
1076 return ObexHeaderDataType::UNICODE_TEXT;
1077 }
1078
GetHeaderClassTypeName() const1079 std::string ObexOptionalUnicodeHeader::GetHeaderClassTypeName() const
1080 {
1081 return "ObexOptionalUnicodeHeader";
1082 }
1083
Clone() const1084 std::unique_ptr<ObexOptionalHeader> ObexOptionalUnicodeHeader::Clone() const
1085 {
1086 return std::make_unique<ObexOptionalUnicodeHeader>(GetHeaderId(), GetUnicodeText());
1087 }
1088
1089 // ObexOptionalByteHeader
ObexOptionalByteHeader(const uint8_t headerId,const uint8_t byte)1090 ObexOptionalByteHeader::ObexOptionalByteHeader(const uint8_t headerId, const uint8_t byte)
1091 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<uint8_t *>(&byte)), 1)
1092 {}
HasLengthField() const1093 bool ObexOptionalByteHeader::HasLengthField() const
1094 {
1095 return false;
1096 }
1097
GetByte() const1098 uint8_t ObexOptionalByteHeader::GetByte() const
1099 {
1100 return data_.data()[0];
1101 }
1102
GetHeaderClassType() const1103 ObexHeaderDataType ObexOptionalByteHeader::GetHeaderClassType() const
1104 {
1105 return ObexHeaderDataType::BYTE;
1106 }
1107
GetHeaderClassTypeName() const1108 std::string ObexOptionalByteHeader::GetHeaderClassTypeName() const
1109 {
1110 return "ObexOptionalByteHeader";
1111 }
1112
Clone() const1113 std::unique_ptr<ObexOptionalHeader> ObexOptionalByteHeader::Clone() const
1114 {
1115 return std::make_unique<ObexOptionalByteHeader>(GetHeaderId(), GetByte());
1116 }
1117
1118 // ObexOptionalWordHeader
ObexOptionalWordHeader(const uint8_t headerId,const uint32_t word)1119 ObexOptionalWordHeader::ObexOptionalWordHeader(const uint8_t headerId, const uint32_t word)
1120 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<uint32_t *>(&word)),
1121 ObexHeader::UINT32_LENGTH, ObexHeader::UINT32_LENGTH)
1122 {}
GetWord() const1123 uint32_t ObexOptionalWordHeader::GetWord() const
1124 {
1125 return ((const uint32_t *)data_.data())[0];
1126 }
1127
GetHeaderClassType() const1128 ObexHeaderDataType ObexOptionalWordHeader::GetHeaderClassType() const
1129 {
1130 return ObexHeaderDataType::WORD;
1131 }
1132
GetHeaderClassTypeName() const1133 std::string ObexOptionalWordHeader::GetHeaderClassTypeName() const
1134 {
1135 return "ObexOptionalWordHeader";
1136 }
1137
Clone() const1138 std::unique_ptr<ObexOptionalHeader> ObexOptionalWordHeader::Clone() const
1139 {
1140 return std::make_unique<ObexOptionalWordHeader>(GetHeaderId(), GetWord());
1141 }
1142
HasLengthField() const1143 bool ObexOptionalWordHeader::HasLengthField() const
1144 {
1145 return false;
1146 }
1147
1148 // ObexOptionalTLVHeader
ObexOptionalTlvHeader(const uint8_t headerId)1149 ObexOptionalTlvHeader::ObexOptionalTlvHeader(const uint8_t headerId) : ObexOptionalHeader(headerId)
1150 {
1151 dataSize_ = 0;
1152 unitLen_ = 1;
1153 }
1154
ObexOptionalTlvHeader(const uint8_t headerId,const ObexTlvParamters & tlvParamters)1155 ObexOptionalTlvHeader::ObexOptionalTlvHeader(const uint8_t headerId, const ObexTlvParamters &tlvParamters)
1156 : ObexOptionalTlvHeader(headerId)
1157 {
1158 uint16_t dataSize = 0;
1159 auto newTlvParamters = std::make_unique<ObexTlvParamters>();
1160 for (auto ¶m : tlvParamters.GetTlvTriplets()) {
1161 dataSize += param->GetLen() + TAG_PREFIX_LEN;
1162 newTlvParamters->AppendTlvtriplet(*(param.get()));
1163 }
1164 tlvParamters_ = std::move(newTlvParamters);
1165 dataSize_ = dataSize;
1166 }
1167
ObexOptionalTlvHeader(const uint8_t headerId,const uint8_t * data,const uint16_t dataSize)1168 ObexOptionalTlvHeader::ObexOptionalTlvHeader(const uint8_t headerId, const uint8_t *data, const uint16_t dataSize)
1169 : ObexOptionalTlvHeader(headerId)
1170 {
1171 auto newTlvParamters = std::make_unique<ObexTlvParamters>();
1172 uint16_t pos = 0;
1173 while (pos < dataSize) {
1174 const uint8_t tagId = data[pos++];
1175 const uint8_t len = data[pos++];
1176 TlvTriplet tlv(tagId, len, &data[pos]);
1177 newTlvParamters->AppendTlvtriplet(tlv);
1178 pos += len;
1179 }
1180 tlvParamters_ = std::move(newTlvParamters);
1181 dataSize_ = dataSize;
1182 }
1183
GetTlvParamters() const1184 const std::unique_ptr<ObexTlvParamters> &ObexOptionalTlvHeader::GetTlvParamters() const
1185 {
1186 return tlvParamters_;
1187 }
1188
GetTlvtriplet(const uint8_t tagId) const1189 const TlvTriplet *ObexOptionalTlvHeader::GetTlvtriplet(const uint8_t tagId) const
1190 {
1191 if (tlvParamters_ == nullptr) {
1192 return nullptr;
1193 }
1194 return tlvParamters_->GetTlvtriplet(tagId);
1195 }
1196
HasLengthField() const1197 bool ObexOptionalTlvHeader::HasLengthField() const
1198 {
1199 return true;
1200 }
1201
GetHeaderClassType() const1202 ObexHeaderDataType ObexOptionalTlvHeader::GetHeaderClassType() const
1203 {
1204 return ObexHeaderDataType::TLV;
1205 }
1206
GetHeaderClassTypeName() const1207 std::string ObexOptionalTlvHeader::GetHeaderClassTypeName() const
1208 {
1209 return "ObexOptionalTlvHeader";
1210 }
1211
GetBytes() const1212 std::unique_ptr<uint8_t[]> ObexOptionalTlvHeader::GetBytes() const
1213 {
1214 if (dataSize_ < 1) {
1215 return nullptr;
1216 }
1217 auto buf = std::make_unique<uint8_t[]>(dataSize_);
1218 (void)memset_s(buf.get(), dataSize_, 0x00, dataSize_);
1219 size_t p = 0;
1220 bool isBigEndian = ObexUtils::SysIsBigEndian();
1221 for (auto ¶m : GetTlvParamters()->GetTlvTriplets()) {
1222 *(buf.get() + p) = param->GetTagId();
1223 p++;
1224 *(buf.get() + p) = param->GetLen();
1225 p++;
1226 (void)memcpy_s(buf.get() + p, dataSize_ - p, param->GetVal(), param->GetLen());
1227 if (!isBigEndian && param->GetUnitLen() > 1) {
1228 ObexUtils::DataReverse(buf.get() + p, param->GetLen(), param->GetUnitLen());
1229 }
1230 p += param->GetLen();
1231 }
1232 return buf;
1233 }
1234
Clone() const1235 std::unique_ptr<ObexOptionalHeader> ObexOptionalTlvHeader::Clone() const
1236 {
1237 return std::make_unique<ObexOptionalTlvHeader>(GetHeaderId(), *GetTlvParamters().get());
1238 }
1239
1240 // ObexTlvParamters
GetTlvTriplets() const1241 const std::vector<std::unique_ptr<TlvTriplet>> &ObexTlvParamters::GetTlvTriplets() const
1242 {
1243 return tlvTriplets_;
1244 }
1245
GetTlvtriplet(const uint8_t tagId) const1246 const TlvTriplet *ObexTlvParamters::GetTlvtriplet(const uint8_t tagId) const
1247 {
1248 auto itr = std::find_if(tlvTriplets_.begin(), tlvTriplets_.end(),
1249 [tagId](const std::unique_ptr<TlvTriplet> &rhs)->bool {
1250 return (tagId == rhs->GetTagId());
1251 });
1252 if (itr != tlvTriplets_.end()) {
1253 return itr->get();
1254 }
1255 return nullptr;
1256 }
1257
AppendTlvtriplet(const TlvTriplet & tlvTriplet)1258 void ObexTlvParamters::AppendTlvtriplet(const TlvTriplet &tlvTriplet)
1259 {
1260 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(tlvTriplet));
1261 }
1262
1263 // ObexDigestChallenge
1264
1265 /************************* OBEX Auth Digest Challenge *******************************/
1266 const uint8_t ObexDigestChallenge::NONCE;
1267 const uint8_t ObexDigestChallenge::OPTIONS;
1268 const uint8_t ObexDigestChallenge::REALM;
GetNonce() const1269 const TlvTriplet *ObexDigestChallenge::GetNonce() const
1270 {
1271 return GetTlvtriplet(ObexDigestChallenge::NONCE);
1272 }
1273
GetOptions() const1274 const TlvTriplet *ObexDigestChallenge::GetOptions() const
1275 {
1276 return GetTlvtriplet(ObexDigestChallenge::OPTIONS);
1277 }
1278
GetRealm() const1279 const TlvTriplet *ObexDigestChallenge::GetRealm() const
1280 {
1281 return GetTlvtriplet(ObexDigestChallenge::REALM);
1282 }
1283
AppendNonce(const uint8_t * nonce,const uint8_t length)1284 void ObexDigestChallenge::AppendNonce(const uint8_t *nonce, const uint8_t length)
1285 {
1286 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestChallenge::NONCE, length, nonce));
1287 }
1288
AppendOptions(const uint8_t options)1289 void ObexDigestChallenge::AppendOptions(const uint8_t options)
1290 {
1291 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestChallenge::OPTIONS, options));
1292 }
1293
AppendRealm(const uint8_t * realm,const uint8_t length)1294 void ObexDigestChallenge::AppendRealm(const uint8_t *realm, const uint8_t length)
1295 {
1296 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestChallenge::REALM, length, realm));
1297 }
1298
1299 /************************* OBEX Auth Digest Response *******************************/
1300 const uint8_t ObexDigestResponse::REQUEST_DIGEST;
1301 const uint8_t ObexDigestResponse::USER_ID;
1302 const uint8_t ObexDigestResponse::NONCE;
1303 const uint8_t ObexDigestResponse::MAX_USER_ID_LEN;
1304
GetRequestDigest() const1305 const TlvTriplet *ObexDigestResponse::GetRequestDigest() const
1306 {
1307 return GetTlvtriplet(ObexDigestResponse::REQUEST_DIGEST);
1308 }
1309
GetUserId() const1310 const TlvTriplet *ObexDigestResponse::GetUserId() const
1311 {
1312 return GetTlvtriplet(ObexDigestResponse::USER_ID);
1313 }
1314
GetNonce() const1315 const TlvTriplet *ObexDigestResponse::GetNonce() const
1316 {
1317 return GetTlvtriplet(ObexDigestResponse::NONCE);
1318 }
1319
AppendRequestDigest(const uint8_t * requestDigest,const uint8_t length)1320 void ObexDigestResponse::AppendRequestDigest(const uint8_t *requestDigest, const uint8_t length)
1321 {
1322 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestResponse::REQUEST_DIGEST, length, requestDigest));
1323 }
1324
AppendUserId(const uint8_t * userId,const uint8_t length)1325 void ObexDigestResponse::AppendUserId(const uint8_t *userId, const uint8_t length)
1326 {
1327 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestResponse::USER_ID, length, userId));
1328 }
1329
AppendNonce(const uint8_t * nonce,const uint8_t length)1330 void ObexDigestResponse::AppendNonce(const uint8_t *nonce, const uint8_t length)
1331 {
1332 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestResponse::NONCE, length, nonce));
1333 }
1334
1335 /************************* OBEX Session Parameter ID *******************************/
1336 const uint8_t ObexSessionParameters::DEVICE_ADDRESS;
1337 const uint8_t ObexSessionParameters::NONCE;
1338 const uint8_t ObexSessionParameters::SESSION_ID;
1339 const uint8_t ObexSessionParameters::NEXT_SEQUENCE_NUMBER;
1340 const uint8_t ObexSessionParameters::TIMEOUT;
1341 const uint8_t ObexSessionParameters::SESSION_OPCODE;
GetDeviceAddress() const1342 const TlvTriplet *ObexSessionParameters::GetDeviceAddress() const
1343 {
1344 return GetTlvtriplet(ObexSessionParameters::DEVICE_ADDRESS);
1345 }
1346
GetNonce() const1347 const TlvTriplet *ObexSessionParameters::GetNonce() const
1348 {
1349 return GetTlvtriplet(ObexSessionParameters::NONCE);
1350 }
1351
GetSessionId() const1352 const TlvTriplet *ObexSessionParameters::GetSessionId() const
1353 {
1354 return GetTlvtriplet(ObexSessionParameters::SESSION_ID);
1355 }
1356
GetNextSeqNum() const1357 const TlvTriplet *ObexSessionParameters::GetNextSeqNum() const
1358 {
1359 return GetTlvtriplet(ObexSessionParameters::NEXT_SEQUENCE_NUMBER);
1360 }
1361
GetTimeout() const1362 const TlvTriplet *ObexSessionParameters::GetTimeout() const
1363 {
1364 return GetTlvtriplet(ObexSessionParameters::TIMEOUT);
1365 }
1366
GetSessionOpcode() const1367 const TlvTriplet *ObexSessionParameters::GetSessionOpcode() const
1368 {
1369 return GetTlvtriplet(ObexSessionParameters::SESSION_OPCODE);
1370 }
1371
AppendDeviceAddress(const uint8_t * deviceAddress,const uint8_t length)1372 void ObexSessionParameters::AppendDeviceAddress(const uint8_t *deviceAddress, const uint8_t length)
1373 {
1374 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::DEVICE_ADDRESS, length, deviceAddress));
1375 }
1376
AppendNonce(const uint8_t * nonce,const uint8_t length)1377 void ObexSessionParameters::AppendNonce(const uint8_t *nonce, const uint8_t length)
1378 {
1379 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::NONCE, length, nonce));
1380 }
1381
AppendSessionId(const uint8_t * sessionId,const uint8_t length)1382 void ObexSessionParameters::AppendSessionId(const uint8_t *sessionId, const uint8_t length)
1383 {
1384 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::SESSION_ID, length, sessionId));
1385 }
1386
AppendNextSeqNum(const uint8_t nextSeqNum)1387 void ObexSessionParameters::AppendNextSeqNum(const uint8_t nextSeqNum)
1388 {
1389 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::NEXT_SEQUENCE_NUMBER, nextSeqNum));
1390 }
1391
AppendTimeout(const uint32_t timeout)1392 void ObexSessionParameters::AppendTimeout(const uint32_t timeout)
1393 {
1394 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::TIMEOUT, timeout));
1395 }
1396
AppendSessionOpcode(const SessionOpcode opcode)1397 void ObexSessionParameters::AppendSessionOpcode(const SessionOpcode opcode)
1398 {
1399 tlvTriplets_.push_back(
1400 std::make_unique<TlvTriplet>(ObexSessionParameters::SESSION_OPCODE, static_cast<uint8_t>(opcode)));
1401 }
1402 } // namespace bluetooth
1403 } // namespace OHOS