• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &params)
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 &params)
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 &param : 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 &param : 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