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 #ifndef OBEX_HEADERS_H
17 #define OBEX_HEADERS_H
18 
19 #include <cstdint>
20 #include <cstring>
21 #include <memory>
22 #include <vector>
23 #include <unordered_map>
24 #include "obex_body.h"
25 #include "obex_packet.h"
26 #include "obex_types.h"
27 
28 namespace OHOS {
29 namespace bluetooth {
30 class ObexHdrType {
31 public:
32     /************************* The 2 high order bits of HI have the following meanings *******************************/
33     // 00, null terminated Unicode text, length prefixed with 2 byte unsigned integer
34     static const uint8_t UNICODE_TEXT = 0x00;
35     // 01, byte sequence, length prefixed with 2 byte unsigned integer
36     // 00, null terminated Unicode text, length prefixed with 2 byte unsigned integer
37     static const uint8_t BYTES = 0x40;
38     // 10, 1 byte quantity
39     // 00, null terminated Unicode text, length prefixed with 2 byte unsigned integer
40     static const uint8_t BYTE = 0x80;
41     // 11, 4 byte quantity – transmitted in network byte order (high byte first)
42     // 00, null terminated Unicode text, length prefixed with 2 byte unsigned integer
43     static const uint8_t WORD = 0xC0;
44     // Mask 11000000
45     static const uint8_t MASK = 0xC0;
46 };
47 
48 /************************* OBEX the type of Action to perform *******************************/
49 enum class ObexActionType : uint8_t {
50     COPY = 0x00,            // Copy
51     MOVE_OR_RENAME = 0x01,  // Move/Rename
52     SET_PERMISSIONS = 0x02  // Set Permissions
53 };
54 
55 class ObexHdrSrmMode {
56 public:
57     // normal response mode
58     static const uint8_t NORMAL = 0x00;
59     // single response mode (SRM)
60     static const uint8_t SINGLE = 0x01;
61 };
62 class ObexHdrSrmpMode {
63 public:
64     // only "wait" is supported by Bluetooth
65     static const uint8_t WAIT = 0x01;
66 };
67 
68 // Tag-Length-Value encoding scheme,
69 // used by Application parameters , Authenticate Challenge , Authenticate Response, and session_parameter
70 // Optional Header
71 class TlvTriplet {
72 public:
73     virtual ~TlvTriplet() = default;
74     explicit TlvTriplet(const uint8_t tagId, const uint8_t len, const uint8_t *val, const uint8_t unitLen = 1);
75     explicit TlvTriplet(const uint8_t tagId, const uint8_t val);
76     explicit TlvTriplet(const uint8_t tagId, const uint16_t val);
77     explicit TlvTriplet(const uint8_t tagId, const uint32_t val);
78     explicit TlvTriplet(const uint8_t tagId, const uint64_t val);
79     explicit TlvTriplet(const TlvTriplet &tlvTriplet);
80     uint8_t GetTagId() const;
81     uint8_t GetLen() const;
82     uint8_t GetUnitLen() const;
83     const uint8_t *GetVal() const;
84     uint16_t GetUint16() const;
85     uint32_t GetUint32() const;
86     uint64_t GetUint64() const;
87 
88 private:
89     TlvTriplet();
90     uint8_t tagId_ = 0;
91     uint8_t len_ = 0;
92     std::vector<uint8_t> val_ {};
93     uint8_t unitLen_ = 1;
94 };
95 /**
96  * @brief ObexTlvParamters
97  * ObexTlvParamters
98  */
99 class ObexTlvParamters {
100 public:
101     ObexTlvParamters() = default;
102     virtual ~ObexTlvParamters() = default;
103     void AppendTlvtriplet(const TlvTriplet &tlvTriplet);
104     const std::vector<std::unique_ptr<TlvTriplet>> &GetTlvTriplets() const;
105     const TlvTriplet *GetTlvtriplet(const uint8_t tagId) const;
106 
107 protected:
108     std::vector<std::unique_ptr<TlvTriplet>> tlvTriplets_ {};
109 };
110 /**
111  * @brief ObexDigestChallenge
112  * ObexDigestChallenge
113  */
114 class ObexDigestChallenge : public ObexTlvParamters {
115 public:
116     /************************* OBEX Auth Digest Challenge *******************************/
117     // String of bytes representing the nonce. Value Len 16
118     static const uint8_t NONCE = 0x00;
119     // Optional Challenge Information Value Len 1
120     static const uint8_t OPTIONS = 0x01;
121     // A displayable string indicating which userid and/or
122     // password to use. The first byte of the string is the
123     // character set to use. The character set uses the
124     // same values as those defined in IrLMP for the nickname.
125     // Value Len N
126     static const uint8_t REALM = 0x02;
127 
128     const TlvTriplet *GetNonce() const;
129     const TlvTriplet *GetOptions() const;
130     const TlvTriplet *GetRealm() const;
131     void AppendNonce(const uint8_t *nonce, const uint8_t length);
132     void AppendOptions(const uint8_t options);
133     void AppendRealm(const uint8_t *realm, const uint8_t length);
134 };
135 class ObexDigestResponse : public ObexTlvParamters {
136 public:
137     // String of bytes representing the request digest. Value Len 16
138     static const uint8_t REQUEST_DIGEST = 0x00;
139     // User ID string of length n. Max size is 20 bytes.
140     static const uint8_t USER_ID = 0x01;
141     // The nonce sent in the digest challenge string. Value Len 16
142     static const uint8_t NONCE = 0x02;
143     static const uint8_t MAX_USER_ID_LEN = 20;
144     const TlvTriplet *GetRequestDigest() const;
145     const TlvTriplet *GetUserId() const;
146     const TlvTriplet *GetNonce() const;
147     void AppendRequestDigest(const uint8_t *requestDigest, const uint8_t length);
148     void AppendUserId(const uint8_t *userId, const uint8_t length);
149     void AppendNonce(const uint8_t *nonce, const uint8_t length);
150 };
151 /**
152  * @brief ObexSessionParameters
153  * ObexSessionParameters
154  */
155 class ObexSessionParameters : public ObexTlvParamters {
156 public:
157     // Device Address
158     // The device address of the device sending the header.
159     // If running over IrDA this is the 32-bit device address.
160     // For Bluetooth this is the 48-bit Bluetooth address.
161     // If Running over TCP/IP this is the IP address.
162     static const uint8_t DEVICE_ADDRESS = 0x00;
163     // Nonce
164     // The nonce is a value provided by the device, which will be used in the
165     // creation of the session ID. This number must be unique for each session
166     // created by the device. One method for creating the nonce is to start with a
167     // random number then increment the value each time a new session is
168     // created. The Nonce should be at least 4 bytes and at most 16 bytes in size.
169     static const uint8_t NONCE = 0x01;
170     // Session ID
171     // This is a 16-byte value, which is formed by taking the device
172     // address and nonce from the client and server and running the MD5 algorithm
173     // over the resulting string. The Session ID is created as follows: MD5(“Client
174     // Device Address” “Client Nonce” “Server Device Address” “Server Nonce”)
175     static const uint8_t SESSION_ID = 0x02;
176     // Next Sequence Number
177     // This is a one-byte value sent by the server, which indicates the next
178     // sequence number expected when the session is resumed.
179     static const uint8_t NEXT_SEQUENCE_NUMBER = 0x03;
180     // Timeout
181     // This is a 4-byte value that contains the number of seconds a session can be
182     // in suspend mode before it is considered closed. The value of 0xffffffff
183     // indicates a timeout of infinity. This is the default timeout. If a device does not
184     // send a timeout field then it can be assumed that the desired timeout is infinity.
185     // The timeout in affect is the smallest timeout sent by the client or server.
186     static const uint8_t TIMEOUT = 0x04;
187     // Session Opcode
188     // The session opcode is a 1-byte value sent by the client to indicate the
189     // Session command that is to be performed. This tag-length-value is only sent
190     // in SESSION commands and must be the first tag in the Session-Parameters
191     // header. The session opcode definitions are defined in the bulleted list below.
192     static const uint8_t SESSION_OPCODE = 0x05;
193     /************************* OBEX Session Opcode *******************************/
194     enum class SessionOpcode : uint8_t {
195         CREATE = 0x00,      // Create Session
196         CLOSE = 0x01,       // Close Session
197         SUSPEND = 0x02,     // Suspend Session
198         RESUME = 0x03,      // Resume Session
199         SET_TIMEOUT = 0x04  // Set Timeout
200     };
201     const TlvTriplet *GetDeviceAddress() const;
202     const TlvTriplet *GetNonce() const;
203     const TlvTriplet *GetSessionId() const;
204     const TlvTriplet *GetNextSeqNum() const;
205     const TlvTriplet *GetTimeout() const;
206     const TlvTriplet *GetSessionOpcode() const;
207     void AppendDeviceAddress(const uint8_t *deviceAddress, const uint8_t length);
208     void AppendNonce(const uint8_t *nonce, const uint8_t length);
209     void AppendSessionId(const uint8_t *sessionId, const uint8_t length);
210     void AppendNextSeqNum(const uint8_t nextSeqNum);
211     void AppendTimeout(const uint32_t timeout);
212     void AppendSessionOpcode(const SessionOpcode opcode);
213 };
214 /**
215  * @brief ObexOptionalHeader's Data Type
216  *
217  */
218 enum class ObexHeaderDataType : uint8_t {
219     UNICODE_TEXT = 0x00,  // Unicode text
220     BYTES = 0x40,         // BYTES
221     STRING,               // STRING
222     TLV,                  // TLV
223     BYTE = 0x80,          // BYTE
224     WORD = 0XC0           // WORD
225 };
226 // Optional Header
227 class ObexOptionalHeader {
228 public:
229     virtual ~ObexOptionalHeader() = default;
230     virtual std::unique_ptr<ObexOptionalHeader> Clone() const = 0;
231     uint8_t GetHeaderId() const;
232     uint16_t GetHeaderTotalSize() const;
233     uint16_t GetHeaderDataSize() const;
234     uint8_t GetHeaderUnitLen() const;
235 
236     virtual bool HasLengthField() const = 0;
237     virtual ObexHeaderDataType GetHeaderClassType() const = 0;
238     virtual std::string GetHeaderClassTypeName() const = 0;
239     virtual std::unique_ptr<uint8_t[]> GetBytes() const = 0;
240 
241 protected:
242     ObexOptionalHeader(uint8_t headerId);
243     ObexOptionalHeader();
244     uint8_t headerId_ = 0;
245     uint16_t dataSize_ = 0;
246     uint8_t unitLen_ = 1;
247 };
248 class ObexOptionalBytesHeader : public ObexOptionalHeader {
249 public:
250     ObexOptionalBytesHeader(const uint8_t headerId, const uint8_t *data,
251         const uint16_t dataSize, const uint16_t unitLen = 1);
252     ~ObexOptionalBytesHeader() override = default;
253     std::unique_ptr<uint8_t[]> GetBytes() const override;
254     bool HasLengthField() const override;
255     ObexHeaderDataType GetHeaderClassType() const override;
256     std::string GetHeaderClassTypeName() const override;
257     std::unique_ptr<ObexOptionalHeader> Clone() const override;
258 
259 protected:
260     std::vector<uint8_t> data_ {};
261 };
262 
263 class ObexOptionalByteHeader : public ObexOptionalBytesHeader {
264 public:
265     ObexOptionalByteHeader(const uint8_t headerId, const uint8_t byte);
266     ~ObexOptionalByteHeader() override = default;
267     bool HasLengthField() const override;
268     uint8_t GetByte() const;
269     ObexHeaderDataType GetHeaderClassType() const override;
270     std::string GetHeaderClassTypeName() const override;
271     std::unique_ptr<ObexOptionalHeader> Clone() const override;
272 };
273 class ObexOptionalWordHeader : public ObexOptionalBytesHeader {
274 public:
275     ObexOptionalWordHeader(const uint8_t headerId, const uint32_t word);
276     ~ObexOptionalWordHeader() override = default;
277     bool HasLengthField() const override;
278     uint32_t GetWord() const;
279     ObexHeaderDataType GetHeaderClassType() const override;
280     std::string GetHeaderClassTypeName() const override;
281     std::unique_ptr<ObexOptionalHeader> Clone() const override;
282 };
283 class ObexOptionalStringHeader : public ObexOptionalBytesHeader {
284 public:
285     ObexOptionalStringHeader(const uint8_t headerId, const std::string &str);
286     ObexOptionalStringHeader(const uint8_t headerId, const uint8_t *data, const uint16_t dataSize);
287 
288     ~ObexOptionalStringHeader() override = default;
289     std::string GetString() const;
290     ObexHeaderDataType GetHeaderClassType() const override;
291     std::string GetHeaderClassTypeName() const override;
292     std::unique_ptr<ObexOptionalHeader> Clone() const override;
293 };
294 class ObexOptionalUnicodeHeader : public ObexOptionalBytesHeader {
295 public:
296     ObexOptionalUnicodeHeader(const uint8_t headerId, const std::u16string &unicodeText);
297     ~ObexOptionalUnicodeHeader() override = default;
298     std::u16string GetUnicodeText() const;
299     ObexHeaderDataType GetHeaderClassType() const override;
300     std::string GetHeaderClassTypeName() const override;
301     std::unique_ptr<ObexOptionalHeader> Clone() const override;
302 };
303 class ObexOptionalTlvHeader : public ObexOptionalHeader {
304 public:
305     explicit ObexOptionalTlvHeader(const uint8_t headerId, const uint8_t *data, const uint16_t dataSize);
306     ObexOptionalTlvHeader(const uint8_t headerId);
307     ObexOptionalTlvHeader(const uint8_t headerId, const ObexTlvParamters &tlvParamters);
308     ~ObexOptionalTlvHeader() override = default;
309     std::unique_ptr<uint8_t[]> GetBytes() const override;
310     bool HasLengthField() const override;
311     ObexHeaderDataType GetHeaderClassType() const override;
312     std::string GetHeaderClassTypeName() const override;
313     std::unique_ptr<ObexOptionalHeader> Clone() const override;
314     const std::unique_ptr<ObexTlvParamters> &GetTlvParamters() const;
315     // Get TlvTriplet By TagId
316     const TlvTriplet *GetTlvtriplet(const uint8_t tagId) const;
317 
318 private:
319     static const uint8_t TAG_PREFIX_LEN = 2;
320     std::unique_ptr<ObexTlvParamters> tlvParamters_ = nullptr;
321 };
322 // Obex Header Struct
323 
324 class ObexHeader {
325 public:
326     /************************* The Header identifiers *******************************/
327     // Number of objects (used by Connect)
328     static const uint8_t COUNT = 0xC0;
329     // name of the object (often a file name)
330     static const uint8_t NAME = 0x01;
331     // type of object - e.g. text, html, binary, manufacturer specific
332     static const uint8_t TYPE = 0x42;
333     // the length of the object in bytes
334     static const uint8_t LENGTH = 0xC3;
335     // date/time stamp – ISO 8601 version - preferred
336     static const uint8_t TIME_ISO8601 = 0x44;
337     // date/time stamp – 4 byte version (for compatibility only)
338     static const uint8_t TIME_4BYTE_VERSION = 0xC4;
339     // text description of the object
340     static const uint8_t DESCRIPTION = 0x05;
341     // name of service that operation is targeted to
342     static const uint8_t TARGET = 0x46;
343     // an HTTP 1.x header
344     static const uint8_t HTTP = 0x47;
345     // a chunk of the object body.
346     static const uint8_t BODY = 0x48;
347     // the final chunk of the object body
348     static const uint8_t END_OF_BODY = 0x49;
349     // identifies the OBEX application, used to tell if talking to a peer
350     static const uint8_t WHO = 0x4A;
351     // an identifier used for OBEX connection multiplexing
352     static const uint8_t CONNECTION_ID = 0xCB;
353     // extended application request & response information
354     static const uint8_t APP_PARAMETERS = 0x4C;
355     // authentication digest-challenge
356     static const uint8_t AUTH_CHALLENGE = 0x4D;
357     // authentication digest-response
358     static const uint8_t AUTH_RESPONSE = 0x4E;
359     // indicates the creator of an object
360     static const uint8_t CREATOR_ID = 0xCF;
361     // uniquely identifies the network client (OBEX server)
362     static const uint8_t WAN_UUID = 0x50;
363     // OBEX Object class of object
364     static const uint8_t OBJECT_CLASS = 0x51;
365     // Parameters used in session commands/responses
366     static const uint8_t SESSION_PARAMETERS = 0x52;
367     // Sequence number used in each OBEX packet for reliability
368     static const uint8_t SESSION_SEQUENCE_NUMBER = 0x93;
369     // Action (copy, move/rename, or set permissions)
370     static const uint8_t ACTION_ID = 0x94;
371     // Indicates the destination name for a Copy or Move/Rename action.
372     static const uint8_t DEST_NAME = 0x15;
373     // Indicates the permissions for a Set Permissions action.
374     static const uint8_t PERMISSIONS = 0xD6;
375     // Single Response Mode
376     static const uint8_t SRM = 0x97;
377     // Single Response Mode Parameter
378     static const uint8_t SRMP = 0x98;
379     // HeaderId Name Map
380     static const std::unordered_map<uint8_t, std::string> HEADER_ID_NAME_MAP;
381     /************************* The Header const *******************************/
382     static const uint8_t MIN_PACKET_LENGTH = 3;
383     static const uint8_t TARGET_LENGTH = 16;
384     static const uint8_t U16STRING_NULL_LENGTH = 2;
385     static const uint8_t U16STRING_LENGTH = 2;
386     static const uint8_t UINT16_LENGTH = 2;
387     static const uint8_t UINT32_LENGTH = 4;
388     static const uint8_t UINT64_LENGTH = 8;
389     static const uint8_t HDR_UNICODE_PREFIX_LENGTH = 3;
390     static const uint8_t HDR_BYTES_PREFIX_LENGTH = 3;
391     /**
392      * @brief Create a Request object
393      *
394      * @param opcode Opcode code
395      * @return std::unique_ptr<ObexHeader>
396      */
397     static std::unique_ptr<ObexHeader> CreateRequest(ObexOpeId opcode);
398     /**
399      * @brief Create a Response object
400      *
401      * @param rspCode Response Code
402      * @param isConnectResp the response of connect request is set to true
403      *                  otherwise otherwise set to false
404      * @return std::unique_ptr<ObexHeader>
405      */
406     static std::unique_ptr<ObexHeader> CreateResponse(ObexRspCode rspCode, bool isConnectResp = false);
407     static std::unique_ptr<ObexHeader> ParseRequest(const uint8_t *buf, const uint16_t size);
408     static std::unique_ptr<ObexHeader> ParseResponse(const uint8_t *buf, const uint16_t size, bool isConnect);
409     bool Parse(const uint8_t *buf, const uint16_t size, bool isRequest, bool isConnect);
410     // note: please don't use this construction method
411     ObexHeader();
412     ObexHeader(const ObexHeader &header, bool fieldOnly = false);
413     virtual ~ObexHeader() = default;
414     uint8_t GetFieldCode() const;
415     uint16_t GetFieldPacketLength() const;
416     const uint8_t *GetFieldObexVersionNum() const;
417     const uint8_t *GetFieldFlags() const;
418     const uint16_t *GetFieldMaxPacketLength() const;
419     const uint8_t *GetFieldConstants() const;
420 
421     void SetRespCode(uint8_t code);
422     void SetFinalBit(bool finalBit);
423     void SetFieldObexVersionNum(const uint8_t obexVersionNum);
424     void SetFieldFlags(const uint8_t flags);
425     void SetFieldMaxPacketLength(const uint16_t maxPacketLength);
426     void SetFieldConstants(uint8_t constants);
427 
428     // obex header add methods
429     // bytes
430     bool AppendItemTarget(const uint8_t *target, const uint16_t length);
431     void AppendItemTimeIso8601(const uint8_t *time, const uint16_t length);
432     void AppendItemHttp(const uint8_t *http, const uint16_t length);
433     void AppendItemBody(const uint8_t *body, const uint16_t length);
434     void AppendItemEndBody(const uint8_t *endBody, const uint16_t length);
435     void AppendItemWho(const uint8_t *who, const uint16_t length);
436     void AppendItemObjectClass(const uint8_t *objectClass, const uint16_t length);
437 
438     // tlv
439     void AppendItemAppParams(ObexTlvParamters &params);
440     void AppendItemAuthChallenges(ObexDigestChallenge &challenges);
441     void AppendItemAuthResponse(ObexDigestResponse &responses);
442     bool AppendItemSessionParams(ObexSessionParameters &params);
443 
444     // String
445     void AppendItemType(const std::string &type);
446 
447     // Word
448     bool AppendItemConnectionId(const uint32_t connectionId);
449     void AppendItemCount(const uint32_t count);
450     void AppendItemLength(const uint32_t length);
451     void AppendItemTime4byte(const uint32_t time);
452     void AppendItemPermissions(const uint32_t permissions);
453 
454     // Unicode
455     void AppendItemName(const std::u16string &name);
456     void AppendItemDescription(const std::u16string &description);
457     void AppendItemDestName(const std::u16string &destName);
458 
459     // byte
460     bool AppendItemSessionSeqNum(const uint8_t num);
461     /************************* OBEX the type of Action to perform *******************************/
462     void AppendItemActionId(const ObexActionType actionId);
463     void AppendItemSrm(const bool srm);
464     void AppendItemSrmp();
465 
466     // obex header get methods
467     const ObexOptionalHeader *Get(uint8_t headerId) const;
468 
469     // ObexOptionalHeader
470     const ObexOptionalHeader *GetItemTarget() const;
471     const ObexOptionalHeader *GetItemTimeIso8601() const;
472     const ObexOptionalHeader *GetItemHttp() const;
473     const ObexOptionalHeader *GetItemBody() const;
474     const ObexOptionalHeader *GetItemEndBody() const;
475     const ObexOptionalHeader *GetItemWho() const;
476     const ObexOptionalHeader *GetItemObjectClass() const;
477 
478     // ObexOptionalTlvHeader
479     const ObexOptionalTlvHeader *GetItemAuthChallenges() const;
480     const ObexOptionalTlvHeader *GetItemSessionParams() const;
481     const ObexOptionalTlvHeader *GetItemAppParams() const;
482     const ObexOptionalTlvHeader *GetItemAuthResponse() const;
483 
484     // ObexOptionalStringHeader
485     const ObexOptionalStringHeader *GetItemType() const;
486 
487     // ObexOptionalWordHeader
488     const ObexOptionalWordHeader *GetItemCount() const;
489     const ObexOptionalWordHeader *GetItemLength() const;
490     const ObexOptionalWordHeader *GetItemTime4byte() const;
491     const ObexOptionalWordHeader *GetItemConnectionId() const;
492     const ObexOptionalWordHeader *GetItemPermissions() const;
493 
494     // ObexOptionalUnicodeHeader
495     const ObexOptionalUnicodeHeader *GetItemName() const;
496     const ObexOptionalUnicodeHeader *GetItemDescription() const;
497     const ObexOptionalUnicodeHeader *GetItemDestName() const;
498 
499     // ObexOptionalByteHeader
500     const ObexOptionalByteHeader *GetItemSessionSeqNum() const;
501     const ObexOptionalByteHeader *GetItemActionId() const;
502     bool GetItemSrm() const;
503     bool GetItemSrmp() const;
504 
505     bool HasHeader(const uint8_t headerId) const;
506     void RemoveItem(const uint8_t headerId);
507     std::vector<std::unique_ptr<ObexOptionalHeader>> const &GetOptionalHeaders() const;
508 
509     std::unique_ptr<ObexPacket> Build() const;
510 
511     const std::shared_ptr<ObexBodyObject> &GetExtendBodyObject() const;
512     void SetExtendBodyObject(const std::shared_ptr<ObexBodyObject> &extendBodyObject);
513 
514 private:
515     // response code OR operation code
516     uint8_t code_ = 0;
517     // obex package total byte length
518     uint16_t packetLength_ = 0;
519     bool isRequest_ = false;
520     // used by connect
521     std::unique_ptr<uint8_t> obexVersionNum_ = nullptr;
522     // used by set_path and connect
523     std::unique_ptr<uint8_t> flags_ = nullptr;
524     // obex package max byte length, used by connect
525     std::unique_ptr<uint16_t> maxPacketLength_ = nullptr;
526     // used by set_path
527     std::unique_ptr<uint8_t> constants_ = nullptr;
528 
529     template<typename T>
530     const T GetItem(uint8_t headerId) const;
531 
532     void Append(std::unique_ptr<ObexOptionalHeader> &header);
533     void AppendUnicode(const uint8_t headerId, const std::u16string &text);
534     void AppendByte(const uint8_t headerId, const uint8_t byte);
535     void AppendBytes(const uint8_t headerId, const uint8_t *byteBuf, const uint32_t size);
536     void AppendWord(const uint8_t headerId, const uint32_t word);
537     void AppendString(const uint8_t headerId, const std::string &str);
538     void AppendTlvTriplets(const uint8_t headerId, ObexTlvParamters &tlvParamters);
539 
540     void ParseBytes(const uint8_t &headerId, const uint8_t *buf, uint16_t &pos);
541     void ParseUnicodeText(const uint8_t &headerId, const uint8_t *buf, uint16_t &pos);
542     void ParseFields(const uint8_t *buf, const uint8_t &code, uint16_t &pos, bool isRequest, bool isConnect);
543     bool ParseOptionalHeaders(const uint8_t *buf, const uint16_t &size, uint16_t &pos);
544     static const std::string &GetHeaderName(uint8_t headerId);
545     std::vector<std::unique_ptr<ObexOptionalHeader>> optionalHeaders_ {};
546     std::unordered_map<uint8_t, size_t> headerIndexMap_ {};
547     std::shared_ptr<ObexBodyObject> extendBodyObject_ = nullptr;
548 };
549 }  // namespace bluetooth
550 }  // namespace OHOS
551 #endif  // OBEX_HEADERS_H
552