3 * Copyright (c) 2020 Project CHIP Authors
4 * Copyright (c) 2013-2017 Nest Labs, Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 * This file defines macros and objects commonly used for the
23 * processing of CHIP messages.
27 #ifndef _CHIP_MESSAGE_H
28 #define _CHIP_MESSAGE_H
30 #include <core/CHIPEncoding.h>
31 #include <core/CHIPError.h>
32 #include <core/CHIPTLV.h>
33 #include <support/DLLUtil.h>
35 #include <system/SystemPacketBuffer.h>
38 * these macros are the guts of the packing and parsing stuff and they're used
41 * here are the writers
43 * - PTR, a pointer into a buffer of type uint8_t
44 * - VAL, a value to write
46 #define WRITEBYTE(PTR, VAL) \
49 *(PTR)++ = (uint8_t)(VAL); \
52 #define WRITE16(PTR, VAL) \
55 WRITEBYTE((PTR), ((VAL) >> 0)); \
56 WRITEBYTE((PTR), ((VAL) >> 8)); \
59 #define WRITE32(PTR, VAL) \
62 WRITEBYTE((PTR), ((VAL) >> 0)); \
63 WRITEBYTE((PTR), ((VAL) >> 8)); \
64 WRITEBYTE((PTR), ((VAL) >> 16)); \
65 WRITEBYTE((PTR), ((VAL) >> 24)); \
70 * parameter: PTR, a pointer into a buffer of type uint8_t
71 * value: the value read form the buffer
73 #define READBYTE(PTR) (*(uint8_t *) (PTR)++)
76 * - PTR, a pointer into a buffer of type uint8_t
77 * - DEST, where to put what's read from *p
79 #define READ16(PTR, DEST) \
82 uint16_t __byte0 = (uint16_t) READBYTE(PTR); \
83 uint16_t __byte1 = (uint16_t) READBYTE(PTR); \
84 DEST = __byte0 + (__byte1 << 8); \
87 #define READ32(PTR, DEST) \
90 uint16_t __byte0 = (uint16_t) READBYTE(PTR); \
91 uint16_t __byte1 = (uint16_t) READBYTE(PTR); \
92 uint16_t __byte2 = (uint16_t) READBYTE(PTR); \
93 uint16_t __byte3 = (uint16_t) READBYTE(PTR); \
94 DEST = __byte0 + (__byte1 << 8) + (__byte2 << 16) + (__byte3 << 24); \
98 * the message iterator class allows packet handling to operate in
99 * a regular manner, do a bit of work, check the result, get out if
100 * it's not good and so on. this results in a bunch of boilerplate
101 * code, which is captured here.
103 #define TRY(OPERATION) \
106 CHIP_ERROR e = (OPERATION); \
107 if (e != CHIP_NO_ERROR) \
111 #define RESCUE(ERR, OPERATION, OUT) \
115 if (ERR != CHIP_NO_ERROR) \
121 namespace Protocols {
124 * @class RetainedPacketBuffer
127 * This is a base class that serves as a convenience object for
128 * automatically reference counting a System::PacketBuffer.
131 class DLL_EXPORT RetainedPacketBuffer
135 RetainedPacketBuffer();
136 RetainedPacketBuffer(const RetainedPacketBuffer & aRetainedPacketBuffer);
137 ~RetainedPacketBuffer();
139 RetainedPacketBuffer & operator=(const RetainedPacketBuffer & aRetainedPacketBuffer);
141 virtual bool IsRetaining() const;
143 void Retain(System::PacketBuffer * aBuffer);
144 virtual void Release();
146 inline System::PacketBuffer * GetBuffer() { return (mBuffer); }
149 System::PacketBuffer * mBuffer; ///< A pointer to the retained packet buffer.
153 * In order to use message buffers sensibly, we define this iterator,
154 * which can be used to keep track of boundaries and so on.
156 class DLL_EXPORT MessageIterator : public RetainedPacketBuffer
160 MessageIterator(System::PacketBuffer *);
161 // reading and writing
162 CHIP_ERROR readByte(uint8_t *);
163 CHIP_ERROR read16(uint16_t *);
164 CHIP_ERROR read32(uint32_t *);
165 CHIP_ERROR read64(uint64_t *);
166 CHIP_ERROR readString(uint16_t, char *);
167 CHIP_ERROR readBytes(uint16_t, uint8_t *);
168 CHIP_ERROR writeByte(uint8_t);
169 CHIP_ERROR write16(uint16_t);
170 CHIP_ERROR write32(uint32_t);
171 CHIP_ERROR write64(uint64_t);
172 CHIP_ERROR writeString(uint16_t, char *);
173 CHIP_ERROR writeBytes(uint16_t, uint8_t *);
174 // standard iterator operations
175 MessageIterator & operator++();
176 MessageIterator & operator+(uint16_t);
177 MessageIterator & operator-(uint16_t);
178 bool operator==(const MessageIterator &);
179 bool operator!=(const MessageIterator &);
180 uint8_t & operator*();
183 bool hasData(uint16_t);
184 bool hasRoom(uint16_t);
186 void finishWriting();
191 * Here's how to handle strings in CHIP. This class has 8-bit
192 * and 16-bit variants.
194 class DLL_EXPORT ReferencedString : public RetainedPacketBuffer
200 CHIP_ERROR init(uint16_t aLength, char * aString, System::PacketBuffer * aBuffer);
201 CHIP_ERROR init(uint16_t aLength, char * aString);
202 CHIP_ERROR init(uint8_t aLength, char * aString, System::PacketBuffer * aBuffer);
203 CHIP_ERROR init(uint8_t aLength, char * aString);
205 CHIP_ERROR pack(MessageIterator &);
206 static CHIP_ERROR parse(MessageIterator &, ReferencedString &);
208 bool operator==(const ReferencedString &) const;
209 // print string generation (for testing)
210 char * printString();
217 * Similarly, we need to be able to represent a big old blob
220 class DLL_EXPORT ReferencedTLVData : public RetainedPacketBuffer
224 * under certain circumstances, e.g. when we don't want to blow out the
225 * stack by writing some big thing into it in preparation for sending
226 * a message with a referenced extent in it, we want to only write the
227 * bits AFTER we've obtained the outgoing buffer. we do that using one
230 * NOTE!!! the handler set up below does NOT return an error and, in
231 * the case where one is supplied, the pack method will not return an
232 * error either. this means that the NHL-supplied handler MUST handler
233 * all errors that arise from the formatting of TLV.
236 * - TLVWriter&, a TLV writer to use to write things out
237 * - void*, a state object known to the application
240 typedef void (*TLVWriteCallback)(TLV::TLVWriter & aWriter, void * aAppState);
248 CHIP_ERROR init(System::PacketBuffer * aBuffer);
249 CHIP_ERROR init(MessageIterator & i);
250 CHIP_ERROR init(uint16_t aLength, uint16_t aMaxLength, uint8_t * aByteString);
251 CHIP_ERROR init(TLVWriteCallback aWriteCallback, void * anAppState);
254 * ReferencedTLVData needs to override the free() and isFree()
255 * methods because "freedom", in this case, is more than nothing
264 * Check if a ReferencedTLVData object has anything in it.
266 * There are two possible ways such an object could "have"
267 * something. Either it could have 0 length OR it could have no
270 * @return true if the data set has 0 length or there's no write
271 * callback in hand, false otherwise.
274 inline bool isEmpty() { return (theLength == 0 && theWriteCallback == nullptr); }
276 // packing and parsing
279 * @fn CHIP_ERROR ReferencedTLVData::pack(System::PacketBuffer *buff)
281 * @brief Pack a ReferencedTLVData object directly into a PacketBuffer
283 * @param [in] buff the buffer to fill.
285 * @return a CHIP_ERROR reflecting the success of the underlying
289 inline CHIP_ERROR pack(System::PacketBuffer * buff)
291 MessageIterator i(buff);
296 CHIP_ERROR pack(MessageIterator & i, uint32_t maxLen = 0xFFFFFFFFUL);
299 * Return the data length assuming that the object has been packed
302 * @return the integer length of the packed data.
305 inline uint16_t packedLength() { return theLength; }
308 * @fn CHIP_ERROR parse(System::PacketBuffer *buff, ReferencedTLVData &aTarget)
310 * @brief Parse a ReferencedTLVData object from a supplied PacketBuffer
312 * Parse a ReferencedTLVData object out of an inet buffer
313 * (assuming it just contains TLV).
315 * @param [in] buff the buffer to read from.
317 * @param [out] aTarget a ReferencedTLVData object to "fill" with the result.
319 * @return a CHIP_ERROR reflecting the success of the underlying
323 static inline CHIP_ERROR parse(System::PacketBuffer * buff, ReferencedTLVData & aTarget)
325 MessageIterator i(buff);
327 return parse(i, aTarget);
330 static CHIP_ERROR parse(MessageIterator & i, ReferencedTLVData & aTarget);
334 bool operator==(const ReferencedTLVData &) const;
339 uint16_t theMaxLength;
343 TLVWriteCallback theWriteCallback;
347 } // namespace Protocols
350 #endif // _CHIP_MESSAGE_H