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]",
159 isRequest, isConnect, size);
160 isRequest_ = isRequest;
161 uint16_t pos = 0;
162 uint8_t code = buf[pos++];
163 uint16_t packetLengthForCheck = ObexUtils::GetBufData16(buf, pos);
164 OBEX_LOG_DEBUG("ObexHeader Parse: packetLength=%{public}d", int(packetLengthForCheck));
165 pos += UINT16_LENGTH;
166 if (packetLengthForCheck != size) {
167 OBEX_LOG_ERROR("packetLength size is wrong packetSize=%{public}d, actualSize=%{public}d",
168 int(packetLengthForCheck), int(size));
169 return false;
170 }
171 code_ = code;
172 packetLength_ = MIN_PACKET_LENGTH;
173
174 ParseFields(buf, code, pos, isRequest, isConnect);
175
176 if (!ParseOptionalHeaders(buf, size, pos)) {
177 return false;
178 }
179
180 if (packetLength_ != packetLengthForCheck) {
181 OBEX_LOG_ERROR(
182 "parse error packetLength_[%{public}d] != packetLengthForCheck[%{public}d]",
183 packetLength_, packetLengthForCheck);
184 ObexUtils::ObexHeaderDebug(*this);
185 return false;
186 }
187 return true;
188 }
189
ParseBytes(const uint8_t & headerId,const uint8_t * buf,uint16_t & pos)190 void ObexHeader::ParseBytes(const uint8_t &headerId, const uint8_t *buf, uint16_t &pos)
191 {
192 uint16_t dataLen = ObexUtils::GetBufData16(buf, pos) - HDR_BYTES_PREFIX_LENGTH;
193 pos += UINT16_LENGTH;
194 std::unique_ptr<ObexOptionalHeader> header = nullptr;
195 switch (headerId) {
196 case ObexHeader::TYPE:
197 header = std::make_unique<ObexOptionalStringHeader>(headerId, &buf[pos], dataLen);
198 Append(header);
199 break;
200 case ObexHeader::APP_PARAMETERS:
201 case ObexHeader::SESSION_PARAMETERS:
202 case ObexHeader::AUTH_CHALLENGE:
203 case ObexHeader::AUTH_RESPONSE:
204 header = std::make_unique<ObexOptionalTlvHeader>(headerId, &buf[pos], dataLen);
205 Append(header);
206 break;
207 default:
208 header = std::make_unique<ObexOptionalBytesHeader>(headerId, &buf[pos], dataLen);
209 Append(header);
210 break;
211 }
212 pos += dataLen;
213 }
214
ParseUnicodeText(const uint8_t & headerId,const uint8_t * buf,uint16_t & pos)215 void ObexHeader::ParseUnicodeText(const uint8_t &headerId, const uint8_t *buf, uint16_t &pos)
216 {
217 uint16_t bytesLen = ObexUtils::GetBufData16(buf, pos) - HDR_UNICODE_PREFIX_LENGTH;
218 pos += UINT16_LENGTH;
219 if (bytesLen > 0) {
220 auto tmpBuf = std::make_unique<uint8_t[]>(bytesLen);
221 if (memcpy_s(tmpBuf.get(), bytesLen, &buf[pos], bytesLen) != EOK) {
222 OBEX_LOG_ERROR("ParseUnicodeText, memcpy_s fail");
223 return;
224 }
225 if (!ObexUtils::SysIsBigEndian()) {
226 ObexUtils::DataReverse(tmpBuf.get(), bytesLen, UINT16_LENGTH);
227 }
228 std::u16string str((char16_t *)tmpBuf.get());
229 AppendUnicode(headerId, str);
230 } else {
231 AppendUnicode(headerId, u"");
232 }
233 pos += bytesLen;
234 }
235
ObexHeader(const ObexHeader & header,bool fieldOnly)236 ObexHeader::ObexHeader(const ObexHeader &header, bool fieldOnly)
237 {
238 code_ = header.GetFieldCode();
239 isRequest_ = header.isRequest_;
240 uint16_t filedPacketLength = MIN_PACKET_LENGTH;
241 if (header.GetFieldObexVersionNum() != nullptr) {
242 obexVersionNum_ = std::make_unique<uint8_t>();
243 *obexVersionNum_ = *header.GetFieldObexVersionNum();
244 filedPacketLength += 1;
245 }
246 if (header.GetFieldFlags() != nullptr) {
247 flags_ = std::make_unique<uint8_t>();
248 *flags_ = *header.GetFieldFlags();
249 filedPacketLength += 1;
250 }
251 if (header.GetFieldMaxPacketLength() != nullptr) {
252 maxPacketLength_ = std::make_unique<uint16_t>();
253 *maxPacketLength_ = *header.GetFieldMaxPacketLength();
254 filedPacketLength += UINT16_LENGTH;
255 }
256 if (header.GetFieldConstants() != nullptr) {
257 constants_ = std::make_unique<uint8_t>();
258 *constants_ = *header.GetFieldConstants();
259 filedPacketLength += 1;
260 }
261 if (fieldOnly) {
262 packetLength_ = filedPacketLength;
263 } else {
264 packetLength_ = header.GetFieldPacketLength();
265 for (auto &optHeader : header.GetOptionalHeaders()) {
266 headerIndexMap_.insert(std::pair<uint8_t, size_t>(optHeader->GetHeaderId(), optionalHeaders_.size()));
267 optionalHeaders_.push_back(optHeader->Clone());
268 }
269 SetExtendBodyObject(header.GetExtendBodyObject());
270 }
271 }
272
CreateRequest(ObexOpeId opcode)273 std::unique_ptr<ObexHeader> ObexHeader::CreateRequest(ObexOpeId opcode)
274 {
275 auto header = std::make_unique<ObexHeader>();
276 header->isRequest_ = true;
277 header->code_ = static_cast<uint8_t>(opcode);
278 // code + pack length
279 header->packetLength_ = MIN_PACKET_LENGTH;
280 if (opcode == ObexOpeId::CONNECT) {
281 header->SetFieldObexVersionNum(OBEX_VERSION);
282 header->SetFieldFlags(0x00);
283 header->SetFieldMaxPacketLength(OBEX_DEFAULT_MTU);
284 } else if (opcode == ObexOpeId::SETPATH) {
285 // 0bit backup a level before applying name (equivalent to ../ on many systems)
286 // 1bit Don’t create folder if it does not exist, return an error instead.
287 header->SetFieldFlags(0x00);
288 header->SetFieldConstants(0x00);
289 }
290 return header;
291 }
292
CreateResponse(ObexRspCode rspCode,bool isConnectResp)293 std::unique_ptr<ObexHeader> ObexHeader::CreateResponse(ObexRspCode rspCode, bool isConnectResp)
294 {
295 auto header = std::make_unique<ObexHeader>();
296 header->isRequest_ = false;
297 header->code_ = static_cast<uint8_t>(rspCode);
298 // code + pack length
299 header->packetLength_ = MIN_PACKET_LENGTH;
300 if (isConnectResp) {
301 header->SetFieldObexVersionNum(OBEX_VERSION);
302 header->SetFieldFlags(0x00);
303 header->SetFieldMaxPacketLength(OBEX_DEFAULT_MTU);
304 }
305 return header;
306 }
307
ParseRequest(const uint8_t * buf,const uint16_t size)308 std::unique_ptr<ObexHeader> ObexHeader::ParseRequest(const uint8_t *buf, const uint16_t size)
309 {
310 auto header = std::make_unique<ObexHeader>();
311 if (header->Parse(buf, size, true, false)) {
312 return header;
313 }
314 return nullptr;
315 }
316
ParseResponse(const uint8_t * buf,const uint16_t size,bool isConnect)317 std::unique_ptr<ObexHeader> ObexHeader::ParseResponse(const uint8_t *buf, const uint16_t size, bool isConnect)
318 {
319 auto header = std::make_unique<ObexHeader>();
320 if (header->Parse(buf, size, false, isConnect)) {
321 return header;
322 }
323 return nullptr;
324 }
325
GetFieldCode() const326 uint8_t ObexHeader::GetFieldCode() const
327 {
328 return code_;
329 }
330
GetFieldPacketLength() const331 uint16_t ObexHeader::GetFieldPacketLength() const
332 {
333 return packetLength_;
334 }
335
GetFieldObexVersionNum() const336 const uint8_t *ObexHeader::GetFieldObexVersionNum() const
337 {
338 if (obexVersionNum_ == nullptr) {
339 return nullptr;
340 }
341 return obexVersionNum_.get();
342 }
343
GetFieldFlags() const344 const uint8_t *ObexHeader::GetFieldFlags() const
345 {
346 if (flags_ == nullptr) {
347 return nullptr;
348 }
349 return flags_.get();
350 }
351
GetFieldMaxPacketLength() const352 const uint16_t *ObexHeader::GetFieldMaxPacketLength() const
353 {
354 if (maxPacketLength_ == nullptr) {
355 return nullptr;
356 }
357 return maxPacketLength_.get();
358 }
359
GetFieldConstants() const360 const uint8_t *ObexHeader::GetFieldConstants() const
361 {
362 if (constants_ == nullptr) {
363 return nullptr;
364 }
365 return constants_.get();
366 }
367
SetRespCode(uint8_t code)368 void ObexHeader::SetRespCode(uint8_t code)
369 {
370 if (!isRequest_) {
371 code_ = code;
372 }
373 }
374
SetFinalBit(bool finalBit)375 void ObexHeader::SetFinalBit(bool finalBit)
376 {
377 if (finalBit) {
378 code_ = code_ | OBEX_FINAL_BIT_MASK;
379 } else {
380 code_ = code_ & ~OBEX_FINAL_BIT_MASK;
381 }
382 }
383
SetFieldObexVersionNum(const uint8_t obexVersionNum)384 void ObexHeader::SetFieldObexVersionNum(const uint8_t obexVersionNum)
385 {
386 if (obexVersionNum_ == nullptr) {
387 obexVersionNum_ = std::make_unique<uint8_t>();
388 packetLength_ += 1;
389 }
390 *obexVersionNum_ = obexVersionNum;
391 }
392
SetFieldFlags(const uint8_t flags)393 void ObexHeader::SetFieldFlags(const uint8_t flags)
394 {
395 if (flags_ == nullptr) {
396 flags_ = std::make_unique<uint8_t>();
397 packetLength_ += 1;
398 }
399 *flags_ = flags;
400 }
401
SetFieldMaxPacketLength(const uint16_t maxPacketLength)402 void ObexHeader::SetFieldMaxPacketLength(const uint16_t maxPacketLength)
403 {
404 if (maxPacketLength_ == nullptr) {
405 maxPacketLength_ = std::make_unique<uint16_t>();
406 packetLength_ += UINT16_LENGTH;
407 }
408 *maxPacketLength_ = maxPacketLength;
409 }
410
SetFieldConstants(uint8_t constants)411 void ObexHeader::SetFieldConstants(uint8_t constants)
412 {
413 if (constants_ == nullptr) {
414 constants_ = std::make_unique<uint8_t>();
415 packetLength_ += 1;
416 }
417 *constants_ = constants;
418 }
419
Append(std::unique_ptr<ObexOptionalHeader> & header)420 void ObexHeader::Append(std::unique_ptr<ObexOptionalHeader> &header)
421 {
422 uint8_t headerId = header->GetHeaderId();
423 if (HasHeader(headerId)) {
424 OBEX_LOG_ERROR("duplicate headerId: 0x%02X", headerId);
425 return;
426 }
427 headerIndexMap_[headerId] = optionalHeaders_.size();
428 packetLength_ += header->GetHeaderTotalSize();
429 optionalHeaders_.push_back(std::move(header));
430 }
431
432 template<typename T>
GetItem(uint8_t headerId) const433 const T ObexHeader::GetItem(uint8_t headerId) const
434 {
435 const ObexOptionalHeader *headerItem = Get(headerId);
436 if (headerItem == nullptr) {
437 return nullptr;
438 }
439 return static_cast<T>(const_cast<ObexOptionalHeader *>(headerItem));
440 }
441
AppendUnicode(const uint8_t headerId,const std::u16string & text)442 void ObexHeader::AppendUnicode(const uint8_t headerId, const std::u16string &text)
443 {
444 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalUnicodeHeader>(headerId, text);
445 Append(header);
446 }
447
AppendByte(const uint8_t headerId,const uint8_t byte)448 void ObexHeader::AppendByte(const uint8_t headerId, const uint8_t byte)
449 {
450 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalByteHeader>(headerId, byte);
451 Append(header);
452 }
453
AppendBytes(const uint8_t headerId,const uint8_t * byteBuf,const uint32_t size)454 void ObexHeader::AppendBytes(const uint8_t headerId, const uint8_t *byteBuf, const uint32_t size)
455 {
456 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalBytesHeader>(headerId, byteBuf, size);
457 Append(header);
458 }
459
AppendWord(const uint8_t headerId,const uint32_t word)460 void ObexHeader::AppendWord(const uint8_t headerId, const uint32_t word)
461 {
462 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalWordHeader>(headerId, word);
463 Append(header);
464 }
465
AppendString(const uint8_t headerId,const std::string & str)466 void ObexHeader::AppendString(const uint8_t headerId, const std::string &str)
467 {
468 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalStringHeader>(headerId, str);
469 Append(header);
470 }
471
AppendTlvTriplets(const uint8_t headerId,ObexTlvParamters & tlvParamters)472 void ObexHeader::AppendTlvTriplets(const uint8_t headerId, ObexTlvParamters &tlvParamters)
473 {
474 std::unique_ptr<ObexOptionalHeader> header = std::make_unique<ObexOptionalTlvHeader>(headerId, tlvParamters);
475 Append(header);
476 }
477
GetOptionalHeaders() const478 std::vector<std::unique_ptr<ObexOptionalHeader>> const &ObexHeader::GetOptionalHeaders() const
479 {
480 return optionalHeaders_;
481 }
482
483 // Header add methods
484 // bytes
AppendItemTarget(const uint8_t * target,const uint16_t length)485 bool ObexHeader::AppendItemTarget(const uint8_t *target, const uint16_t length)
486 {
487 if (optionalHeaders_.size() != 0) {
488 bool error = true;
489 if (optionalHeaders_.size() == 1) {
490 if (optionalHeaders_.at(0)->GetHeaderId() == ObexHeader::SESSION_SEQUENCE_NUMBER) {
491 error = false;
492 }
493 }
494 if (error) {
495 OBEX_LOG_ERROR("Target must the first header in the request");
496 return false;
497 }
498 }
499 if (length != TARGET_LENGTH) {
500 OBEX_LOG_ERROR("AppendItemTarget length is wrong!");
501 return false;
502 }
503 AppendBytes(ObexHeader::TARGET, target, length);
504 return true;
505 }
506
AppendItemTimeIso8601(const uint8_t * time,const uint16_t length)507 void ObexHeader::AppendItemTimeIso8601(const uint8_t *time, const uint16_t length)
508 {
509 AppendBytes(ObexHeader::TIME_ISO8601, time, length);
510 }
511
AppendItemHttp(const uint8_t * http,const uint16_t length)512 void ObexHeader::AppendItemHttp(const uint8_t *http, const uint16_t length)
513 {
514 AppendBytes(ObexHeader::HTTP, http, length);
515 }
516
AppendItemBody(const uint8_t * body,const uint16_t length)517 void ObexHeader::AppendItemBody(const uint8_t *body, const uint16_t length)
518 {
519 AppendBytes(ObexHeader::BODY, body, length);
520 }
521
AppendItemEndBody(const uint8_t * endBody,const uint16_t length)522 void ObexHeader::AppendItemEndBody(const uint8_t *endBody, const uint16_t length)
523 {
524 AppendBytes(ObexHeader::END_OF_BODY, endBody, length);
525 }
526
AppendItemWho(const uint8_t * who,const uint16_t length)527 void ObexHeader::AppendItemWho(const uint8_t *who, const uint16_t length)
528 {
529 AppendBytes(ObexHeader::WHO, who, length);
530 }
531
AppendItemObjectClass(const uint8_t * objectClass,const uint16_t length)532 void ObexHeader::AppendItemObjectClass(const uint8_t *objectClass, const uint16_t length)
533 {
534 AppendBytes(ObexHeader::OBJECT_CLASS, objectClass, length);
535 }
536
537 // tlv
AppendItemAppParams(ObexTlvParamters & params)538 void ObexHeader::AppendItemAppParams(ObexTlvParamters ¶ms)
539 {
540 AppendTlvTriplets(ObexHeader::APP_PARAMETERS, params);
541 }
542
AppendItemAuthChallenges(ObexDigestChallenge & challenges)543 void ObexHeader::AppendItemAuthChallenges(ObexDigestChallenge &challenges)
544 {
545 AppendTlvTriplets(ObexHeader::AUTH_CHALLENGE, challenges);
546 }
547
AppendItemAuthResponse(ObexDigestResponse & responses)548 void ObexHeader::AppendItemAuthResponse(ObexDigestResponse &responses)
549 {
550 AppendTlvTriplets(ObexHeader::AUTH_RESPONSE, responses);
551 }
552
AppendItemSessionParams(ObexSessionParameters & params)553 bool ObexHeader::AppendItemSessionParams(ObexSessionParameters ¶ms)
554 {
555 if (optionalHeaders_.size() != 0) {
556 OBEX_LOG_ERROR("SessionParams must the first header in the request");
557 return false;
558 }
559 AppendTlvTriplets(ObexHeader::SESSION_PARAMETERS, params);
560 return true;
561 }
562
563 // String
AppendItemType(const std::string & type)564 void ObexHeader::AppendItemType(const std::string &type)
565 {
566 AppendString(ObexHeader::TYPE, type);
567 }
568
569 // Word
AppendItemConnectionId(const uint32_t connectionId)570 bool ObexHeader::AppendItemConnectionId(const uint32_t connectionId)
571 {
572 if (optionalHeaders_.size() != 0) {
573 bool error = true;
574 if (optionalHeaders_.size() == 1) {
575 if (optionalHeaders_.at(0)->GetHeaderId() == ObexHeader::SESSION_SEQUENCE_NUMBER) {
576 error = false;
577 }
578 }
579 if (error) {
580 OBEX_LOG_ERROR("ConnectionId must the first header in the request");
581 return false;
582 }
583 }
584 AppendWord(ObexHeader::CONNECTION_ID, connectionId);
585 return true;
586 }
587
AppendItemCount(const uint32_t count)588 void ObexHeader::AppendItemCount(const uint32_t count)
589 {
590 AppendWord(ObexHeader::COUNT, count);
591 }
592
AppendItemLength(const uint32_t length)593 void ObexHeader::AppendItemLength(const uint32_t length)
594 {
595 AppendWord(ObexHeader::LENGTH, length);
596 }
597
AppendItemTime4byte(const uint32_t time)598 void ObexHeader::AppendItemTime4byte(const uint32_t time)
599 {
600 AppendWord(ObexHeader::TIME_4BYTE_VERSION, time);
601 }
602
AppendItemPermissions(const uint32_t permissions)603 void ObexHeader::AppendItemPermissions(const uint32_t permissions)
604 {
605 AppendWord(ObexHeader::PERMISSIONS, permissions);
606 }
607
608 // Unicode
AppendItemName(const std::u16string & name)609 void ObexHeader::AppendItemName(const std::u16string &name)
610 {
611 AppendUnicode(ObexHeader::NAME, name);
612 }
613
AppendItemDescription(const std::u16string & description)614 void ObexHeader::AppendItemDescription(const std::u16string &description)
615 {
616 AppendUnicode(ObexHeader::DESCRIPTION, description);
617 }
618
AppendItemDestName(const std::u16string & destName)619 void ObexHeader::AppendItemDestName(const std::u16string &destName)
620 {
621 AppendUnicode(ObexHeader::DEST_NAME, destName);
622 }
623
624 // byte
AppendItemSessionSeqNum(const uint8_t num)625 bool ObexHeader::AppendItemSessionSeqNum(const uint8_t num)
626 {
627 if (optionalHeaders_.size() != 0) {
628 OBEX_LOG_ERROR("SessionSeqNum must the first header in the request");
629 return false;
630 }
631 AppendByte(ObexHeader::SESSION_SEQUENCE_NUMBER, num);
632 return true;
633 }
634
AppendItemActionId(const ObexActionType actionId)635 void ObexHeader::AppendItemActionId(const ObexActionType actionId)
636 {
637 AppendByte(ObexHeader::ACTION_ID, static_cast<uint8_t>(actionId));
638 }
639
AppendItemSrm(const bool srm)640 void ObexHeader::AppendItemSrm(const bool srm)
641 {
642 AppendByte(ObexHeader::SRM, srm ? ObexHdrSrmMode::SINGLE : ObexHdrSrmMode::NORMAL);
643 }
644
AppendItemSrmp()645 void ObexHeader::AppendItemSrmp()
646 {
647 AppendByte(ObexHeader::SRMP, ObexHdrSrmpMode::WAIT);
648 }
649
650 // obex header get methods
Get(uint8_t headerId) const651 const ObexOptionalHeader *ObexHeader::Get(uint8_t headerId) const
652 {
653 if (!HasHeader(headerId)) {
654 return nullptr;
655 }
656 size_t index = headerIndexMap_.at(headerId);
657 return optionalHeaders_.at(index).get();
658 }
659
660 // ObexOptionalHeader
GetItemTarget() const661 const ObexOptionalHeader *ObexHeader::GetItemTarget() const
662 {
663 return Get(ObexHeader::TARGET);
664 }
665
GetItemTimeIso8601() const666 const ObexOptionalHeader *ObexHeader::GetItemTimeIso8601() const
667 {
668 return Get(ObexHeader::TIME_ISO8601);
669 }
670
GetItemHttp() const671 const ObexOptionalHeader *ObexHeader::GetItemHttp() const
672 {
673 return Get(ObexHeader::HTTP);
674 }
675
GetItemBody() const676 const ObexOptionalHeader *ObexHeader::GetItemBody() const
677 {
678 return Get(ObexHeader::BODY);
679 }
680
GetItemEndBody() const681 const ObexOptionalHeader *ObexHeader::GetItemEndBody() const
682 {
683 return Get(ObexHeader::END_OF_BODY);
684 }
685
GetItemWho() const686 const ObexOptionalHeader *ObexHeader::GetItemWho() const
687 {
688 return Get(ObexHeader::WHO);
689 }
690
GetItemObjectClass() const691 const ObexOptionalHeader *ObexHeader::GetItemObjectClass() const
692 {
693 return Get(ObexHeader::OBJECT_CLASS);
694 }
695
696 // ObexOptionalTlvHeader
GetItemAuthChallenges() const697 const ObexOptionalTlvHeader *ObexHeader::GetItemAuthChallenges() const
698 {
699 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::AUTH_CHALLENGE);
700 }
701
GetItemSessionParams() const702 const ObexOptionalTlvHeader *ObexHeader::GetItemSessionParams() const
703 {
704 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::SESSION_PARAMETERS);
705 }
706
GetItemAppParams() const707 const ObexOptionalTlvHeader *ObexHeader::GetItemAppParams() const
708 {
709 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::APP_PARAMETERS);
710 }
711
GetItemAuthResponse() const712 const ObexOptionalTlvHeader *ObexHeader::GetItemAuthResponse() const
713 {
714 return GetItem<ObexOptionalTlvHeader *>(ObexHeader::AUTH_RESPONSE);
715 }
716
717 // ObexOptionalStringHeader
GetItemType() const718 const ObexOptionalStringHeader *ObexHeader::GetItemType() const
719 {
720 return GetItem<ObexOptionalStringHeader *>(ObexHeader::TYPE);
721 }
722
723 // ObexOptionalWordHeader
GetItemCount() const724 const ObexOptionalWordHeader *ObexHeader::GetItemCount() const
725 {
726 return GetItem<ObexOptionalWordHeader *>(ObexHeader::COUNT);
727 }
728
GetItemLength() const729 const ObexOptionalWordHeader *ObexHeader::GetItemLength() const
730 {
731 return GetItem<ObexOptionalWordHeader *>(ObexHeader::LENGTH);
732 }
733
GetItemTime4byte() const734 const ObexOptionalWordHeader *ObexHeader::GetItemTime4byte() const
735 {
736 return GetItem<ObexOptionalWordHeader *>(ObexHeader::TIME_4BYTE_VERSION);
737 }
738
GetItemConnectionId() const739 const ObexOptionalWordHeader *ObexHeader::GetItemConnectionId() const
740 {
741 return GetItem<ObexOptionalWordHeader *>(ObexHeader::CONNECTION_ID);
742 }
743
GetItemPermissions() const744 const ObexOptionalWordHeader *ObexHeader::GetItemPermissions() const
745 {
746 return GetItem<ObexOptionalWordHeader *>(ObexHeader::PERMISSIONS);
747 }
748
749 // ObexOptionalUnicodeHeader
GetItemName() const750 const ObexOptionalUnicodeHeader *ObexHeader::GetItemName() const
751 {
752 return GetItem<ObexOptionalUnicodeHeader *>(ObexHeader::NAME);
753 }
754
GetItemDescription() const755 const ObexOptionalUnicodeHeader *ObexHeader::GetItemDescription() const
756 {
757 return GetItem<ObexOptionalUnicodeHeader *>(ObexHeader::DESCRIPTION);
758 }
759
GetItemDestName() const760 const ObexOptionalUnicodeHeader *ObexHeader::GetItemDestName() const
761 {
762 return GetItem<ObexOptionalUnicodeHeader *>(ObexHeader::DEST_NAME);
763 }
764
765 // ObexOptionalByteHeader
GetItemSessionSeqNum() const766 const ObexOptionalByteHeader *ObexHeader::GetItemSessionSeqNum() const
767 {
768 return GetItem<ObexOptionalByteHeader *>(ObexHeader::SESSION_SEQUENCE_NUMBER);
769 }
770
GetItemActionId() const771 const ObexOptionalByteHeader *ObexHeader::GetItemActionId() const
772 {
773 return GetItem<ObexOptionalByteHeader *>(ObexHeader::ACTION_ID);
774 }
775
HasHeader(const uint8_t headerId) const776 bool ObexHeader::HasHeader(const uint8_t headerId) const
777 {
778 return headerIndexMap_.find(headerId) != headerIndexMap_.end();
779 }
780
RemoveItem(const uint8_t headerId)781 void ObexHeader::RemoveItem(const uint8_t headerId)
782 {
783 if (!HasHeader(headerId)) {
784 return;
785 }
786 size_t index = headerIndexMap_.at(headerId);
787 auto &header = optionalHeaders_.at(index);
788 packetLength_ -= header->GetHeaderTotalSize();
789 optionalHeaders_.erase(optionalHeaders_.begin() + index);
790 headerIndexMap_.clear();
791 for (size_t i = 0; i < optionalHeaders_.size(); i++) {
792 auto &item = optionalHeaders_.at(i);
793 headerIndexMap_[item->GetHeaderId()] = i;
794 }
795 }
796
GetItemSrm() const797 bool ObexHeader::GetItemSrm() const
798 {
799 auto headerItem = GetItem<ObexOptionalByteHeader *>(ObexHeader::SRM);
800 if (headerItem == nullptr) {
801 return false;
802 }
803 return headerItem->GetByte() == ObexHdrSrmMode::SINGLE;
804 }
805
GetItemSrmp() const806 bool ObexHeader::GetItemSrmp() const
807 {
808 auto headerItem = GetItem<ObexOptionalByteHeader *>(ObexHeader::SRMP);
809 if (headerItem == nullptr) {
810 return false;
811 }
812 return headerItem->GetByte() == ObexHdrSrmpMode::WAIT;
813 }
814
Build() const815 std::unique_ptr<ObexPacket> ObexHeader::Build() const
816 {
817 auto obexPacket = std::make_unique<ObexPacket>(packetLength_);
818 uint8_t *packetBuf = obexPacket->GetBuffer();
819 uint16_t pos = 0;
820 packetBuf[pos++] = code_;
821 bool isBigEndian = ObexUtils::SysIsBigEndian();
822 ObexUtils::SetBufData16(packetBuf, pos, packetLength_);
823 pos += UINT16_LENGTH;
824 if (obexVersionNum_ != nullptr) {
825 packetBuf[pos++] = obexVersionNum_.get()[0];
826 }
827 if (flags_ != nullptr) {
828 packetBuf[pos++] = flags_.get()[0];
829 }
830 if (constants_ != nullptr) {
831 packetBuf[pos++] = constants_.get()[0];
832 }
833 if (maxPacketLength_ != nullptr) {
834 ObexUtils::SetBufData16(packetBuf, pos, maxPacketLength_.get()[0]);
835 pos += UINT16_LENGTH;
836 }
837 for (auto &headerItem : optionalHeaders_) {
838 packetBuf[pos++] = headerItem->GetHeaderId();
839 if (headerItem->HasLengthField()) {
840 ObexUtils::SetBufData16(packetBuf, pos, headerItem->GetHeaderTotalSize());
841 pos += UINT16_LENGTH;
842 }
843 (void)memcpy_s(
844 &packetBuf[pos], packetLength_ - pos, headerItem->GetBytes().get(), headerItem->GetHeaderDataSize());
845 if (!isBigEndian && headerItem->GetHeaderUnitLen() > 1) {
846 ObexUtils::DataReverse(&packetBuf[pos], headerItem->GetHeaderDataSize(), headerItem->GetHeaderUnitLen());
847 }
848 pos += headerItem->GetHeaderDataSize();
849 }
850 return obexPacket;
851 }
852
GetExtendBodyObject() const853 const std::shared_ptr<ObexBodyObject> &ObexHeader::GetExtendBodyObject() const
854 {
855 return extendBodyObject_;
856 }
857
SetExtendBodyObject(const std::shared_ptr<ObexBodyObject> & extendBodyObject)858 void ObexHeader::SetExtendBodyObject(const std::shared_ptr<ObexBodyObject> &extendBodyObject)
859 {
860 extendBodyObject_ = extendBodyObject;
861 }
862
TlvTriplet()863 TlvTriplet::TlvTriplet()
864 {
865 tagId_ = 0x00;
866 len_ = 0x00;
867 unitLen_ = 1;
868 }
869
TlvTriplet(const uint8_t tagId,const uint8_t len,const uint8_t * val,const uint8_t unitLen)870 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint8_t len, const uint8_t *val, const uint8_t unitLen)
871 {
872 tagId_ = tagId;
873 len_ = len;
874 unitLen_ = unitLen;
875 val_.insert(val_.end(), val, val + len);
876 }
877
TlvTriplet(const TlvTriplet & tlvTriplet)878 TlvTriplet::TlvTriplet(const TlvTriplet &tlvTriplet)
879 : TlvTriplet(tlvTriplet.tagId_, tlvTriplet.len_, tlvTriplet.val_.data(), tlvTriplet.unitLen_)
880 {}
881
TlvTriplet(const uint8_t tagId,const uint8_t val)882 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint8_t val)
883 : TlvTriplet(tagId, static_cast<uint8_t>(1), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(1))
884 {}
885
TlvTriplet(const uint8_t tagId,const uint16_t val)886 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint16_t val)
887 : TlvTriplet(tagId, static_cast<uint8_t>(2), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(2))
888 {}
889
TlvTriplet(const uint8_t tagId,const uint32_t val)890 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint32_t val)
891 : TlvTriplet(tagId, static_cast<uint8_t>(4), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(4))
892 {}
893
TlvTriplet(const uint8_t tagId,const uint64_t val)894 TlvTriplet::TlvTriplet(const uint8_t tagId, const uint64_t val)
895 : TlvTriplet(tagId, static_cast<uint8_t>(8), reinterpret_cast<const uint8_t *>(&val), static_cast<uint8_t>(8))
896 {}
897
GetTagId() const898 uint8_t TlvTriplet::GetTagId() const
899 {
900 return tagId_;
901 }
902
GetLen() const903 uint8_t TlvTriplet::GetLen() const
904 {
905 return len_;
906 }
907
GetUnitLen() const908 uint8_t TlvTriplet::GetUnitLen() const
909 {
910 return unitLen_;
911 }
912
GetVal() const913 const uint8_t *TlvTriplet::GetVal() const
914 {
915 return val_.data();
916 }
917
GetUint16() const918 uint16_t TlvTriplet::GetUint16() const
919 {
920 if (len_ == ObexHeader::UINT16_LENGTH) {
921 if (unitLen_ > 1) {
922 return *(reinterpret_cast<const uint16_t *>(GetVal()));
923 }
924 return ObexUtils::GetBufData16(GetVal());
925 }
926 return 0;
927 }
928
GetUint32() const929 uint32_t TlvTriplet::GetUint32() const
930 {
931 if (len_ == ObexHeader::UINT32_LENGTH) {
932 if (unitLen_ > 1) {
933 return *(reinterpret_cast<const uint32_t *>(GetVal()));
934 }
935 return ObexUtils::GetBufData32(GetVal());
936 }
937 return 0;
938 }
939
GetUint64() const940 uint64_t TlvTriplet::GetUint64() const
941 {
942 if (len_ == ObexHeader::UINT64_LENGTH) {
943 if (unitLen_ > 1) {
944 return *(reinterpret_cast<const uint64_t *>(GetVal()));
945 }
946 return ObexUtils::GetBufData64(GetVal());
947 }
948 return 0;
949 }
950
ObexOptionalHeader(uint8_t headerId)951 ObexOptionalHeader::ObexOptionalHeader(uint8_t headerId)
952 {
953 headerId_ = headerId;
954 dataSize_ = 0;
955 unitLen_ = 1;
956 }
957
GetHeaderId() const958 uint8_t ObexOptionalHeader::GetHeaderId() const
959 {
960 return headerId_;
961 }
962
GetHeaderTotalSize() const963 uint16_t ObexOptionalHeader::GetHeaderTotalSize() const
964 {
965 uint8_t prefixLen = 1;
966 if (HasLengthField()) {
967 prefixLen += ObexHeader::UINT16_LENGTH;
968 }
969 return prefixLen + GetHeaderDataSize();
970 }
971
GetHeaderDataSize() const972 uint16_t ObexOptionalHeader::GetHeaderDataSize() const
973 {
974 return dataSize_;
975 }
976
GetHeaderUnitLen() const977 uint8_t ObexOptionalHeader::GetHeaderUnitLen() const
978 {
979 return unitLen_;
980 }
981
982 // ObexOptionalBytesHeader
ObexOptionalBytesHeader(const uint8_t headerId,const uint8_t * data,const uint16_t dataSize,const uint16_t unitLen)983 ObexOptionalBytesHeader::ObexOptionalBytesHeader(
984 const uint8_t headerId, const uint8_t *data, const uint16_t dataSize, const uint16_t unitLen)
985 : ObexOptionalHeader(headerId)
986 {
987 dataSize_ = dataSize;
988 data_.insert(data_.end(), data, data + dataSize);
989 unitLen_ = unitLen;
990 }
991
GetBytes() const992 std::unique_ptr<uint8_t[]> ObexOptionalBytesHeader::GetBytes() const
993 {
994 if (dataSize_ < 1) {
995 return nullptr;
996 }
997 if (data_.size() == 0) {
998 return nullptr;
999 }
1000 auto buf = std::make_unique<uint8_t[]>(dataSize_);
1001 (void)memcpy_s(buf.get(), dataSize_, data_.data(), dataSize_);
1002 return buf;
1003 }
1004
HasLengthField() const1005 bool ObexOptionalBytesHeader::HasLengthField() const
1006 {
1007 return true;
1008 }
1009
GetHeaderClassType() const1010 ObexHeaderDataType ObexOptionalBytesHeader::GetHeaderClassType() const
1011 {
1012 return ObexHeaderDataType::BYTES;
1013 }
1014
GetHeaderClassTypeName() const1015 std::string ObexOptionalBytesHeader::GetHeaderClassTypeName() const
1016 {
1017 return "ObexOptionalBytesHeader";
1018 }
1019
Clone() const1020 std::unique_ptr<ObexOptionalHeader> ObexOptionalBytesHeader::Clone() const
1021 {
1022 return std::make_unique<ObexOptionalBytesHeader>(GetHeaderId(), data_.data(), dataSize_, unitLen_);
1023 }
1024
1025 // ObexOptionalStringHeader
ObexOptionalStringHeader(const uint8_t headerId,const std::string & str)1026 ObexOptionalStringHeader::ObexOptionalStringHeader(const uint8_t headerId, const std::string &str)
1027 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<char *>(str.c_str())),
1028 (str.size() == 0) ? 0 : (str.size() + 1), 1)
1029 {}
1030
ObexOptionalStringHeader(const uint8_t headerId,const uint8_t * data,const uint16_t dataSize)1031 ObexOptionalStringHeader::ObexOptionalStringHeader(const uint8_t headerId,
1032 const uint8_t *data, const uint16_t dataSize)
1033 : ObexOptionalBytesHeader(headerId, data, dataSize)
1034 {}
1035
GetString() const1036 std::string ObexOptionalStringHeader::GetString() const
1037 {
1038 if (dataSize_ == 0) {
1039 return "";
1040 }
1041 std::string str((char *)data_.data(), dataSize_ - 1);
1042 return str;
1043 }
1044
GetHeaderClassType() const1045 ObexHeaderDataType ObexOptionalStringHeader::GetHeaderClassType() const
1046 {
1047 return ObexHeaderDataType::STRING;
1048 }
1049
GetHeaderClassTypeName() const1050 std::string ObexOptionalStringHeader::GetHeaderClassTypeName() const
1051 {
1052 return "ObexOptionalStringHeader";
1053 }
1054
Clone() const1055 std::unique_ptr<ObexOptionalHeader> ObexOptionalStringHeader::Clone() const
1056 {
1057 return std::make_unique<ObexOptionalStringHeader>(GetHeaderId(), GetString());
1058 }
1059
1060 // ObexOptionalUnicodeHeader
ObexOptionalUnicodeHeader(const uint8_t headerId,const std::u16string & unicodeText)1061 ObexOptionalUnicodeHeader::ObexOptionalUnicodeHeader(const uint8_t headerId, const std::u16string &unicodeText)
1062 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<char16_t *>(unicodeText.c_str())),
1063 (unicodeText.size() == 0) ? 0 : ((unicodeText.size() + 1) * ObexHeader::U16STRING_LENGTH),
1064 ObexHeader::U16STRING_LENGTH)
1065 {}
GetUnicodeText() const1066 std::u16string ObexOptionalUnicodeHeader::GetUnicodeText() const
1067 {
1068 if (dataSize_ == 0) {
1069 return u"";
1070 }
1071 std::u16string str(
1072 (char16_t *)data_.data(), (dataSize_ - ObexHeader::U16STRING_NULL_LENGTH) / ObexHeader::U16STRING_LENGTH);
1073 return str;
1074 }
1075
GetHeaderClassType() const1076 ObexHeaderDataType ObexOptionalUnicodeHeader::GetHeaderClassType() const
1077 {
1078 return ObexHeaderDataType::UNICODE_TEXT;
1079 }
1080
GetHeaderClassTypeName() const1081 std::string ObexOptionalUnicodeHeader::GetHeaderClassTypeName() const
1082 {
1083 return "ObexOptionalUnicodeHeader";
1084 }
1085
Clone() const1086 std::unique_ptr<ObexOptionalHeader> ObexOptionalUnicodeHeader::Clone() const
1087 {
1088 return std::make_unique<ObexOptionalUnicodeHeader>(GetHeaderId(), GetUnicodeText());
1089 }
1090
1091 // ObexOptionalByteHeader
ObexOptionalByteHeader(const uint8_t headerId,const uint8_t byte)1092 ObexOptionalByteHeader::ObexOptionalByteHeader(const uint8_t headerId, const uint8_t byte)
1093 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<uint8_t *>(&byte)), 1)
1094 {}
HasLengthField() const1095 bool ObexOptionalByteHeader::HasLengthField() const
1096 {
1097 return false;
1098 }
1099
GetByte() const1100 uint8_t ObexOptionalByteHeader::GetByte() const
1101 {
1102 return data_.data()[0];
1103 }
1104
GetHeaderClassType() const1105 ObexHeaderDataType ObexOptionalByteHeader::GetHeaderClassType() const
1106 {
1107 return ObexHeaderDataType::BYTE;
1108 }
1109
GetHeaderClassTypeName() const1110 std::string ObexOptionalByteHeader::GetHeaderClassTypeName() const
1111 {
1112 return "ObexOptionalByteHeader";
1113 }
1114
Clone() const1115 std::unique_ptr<ObexOptionalHeader> ObexOptionalByteHeader::Clone() const
1116 {
1117 return std::make_unique<ObexOptionalByteHeader>(GetHeaderId(), GetByte());
1118 }
1119
1120 // ObexOptionalWordHeader
ObexOptionalWordHeader(const uint8_t headerId,const uint32_t word)1121 ObexOptionalWordHeader::ObexOptionalWordHeader(const uint8_t headerId, const uint32_t word)
1122 : ObexOptionalBytesHeader(headerId, reinterpret_cast<uint8_t *>(const_cast<uint32_t *>(&word)),
1123 ObexHeader::UINT32_LENGTH, ObexHeader::UINT32_LENGTH)
1124 {}
GetWord() const1125 uint32_t ObexOptionalWordHeader::GetWord() const
1126 {
1127 return ((const uint32_t *)data_.data())[0];
1128 }
1129
GetHeaderClassType() const1130 ObexHeaderDataType ObexOptionalWordHeader::GetHeaderClassType() const
1131 {
1132 return ObexHeaderDataType::WORD;
1133 }
1134
GetHeaderClassTypeName() const1135 std::string ObexOptionalWordHeader::GetHeaderClassTypeName() const
1136 {
1137 return "ObexOptionalWordHeader";
1138 }
1139
Clone() const1140 std::unique_ptr<ObexOptionalHeader> ObexOptionalWordHeader::Clone() const
1141 {
1142 return std::make_unique<ObexOptionalWordHeader>(GetHeaderId(), GetWord());
1143 }
1144
HasLengthField() const1145 bool ObexOptionalWordHeader::HasLengthField() const
1146 {
1147 return false;
1148 }
1149
1150 // ObexOptionalTLVHeader
ObexOptionalTlvHeader(const uint8_t headerId)1151 ObexOptionalTlvHeader::ObexOptionalTlvHeader(const uint8_t headerId) : ObexOptionalHeader(headerId)
1152 {
1153 dataSize_ = 0;
1154 unitLen_ = 1;
1155 }
1156
ObexOptionalTlvHeader(const uint8_t headerId,const ObexTlvParamters & tlvParamters)1157 ObexOptionalTlvHeader::ObexOptionalTlvHeader(const uint8_t headerId, const ObexTlvParamters &tlvParamters)
1158 : ObexOptionalTlvHeader(headerId)
1159 {
1160 uint16_t dataSize = 0;
1161 auto newTlvParamters = std::make_unique<ObexTlvParamters>();
1162 for (auto ¶m : tlvParamters.GetTlvTriplets()) {
1163 dataSize += param->GetLen() + TAG_PREFIX_LEN;
1164 newTlvParamters->AppendTlvtriplet(*(param.get()));
1165 }
1166 tlvParamters_ = std::move(newTlvParamters);
1167 dataSize_ = dataSize;
1168 }
1169
ObexOptionalTlvHeader(const uint8_t headerId,const uint8_t * data,const uint16_t dataSize)1170 ObexOptionalTlvHeader::ObexOptionalTlvHeader(const uint8_t headerId, const uint8_t *data, const uint16_t dataSize)
1171 : ObexOptionalTlvHeader(headerId)
1172 {
1173 auto newTlvParamters = std::make_unique<ObexTlvParamters>();
1174 uint16_t pos = 0;
1175 while (pos < dataSize) {
1176 const uint8_t tagId = data[pos++];
1177 const uint8_t len = data[pos++];
1178 TlvTriplet tlv(tagId, len, &data[pos]);
1179 newTlvParamters->AppendTlvtriplet(tlv);
1180 pos += len;
1181 }
1182 tlvParamters_ = std::move(newTlvParamters);
1183 dataSize_ = dataSize;
1184 }
1185
GetTlvParamters() const1186 const std::unique_ptr<ObexTlvParamters> &ObexOptionalTlvHeader::GetTlvParamters() const
1187 {
1188 return tlvParamters_;
1189 }
1190
GetTlvtriplet(const uint8_t tagId) const1191 const TlvTriplet *ObexOptionalTlvHeader::GetTlvtriplet(const uint8_t tagId) const
1192 {
1193 if (tlvParamters_ == nullptr) {
1194 return nullptr;
1195 }
1196 return tlvParamters_->GetTlvtriplet(tagId);
1197 }
1198
HasLengthField() const1199 bool ObexOptionalTlvHeader::HasLengthField() const
1200 {
1201 return true;
1202 }
1203
GetHeaderClassType() const1204 ObexHeaderDataType ObexOptionalTlvHeader::GetHeaderClassType() const
1205 {
1206 return ObexHeaderDataType::TLV;
1207 }
1208
GetHeaderClassTypeName() const1209 std::string ObexOptionalTlvHeader::GetHeaderClassTypeName() const
1210 {
1211 return "ObexOptionalTlvHeader";
1212 }
1213
GetBytes() const1214 std::unique_ptr<uint8_t[]> ObexOptionalTlvHeader::GetBytes() const
1215 {
1216 if (dataSize_ < 1) {
1217 return nullptr;
1218 }
1219 auto buf = std::make_unique<uint8_t[]>(dataSize_);
1220 (void)memset_s(buf.get(), dataSize_, 0x00, dataSize_);
1221 size_t p = 0;
1222 bool isBigEndian = ObexUtils::SysIsBigEndian();
1223 for (auto ¶m : GetTlvParamters()->GetTlvTriplets()) {
1224 *(buf.get() + p) = param->GetTagId();
1225 p++;
1226 *(buf.get() + p) = param->GetLen();
1227 p++;
1228 (void)memcpy_s(buf.get() + p, dataSize_ - p, param->GetVal(), param->GetLen());
1229 if (!isBigEndian && param->GetUnitLen() > 1) {
1230 ObexUtils::DataReverse(buf.get() + p, param->GetLen(), param->GetUnitLen());
1231 }
1232 p += param->GetLen();
1233 }
1234 return buf;
1235 }
1236
Clone() const1237 std::unique_ptr<ObexOptionalHeader> ObexOptionalTlvHeader::Clone() const
1238 {
1239 return std::make_unique<ObexOptionalTlvHeader>(GetHeaderId(), *GetTlvParamters().get());
1240 }
1241
1242 // ObexTlvParamters
GetTlvTriplets() const1243 const std::vector<std::unique_ptr<TlvTriplet>> &ObexTlvParamters::GetTlvTriplets() const
1244 {
1245 return tlvTriplets_;
1246 }
1247
GetTlvtriplet(const uint8_t tagId) const1248 const TlvTriplet *ObexTlvParamters::GetTlvtriplet(const uint8_t tagId) const
1249 {
1250 auto itr = std::find_if(tlvTriplets_.begin(), tlvTriplets_.end(),
1251 [tagId](const std::unique_ptr<TlvTriplet> &rhs)->bool {
1252 return (tagId == rhs->GetTagId());
1253 });
1254 if (itr != tlvTriplets_.end()) {
1255 return itr->get();
1256 }
1257 return nullptr;
1258 }
1259
AppendTlvtriplet(const TlvTriplet & tlvTriplet)1260 void ObexTlvParamters::AppendTlvtriplet(const TlvTriplet &tlvTriplet)
1261 {
1262 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(tlvTriplet));
1263 }
1264
1265 // ObexDigestChallenge
1266
1267 /************************* OBEX Auth Digest Challenge *******************************/
1268 const uint8_t ObexDigestChallenge::NONCE;
1269 const uint8_t ObexDigestChallenge::OPTIONS;
1270 const uint8_t ObexDigestChallenge::REALM;
GetNonce() const1271 const TlvTriplet *ObexDigestChallenge::GetNonce() const
1272 {
1273 return GetTlvtriplet(ObexDigestChallenge::NONCE);
1274 }
1275
GetOptions() const1276 const TlvTriplet *ObexDigestChallenge::GetOptions() const
1277 {
1278 return GetTlvtriplet(ObexDigestChallenge::OPTIONS);
1279 }
1280
GetRealm() const1281 const TlvTriplet *ObexDigestChallenge::GetRealm() const
1282 {
1283 return GetTlvtriplet(ObexDigestChallenge::REALM);
1284 }
1285
AppendNonce(const uint8_t * nonce,const uint8_t length)1286 void ObexDigestChallenge::AppendNonce(const uint8_t *nonce, const uint8_t length)
1287 {
1288 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestChallenge::NONCE, length, nonce));
1289 }
1290
AppendOptions(const uint8_t options)1291 void ObexDigestChallenge::AppendOptions(const uint8_t options)
1292 {
1293 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestChallenge::OPTIONS, options));
1294 }
1295
AppendRealm(const uint8_t * realm,const uint8_t length)1296 void ObexDigestChallenge::AppendRealm(const uint8_t *realm, const uint8_t length)
1297 {
1298 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestChallenge::REALM, length, realm));
1299 }
1300
1301 /************************* OBEX Auth Digest Response *******************************/
1302 const uint8_t ObexDigestResponse::REQUEST_DIGEST;
1303 const uint8_t ObexDigestResponse::USER_ID;
1304 const uint8_t ObexDigestResponse::NONCE;
1305 const uint8_t ObexDigestResponse::MAX_USER_ID_LEN;
1306
GetRequestDigest() const1307 const TlvTriplet *ObexDigestResponse::GetRequestDigest() const
1308 {
1309 return GetTlvtriplet(ObexDigestResponse::REQUEST_DIGEST);
1310 }
1311
GetUserId() const1312 const TlvTriplet *ObexDigestResponse::GetUserId() const
1313 {
1314 return GetTlvtriplet(ObexDigestResponse::USER_ID);
1315 }
1316
GetNonce() const1317 const TlvTriplet *ObexDigestResponse::GetNonce() const
1318 {
1319 return GetTlvtriplet(ObexDigestResponse::NONCE);
1320 }
1321
AppendRequestDigest(const uint8_t * requestDigest,const uint8_t length)1322 void ObexDigestResponse::AppendRequestDigest(const uint8_t *requestDigest, const uint8_t length)
1323 {
1324 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestResponse::REQUEST_DIGEST, length, requestDigest));
1325 }
1326
AppendUserId(const uint8_t * userId,const uint8_t length)1327 void ObexDigestResponse::AppendUserId(const uint8_t *userId, const uint8_t length)
1328 {
1329 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestResponse::USER_ID, length, userId));
1330 }
1331
AppendNonce(const uint8_t * nonce,const uint8_t length)1332 void ObexDigestResponse::AppendNonce(const uint8_t *nonce, const uint8_t length)
1333 {
1334 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexDigestResponse::NONCE, length, nonce));
1335 }
1336
1337 /************************* OBEX Session Parameter ID *******************************/
1338 const uint8_t ObexSessionParameters::DEVICE_ADDRESS;
1339 const uint8_t ObexSessionParameters::NONCE;
1340 const uint8_t ObexSessionParameters::SESSION_ID;
1341 const uint8_t ObexSessionParameters::NEXT_SEQUENCE_NUMBER;
1342 const uint8_t ObexSessionParameters::TIMEOUT;
1343 const uint8_t ObexSessionParameters::SESSION_OPCODE;
GetDeviceAddress() const1344 const TlvTriplet *ObexSessionParameters::GetDeviceAddress() const
1345 {
1346 return GetTlvtriplet(ObexSessionParameters::DEVICE_ADDRESS);
1347 }
1348
GetNonce() const1349 const TlvTriplet *ObexSessionParameters::GetNonce() const
1350 {
1351 return GetTlvtriplet(ObexSessionParameters::NONCE);
1352 }
1353
GetSessionId() const1354 const TlvTriplet *ObexSessionParameters::GetSessionId() const
1355 {
1356 return GetTlvtriplet(ObexSessionParameters::SESSION_ID);
1357 }
1358
GetNextSeqNum() const1359 const TlvTriplet *ObexSessionParameters::GetNextSeqNum() const
1360 {
1361 return GetTlvtriplet(ObexSessionParameters::NEXT_SEQUENCE_NUMBER);
1362 }
1363
GetTimeout() const1364 const TlvTriplet *ObexSessionParameters::GetTimeout() const
1365 {
1366 return GetTlvtriplet(ObexSessionParameters::TIMEOUT);
1367 }
1368
GetSessionOpcode() const1369 const TlvTriplet *ObexSessionParameters::GetSessionOpcode() const
1370 {
1371 return GetTlvtriplet(ObexSessionParameters::SESSION_OPCODE);
1372 }
1373
AppendDeviceAddress(const uint8_t * deviceAddress,const uint8_t length)1374 void ObexSessionParameters::AppendDeviceAddress(const uint8_t *deviceAddress, const uint8_t length)
1375 {
1376 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::DEVICE_ADDRESS, length, deviceAddress));
1377 }
1378
AppendNonce(const uint8_t * nonce,const uint8_t length)1379 void ObexSessionParameters::AppendNonce(const uint8_t *nonce, const uint8_t length)
1380 {
1381 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::NONCE, length, nonce));
1382 }
1383
AppendSessionId(const uint8_t * sessionId,const uint8_t length)1384 void ObexSessionParameters::AppendSessionId(const uint8_t *sessionId, const uint8_t length)
1385 {
1386 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::SESSION_ID, length, sessionId));
1387 }
1388
AppendNextSeqNum(const uint8_t nextSeqNum)1389 void ObexSessionParameters::AppendNextSeqNum(const uint8_t nextSeqNum)
1390 {
1391 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::NEXT_SEQUENCE_NUMBER, nextSeqNum));
1392 }
1393
AppendTimeout(const uint32_t timeout)1394 void ObexSessionParameters::AppendTimeout(const uint32_t timeout)
1395 {
1396 tlvTriplets_.push_back(std::make_unique<TlvTriplet>(ObexSessionParameters::TIMEOUT, timeout));
1397 }
1398
AppendSessionOpcode(const SessionOpcode opcode)1399 void ObexSessionParameters::AppendSessionOpcode(const SessionOpcode opcode)
1400 {
1401 tlvTriplets_.push_back(
1402 std::make_unique<TlvTriplet>(ObexSessionParameters::SESSION_OPCODE, static_cast<uint8_t>(opcode)));
1403 }
1404 } // namespace bluetooth
1405 } // namespace OHOS