From 73ea7db7777466499dbef1b4faf4802507845327 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Tue, 10 Mar 2020 13:38:20 -0700 Subject: [PATCH 1/3] Bring in WeaveTLV --- src/lib/core/WeaveTLV.h | 470 +++++++ src/lib/core/WeaveTLVData.hpp | 399 ++++++ src/lib/core/WeaveTLVDebug.cpp | 387 ++++++ src/lib/core/WeaveTLVDebug.hpp | 76 ++ src/lib/core/WeaveTLVReader.cpp | 1584 +++++++++++++++++++++++ src/lib/core/WeaveTLVTags.h | 190 +++ src/lib/core/WeaveTLVTypes.h | 172 +++ src/lib/core/WeaveTLVUpdater.cpp | 505 ++++++++ src/lib/core/WeaveTLVUtilities.cpp | 452 +++++++ src/lib/core/WeaveTLVUtilities.hpp | 72 ++ src/lib/core/WeaveTLVWriter.cpp | 1898 ++++++++++++++++++++++++++++ 11 files changed, 6205 insertions(+) create mode 100644 src/lib/core/WeaveTLV.h create mode 100644 src/lib/core/WeaveTLVData.hpp create mode 100644 src/lib/core/WeaveTLVDebug.cpp create mode 100644 src/lib/core/WeaveTLVDebug.hpp create mode 100644 src/lib/core/WeaveTLVReader.cpp create mode 100644 src/lib/core/WeaveTLVTags.h create mode 100644 src/lib/core/WeaveTLVTypes.h create mode 100644 src/lib/core/WeaveTLVUpdater.cpp create mode 100644 src/lib/core/WeaveTLVUtilities.cpp create mode 100644 src/lib/core/WeaveTLVUtilities.hpp create mode 100644 src/lib/core/WeaveTLVWriter.cpp diff --git a/src/lib/core/WeaveTLV.h b/src/lib/core/WeaveTLV.h new file mode 100644 index 00000000000000..04fbdd5f8e8fa9 --- /dev/null +++ b/src/lib/core/WeaveTLV.h @@ -0,0 +1,470 @@ +/* + * + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file contains definitions for working with data encoded in Weave TLV format. + * + * Weave TLV (Tag-Length-Value) is a generalized encoding method for simple structured data. It + * shares many properties with the commonly used JSON serialization format while being considerably + * more compact over the wire. + */ + +#ifndef WEAVETLV_H_ +#define WEAVETLV_H_ + +#include +#include + +#include +#include +#include "WeaveTLVTags.h" +#include "WeaveTLVTypes.h" + +// forward declaration of the PacketBuffer class used within the header. +namespace nl { +namespace Weave { +namespace System { + +class PacketBuffer; + +} // namespace System +} // namespace Weave +} // namespace nl + +/** + * @namespace nl::Weave::TLV + * + * Definitions for working with data encoded in Weave TLV format. + * + * Weave TLV is a generalized encoding method for simple structured data. It shares many properties + * with the commonly used JSON serialization format while being considerably more compact over the wire. + */ + +namespace nl { +namespace Weave { +namespace TLV { + +using nl::Weave::System::PacketBuffer; + +enum { + kTLVControlByte_NotSpecified = 0xFFFF +}; + +/** + * Provides a memory efficient parser for data encoded in Weave TLV format. + * + * TLVReader implements a forward-only, “pull-style” parser for Weave TLV data. The TLVReader + * object operates as a cursor that can be used to iterate over a sequence of TLV elements + * and interpret their contents. When positioned on an element, applications can make calls + * to the reader's Get() methods to query the current element’s type and tag, and to extract + * any associated value. The reader’s Next() method is used to advance from element to element. + * + * A TLVReader object is always positioned either before, on or after a TLV element. When first + * initialized, a TLVReader is positioned immediately before the first element of the encoding. + * To begin reading, an application must make an initial call to the Next() method to position + * the reader on the first element. When a container element is encountered--either a structure, + * an array or a path--the OpenContainer() or EnterContainer() methods can be used to iterate + * through the contents of the container. + * + * When the reader reaches the end of a TLV encoding, or the last element within a container, + * it signals the application by returning a WEAVE_END_OF_TLV error from the Next() method. + * The reader will continue to return WEAVE_END_OF_TLV until it is reinitialized, or the current + * container is exited (via CloseContainer() / ExitContainer()). + * + * A TLVReader object can parse data directly from a fixed input buffer, or from a chain of one + * or more PacketBuffers. Additionally, applications can supply a @p GetNextBuffer function to + * feed data to the reader from an arbitrary source, e.g. a socket or a serial port. + * + */ +class NL_DLL_EXPORT TLVReader +{ +friend class TLVWriter; +friend class TLVUpdater; + +public: + // *** See WeaveTLVReader.cpp file for API documentation *** + + void Init(const TLVReader &aReader); + void Init(const uint8_t *data, uint32_t dataLen); + void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL); + void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers); + + WEAVE_ERROR Next(void); + WEAVE_ERROR Next(TLVType expectedType, uint64_t expectedTag); + + TLVType GetType(void) const; + uint64_t GetTag(void) const; + uint32_t GetLength(void) const; + uint16_t GetControlByte(void) const; + + WEAVE_ERROR Get(bool& v); + WEAVE_ERROR Get(int8_t& v); + WEAVE_ERROR Get(int16_t& v); + WEAVE_ERROR Get(int32_t& v); + WEAVE_ERROR Get(int64_t& v); + WEAVE_ERROR Get(uint8_t& v); + WEAVE_ERROR Get(uint16_t& v); + WEAVE_ERROR Get(uint32_t& v); + WEAVE_ERROR Get(uint64_t& v); + WEAVE_ERROR Get(float& v); + WEAVE_ERROR Get(double& v); + WEAVE_ERROR GetBytes(uint8_t *buf, uint32_t bufSize); + WEAVE_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen); + WEAVE_ERROR GetString(char *buf, uint32_t bufSize); + WEAVE_ERROR DupString(char *& buf); + WEAVE_ERROR GetDataPtr(const uint8_t *& data); + + WEAVE_ERROR EnterContainer(TLVType& outerContainerType); + WEAVE_ERROR ExitContainer(TLVType outerContainerType); + WEAVE_ERROR OpenContainer(TLVReader& containerReader); + WEAVE_ERROR CloseContainer(TLVReader& containerReader); + TLVType GetContainerType(void) const; + WEAVE_ERROR VerifyEndOfContainer(void); + + uint32_t GetLengthRead(void) const { return mLenRead; } + uint32_t GetRemainingLength(void) const { return mMaxLen - mLenRead; } + + const uint8_t *GetReadPoint(void) const { return mReadPoint; } + uintptr_t GetBufHandle(void) const { return mBufHandle; } + + WEAVE_ERROR Skip(void); + + uint32_t ImplicitProfileId; + void *AppData; + + typedef WEAVE_ERROR (*GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); + GetNextBufferFunct GetNextBuffer; + +protected: + uint64_t mElemTag; + uint64_t mElemLenOrVal; + uintptr_t mBufHandle; + const uint8_t *mReadPoint; + const uint8_t *mBufEnd; + uint32_t mLenRead; + uint32_t mMaxLen; + TLVType mContainerType; + uint16_t mControlByte; + +private: + bool mContainerOpen; + +protected: + bool IsContainerOpen(void) const { return mContainerOpen; } + void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; } + + WEAVE_ERROR ReadElement(void); + void ClearElementState(void); + WEAVE_ERROR SkipData(void); + WEAVE_ERROR SkipToEndOfContainer(void); + WEAVE_ERROR VerifyElement(void); + uint64_t ReadTag(TLVTagControl tagControl, const uint8_t *& p); + WEAVE_ERROR EnsureData(WEAVE_ERROR noDataErr); + WEAVE_ERROR ReadData(uint8_t *buf, uint32_t len); + WEAVE_ERROR GetElementHeadLength(uint8_t& elemHeadBytes) const; + TLVElementType ElementType(void) const; + + static WEAVE_ERROR GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); + static WEAVE_ERROR FailGetNextBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); + +#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + static WEAVE_ERROR GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); +#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES +}; + +#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES +inline WEAVE_ERROR TLVReader::GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen) +{ + return GetNextPacketBuffer(reader, bufHandle, bufStart, bufLen); +} +#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + +/** + * Provides a memory efficient encoder for writing data in Weave TLV format. + * + * TLVWriter implements a forward-only, stream-style encoder for Weave TLV data. Applications + * write data to an encoding by calling one of the writer's Put() methods, passing associated + * tag and value information as necessary. Similarly applications can encode TLV container types + * (structures, arrays or paths) by calling the writer's OpenContainer() or EnterContainer() + * methods. + * + * A TLVWriter object can write data directly to a fixed output buffer, or to a chain of one or + * more PacketBuffer objects. Additionally, applications can supply their own @p GetNewBuffer and + * @p FinalizeBuffer functions to direct output to an arbitrary destination, e.g. a socket or an + * event queue. + * + */ +class NL_DLL_EXPORT TLVWriter +{ +friend class TLVUpdater; +public: + // *** See WeaveTLVWriter.cpp file for API documentation *** + + void Init(uint8_t *buf, uint32_t maxLen); + void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL); + void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers); + + WEAVE_ERROR Finalize(void); + + WEAVE_ERROR Put(uint64_t tag, int8_t v); + WEAVE_ERROR Put(uint64_t tag, int8_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, int16_t v); + WEAVE_ERROR Put(uint64_t tag, int16_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, int32_t v); + WEAVE_ERROR Put(uint64_t tag, int32_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, int64_t v); + WEAVE_ERROR Put(uint64_t tag, int64_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, uint8_t v); + WEAVE_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, uint16_t v); + WEAVE_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, uint32_t v); + WEAVE_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, uint64_t v); + WEAVE_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize); + WEAVE_ERROR Put(uint64_t tag, float v); + WEAVE_ERROR Put(uint64_t tag, double v); + WEAVE_ERROR PutBoolean(uint64_t tag, bool v); + WEAVE_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len); + WEAVE_ERROR PutString(uint64_t tag, const char *buf); + WEAVE_ERROR PutString(uint64_t tag, const char *buf, uint32_t len); + WEAVE_ERROR PutStringF(uint64_t tag, const char *fmt, ...); + WEAVE_ERROR VPutStringF(uint64_t tag, const char *fmt, va_list ap); + WEAVE_ERROR PutNull(uint64_t tag); + WEAVE_ERROR CopyElement(TLVReader& reader); + WEAVE_ERROR CopyElement(uint64_t tag, TLVReader& reader); + + WEAVE_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType); + WEAVE_ERROR EndContainer(TLVType outerContainerType); + WEAVE_ERROR OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter); + WEAVE_ERROR CloseContainer(TLVWriter& containerWriter); + WEAVE_ERROR PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen); + WEAVE_ERROR CopyContainer(TLVReader& container); + WEAVE_ERROR CopyContainer(uint64_t tag, TLVReader& container); + WEAVE_ERROR CopyContainer(uint64_t tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen); + TLVType GetContainerType(void) const; + + uint32_t GetLengthWritten(void); + + uint32_t ImplicitProfileId; + void *AppData; + + typedef WEAVE_ERROR (*GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, + uint32_t& bufLen); + GetNewBufferFunct GetNewBuffer; + + typedef WEAVE_ERROR (*FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, + uint32_t bufLen); + FinalizeBufferFunct FinalizeBuffer; + + // Implementations of GetNewBufferFunct/FinalizeBufferFunct that support writing into one or more + // PacketBuffers. + static WEAVE_ERROR GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen); + static WEAVE_ERROR FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen); + +#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + static WEAVE_ERROR GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen); + static WEAVE_ERROR FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen); +#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + +protected: + uintptr_t mBufHandle; + uint8_t *mBufStart; + uint8_t *mWritePoint; + uint32_t mRemainingLen; + uint32_t mLenWritten; + uint32_t mMaxLen; + TLVType mContainerType; + +private: + bool mContainerOpen; + bool mCloseContainerReserved; + +protected: + bool IsContainerOpen(void) const { return mContainerOpen; } + void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; } + + enum { + kEndOfContainerMarkerSize = 1, /**< Size of the EndOfContainer marker, used in reserving space. */ + }; + + /** + * @brief + * Determine whether the container should reserve space for the + * CloseContainer symbol at the point of starting / opening the + * container. + */ + bool IsCloseContainerReserved(void) const { return mCloseContainerReserved; } + + /** + * @brief + * Set whether the container should reserve the space for the + * CloseContainer symbol at the point of starting / opening the + * container. + */ + void SetCloseContainerReserved(bool aCloseContainerReserved) { mCloseContainerReserved = aCloseContainerReserved; } + +#if CONFIG_HAVE_VCBPRINTF + static void WeaveTLVWriterPutcharCB(uint8_t c, void *appState); +#endif + WEAVE_ERROR WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal); + WEAVE_ERROR WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen); + WEAVE_ERROR WriteData(const uint8_t *p, uint32_t len); +}; + +#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES +inline WEAVE_ERROR TLVWriter::GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) +{ + return GetNewPacketBuffer(writer, bufHandle, bufStart, bufLen); +} + +inline WEAVE_ERROR TLVWriter::FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen) +{ + return FinalizePacketBuffer(writer, bufHandle, bufStart, dataLen); +} +#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + +/** + * Provides a unified Reader/Writer interface for editing/adding/deleting elements in TLV encoding. + * + * The TLVUpdater is a union of the TLVReader and TLVWriter objects and provides interface methods + * for editing/deleting data in an encoding as well as adding new elements to the TLV encoding. The + * TLVUpdater object essentially acts like two cursors, one for reading existing encoding and + * another for writing (either for copying over existing data or writing new data). + * + * Semantically, the TLVUpdater object functions like a union of the TLVReader and TLVWriter. The + * TLVUpdater methods have more or less similar meanings as similarly named counterparts in + * TLVReader/TLVWriter. Where there are differences in the semantics, the differences are clearly + * documented in the function's comment section in WeaveTLVUpdater.cpp. + * + * One particularly important note about the TLVUpdater's PutBytes() and PutString() methods is that + * it can leave the encoding in a corrupt state with only the element header written when an + * overflow occurs. Applications can call GetRemainingFreeLength() to make sure there is + * @em approximately enough free space to write the encoding. Note that GetRemainingFreeLength() + * only tells you the available free bytes and there is @em no way for the application to know the + * length of encoded data that gets written. In the event of an overflow, both PutBytes() and + * PutString() will return WEAVE_ERROR_BUFFER_TOO_SMALL to the caller. + * + * Also, note that Next() method is overloaded to both skip the current element and also advance the + * internal reader to the next element. Because skipping already encoded elements requires changing + * the internal writer's free space state variables to account for the new freed space (made + * available by skipping), the application is expected to call Next() on the updater after a Get() + * method whose value it doesn't wish to write back (which is equivalent to skipping the current + * element). + * + * @note The application is expected to use the TLVUpdater object atomically from the time it calls + * Init() till it calls Finalize(). The same buffer should NOT be used with other TLVWriter objects. + * + * @note The TLVUpdater currently only supports single static buffers. Support for chain of buffers + * (PacketBuffer) is NOT supported. + */ +class NL_DLL_EXPORT TLVUpdater +{ +public: + WEAVE_ERROR Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen); + WEAVE_ERROR Init(TLVReader& aReader, uint32_t freeLen); + WEAVE_ERROR Finalize(void) { return mUpdaterWriter.Finalize(); } + + // Common methods + void SetImplicitProfileId(uint32_t profileId); + uint32_t GetImplicitProfileId(void) { return mUpdaterReader.ImplicitProfileId; } + WEAVE_ERROR Move(void); + void MoveUntilEnd(void); + WEAVE_ERROR EnterContainer(TLVType& outerContainerType); + WEAVE_ERROR ExitContainer(TLVType outerContainerType); + void GetReader(TLVReader& containerReader) { containerReader = mUpdaterReader; } + + // Reader methods + WEAVE_ERROR Next(void); + + WEAVE_ERROR Get(bool& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(int8_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(int16_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(int32_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(int64_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(uint8_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(uint16_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(uint32_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(uint64_t& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(float& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR Get(double& v) { return mUpdaterReader.Get(v); } + WEAVE_ERROR GetBytes(uint8_t *buf, uint32_t bufSize) { return mUpdaterReader.GetBytes(buf, bufSize); } + WEAVE_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen) { return mUpdaterReader.DupBytes(buf, dataLen); } + WEAVE_ERROR GetString(char *buf, uint32_t bufSize) { return mUpdaterReader.GetString(buf, bufSize); } + WEAVE_ERROR DupString(char *& buf) { return mUpdaterReader.DupString(buf); } + + TLVType GetType(void) const { return mUpdaterReader.GetType(); } + uint64_t GetTag(void) const { return mUpdaterReader.GetTag(); } + uint32_t GetLength(void) const { return mUpdaterReader.GetLength(); } + WEAVE_ERROR GetDataPtr(const uint8_t *& data) { return mUpdaterReader.GetDataPtr(data); } + WEAVE_ERROR VerifyEndOfContainer(void) { return mUpdaterReader.VerifyEndOfContainer(); } + TLVType GetContainerType(void) const { return mUpdaterReader.GetContainerType(); } + uint32_t GetLengthRead(void) const { return mUpdaterReader.GetLengthRead(); } + uint32_t GetRemainingLength(void) const { return mUpdaterReader.GetRemainingLength(); } + + // Writer methods + WEAVE_ERROR Put(uint64_t tag, int8_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, int16_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, int32_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, int64_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, uint8_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, uint16_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, uint32_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, uint64_t v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, int8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, int16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, int32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, int64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + WEAVE_ERROR Put(uint64_t tag, float v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR Put(uint64_t tag, double v) { return mUpdaterWriter.Put(tag, v); } + WEAVE_ERROR PutBoolean(uint64_t tag, bool v) { return mUpdaterWriter.PutBoolean(tag, v); } + WEAVE_ERROR PutNull(uint64_t tag) { return mUpdaterWriter.PutNull(tag); } + WEAVE_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) { return mUpdaterWriter.PutBytes(tag, buf, len); } + WEAVE_ERROR PutString(uint64_t tag, const char *buf) { return mUpdaterWriter.PutString(tag, buf); } + WEAVE_ERROR PutString(uint64_t tag, const char *buf, uint32_t len) { return mUpdaterWriter.PutString(tag, buf, len); } + WEAVE_ERROR CopyElement(TLVReader& reader) { return mUpdaterWriter.CopyElement(reader); } + WEAVE_ERROR CopyElement(uint64_t tag, TLVReader& reader) { return mUpdaterWriter.CopyElement(tag, reader); } + WEAVE_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) { return mUpdaterWriter.StartContainer(tag, containerType, outerContainerType); } + WEAVE_ERROR EndContainer(TLVType outerContainerType) { return mUpdaterWriter.EndContainer(outerContainerType); } + uint32_t GetLengthWritten(void) { return mUpdaterWriter.GetLengthWritten(); } + uint32_t GetRemainingFreeLength(void) { return mUpdaterWriter.mRemainingLen; } + +private: + void AdjustInternalWriterFreeSpace(void); + +private: + TLVWriter mUpdaterWriter; + TLVReader mUpdaterReader; + const uint8_t * mElementStartAddr; +}; + +} // namespace TLV +} // namespace Weave +} // namespace nl + +#endif /* WEAVETLV_H_ */ diff --git a/src/lib/core/WeaveTLVData.hpp b/src/lib/core/WeaveTLVData.hpp new file mode 100644 index 00000000000000..d6c7643d710204 --- /dev/null +++ b/src/lib/core/WeaveTLVData.hpp @@ -0,0 +1,399 @@ +/* + * + * Copyright (c) 2015-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file contains macros to create static Weave TLV data. + * + * These macros are designed to be used in statically initializing a byte array + * containing various TLV elements. TLVWriter can achieve similar functionality + * but only on RAM, while macros here can be used to create TLV elements in ROM. + * + */ + + +#ifndef WEAVETLVDATA_H_ +#define WEAVETLVDATA_H_ + +#include +#include + +/* + * @brief Integral truncate L to the least significant 32-bit + * + * @note Integral truncate would take the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_GetLower32From64(v) ((uint32_t)(((uint64_t)(v) >> 0) & 0xFFFFFFFFUL)) + +/* + * @brief Integral truncate argument X to the next least significant 32-bit + * + * @note Right bit shift gets rid of the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_GetUpper32From64(v) ((uint32_t)(((uint64_t)(v) >> 32) & 0xFFFFFFFFUL)) + +/* + * @brief Integral truncate L to the least significant 16-bit + * + * @note Integral truncate would take the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_GetLower16From32(v) ((uint16_t)(((uint32_t)(v) >> 0) & 0xFFFFU)) + +/* + * @brief Integral truncate argument X to the next least significant 16-bit + * + * @note Right bit shift gets rid of the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_GetUpper16From32(v) ((uint16_t)(((uint32_t)(v) >> 16) & 0xFFFFU)) + +/* + * @brief Integral truncate L to the least significant 8-bit + * + * @note Integral truncate would take the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_GetLower8From16(v) ((uint8_t)(((uint16_t)(v) >> 0) & 0xFFU)) + +/* + * @brief Integral truncate argument X to the next least significant 8-bit + * + * @note Right bit shift gets rid of the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_GetUpper8From16(v) ((uint8_t)(((uint16_t)(v) >> 8) & 0xFFU)) + +/* + * @brief Integral truncate argument v to 8-bit + * + * @note Integral truncate would take the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_Serialize8(v) ((uint8_t)(v)) + +/* + * @brief Integral truncate argument v to 16-bit, and then serialize it using Weave standard Little Endian order + * + * @note Integral truncate would preserve the least significant bits, regardless of hardware endianness. + * Right bit shift gets rid of the least significant bits, regardless of hardware endianness. + */ +#define nlWeaveTLV_Serialize16(v) nlWeaveTLV_GetLower8From16(v), nlWeaveTLV_GetUpper8From16(v) + +/* + * @brief Integral truncate argument v to 32-bit, and then serialize it using Weave standard Little Endian order + */ +#define nlWeaveTLV_Serialize32(v) nlWeaveTLV_Serialize16(nlWeaveTLV_GetLower16From32(v)), nlWeaveTLV_Serialize16(nlWeaveTLV_GetUpper16From32(v)) + +/* + * @brief Integral truncate argument v to 64-bit, and then serialize it using Weave standard Little Endian order + */ +#define nlWeaveTLV_Serialize64(v) nlWeaveTLV_Serialize32(nlWeaveTLV_GetLower32From64(v)), nlWeaveTLV_Serialize32(nlWeaveTLV_GetUpper32From64(v)) + +/* + * @brief Specifies an anonymous TLV element, which doesn't have any tag + */ +#define nlWeaveTLV_TAG_ANONYMOUS nl::Weave::TLV::kTLVTagControl_Anonymous + +/* + * @brief Specifies a TLV element with a context-specific tag + * @param Tag The context-specific tag for this TLV element. Would be truncated to 8 bits. + */ +#define nlWeaveTLV_TAG_CONTEXT_SPECIFIC(Tag) nl::Weave::TLV::kTLVTagControl_ContextSpecific, nlWeaveTLV_Serialize8(Tag) + +/* + * @brief Specifies a TLV element with a Common Profile tag + * @param Tag The tag for this TLV element, defined under Common Profile. + * Would be truncated to 16 bites. + */ +#define nlWeaveTLV_TAG_COMMON_PROFILE_2Bytes(Tag) \ + nl::Weave::TLV::kTLVTagControl_CommonProfile_2Bytes, nlWeaveTLV_Serialize16(Tag) + +/* + * @brief Specifies a TLV element with a Common Profile tag + * @param Tag The tag for this TLV element, defined under Common Profile. + * Would be truncated to 32 bites. + */ +#define nlWeaveTLV_TAG_COMMON_PROFILE_4Bytes(Tag) \ + nl::Weave::TLV::kTLVTagControl_CommonProfile_4Bytes, nlWeaveTLV_Serialize32(Tag) + +/* + * @brief Specifies a TLV element with an Implicit Profile tag + * @param Tag The tag for this TLV element, defined under the current implicit profile. + * Would be truncated to 16 bits. + */ +#define nlWeaveTLV_TAG_IMPLICIT_PROFILE_2Bytes(Tag) \ + nl::Weave::TLV::kTLVTagControl_ImplicitProfile_2Bytes, nlWeaveTLV_Serialize16(Tag) + +/* + * @brief Specifies a TLV element with an Implicit Profile tag + * @param Tag The tag for this TLV element, defined under the current implicit profile. + * Would be truncated to 32 bits. + */ +#define nlWeaveTLV_TAG_IMPLICIT_PROFILE_4Bytes(Tag) \ + nl::Weave::TLV::kTLVTagControl_ImplicitProfile_4Bytes, nlWeaveTLV_Serialize32(Tag) + +/* + * @brief Specifies a TLV element with a Fully Qualified tag + * @param ProfileId {Vendor ID, Profile Number}, as in #WeaveProfileId + * @param Tag The tag for this TLV element, defined under ProfileId. + * Would be truncated to 16 bits. + */ +#define nlWeaveTLV_TAG_FULLY_QUALIFIED_6Bytes(ProfileId, Tag) \ + nl::Weave::TLV::kTLVTagControl_FullyQualified_6Bytes, nlWeaveTLV_Serialize16(ProfileId >> 16), nlWeaveTLV_Serialize16(ProfileId), nlWeaveTLV_Serialize16(Tag) + +/* + * @brief Specifies a TLV element with a Fully Qualified tag + * @param ProfileId {Vendor ID, Profile Number}, as in #WeaveProfileId + * @param Tag The tag for this TLV element, defined under ProfileId. + * Would be truncated to 32 bits. + */ +#define nlWeaveTLV_TAG_FULLY_QUALIFIED_8Bytes(ProfileId, Tag) \ + nl::Weave::TLV::kTLVTagControl_FullyQualified_8Bytes, nlWeaveTLV_Serialize16(ProfileId >> 16), nlWeaveTLV_Serialize16(ProfileId), nlWeaveTLV_Serialize32(Tag) + +/* + * @brief Specifies a NULL TLV element, which has just the tag but no value + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + */ +#define nlWeaveTLV_NULL(TagSpec) nl::Weave::TLV::kTLVElementType_Null | TagSpec + +/* + * @brief Specifies a Structure TLV element, marking the beginning of a Structure + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + */ +#define nlWeaveTLV_STRUCTURE(TagSpec) nl::Weave::TLV::kTLVElementType_Structure | TagSpec + +/* + * @brief Specifies a Array TLV element, marking the beginning of an Array + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + */ +#define nlWeaveTLV_ARRAY(TagSpec) nl::Weave::TLV::kTLVElementType_Array | TagSpec + +/* + * @brief Specifies a Path TLV element, marking the beginning of a Path + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + */ +#define nlWeaveTLV_PATH(TagSpec) nl::Weave::TLV::kTLVElementType_Path | TagSpec + +/* + * @brief Specifies a Boolean TLV element, which can be either true or false + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Should be either true or false + */ +#define nlWeaveTLV_BOOL(TagSpec, Value) \ + ((Value) ? nl::Weave::TLV::kTLVElementType_BooleanTrue : nl::Weave::TLV::kTLVElementType_BooleanFalse) | TagSpec + +/** + * @brief + * Specifies a Single Precision Floating Point TLV element, marking the beginning of 32-bit data + * + * @param TagSpec Should be filled with macros beginning with nlWeaveTLV_TAG_ + * + * @param ... Bytes representing the floating point value to serialize + */ +#define nlWeaveTLV_FLOAT32(TagSpec, ...) \ + nl::Weave::TLV::kTLVElementType_FloatingPointNumber32 | TagSpec, ## __VA_ARGS__ + +/** + * @brief + * Specifies a Double Precision Floating Point TLV element, marking the beginning of 64-bit data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param ... Bytes representing the floating point value to serialize + */ +#define nlWeaveTLV_FLOAT64(TagSpec, ...) \ + nl::Weave::TLV::kTLVElementType_FloatingPointNumber64 | TagSpec, ## __VA_ARGS__ + +/* + * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path + */ +#define nlWeaveTLV_END_OF_CONTAINER nl::Weave::TLV::kTLVElementType_EndOfContainer | nl::Weave::TLV::kTLVTagControl_Anonymous + +/* + * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path + */ +#define nlWeaveTLV_END_OF_STRUCTURE nlWeaveTLV_END_OF_CONTAINER + +/* + * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path + */ +#define nlWeaveTLV_END_OF_ARRAY nlWeaveTLV_END_OF_CONTAINER + +/* + * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path + */ +#define nlWeaveTLV_END_OF_PATH nlWeaveTLV_END_OF_CONTAINER + + +/* + * @brief Specifies an 8-bit Signed Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to int8_t, and then serialized + */ +#define nlWeaveTLV_INT8(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int8 | TagSpec, nlWeaveTLV_Serialize8(int8_t(Value)) + +/* + * @brief Specifies a 16-bit Signed Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to int16_t, and then serialized + */ +#define nlWeaveTLV_INT16(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int16 | TagSpec, nlWeaveTLV_Serialize16(int16_t(Value)) + +/* + * @brief Specifies a 32-bit Signed Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to int32_t, and then serialized + */ +#define nlWeaveTLV_INT32(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int32 | TagSpec, nlWeaveTLV_Serialize32(int32_t(Value)) + +/* + * @brief Specifies a 32-bit Signed Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to int64_t, and then serialized + */ +#define nlWeaveTLV_INT64(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int64 | TagSpec, nlWeaveTLV_Serialize64(int64_t(Value)) + +/* + * @brief Specifies an 8-bit Unsigned Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to (uint8_t), and then serialized + */ +#define nlWeaveTLV_UINT8(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt8 | TagSpec, nlWeaveTLV_Serialize8((uint8_t)(Value)) + +/* + * @brief Specifies a 16-bit Unsigned Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to (uint16_t), and then serialized + */ +#define nlWeaveTLV_UINT16(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt16 | TagSpec, nlWeaveTLV_Serialize16((uint16_t)(Value)) + +/* + * @brief Specifies a 32-bit Unsigned Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to (uint32_t), and then serialized + */ +#define nlWeaveTLV_UINT32(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt32 | TagSpec, nlWeaveTLV_Serialize32((uint32_t)(Value)) + +/* + * @brief Specifies a 64-bit Unsigned Integer TLV element + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param Value Would be first converted to (uint64_t), and then serialized + */ +#define nlWeaveTLV_UINT64(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt64 | TagSpec, nlWeaveTLV_Serialize64((uint64_t)(Value)) + +/** + * @brief + * Specifies an UTF8 String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x100 + * + * @param ... Bytes representing the string characters to serialize + */ +#define nlWeaveTLV_UTF8_STRING_1ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_UTF8String_1ByteLength | TagSpec, nlWeaveTLV_Serialize8((uint8_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies an UTF8 String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x10000 + * + * @param ... Bytes representing the string characters to serialize + */ +#define nlWeaveTLV_UTF8_STRING_2ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_UTF8String_2ByteLength | TagSpec, nlWeaveTLV_Serialize16((uint16_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies an UTF8 String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x100000000 + * + * @param ... Bytes representing the string characters to serialize + */ +#define nlWeaveTLV_UTF8_STRING_4ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_UTF8String_4ByteLength | TagSpec, nlWeaveTLV_Serialize32((uint32_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies an UTF8 String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x10000000000000000 + * + * @param ... Bytes representing the string characters to serialize + */ +#define nlWeaveTLV_UTF8_STRING_8ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_UTF8String_8ByteLength | TagSpec, nlWeaveTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies a BYTE String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x100 + * + * @param ... Bytes to serialize + */ +#define nlWeaveTLV_BYTE_STRING_1ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_ByteString_1ByteLength | TagSpec, nlWeaveTLV_Serialize8((uint8_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies a BYTE String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x10000 + * + * @param ... Bytes to serialize + */ +#define nlWeaveTLV_BYTE_STRING_2ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_ByteString_2ByteLength | TagSpec, nlWeaveTLV_Serialize16((uint16_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies a BYTE String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x100000000 + * + * @param ... Bytes to serialize + */ +#define nlWeaveTLV_BYTE_STRING_4ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_ByteString_4ByteLength | TagSpec, nlWeaveTLV_Serialize32((uint32_t)(StringLength)), ## __VA_ARGS__ + +/** + * @brief + * Specifies a BYTE String TLV element, marking the beginning of String data + * + * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * + * @param StringLength Number of bytes in this string, must be less than 0x10000000000000000 + * + * @param ... Bytes to serialize + */ +#define nlWeaveTLV_BYTE_STRING_8ByteLength(TagSpec, StringLength, ...) \ + nl::Weave::TLV::kTLVElementType_ByteString_8ByteLength | TagSpec, nlWeaveTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ + +#endif /* WEAVETLVDATA_H_ */ diff --git a/src/lib/core/WeaveTLVDebug.cpp b/src/lib/core/WeaveTLVDebug.cpp new file mode 100644 index 00000000000000..b5c12103b2815f --- /dev/null +++ b/src/lib/core/WeaveTLVDebug.cpp @@ -0,0 +1,387 @@ +/* + * + * Copyright (c) 2015-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements interfaces for debugging and logging + * Weave TLV. + * + */ + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace nl { + +namespace Weave { + +namespace TLV { + +namespace Debug { + +/** + * Dump the TLV element referenced by @a aReader in human-readable form using + * @a aWriter. + * + * @param[in] aWriter The writer to log the TLV data. + * @param[in] aIndent The indentation for logging the current depth into + * the TLV data. + * @param[in] aReader A read-only reference to the TLV reader containing + * the TLV data to log. + * @param[in] aDepth The current depth into the TLV data. + * + */ +static void DumpHandler(DumpWriter aWriter, const char *aIndent, const TLVReader &aReader, size_t aDepth) +{ + const TLVType type = aReader.GetType(); + const uint64_t tag = aReader.GetTag(); + const uint32_t len = aReader.GetLength(); + const uint8_t *strbuf = NULL; + WEAVE_ERROR err = WEAVE_NO_ERROR; + TLVReader temp; + TLVTagControl tagControl; + + temp.Init(aReader); + tagControl = static_cast(temp.GetControlByte() & kTLVTagControlMask); + + aWriter("%zd ", aDepth); + + for (size_t i = 0; i < aDepth; i++) + aWriter("%s", aIndent); + + aWriter("%p, ", temp.GetReadPoint()); + + if (IsProfileTag(tag)) + { + aWriter("tag[%s]: 0x%x::0x%x::0x%x, ", DecodeTagControl(tagControl), VendorIdFromTag(tag), ProfileNumFromTag(tag), TagNumFromTag(tag)); + } + else if (IsContextTag(tag)) + { + aWriter("tag[%s]: 0x%x, ", DecodeTagControl(tagControl), (uint32_t)ContextTag(tag)); + } + else if (IsSpecialTag(tag)) + { + + aWriter("tag[%s]: 0x%x, ", DecodeTagControl(tagControl), tag); + } + else + { + aWriter("tag[unknown]: 0x%x, ", tag); + } + + aWriter("type: %s (0x%02x), ", DecodeType(type), type); + + + if (TLVTypeIsContainer(type)) + { + aWriter("container: "); + } + else + { + if (type == kTLVType_UTF8String || type == kTLVType_ByteString) + aWriter("length: %" PRIu32 ", ", len); + + aWriter("value: "); + + switch (type) { + + case kTLVType_SignedInteger: + int64_t sVal; + err = temp.Get(sVal); + VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_SignedInteger")); + aWriter("%" PRIi64, sVal); + break; + + case kTLVType_UnsignedInteger: + uint64_t uVal; + err = temp.Get(uVal); + VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_UnsignedInteger")); + aWriter("%" PRIu64, uVal); + break; + + case kTLVType_Boolean: + bool bVal; + err = temp.Get(bVal); + VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_Boolean")); + aWriter("%s", bVal ? "true" : "false"); + break; + + case kTLVType_FloatingPointNumber: + double fpVal; + err = temp.Get(fpVal); + VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_FloatingPointNumber")); + aWriter("%lf", fpVal); + break; + + case kTLVType_UTF8String: + err = temp.GetDataPtr(strbuf); + VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_UTF8String")); + aWriter("\"%-.*s\"", static_cast(len), strbuf); + break; + + case kTLVType_ByteString: + err = temp.GetDataPtr(strbuf); + VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_ByteString")); + aWriter("%p\n", strbuf); + break; + + case kTLVType_Null: + aWriter("NULL"); + break; + + case kTLVType_NotSpecified: + aWriter("Not Specified"); + break; + + default: + aWriter("Error: Type is not primitive."); + break; + + } + } + +exit: + aWriter("\n"); +} + +/** + * Decode a TLV tag control with a descriptive string. + * + * @param[in] aTagControl The TLV tag control to decode and for which to return + * a descriptive string. + * + * @return A pointer to a NULL-terminated string describing the specified + * tag control on success; otherwise, NULL. + * + */ +const char *DecodeTagControl(const TLVTagControl aTagControl) +{ + const char *retval; + + switch (aTagControl) + { + + case kTLVTagControl_Anonymous: + retval = "Anonymous"; + break; + + case kTLVTagControl_ContextSpecific: + retval = "Context Specific"; + break; + + case kTLVTagControl_CommonProfile_2Bytes: + retval = "Common Profile (2 Bytes)"; + break; + + case kTLVTagControl_CommonProfile_4Bytes: + retval = "Common Profile (4 Bytes)"; + break; + + case kTLVTagControl_ImplicitProfile_2Bytes: + retval = "Implicit Profile (2 Bytes)"; + break; + + case kTLVTagControl_ImplicitProfile_4Bytes: + retval = "Implicit Profile (4 Bytes)"; + break; + + case kTLVTagControl_FullyQualified_6Bytes: + retval = "Fully Qualified (6 Bytes)"; + break; + + case kTLVTagControl_FullyQualified_8Bytes: + retval = "Fully Qualified (8 Bytes)"; + break; + + default: + retval = NULL; + break; + + } + + return retval; +} + +/** + * Decode a TLV type with a descriptive string. + * + * @param[in] aType The TLV type to decode and for which to return + * a descriptive string. + * + * @return A pointer to a NULL-terminated string describing the specified + * type on success; otherwise, NULL. + * + */ +const char *DecodeType(const TLVType aType) +{ + const char *retval; + + switch (aType) + { + + case kTLVType_NotSpecified: + retval = "Not Specified"; + break; + + case kTLVType_SignedInteger: + retval = "Signed Fixed Point"; + break; + + case kTLVType_UnsignedInteger: + retval = "Unsigned Fixed Point"; + break; + + case kTLVType_Boolean: + retval = "Boolean"; + break; + + case kTLVType_FloatingPointNumber: + retval = "Floating Point"; + break; + + case kTLVType_UTF8String: + retval = "UTF-8 String"; + break; + + case kTLVType_ByteString: + retval = "Data"; + break; + + case kTLVType_Null: + retval = "Null"; + break; + + case kTLVType_Structure: + retval = "Structure"; + break; + + case kTLVType_Array: + retval = "Array"; + break; + + case kTLVType_Path: + retval = "Path"; + break; + + default: + retval = NULL; + break; + + } + + return retval; +} + +/** + * Log the TLV data within the specified reader in human-readable form to + * the specified writer. + * + * @param[in] aWriter The writer to log the TLV data. + * @param[in] aReader A read-only reference to the TLV reader containing + * the TLV data to log. + * + * @retval #WEAVE_NO_ERROR Unconditionally. + * + */ +WEAVE_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader) +{ + const char * tabs = ""; + const size_t depth = 0; + WEAVE_ERROR retval = WEAVE_NO_ERROR; + + DumpHandler(aWriter, tabs, aReader, depth); + + return retval; +} + +/** + * Log the TLV data within the specified reader in human-readable form. + * + * @param[in] aReader A read-only reference to the TLV reader containing + * the TLV data to log. + * @param[in] aDepth The current depth into the TLV data. + * @param[inout] aContext A pointer to the handler-specific context. + * + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If aContext is NULL or if + * aContext->mWriter is NULL. + * + */ +WEAVE_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext) +{ + static const char indent[] = " "; + WEAVE_ERROR retval = WEAVE_NO_ERROR; + DumpContext * context; + + VerifyOrExit(aContext != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + + context = static_cast(aContext); + + VerifyOrExit(context->mWriter != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + + DumpHandler(context->mWriter, + indent, + aReader, + aDepth); + + exit: + return retval; +} + +/** + * Dump the TLV data within the specified reader in human-readable form with + * the specified writer. + * + * @param[in] aReader A read-only reference to the TLV reader containing + * the TLV data to log. + * + * @param[in] aWriter A dump writer to log the TLV data of the TLV reader. + * + * @retval #WEAVE_NO_ERROR On success. + * + */ +WEAVE_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter) +{ + void * context = NULL; + DumpContext dumpContext = { aWriter, context }; + WEAVE_ERROR retval; + + retval = Utilities::Iterate(aReader, DumpHandler, &dumpContext); + + return retval; +} + +} // namespace Debug + +} // namespace TLV + +} // namespace Weave + +} // namespace nl diff --git a/src/lib/core/WeaveTLVDebug.hpp b/src/lib/core/WeaveTLVDebug.hpp new file mode 100644 index 00000000000000..2e575ef9c97be0 --- /dev/null +++ b/src/lib/core/WeaveTLVDebug.hpp @@ -0,0 +1,76 @@ +/* + * + * Copyright (c) 2015-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file defines types and interfaces for debugging and + * logging Weave TLV. + * + */ + +#ifndef WEAVETLVDEBUG_HPP +#define WEAVETLVDEBUG_HPP + +#include +#include + +#include +#include + +namespace nl { + +namespace Weave { + +namespace TLV { + +/** + * @namespace nl::Weave::TLV::Debug + * + * @brief + * This namespace includes types and interfaces for debugging and + * logging Weave TLV. + * + */ +namespace Debug { + +typedef void (*DumpWriter)(const char *aFormat, ...); + +struct DumpContext { + DumpWriter mWriter; + void * mContext; +}; + +extern const char *DecodeType(const TLVType aType); + +extern const char *DecodeTagControl(const TLVTagControl aTagControl); + +extern WEAVE_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader); + +extern WEAVE_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext); + +extern WEAVE_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter); + +} // namespace Debug + +} // namespace TLV + +} // namespace Weave + +} // namespace nl + +#endif // WEAVETLVDEBUG_HPP diff --git a/src/lib/core/WeaveTLVReader.cpp b/src/lib/core/WeaveTLVReader.cpp new file mode 100644 index 00000000000000..4d06134a1b6d96 --- /dev/null +++ b/src/lib/core/WeaveTLVReader.cpp @@ -0,0 +1,1584 @@ +/* + * + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements a parser for the Weave TLV (Tag-Length-Value) encoding format. + * + */ + +#include + +#include +#include +#include +#include + +namespace nl { +namespace Weave { +namespace TLV { + +using namespace nl::Weave::Encoding; + +static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 }; + +/** + * @fn uint32_t TLVReader::GetLengthRead() const + * + * Returns the total number of bytes read since the reader was initialized. + * + * @return Total number of bytes read since the reader was initialized. + */ + +/** + * @fn uint32_t TLVReader::GetRemainingLength() const + * + * Returns the total number of bytes that can be read until the max read length is reached. + * + * @return Total number of bytes that can be read until the max read length is reached. + */ + +/** + * @fn const uint8_t *TLVReader::GetReadPoint() const + * + * Gets the point in the underlying input buffer that corresponds to the reader's current position. + * + * @note Depending on the type of the current element, GetReadPoint() will return a pointer that + * is some number of bytes *after* the first byte of the element. For string types (UTF8 and byte + * strings), the pointer will point to the first byte of the string's value. For container types + * (structures, arrays and paths), the pointer will point to the first member element within the + * container. For all other types, the pointer will point to the byte immediately after the element's + * encoding. + * + * @return A pointer into underlying input buffer that corresponds to the reader's current position. + */ + +/** + * + * @var uint32_t TLVReader::ImplicitProfileId + * + * The profile id to be used for profile tags encoded in implicit form. + * + * When the reader encounters a profile-specific tag that has been encoded in implicit form, it + * uses the value of the @p ImplicitProfileId property as the assumed profile id for the tag. + * + * By default, the @p ImplicitProfileId property is set to kProfileIdNotSpecified. When decoding + * TLV that contains implicitly-encoded tags, applications must set @p ImplicitProfileId prior + * to reading any TLV elements having such tags. The appropriate profile id is usually dependent + * on the context of the application or protocol being spoken. + * + * If an implicitly-encoded tag is encountered while @p ImplicitProfileId is set to + * kProfileIdNotSpecified, the reader will return a #WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG error. + */ + +/** + * @var void *TLVReader::AppData + * + * A pointer field that can be used for application-specific data. + */ + +/** + * @typedef WEAVE_ERROR (*TLVReader::GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, uint32_t& bufLen) + * + * A function that can be used to retrieve additional TLV data to be parsed. + * + * Functions of this type are used to feed input data to a TLVReader. When called, the function is + * expected to produce additional data for the reader to parse or signal the reader that no more + * data is available. + * + * @param[in] reader A reference to the TLVReader object that is requesting input data. + * @param[in,out] bufHandle A reference to a uintptr_t value that the function can use to store + * context data between calls. This value is initialized to 0 + * prior to the first call. + * @param[in,out] bufStart A reference to a data pointer. On entry to the function, @p bufStart + * points to one byte beyond the last TLV data byte consumed by the + * reader. On exit, bufStart is expected to point to the first byte + * of new TLV data to be parsed. The new pointer value can be within + * the same buffer as the previously consumed data, or it can point + * to an entirely new buffer. + * @param[out] bufLen A reference to an unsigned integer that the function must set to + * the number of TLV data bytes being returned. If the end of the + * input TLV data has been reached, the function should set this value + * to 0. + * + * @retval #WEAVE_NO_ERROR If the function successfully produced more TLV data, or the end of + * the input data was reached (@p bufLen should be set to 0 in this case). + * @retval other Other Weave or platform-specific error codes indicating that an error + * occurred preventing the function from producing the requested data. + * + */ + +/** + * @var GetNextBufferFunct TLVReader::GetNextBuffer + * + * A pointer to a function that will produce input data for the TLVReader object. If set to NULL (the + * default value), the reader will assume that no further input data is available. + * + * GetNextBuffer can be set by an application at any time, but is typically set when the reader + * is initialized. + * + * See the GetNextBufferFunct type definition for additional information on implementing a + * GetNextBuffer function. + */ + +/** + * Initializes a TLVReader object to read from a single input buffer. + * + * @param[in] data A pointer to a buffer containing the TLV data to be parsed. + * @param[in] dataLen The length of the TLV data to be parsed. + * + */ +void TLVReader::Init(const uint8_t *data, uint32_t dataLen) +{ + mBufHandle = 0; + mReadPoint = data; + mBufEnd = data + dataLen; + mLenRead = 0; + mMaxLen = dataLen; + ClearElementState(); + mContainerType = kTLVType_NotSpecified; + SetContainerOpen(false); + + ImplicitProfileId = kProfileIdNotSpecified; + AppData = NULL; + GetNextBuffer = NULL; +} + +/** + * Initializes a TLVReader object to read from a single PacketBuffer. + * + * Parsing begins at the buffer's start position (buf->DataStart()) and continues until the + * end of the data in the buffer (as denoted by buf->Datalen()), or maxLen bytes have been parsed. + * + * @param[in] buf A pointer to an PacketBuffer containing the TLV data to be parsed. + * @param[in] maxLen The maximum of bytes to parse. Defaults to the amount of data + * in the input buffer. + */ +void TLVReader::Init(PacketBuffer *buf, uint32_t maxLen) +{ + mBufHandle = (uintptr_t) buf; + mReadPoint = buf->Start(); + mBufEnd = mReadPoint + buf->DataLength(); + mLenRead = 0; + mMaxLen = maxLen; + ClearElementState(); + mContainerType = kTLVType_NotSpecified; + SetContainerOpen(false); + + ImplicitProfileId = kProfileIdNotSpecified; + AppData = NULL; + GetNextBuffer = NULL; +} + +/** + * Initializes a TLVReader object to read from a one or more PacketBuffers. + * + * Parsing begins at the initial buffer's start position (buf->DataStart()). If + * allowDiscontiguousBuffers is true, the reader will advance through the chain of buffers linked + * by their Next() pointers. Parsing continues until all data in the buffer chain has been consumed + * (as denoted by buf->Datalen()), or maxLen bytes have been parsed. + * + * @param[in] buf A pointer to an PacketBuffer containing the TLV data to be parsed. + * @param[in] maxLen The maximum of bytes to parse. Defaults to the total amount of data + * in the input buffer chain. + * @param[in] allowDiscontiguousBuffers + * If true, advance to the next buffer in the chain once all data in the + * current buffer has been consumed. If false, stop parsing at the end + * of the initial buffer. + */ +void TLVReader::Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers) +{ + mBufHandle = (uintptr_t) buf; + mReadPoint = buf->Start(); + mBufEnd = mReadPoint + buf->DataLength(); + mLenRead = 0; + mMaxLen = maxLen; + ClearElementState(); + mContainerType = kTLVType_NotSpecified; + SetContainerOpen(false); + + ImplicitProfileId = kProfileIdNotSpecified; + AppData = NULL; + + if (allowDiscontiguousBuffers) + { + GetNextBuffer = GetNextPacketBuffer; + } + else + { + GetNextBuffer = NULL; + } +} + +/** + * Initializes a TLVReader object from another TLVReader object. + * + * @param[in] aReader A read-only reference to the TLVReader to initialize + * this from. + * + */ +void TLVReader::Init(const TLVReader &aReader) +{ + // Initialize private data members + + mElemTag = aReader.mElemTag; + mElemLenOrVal = aReader.mElemLenOrVal; + mBufHandle = aReader.mBufHandle; + mReadPoint = aReader.mReadPoint; + mBufEnd = aReader.mBufEnd; + mLenRead = aReader.mLenRead; + mMaxLen = aReader.mMaxLen; + mControlByte = aReader.mControlByte; + mContainerType = aReader.mContainerType; + SetContainerOpen(aReader.IsContainerOpen()); + + // Initialize public data members + + ImplicitProfileId = aReader.ImplicitProfileId; + AppData = aReader.AppData; + GetNextBuffer = aReader.GetNextBuffer; +} + +/** + * Returns the type of the current TLV element. + * + * @return A TLVType value describing the data type of the current TLV element. If the reader + * is not positioned on a TLV element, the return value will be kTLVType_NotSpecified. + */ +TLVType TLVReader::GetType() const +{ + TLVElementType elemType = ElementType(); + if (elemType == kTLVElementType_EndOfContainer) + return kTLVType_NotSpecified; + if (elemType == kTLVElementType_FloatingPointNumber32 || elemType == kTLVElementType_FloatingPointNumber64) + return kTLVType_FloatingPointNumber; + if (elemType == kTLVElementType_NotSpecified || elemType >= kTLVElementType_Null) + return (TLVType) elemType; + return (TLVType) (elemType & ~kTLVTypeSizeMask); +} + +/** + * Returns the control byte associated with current TLV element. + * + * Ideally, nobody ever needs to know about the control byte and only the + * internal implementation of TLV should have access to it. But, nevertheless, + * having access to the control byte is helpful for debugging purposes by the + * TLV Debug Utilities (that try to decode the tag control byte when pretty + * printing the TLV buffer contents). + * + * @note Unless you really know what you are doing, please refrain from using + * this method and the associated control byte information. + * + * @return An unsigned integer containing the control byte associated with + * the current TLV element. kTLVControlByte_NotSpecified is + * returned if the reader is not positioned @em on an element. + */ +uint16_t TLVReader::GetControlByte() const +{ + return mControlByte; +} + +/** + * Returns the tag associated with current TLV element. + * + * The value returned by GetTag() can be used with the tag utility functions (IsProfileTag(), + * IsContextTag(), ProfileIdFromTag(), etc.) to determine the type of tag and to extract various tag + * field values. + * + * @note If the reader is not positioned on a TLV element when GetTag() is called, the return value + * is undefined. Therefore whenever the position of the reader is uncertain applications should call + * GetType() to determine if the reader is position on an element (GetType() != kTLVType_NotSpecified) + * before calling GetTag(). + * + * @return An unsigned integer containing information about the tag associated with the current + * TLV element. + */ +uint64_t TLVReader::GetTag() const +{ + return mElemTag; +} + +/** + * Returns the length of data associated with current TLV element. + * + * Data length only applies to elements of type UTF8 string or byte string. For UTF8 strings, the + * value returned is the number of bytes in the string, not the number of characters. + * + * @return The length (in bytes) of data associated with the current TLV element, or 0 if the + * current element is not a UTF8 string or byte string, or if the reader is not + * positioned on an element. + */ +uint32_t TLVReader::GetLength() const +{ + if (TLVTypeHasLength(ElementType())) + return (uint32_t) mElemLenOrVal; + else + return 0; +} + +/** + * Get the value of the current element as a bool type. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV boolean type, or the + * reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(bool& v) +{ + TLVElementType elemType = ElementType(); + if (elemType == kTLVElementType_BooleanFalse) + v = false; + else if (elemType == kTLVElementType_BooleanTrue) + v = true; + else + return WEAVE_ERROR_WRONG_TLV_TYPE; + return WEAVE_NO_ERROR; +} + +/** + * Get the value of the current element as an 8-bit signed integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(int8_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as a 16-bit signed integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(int16_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as a 32-bit signed integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(int32_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as a 64-bit signed integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(int64_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as an 8-bit unsigned integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. Similarly, if the encoded integer value is negative, the value will be converted + * to unsigned. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(uint8_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as a 16-bit unsigned integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. Similarly, if the encoded integer value is negative, the value will be converted + * to unsigned. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(uint16_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as a 32-bit unsigned integer. + * + * If the encoded integer value is larger than the output data type the resultant value will be + * truncated. Similarly, if the encoded integer value is negative, the value will be converted + * to unsigned. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(uint32_t& v) +{ + uint64_t v64 = 0; + WEAVE_ERROR err = Get(v64); + v = v64; + return err; +} + +/** + * Get the value of the current element as a 64-bit unsigned integer. + * + * If the encoded integer value is negative, the value will be converted to unsigned. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * unsigned), or the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(uint64_t& v) +{ + switch (ElementType()) + { + case kTLVElementType_Int8: + v = (int64_t) (int8_t) mElemLenOrVal; + break; + case kTLVElementType_Int16: + v = (int64_t) (int16_t) mElemLenOrVal; + break; + case kTLVElementType_Int32: + v = (int64_t) (int32_t) mElemLenOrVal; + break; + case kTLVElementType_Int64: + case kTLVElementType_UInt8: + case kTLVElementType_UInt16: + case kTLVElementType_UInt32: + case kTLVElementType_UInt64: + v = mElemLenOrVal; + break; + default: + return WEAVE_ERROR_WRONG_TLV_TYPE; + } + return WEAVE_NO_ERROR; +} + +/** + * Get the value of the current element as a double-precision floating point number. + * + * @param[out] v Receives the value associated with current TLV element. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV floating point type, or + * the reader is not positioned on an element. + * + */ +WEAVE_ERROR TLVReader::Get(double& v) +{ + switch (ElementType()) + { + case kTLVElementType_FloatingPointNumber32: + { + union + { + uint32_t u32; + float f; + } cvt; + cvt.u32 = (uint32_t)mElemLenOrVal; + v = cvt.f; + break; + } + case kTLVElementType_FloatingPointNumber64: + { + union + { + uint64_t u64; + double d; + } cvt; + cvt.u64 = mElemLenOrVal; + v = cvt.d; + break; + } + default: + return WEAVE_ERROR_WRONG_TLV_TYPE; + } + return WEAVE_NO_ERROR; +} + +/** + * Get the value of the current byte or UTF8 string element. + * + * To determine the required input buffer size, call the GetLength() method before calling GetBytes(). + * + * @note The data output by this method is NOT null-terminated. + * + * @param[in] buf A pointer to a buffer to receive the string data. + * @param[in] bufSize The size in bytes of the buffer pointed to by @p buf. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * the reader is not positioned on an element. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If the supplied buffer is too small to hold the data associated + * with the current element. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::GetBytes(uint8_t *buf, uint32_t bufSize) +{ + if (!TLVTypeIsString(ElementType())) + return WEAVE_ERROR_WRONG_TLV_TYPE; + + if (mElemLenOrVal > bufSize) + return WEAVE_ERROR_BUFFER_TOO_SMALL; + + WEAVE_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal); + if (err != WEAVE_NO_ERROR) + return err; + + mElemLenOrVal = 0; + + return WEAVE_NO_ERROR; +} + +/** + * Get the value of the current byte or UTF8 string element as a null terminated string. + * + * To determine the required input buffer size, call the GetLength() method before calling GetBytes(). + * The input buffer should be at least one byte bigger than the string length to accommodate the null + * character. + * + * @param[in] buf A pointer to a buffer to receive the byte string data. + * @param[in] bufSize The size in bytes of the buffer pointed to by @p buf. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * the reader is not positioned on an element. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If the supplied buffer is too small to hold the data associated + * with the current element. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::GetString(char *buf, uint32_t bufSize) +{ + if (!TLVTypeIsString(ElementType())) + return WEAVE_ERROR_WRONG_TLV_TYPE; + + if ((mElemLenOrVal + 1) > bufSize) + return WEAVE_ERROR_BUFFER_TOO_SMALL; + + buf[mElemLenOrVal] = 0; + + return GetBytes((uint8_t *) buf, bufSize - 1); +} + +/** + * Allocates and returns a buffer containing the value of the current byte or UTF8 string. + * + * This method creates a buffer for and returns a copy of the data associated with the byte + * or UTF-8 string element at the current position. Memory for the buffer is obtained with + * malloc() and should be freed with free() by the caller when it is no longer needed. + * + * @note The data returned by this method is NOT null-terminated. + * + * @param[out] buf A reference to a pointer to which a heap-allocated buffer of + * @p dataLen bytes will be assigned on success. + * @param[out] dataLen A reference to storage for the size, in bytes, of @p buf on + * success. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * the reader is not positioned on an element. + * @retval #WEAVE_ERROR_NO_MEMORY If memory could not be allocated for the output buffer. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE + * If the target platform does not support malloc() and free(). + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer + * is non-NULL. + * + */ +WEAVE_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t& dataLen) +{ +#if HAVE_MALLOC && HAVE_FREE + if (!TLVTypeIsString(ElementType())) + return WEAVE_ERROR_WRONG_TLV_TYPE; + + buf = (uint8_t *) malloc(mElemLenOrVal); + if (buf == NULL) + return WEAVE_ERROR_NO_MEMORY; + + WEAVE_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal); + if (err != WEAVE_NO_ERROR) + { + free(buf); + return err; + } + + dataLen = mElemLenOrVal; + mElemLenOrVal = 0; + + return WEAVE_NO_ERROR; +#else + return WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE; +#endif // HAVE_MALLOC && HAVE_FREE +} + +/** + * Allocates and returns a buffer containing the null-terminated value of the current byte or UTF8 + * string. + * + * This method creates a buffer for and returns a null-terminated copy of the data associated with + * the byte or UTF-8 string element at the current position. Memory for the buffer is obtained with + * malloc() and should be freed with free() by the caller when it is no longer needed. + * + * @param[out] buf A reference to a pointer to which a heap-allocated buffer of + * will be assigned on success. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * the reader is not positioned on an element. + * @retval #WEAVE_ERROR_NO_MEMORY If memory could not be allocated for the output buffer. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE + * If the target platform does not support malloc() and free(). + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer + * is non-NULL. + * + */ +WEAVE_ERROR TLVReader::DupString(char *& buf) +{ +#if HAVE_MALLOC && HAVE_FREE + if (!TLVTypeIsString(ElementType())) + return WEAVE_ERROR_WRONG_TLV_TYPE; + + buf = (char *) malloc(mElemLenOrVal + 1); + if (buf == NULL) + return WEAVE_ERROR_NO_MEMORY; + + WEAVE_ERROR err = ReadData((uint8_t *) buf, (uint32_t) mElemLenOrVal); + if (err != WEAVE_NO_ERROR) + { + free(buf); + return err; + } + + buf[mElemLenOrVal] = 0; + mElemLenOrVal = 0; + + return err; +#else + return WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE; +#endif // HAVE_MALLOC && HAVE_FREE +} + +/** + * Get a pointer to the initial encoded byte of a TLV byte or UTF8 string element. + * + * This method returns a direct pointer the encoded string value within the underlying input buffer. + * To succeed, the method requires that the entirety of the string value be present in a single buffer. + * Otherwise the method returns #WEAVE_ERROR_TLV_UNDERRUN. This makes the method of limited use when + * reading data from multiple discontiguous buffers. + * + * @param[out] data A reference to a const pointer that will receive a pointer to + * the underlying string data. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or the + * reader is not positioned on an element. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely or the value + * of the current string element is not contained within a single + * contiguous buffer. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::GetDataPtr(const uint8_t *& data) +{ + WEAVE_ERROR err; + + if (!TLVTypeIsString(ElementType())) + return WEAVE_ERROR_WRONG_TLV_TYPE; + + err = EnsureData(WEAVE_ERROR_TLV_UNDERRUN); + if (err != WEAVE_NO_ERROR) + return err; + + uint32_t remainingLen = mBufEnd - mReadPoint; + + // Verify that the entirety of the data is available in the buffer. + // Note that this may not be possible if the reader is reading from a chain of buffers. + if (remainingLen < (uint32_t)mElemLenOrVal) + return WEAVE_ERROR_TLV_UNDERRUN; + + data = mReadPoint; + + return WEAVE_NO_ERROR; +} + +/** + * Initializes a new TLVReader object for reading the members of a TLV container element. + * + * The OpenContainer() method initializes a new TLVReader object for reading the member elements of a + * TLV container (a structure, array or path). When OpenContainer() is called, the current TLVReader + * object must be positioned on the container element to be read. The method takes as its sole argument + * a reference to a new reader that will be initialized to read the container. This reader is known as + * the container reader while the reader on which OpenContainer() is called is known as the parent + * reader. + * + * When the OpenContainer() method returns, the container reader is positioned immediately before the + * first member of the container. Calling Next() on the container reader will advance through the members + * of the collection until the end is reached, at which point the reader will return WEAVE_END_OF_TLV. + * + * While the container reader is open, applications must not make calls on or otherwise alter the state + * of the parent reader. Once an application has finished using the container reader it must close it + * by calling CloseContainer() on the parent reader, passing the container reader as an argument. + * Applications may close the container reader at any point, with or without reading all elements + * contained in the underlying container. After the container reader is closed, applications may + * continue their use of the parent reader. + * + * The container reader inherits various configuration properties from the parent reader. These are: + * + * @li The implicit profile id (ImplicitProfileId) + * @li The application data pointer (AppData) + * @li The GetNextBuffer function pointer + * + * @note The EnterContainer() method can be used as an alternative to OpenContainer() to read a + * container element without initializing a new reader object. + * + * @param[out] containerReader A reference to a TLVReader object that will be initialized for + * reading the members of the current container element. Any data + * associated with the supplied object is overwritten. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE If the current element is not positioned on a container element. + * + */ +WEAVE_ERROR TLVReader::OpenContainer(TLVReader& containerReader) +{ + TLVElementType elemType = ElementType(); + if (!TLVTypeIsContainer(elemType)) + return WEAVE_ERROR_INCORRECT_STATE; + + containerReader.mBufHandle = mBufHandle; + containerReader.mReadPoint = mReadPoint; + containerReader.mBufEnd = mBufEnd; + containerReader.mLenRead = mLenRead; + containerReader.mMaxLen = mMaxLen; + containerReader.ClearElementState(); + containerReader.mContainerType = (TLVType) elemType; + containerReader.SetContainerOpen(false); + containerReader.ImplicitProfileId = ImplicitProfileId; + containerReader.AppData = AppData; + containerReader.GetNextBuffer = GetNextBuffer; + + SetContainerOpen(true); + + return WEAVE_NO_ERROR; +} + +/** + * Completes the reading of a TLV container after a call to OpenContainer(). + * + * The CloseContainer() method restores the state of a parent TLVReader object after a call to + * OpenContainer(). For every call to OpenContainer() applications must make a corresponding + * call to CloseContainer(), passing a reference to the same container reader to both methods. + * + * When CloseContainer() returns, the parent reader is positioned immediately before the first + * element that follows the container. From this point an application can use the Next() method + * to advance through any remaining elements. + * + * Applications can call close CloseContainer() on a parent reader at any point in time, regardless + * of whether all elements in the underlying container have been read. After CloseContainer() has + * been called, the application should consider the container reader 'de-initialized' and must not + * use it further without re-initializing it. + * + * @param[in] containerReader A reference to the TLVReader object that was supplied to the + * OpenContainer() method. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if + * the container reader does not match the one passed to the + * OpenContainer() method. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV + * element type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::CloseContainer(TLVReader& containerReader) +{ + WEAVE_ERROR err; + + if (!IsContainerOpen()) + return WEAVE_ERROR_INCORRECT_STATE; + + if ((TLVElementType) containerReader.mContainerType != ElementType()) + return WEAVE_ERROR_INCORRECT_STATE; + + err = containerReader.SkipToEndOfContainer(); + if (err != WEAVE_NO_ERROR) + return err; + + mBufHandle = containerReader.mBufHandle; + mReadPoint = containerReader.mReadPoint; + mBufEnd = containerReader.mBufEnd; + mLenRead = containerReader.mLenRead; + mMaxLen = containerReader.mMaxLen; + ClearElementState(); + + return WEAVE_NO_ERROR; +} + +/** + * Prepares a TLVReader object for reading the members of TLV container element. + * + * The EnterContainer() method prepares the current TLVReader object to begin reading the member + * elements of a TLV container (a structure, array or path). For every call to EnterContainer() + * applications must make a corresponding call to ExitContainer(). + * + * When EnterContainer() is called the TLVReader object must be positioned on the container element + * to be read. The method takes as an argument a reference to a TLVType value which will be used + * to save the context of the reader while it is reading the container. + * + * When the EnterContainer() method returns, the reader is positioned immediately @em before the + * first member of the container. Repeatedly calling Next() will advance the reader through the members + * of the collection until the end is reached, at which point the reader will return WEAVE_END_OF_TLV. + * + * Once the application has finished reading a container it can continue reading the elements after + * the container by calling the ExitContainer() method. + * + * @param[out] outerContainerType A reference to a TLVType value that will receive the context + * of the reader. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE If the current element is not positioned on a container element. + * + */ +WEAVE_ERROR TLVReader::EnterContainer(TLVType& outerContainerType) +{ + TLVElementType elemType = ElementType(); + if (!TLVTypeIsContainer(elemType)) + return WEAVE_ERROR_INCORRECT_STATE; + + outerContainerType = mContainerType; + mContainerType = (TLVType) elemType; + + ClearElementState(); + SetContainerOpen(false); + + return WEAVE_NO_ERROR; +} + +/** + * Completes the reading of a TLV container and prepares a TLVReader object to read elements + * after the container. + * + * The ExitContainer() method restores the state of a TLVReader object after a call to + * EnterContainer(). For every call to EnterContainer() applications must make a corresponding + * call to ExitContainer(), passing the context value returned by the EnterContainer() method. + * + * When ExitContainer() returns, the reader is positioned immediately before the first element that + * follows the container. From this point an application can use the Next() method to advance + * through any remaining elements. + * + * Once EnterContainer() has been called, applications can call ExitContainer() on a reader at any + * point in time, regardless of whether all elements in the underlying container have been read. + * + * @note Any changes made to the configuration of the reader between the calls to EnterContainer() + * and ExitContainer() are NOT undone by the call to ExitContainer(). For example, a change to the + * implicit profile id (@p ImplicitProfileId) will not be reversed when a container is exited. Thus + * it is the application's responsibility to adjust the configuration accordingly at the appropriate + * times. + * + * @param[in] outerContainerType The TLVType value that was returned by the EnterContainer() method. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if + * the container reader does not match the one passed to the + * OpenContainer() method. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV element type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::ExitContainer(TLVType outerContainerType) +{ + WEAVE_ERROR err; + + err = SkipToEndOfContainer(); + if (err != WEAVE_NO_ERROR) + return err; + + mContainerType = outerContainerType; + ClearElementState(); + + return WEAVE_NO_ERROR; +} + +/** + * Verifies that the TVLReader object is at the end of a TLV container. + * + * The VerifyEndOfContainer() method verifies that there are no further TLV elements to be read + * within the current TLV container. This is a convenience method that is equivalent to calling + * Next() and checking for a return value of WEAVE_END_OF_TLV. + * + * @note When there are more TLV elements in the collection, this method will change the position + * of the reader. + * + * @retval #WEAVE_NO_ERROR If there are no further TLV elements to be read. + * @retval #WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT + * If another TLV element was found in the collection. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV element + * type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::VerifyEndOfContainer() +{ + WEAVE_ERROR err = Next(); + if (err == WEAVE_END_OF_TLV) + return WEAVE_NO_ERROR; + if (err == WEAVE_NO_ERROR) + return WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT; + return err; +} + +/** + * Returns the type of the container within which the TLVReader is currently reading. + * + * The GetContainerType() method returns the type of the TLV container within which the TLVReader + * is reading. If the TLVReader is positioned at the outer-most level of a TLV encoding (i.e. before, + * on or after the outer-most TLV element), the method will return kTLVType_NotSpecified. + * + * @return The TLVType of the current container, or kTLVType_NotSpecified if the TLVReader is not + * positioned within a container. + */ +TLVType TLVReader::GetContainerType() const +{ + return mContainerType; +} + +/** + * Advances the TLVReader object to the next TLV element to be read. + * + * The Next() method positions the reader object on the next element in a TLV encoding that resides + * in the same containment context. In particular, if the reader is positioned at the outer-most + * level of a TLV encoding, calling Next() will advance the reader to the next, top-most element. + * If the reader is positioned within a TLV container element (a structure, array or path), calling + * Next() will advance the reader to the next member element of the container. + * + * Since Next() constrains reader motion to the current containment context, calling Next() when + * the reader is positioned on a container element will advance @em over the container, skipping + * its member elements (and the members of any nested containers) until it reaches the first element + * after the container. + * + * When there are no further elements within a particular containment context the Next() method will + * return a #WEAVE_END_OF_TLV error and the position of the reader will remain unchanged. + * + * @retval #WEAVE_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #WEAVE_END_OF_TLV If no further elements are available. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV element + * type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval #WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG + * If the reader encountered a implicitly-encoded TLV tag for which + * the corresponding profile id is unknown. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::Next() +{ + WEAVE_ERROR err; + TLVElementType elemType = ElementType(); + + err = Skip(); + if (err != WEAVE_NO_ERROR) + return err; + + err = ReadElement(); + if (err != WEAVE_NO_ERROR) + return err; + + elemType = ElementType(); + if (elemType == kTLVElementType_EndOfContainer) + return WEAVE_END_OF_TLV; + + return WEAVE_NO_ERROR; +} + +/** + * Advances the TLVReader object to the next TLV element to be read, asserting the type and tag of + * the new element. + * + * The Next(TLVType expectedType, uint64_t expectedTag) method is a convenience method that has the + * same behavior as Next(), but also verifies that the type and tag of the new TLV element match + * the supplied arguments. + * + * @param[in] expectedType The expected data type for the next element. + * @param[in] expectedTag The expected tag for the next element. + * + * @retval #WEAVE_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #WEAVE_END_OF_TLV If no further elements are available. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the type of the new element does not match the value + * of the @p expectedType argument. + * @retval #WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT + * If the tag associated with the new element does not match the + * value of the @p expectedTag argument. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV + * element type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::Next(TLVType expectedType, uint64_t expectedTag) +{ + WEAVE_ERROR err = Next(); + if (err != WEAVE_NO_ERROR) + return err; + if (GetType() != expectedType) + return WEAVE_ERROR_WRONG_TLV_TYPE; + if (mElemTag != expectedTag) + return WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT; + return WEAVE_NO_ERROR; +} + +/** + * Advances the TLVReader object to immediately after the current TLV element. + * + * The Skip() method positions the reader object immediately @em after the current TLV element, such + * that a subsequent call to Next() will advance the reader to the following element. Like Next(), + * if the reader is positioned on a container element at the time of the call, the members of the + * container will be skipped. If the reader is not positioned on any element, its position remains + * unchanged. + * + * @retval #WEAVE_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #WEAVE_END_OF_TLV If no further elements are available. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the reader encountered an invalid or unsupported TLV + * element type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + * + */ +WEAVE_ERROR TLVReader::Skip() +{ + WEAVE_ERROR err; + TLVElementType elemType = ElementType(); + + if (elemType == kTLVElementType_EndOfContainer) + return WEAVE_END_OF_TLV; + + if (TLVTypeIsContainer(elemType)) + { + TLVType outerContainerType; + err = EnterContainer(outerContainerType); + if (err != WEAVE_NO_ERROR) + return err; + err = ExitContainer(outerContainerType); + if (err != WEAVE_NO_ERROR) + return err; + } + + else + { + err = SkipData(); + if (err != WEAVE_NO_ERROR) + return err; + + ClearElementState(); + } + + return WEAVE_NO_ERROR; +} + +/** + * Clear the state of the TLVReader. + * This method is used to position the reader before the first TLV, + * between TLVs or after the last TLV. + */ +void TLVReader::ClearElementState(void) +{ + mElemTag = AnonymousTag; + mControlByte = kTLVControlByte_NotSpecified; + mElemLenOrVal = 0; +} + +/** + * Skip any data contained in the current TLV by reading over it without + * a destination buffer. + * + * @retval #WEAVE_NO_ERROR If the reader was successfully positioned at the end of the + * data. + * @retval other Other Weave or platform error codes returned by the configured + * GetNextBuffer() function. Only possible when GetNextBuffer is + * non-NULL. + */ +WEAVE_ERROR TLVReader::SkipData(void) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + TLVElementType elemType = ElementType(); + + if (TLVTypeHasLength(elemType)) + { + err = ReadData(NULL, mElemLenOrVal); + if (err != WEAVE_NO_ERROR) + return err; + } + + return err; +} + +WEAVE_ERROR TLVReader::SkipToEndOfContainer() +{ + WEAVE_ERROR err; + TLVType outerContainerType = mContainerType; + uint32_t nestLevel = 0; + + // If the user calls Next() after having called OpenContainer() but before calling + // CloseContainer() they're effectively doing a close container by skipping over + // the container element. So reset the 'container open' flag here to prevent them + // from calling CloseContainer() with the now orphaned container reader. + SetContainerOpen(false); + + while (true) + { + TLVElementType elemType = ElementType(); + + if (elemType == kTLVElementType_EndOfContainer) + { + if (nestLevel == 0) + return WEAVE_NO_ERROR; + + nestLevel--; + mContainerType = (nestLevel == 0) ? outerContainerType : kTLVType_UnknownContainer; + } + + else if (TLVTypeIsContainer(elemType)) + { + nestLevel++; + mContainerType = (TLVType)elemType; + } + + err = SkipData(); + if (err != WEAVE_NO_ERROR) + return err; + + err = ReadElement(); + if (err != WEAVE_NO_ERROR) + return err; + } +} + +WEAVE_ERROR TLVReader::ReadElement() +{ + WEAVE_ERROR err; + uint8_t stagingBuf[17]; // 17 = 1 control byte + 8 tag bytes + 8 length/value bytes + const uint8_t *p; + TLVElementType elemType; + + // Make sure we have input data. Return WEAVE_END_OF_TLV if no more data is available. + err = EnsureData(WEAVE_END_OF_TLV); + if (err != WEAVE_NO_ERROR) + return err; + + // Get the element's control byte. + mControlByte = *mReadPoint; + + // Extract the element type from the control byte. Fail if it's invalid. + elemType = ElementType(); + if (!IsValidTLVType(elemType)) + return WEAVE_ERROR_INVALID_TLV_ELEMENT; + + // Extract the tag control from the control byte. + TLVTagControl tagControl = (TLVTagControl)(mControlByte & kTLVTagControlMask); + + // Determine the number of bytes in the element's tag, if any. + uint8_t tagBytes = sTagSizes[tagControl >> kTLVTagControlShift]; + + // Extract the size of length/value field from the control byte. + TLVFieldSize lenOrValFieldSize = GetTLVFieldSize(elemType); + + // Determine the number of bytes in the length/value field. + uint8_t valOrLenBytes = TLVFieldSizeToBytes(lenOrValFieldSize); + + // Determine the number of bytes in the element's 'head'. This includes: the control byte, the tag bytes (if present), the + // length bytes (if present), and for elements that don't have a length (e.g. integers), the value bytes. + uint8_t elemHeadBytes = 1 + tagBytes + valOrLenBytes; + + // If the head of the element overlaps the end of the input buffer, read the bytes into the staging buffer + // and arrange to parse them from there. Otherwise read them directly from the input buffer. + if (elemHeadBytes > (mBufEnd - mReadPoint)) + { + err = ReadData(stagingBuf, elemHeadBytes); + if (err != WEAVE_NO_ERROR) + return err; + p = stagingBuf; + } + else + { + p = mReadPoint; + mReadPoint += elemHeadBytes; + mLenRead += elemHeadBytes; + } + + // Skip over the control byte. + p++; + + // Read the tag field, if present. + mElemTag = ReadTag(tagControl, p); + + // Read the length/value field, if present. + switch (lenOrValFieldSize) + { + case kTLVFieldSize_0Byte: + mElemLenOrVal = 0; + break; + case kTLVFieldSize_1Byte: + mElemLenOrVal = Read8(p); + break; + case kTLVFieldSize_2Byte: + mElemLenOrVal = LittleEndian::Read16(p); + break; + case kTLVFieldSize_4Byte: + mElemLenOrVal = LittleEndian::Read32(p); + break; + case kTLVFieldSize_8Byte: + mElemLenOrVal = LittleEndian::Read64(p); + break; + } + + return VerifyElement(); +} + +WEAVE_ERROR TLVReader::VerifyElement() +{ + if (ElementType() == kTLVElementType_EndOfContainer) + { + if (mContainerType == kTLVType_NotSpecified) + return WEAVE_ERROR_INVALID_TLV_ELEMENT; + if (mElemTag != AnonymousTag) + return WEAVE_ERROR_INVALID_TLV_TAG; + } + else + { + if (mElemTag == UnknownImplicitTag) + return WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG; + switch (mContainerType) + { + case kTLVType_NotSpecified: + if (IsContextTag(mElemTag)) + return WEAVE_ERROR_INVALID_TLV_TAG; + break; + case kTLVType_Structure: + case kTLVType_Path: + if (mElemTag == AnonymousTag) + return WEAVE_ERROR_INVALID_TLV_TAG; + break; + case kTLVType_Array: + if (mElemTag != AnonymousTag) + return WEAVE_ERROR_INVALID_TLV_TAG; + break; + case kTLVType_UnknownContainer: + break; + default: + return WEAVE_ERROR_INCORRECT_STATE; + } + } + + // If the current element encodes a specific length (e.g. a UTF8 string or a byte string), verify + // that the purported length fits within the remaining bytes of the encoding (as delineated by mMaxLen). + // + // Note that this check is not strictly necessary to prevent runtime errors, as any attempt to access + // the data of an element with an invalid length will result in an error. However checking the length + // here catches the error earlier, and ensures that the application will never see the erroneous length + // value. + // + if (TLVTypeHasLength(ElementType())) + { + uint32_t overallLenRemaining = mMaxLen - mLenRead; + if (overallLenRemaining < (uint32_t)mElemLenOrVal) + return WEAVE_ERROR_TLV_UNDERRUN; + } + + return WEAVE_NO_ERROR; +} + +uint64_t TLVReader::ReadTag(TLVTagControl tagControl, const uint8_t *& p) +{ + uint16_t vendorId; + uint16_t profileNum; + + switch (tagControl) + { + case kTLVTagControl_ContextSpecific: + return ContextTag(Read8(p)); + case kTLVTagControl_CommonProfile_2Bytes: + return CommonTag(LittleEndian::Read16(p)); + case kTLVTagControl_CommonProfile_4Bytes: + return CommonTag(LittleEndian::Read32(p)); + case kTLVTagControl_ImplicitProfile_2Bytes: + if (ImplicitProfileId == kProfileIdNotSpecified) + return UnknownImplicitTag; + return ProfileTag(ImplicitProfileId, LittleEndian::Read16(p)); + case kTLVTagControl_ImplicitProfile_4Bytes: + if (ImplicitProfileId == kProfileIdNotSpecified) + return UnknownImplicitTag; + return ProfileTag(ImplicitProfileId, LittleEndian::Read32(p)); + case kTLVTagControl_FullyQualified_6Bytes: + vendorId = LittleEndian::Read16(p); + profileNum = LittleEndian::Read16(p); + return ProfileTag(vendorId, profileNum, LittleEndian::Read16(p)); + case kTLVTagControl_FullyQualified_8Bytes: + vendorId = LittleEndian::Read16(p); + profileNum = LittleEndian::Read16(p); + return ProfileTag(vendorId, profileNum, LittleEndian::Read32(p)); + case kTLVTagControl_Anonymous: + default: + return AnonymousTag; + } +} + +WEAVE_ERROR TLVReader::ReadData(uint8_t *buf, uint32_t len) +{ + WEAVE_ERROR err; + + while (len > 0) + { + err = EnsureData(WEAVE_ERROR_TLV_UNDERRUN); + if (err != WEAVE_NO_ERROR) + return err; + + uint32_t remainingLen = mBufEnd - mReadPoint; + + uint32_t readLen = len; + if (readLen > remainingLen) + readLen = remainingLen; + + if (buf != NULL) + { + memcpy(buf, mReadPoint, readLen); + buf += readLen; + } + mReadPoint += readLen; + mLenRead += readLen; + len -= readLen; + } + + return WEAVE_NO_ERROR; +} + +WEAVE_ERROR TLVReader::EnsureData(WEAVE_ERROR noDataErr) +{ + WEAVE_ERROR err; + + if (mReadPoint == mBufEnd) + { + if (mLenRead == mMaxLen) + return noDataErr; + + if (GetNextBuffer == NULL) + return noDataErr; + + uint32_t bufLen; + err = GetNextBuffer(*this, mBufHandle, mReadPoint, bufLen); + if (err != WEAVE_NO_ERROR) + return err; + if (bufLen == 0) + return noDataErr; + + // Cap mBufEnd so that we don't read beyond the user's specified maximum length, even + // if the underlying buffer is larger. + uint32_t overallLenRemaining = mMaxLen - mLenRead; + if (overallLenRemaining < bufLen) + bufLen = overallLenRemaining; + + mBufEnd = mReadPoint + bufLen; + } + + return WEAVE_NO_ERROR; +} + +/** + * This is a private method used to compute the length of a TLV element head. + */ +WEAVE_ERROR TLVReader::GetElementHeadLength(uint8_t& elemHeadBytes) const +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + uint8_t tagBytes; + uint8_t valOrLenBytes; + TLVTagControl tagControl; + TLVFieldSize lenOrValFieldSize; + TLVElementType elemType = ElementType(); + + // Verify element is of valid TLVType. + VerifyOrExit(IsValidTLVType(elemType), err = WEAVE_ERROR_INVALID_TLV_ELEMENT); + + // Extract the tag control from the control byte. + tagControl = (TLVTagControl)(mControlByte & kTLVTagControlMask); + + // Determine the number of bytes in the element's tag, if any. + tagBytes = sTagSizes[tagControl >> kTLVTagControlShift]; + + // Extract the size of length/value field from the control byte. + lenOrValFieldSize = GetTLVFieldSize(elemType); + + // Determine the number of bytes in the length/value field. + valOrLenBytes = TLVFieldSizeToBytes(lenOrValFieldSize); + + // Determine the number of bytes in the element's 'head'. This includes: the + // control byte, the tag bytes (if present), the length bytes (if present), + // and for elements that don't have a length (e.g. integers), the value + // bytes. + elemHeadBytes = 1 + tagBytes + valOrLenBytes; + +exit: + return err; +} + +/** + * This is a private method that returns the TLVElementType from mControlByte + */ +TLVElementType TLVReader::ElementType() const +{ + if (mControlByte == (uint16_t) kTLVControlByte_NotSpecified) + return kTLVElementType_NotSpecified; + else + return (TLVElementType) (mControlByte & kTLVTypeMask); +} + +WEAVE_ERROR TLVReader::GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen) +{ + PacketBuffer *& buf = (PacketBuffer *&) bufHandle; + + if (buf != NULL) + buf = buf->Next(); + if (buf != NULL) + { + bufStart = buf->Start(); + bufLen = buf->DataLength(); + } + else + { + bufStart = NULL; + bufLen = 0; + } + + return WEAVE_NO_ERROR; +} + +} // namespace TLV +} // namespace Weave +} // namespace nl diff --git a/src/lib/core/WeaveTLVTags.h b/src/lib/core/WeaveTLVTags.h new file mode 100644 index 00000000000000..2d036830136acd --- /dev/null +++ b/src/lib/core/WeaveTLVTags.h @@ -0,0 +1,190 @@ +/* + * + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file contains definitions for working with Weave TLV tags. + * + */ + +#ifndef WEAVETLVTAGS_H_ +#define WEAVETLVTAGS_H_ + +namespace nl { +namespace Weave { +namespace TLV { + +enum TLVCommonProfiles +{ + /** + * Used to indicate the absence of a profile id in a variable or member. + * This is essentially the same as kWeaveProfile_NotSpecified defined in WeaveProfiles.h + */ + kProfileIdNotSpecified = 0xFFFFFFFF, + + // TODO: Replace with nl::Weave::Profiles::kWeaveProfile_Common + kCommonProfileId = 0 +}; + +// TODO: Move to private namespace +enum TLVTagFields +{ + kProfileIdMask = 0xFFFFFFFF00000000ULL, + kProfileIdShift = 32, + kVendorIdShift = 48, + kProfileNumShift = 32, + kTagNumMask = 0x00000000FFFFFFFFULL, + kSpecialTagMarker = 0xFFFFFFFF00000000ULL, + kContextTagMaxNum = 256 +}; + +// TODO: Move to private namespace +enum TLVTagControl +{ + kTLVTagControl_Anonymous = 0x00, + kTLVTagControl_ContextSpecific = 0x20, + kTLVTagControl_CommonProfile_2Bytes = 0x40, + kTLVTagControl_CommonProfile_4Bytes = 0x60, + kTLVTagControl_ImplicitProfile_2Bytes = 0x80, + kTLVTagControl_ImplicitProfile_4Bytes = 0xA0, + kTLVTagControl_FullyQualified_6Bytes = 0xC0, + kTLVTagControl_FullyQualified_8Bytes = 0xE0 +}; + +// TODO: Move to private namespace +enum +{ + kTLVTagControlMask = 0xE0, + kTLVTagControlShift = 5 +}; + + +/** + * Generates the API representation of a profile-specific TLV tag from a profile id and tag number + * + * @param[in] profileId The id of the profile within which the tag is defined. + * @param[in] tagNum The profile-specific tag number assigned to the tag. + * @return A 64-bit integer representing the tag. + */ +inline uint64_t ProfileTag(uint32_t profileId, uint32_t tagNum) { return (((uint64_t)profileId) << kProfileIdShift) | tagNum; } + +/** + * Generates the API representation of a profile-specific TLV tag from a vendor id, profile number and tag number + * + * @param[in] vendorId The id of the vendor that defined the tag. + * @param[in] profileNum The vendor assigned number for the profile within which the tag is defined. + * @param[in] tagNum The profile-specific tag number assigned to the tag. + * @return A 64-bit integer representing the tag. + */ +inline uint64_t ProfileTag(uint16_t vendorId, uint16_t profileNum, uint32_t tagNum) { return (((uint64_t)vendorId) << kVendorIdShift) | (((uint64_t)profileNum) << kProfileNumShift) | tagNum; } + +/** + * Generates the API representation for of context-specific TLV tag + * + * @param[in] tagNum The context-specific tag number assigned to the tag. + * @return A 64-bit integer representing the tag. + */ +inline uint64_t ContextTag(uint8_t tagNum) { return kSpecialTagMarker | tagNum; } + +/** + * Generates the API representation of a common profile TLV tag + * + * @param[in] tagNum The common profile tag number assigned to the tag. + * @return A 64-bit integer representing the tag. + */ +inline uint64_t CommonTag(uint32_t tagNum) { return ProfileTag(kCommonProfileId, tagNum); } + +enum +{ + /** + * A value signifying a TLV element that has no tag (i.e. an anonymous element). + */ + AnonymousTag = kSpecialTagMarker | 0x00000000FFFFFFFFULL, + + // TODO: Move to private namespace + UnknownImplicitTag = kSpecialTagMarker | 0x00000000FFFFFFFEULL +}; + + +/** + * Returns the profile id from a TLV tag + * + * @note The behavior of this function is undefined if the supplied tag is not a profile-specific tag. + * + * @param[in] tag The API representation of a profile-specific TLV tag. + * @return The profile id. + */ +inline uint32_t ProfileIdFromTag(uint64_t tag) { return (uint32_t)((tag & kProfileIdMask) >> kProfileIdShift); } + + +/** + * Returns the profile number from a TLV tag + * + * @note The behavior of this function is undefined if the supplied tag is not a profile-specific tag. + * + * @param[in] tag The API representation of a profile-specific TLV tag. + * @return The associated profile number. + */ +inline uint16_t ProfileNumFromTag(uint64_t tag) { return (uint16_t) ((tag & kProfileIdMask) >> kProfileIdShift); } + + +/** + * Returns the tag number from a TLV tag + * + * @note The behavior of this function is undefined if the supplied tag is not a profile-specific + * or context-specific tag. + * + * @sa IsProfileTag() and IsContextTag() + * + * @param[in] tag The API representation of a profile-specific or context-specific TLV tag. + * @return The associated tag number. + */ +inline uint32_t TagNumFromTag(uint64_t tag) { return (uint32_t)(tag & kTagNumMask); } + + +/** + * Returns the vendor id from a TLV tag + * + * @note The behavior of this function is undefined if the supplied tag is not a profile-specific tag. + * + * @param[in] tag The API representation of a profile-specific TLV tag. + * @return The associated vendor id. + */ +inline uint16_t VendorIdFromTag(uint64_t tag) { return (uint16_t)((tag & kProfileIdMask) >> kVendorIdShift); } + + +/** + * Returns true of the supplied tag is a profile-specific tag. + */ +inline bool IsProfileTag(uint64_t tag) { return (tag & kProfileIdMask) != kSpecialTagMarker; } + + +/** + * Returns true if the supplied tag is a context-specific tag. + */ +inline bool IsContextTag(uint64_t tag) { return (tag & kProfileIdMask) == kSpecialTagMarker && TagNumFromTag(tag) < kContextTagMaxNum; } + + +// TODO: move to private namespace +inline bool IsSpecialTag(uint64_t tag) { return (tag & kProfileIdMask) == kSpecialTagMarker; } + +} // namespace TLV +} // namespace Weave +} // namespace nl + +#endif /* WEAVETLVTAGS_H_ */ diff --git a/src/lib/core/WeaveTLVTypes.h b/src/lib/core/WeaveTLVTypes.h new file mode 100644 index 00000000000000..856bd40f23b2a5 --- /dev/null +++ b/src/lib/core/WeaveTLVTypes.h @@ -0,0 +1,172 @@ +/* + * + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file contains definitions for working with Weave TLV types. + * + */ + +#ifndef WEAVETLVTYPES_H_ +#define WEAVETLVTYPES_H_ + +namespace nl { +namespace Weave { +namespace TLV { + +/** + * An enumeration identifying the type of a TLV element. + */ +enum TLVType +{ + kTLVType_NotSpecified = -1, + kTLVType_UnknownContainer = -2, + + kTLVType_SignedInteger = 0x00, + kTLVType_UnsignedInteger = 0x04, + kTLVType_Boolean = 0x08, + kTLVType_FloatingPointNumber = 0x0A, + kTLVType_UTF8String = 0x0C, + kTLVType_ByteString = 0x10, + kTLVType_Null = 0x14, + kTLVType_Structure = 0x15, + kTLVType_Array = 0x16, + kTLVType_Path = 0x17 +}; + +// TODO: Move to private namespace +enum TLVElementType +{ + kTLVElementType_NotSpecified = -1, + kTLVElementType_Int8 = 0x00, + kTLVElementType_Int16 = 0x01, + kTLVElementType_Int32 = 0x02, + kTLVElementType_Int64 = 0x03, + kTLVElementType_UInt8 = 0x04, + kTLVElementType_UInt16 = 0x05, + kTLVElementType_UInt32 = 0x06, + kTLVElementType_UInt64 = 0x07, + kTLVElementType_BooleanFalse = 0x08, + kTLVElementType_BooleanTrue = 0x09, + kTLVElementType_FloatingPointNumber32 = 0x0A, + kTLVElementType_FloatingPointNumber64 = 0x0B, + kTLVElementType_UTF8String_1ByteLength = 0x0C, + kTLVElementType_UTF8String_2ByteLength = 0x0D, + kTLVElementType_UTF8String_4ByteLength = 0x0E, + kTLVElementType_UTF8String_8ByteLength = 0x0F, + kTLVElementType_ByteString_1ByteLength = 0x10, + kTLVElementType_ByteString_2ByteLength = 0x11, + kTLVElementType_ByteString_4ByteLength = 0x12, + kTLVElementType_ByteString_8ByteLength = 0x13, + kTLVElementType_Null = 0x14, + kTLVElementType_Structure = 0x15, + kTLVElementType_Array = 0x16, + kTLVElementType_Path = 0x17, + kTLVElementType_EndOfContainer = 0x18 +}; + +// TODO: Move to private namespace +enum TLVFieldSize +{ + kTLVFieldSize_0Byte = -1, + kTLVFieldSize_1Byte = 0, + kTLVFieldSize_2Byte = 1, + kTLVFieldSize_4Byte = 2, + kTLVFieldSize_8Byte = 3 +}; + +// TODO: Move to private namespace +enum +{ + kTLVTypeMask = 0x1F, + kTLVTypeSizeMask = 0x03 +}; + +/** + * Returns true if the specified TLV type is valid. + * + * @return @p true if the specified TLV type is valid; otherwise @p false. + */ +inline bool IsValidTLVType(uint8_t type) +{ + return type <= kTLVElementType_EndOfContainer; +} + +/** + * Returns true if the specified TLV type implies the presence of an associated value field. + * + * @return @p true if the specified TLV type implies the presence of an associated value field; otherwise @p false. + */ +inline bool TLVTypeHasValue(uint8_t type) +{ + return (type <= kTLVElementType_UInt64 || + (type >= kTLVElementType_FloatingPointNumber32 && type <= kTLVElementType_ByteString_8ByteLength)); +} + +/** + * Returns true if the specified TLV type implies the presence of an associated length field. + * + * @return @p true if the specified TLV type implies the presence of an associated length field; otherwise @p false. + */ +inline bool TLVTypeHasLength(uint8_t type) +{ + return type >= kTLVElementType_UTF8String_1ByteLength && type <= kTLVElementType_ByteString_8ByteLength; +} + +/** + * Returns true if the specified TLV type is a container. + * + * @return @p true if the specified TLV type is a container; otherwise @p false. + */ +inline bool TLVTypeIsContainer(uint8_t type) +{ + return type >= kTLVElementType_Structure && type <= kTLVElementType_Path; +} + +/** + * Returns true if the specified TLV type is a UTF8 or byte string. + * + * @return @p true if the specified TLV type is a UTF8 or byte string; otherwise @p false. + */ +inline bool TLVTypeIsString(uint8_t type) +{ + return type >= kTLVElementType_UTF8String_1ByteLength && type <= kTLVElementType_ByteString_8ByteLength; +} + +// TODO: move to private namespace +inline TLVFieldSize GetTLVFieldSize(uint8_t type) +{ + if (TLVTypeHasValue(type)) + return (TLVFieldSize)(type & kTLVTypeSizeMask); + else + return kTLVFieldSize_0Byte; +} + +// TODO: move to private namespace +inline uint8_t TLVFieldSizeToBytes(TLVFieldSize fieldSize) +{ + return (fieldSize != kTLVFieldSize_0Byte) ? (1 << fieldSize) : 0; +} + +} // namespace TLV +} // namespace Weave +} // namespace nl + + + +#endif /* WEAVETLVTYPES_H_ */ diff --git a/src/lib/core/WeaveTLVUpdater.cpp b/src/lib/core/WeaveTLVUpdater.cpp new file mode 100644 index 00000000000000..be83aec45a7a30 --- /dev/null +++ b/src/lib/core/WeaveTLVUpdater.cpp @@ -0,0 +1,505 @@ +/* + * + * Copyright (c) 2015-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements an updating encoder for the Weave TLV + * (Tag-Length-Value) encoding format. + * + */ + +#include +#include +#include +#include + +namespace nl { +namespace Weave { +namespace TLV { + +using namespace nl::Weave::Encoding; + +/** + * Initialize a TLVUpdater object to edit a single input buffer. + * + * On calling this method, the TLV data in the buffer is moved to the end of the + * buffer and a private TLVReader object is initialized on this relocated + * buffer. A private TLVWriter object is also initialized on the free space that + * is now available at the beginning. Applications can use the TLVUpdater object + * to parse the TLV data and modify/delete existing elements or add new elements + * to the encoding. + * + * @param[in] buf A pointer to a buffer containing the TLV data to be edited. + * @param[in] dataLen The length of the TLV data in the buffer. + * @param[in] maxLen The total length of the buffer. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If the buffer address is invalid. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL If the buffer is too small. + * + */ +WEAVE_ERROR TLVUpdater::Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + uint32_t freeLen; + + VerifyOrExit(buf != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT); + + VerifyOrExit(maxLen >= dataLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + + // memmove the buffer data to end of the buffer + freeLen = maxLen - dataLen; + memmove(buf + freeLen, buf, dataLen); + + // Init reader + mUpdaterReader.Init(buf + freeLen, dataLen); + + // Init writer + mUpdaterWriter.Init(buf, freeLen); + mUpdaterWriter.SetCloseContainerReserved(false); + mElementStartAddr = buf + freeLen; + +exit: + return err; +} + +/** + * Initialize a TLVUpdater object using a TLVReader. + * + * On calling this method, TLV data in the buffer pointed to by the TLVReader + * is moved from the current read point to the end of the buffer. A new + * private TLVReader object is initialized to read from this new location, while + * a new private TLVWriter object is initialized to write to the freed up buffer + * space. + * + * Note that if the TLVReader is already positioned "on" an element, it is first + * backed-off to the start of that element. Also note that this backing off + * works well with container elements, i.e., if the TLVReader was already used + * to call EnterContainer(), then there is nothing to back-off. But if the + * TLVReader was positioned on the container element and EnterContainer() was + * not yet called, then the TLVReader object is backed-off to the start of the + * container head. + * + * The input TLVReader object will be destroyed before returning and the + * application must not make use of the same on return. + * + * @param[in,out] aReader Reference to a TLVReader object that will be + * destroyed before returning. + * @param[in] freeLen The length of free space (in bytes) available + * in the pre-encoded data buffer. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If the buffer address is invalid. + * @retval #WEAVE_ERROR_NOT_IMPLEMENTED If reader was initialized on a chain + * of buffers. + */ +WEAVE_ERROR TLVUpdater::Init(TLVReader& aReader, uint32_t freeLen) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + uint8_t *buf = const_cast(aReader.GetReadPoint()); + uint32_t remainingDataLen = aReader.GetRemainingLength(); + uint32_t readDataLen = aReader.GetLengthRead(); + + // TLVUpdater does not support chain of buffers yet + VerifyOrExit(aReader.mBufHandle == 0, err = WEAVE_ERROR_NOT_IMPLEMENTED); + + // TLVReader should point to a non-NULL buffer + VerifyOrExit(buf != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT); + + // If reader is already on an element, reset it to start of element + if (aReader.ElementType() != kTLVElementType_NotSpecified) + { + uint8_t elemHeadLen; + + err = aReader.GetElementHeadLength(elemHeadLen); + SuccessOrExit(err); + + buf -= elemHeadLen; + remainingDataLen += elemHeadLen; + readDataLen -= elemHeadLen; + } + + // memmove the buffer data to end of the buffer + memmove(buf + freeLen, buf, remainingDataLen); + + // Initialize the internal reader object + mUpdaterReader.mBufHandle = 0; + mUpdaterReader.mReadPoint = buf + freeLen; + mUpdaterReader.mBufEnd = buf + freeLen + remainingDataLen; + mUpdaterReader.mLenRead = readDataLen; + mUpdaterReader.mMaxLen = aReader.mMaxLen; + mUpdaterReader.mControlByte = kTLVControlByte_NotSpecified; + mUpdaterReader.mElemTag = AnonymousTag; + mUpdaterReader.mElemLenOrVal = 0; + mUpdaterReader.mContainerType = aReader.mContainerType; + mUpdaterReader.SetContainerOpen(false); + + mUpdaterReader.ImplicitProfileId = aReader.ImplicitProfileId; + mUpdaterReader.AppData = aReader.AppData; + mUpdaterReader.GetNextBuffer = NULL; + + // Initialize the internal writer object + mUpdaterWriter.mBufHandle = 0; + mUpdaterWriter.mBufStart = buf - readDataLen; + mUpdaterWriter.mWritePoint = buf; + mUpdaterWriter.mRemainingLen = freeLen; + mUpdaterWriter.mLenWritten = readDataLen; + mUpdaterWriter.mMaxLen = readDataLen + freeLen; + mUpdaterWriter.mContainerType = aReader.mContainerType; + mUpdaterWriter.SetContainerOpen(false); + mUpdaterWriter.SetCloseContainerReserved(false); + + mUpdaterWriter.ImplicitProfileId = aReader.ImplicitProfileId; + mUpdaterWriter.GetNewBuffer = NULL; + mUpdaterWriter.FinalizeBuffer = NULL; + + // Cache element start address for internal use + mElementStartAddr = buf + freeLen; + + // Clear the input reader object before returning. The user can no longer + // use the original TLVReader object anymore. + aReader.Init((const uint8_t *) NULL, 0); + +exit: + return err; +} + +/** + * Set the Implicit Profile ID for the TLVUpdater object. + * + * This method sets the implicit profile ID for the TLVUpdater object. When the + * updater is asked to encode a new element, if the profile ID of the tag + * associated with the new element matches the value of the @p profileId, the + * updater will encode the tag in implicit form, thereby omitting the profile ID + * in the process. + * + * @param[in] profileId The profile id of tags that should be encoded in + * implicit form. + */ +void TLVUpdater::SetImplicitProfileId(uint32_t profileId) +{ + mUpdaterReader.ImplicitProfileId = profileId; + mUpdaterWriter.ImplicitProfileId = profileId; +} + +/** + * Skip the current element and advance the TLVUpdater object to the next + * element in the input TLV. + * + * The Next() method skips the current element in the input TLV and advances the + * TLVUpdater's reader to the next element that resides in the same containment + * context. In particular, if the reader is positioned at the outer most level + * of a TLV encoding, calling Next() will advance it to the next, top most + * element. If the reader is positioned within a TLV container element (a + * structure, array or path), calling Next() will advance it to the next member + * element of the container. + * + * Since Next() constrains reader motion to the current containment context, + * calling Next() when the reader is positioned on a container element will + * advance @em over the container, skipping its member elements (and the members + * of any nested containers) until it reaches the first element after the + * container. + * + * When there are no further elements within a particular containment context + * the Next() method will return a #WEAVE_END_OF_TLV error and the position of + * the reader will remain unchanged. + * + * @note The Next() method implicitly skips the current element. Hence, the + * TLVUpdater's private writer state variables will be adjusted to account for + * the new freed space (made available by skipping). This means that the + * application is expected to call Next() on the TLVUpdater object after a Get() + * whose value the application does @em not write back (which from the + * TLVUpdater's view is equivalent to skipping that element). + * + * @note Applications are also expected to call Next() when they are at the end + * of a container, and want to add new elements there. This is particularly + * important in situations where there is a fixed schema. Applications that have + * fixed schemas and know where the container end is cannot just add new + * elements at the end, because the TLVUpdater writer's state will not reflect + * the correct free space available for the Put() operation. Hence, applications + * must call Next() (and possibly also test for WEAVE_END_OF_TLV) before adding + * elements at the end of a container. + * + * @retval #WEAVE_NO_ERROR If the TLVUpdater reader was + * successfully positioned on a new + * element. + * @retval other Returns the Weave or platform error + * codes returned by the TLVReader::Skip() + * and TLVReader::Next() method. + * + */ +WEAVE_ERROR TLVUpdater::Next() +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + // Skip current element if the reader is already positioned on an element + err = mUpdaterReader.Skip(); + SuccessOrExit(err); + + AdjustInternalWriterFreeSpace(); + + // Move the reader to next element + err = mUpdaterReader.Next(); + SuccessOrExit(err); + +exit: + return err; +} + +/** + * Copies the current element from input TLV to output TLV. + * + * The Move() method copies the current element on which the TLVUpdater's reader + * is positioned on, to the TLVUpdater's writer. The application should call + * Next() and position the TLVUpdater's reader on an element before calling this + * method. Just like the TLVReader::Next() method, if the reader is positioned + * on a container element at the time of the call, all the members of the + * container will be copied. If the reader is not positioned on any element, + * nothing changes on calling this method. + * + * @retval #WEAVE_NO_ERROR If the TLVUpdater reader was + * successfully positioned on a new + * element. + * @retval #WEAVE_END_OF_TLV If the TLVUpdater's reader is pointing + * to end of container. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the TLVIpdater's reader is not + * positioned on a valid TLV element. + * @retval other Returns other error codes returned by + * TLVReader::Skip() method. + * + */ +WEAVE_ERROR TLVUpdater::Move() +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + const uint8_t *elementEnd; + uint32_t copyLen; + + VerifyOrExit((mUpdaterReader.mControlByte & kTLVTypeMask) != kTLVElementType_EndOfContainer, + err = WEAVE_END_OF_TLV); + + VerifyOrExit(mUpdaterReader.GetType() != kTLVType_NotSpecified, + err = WEAVE_ERROR_INVALID_TLV_ELEMENT); + + // Skip to the end of the element + err = mUpdaterReader.Skip(); + SuccessOrExit(err); + + elementEnd = mUpdaterReader.mReadPoint; + + copyLen = elementEnd - mElementStartAddr; + + // Move the element to output TLV + memmove(mUpdaterWriter.mWritePoint, mElementStartAddr, copyLen); + + // Adjust the updater state + mElementStartAddr += copyLen; + mUpdaterWriter.mWritePoint += copyLen; + mUpdaterWriter.mLenWritten += copyLen; + mUpdaterWriter.mMaxLen += copyLen; + +exit: + return err; +} + +/** + * Move everything from the TLVUpdater's current read point till end of input + * TLV buffer over to output. + * + * This method supports moving everything from the TLVUpdater's current read + * point till the end of the reader buffer over to the TLVUpdater's writer. + * + * @note This method can be called with the TLVUpdater's reader positioned + * anywhere within the input TLV. The reader can also be positioned under + * multiple levels of nested containers and this method will still work. + * + * @note This method also changes the state of the TLVUpdater object to a state + * it would be in if the application had painstakingly parsed each element from + * the current read point till the end of the input encoding and copied them to + * the output TLV. + */ +void TLVUpdater::MoveUntilEnd() +{ + const uint8_t *buffEnd = mUpdaterReader.GetReadPoint() + + mUpdaterReader.GetRemainingLength(); + + uint32_t copyLen = buffEnd - mElementStartAddr; + + // Move all elements till end to output TLV + memmove(mUpdaterWriter.mWritePoint, mElementStartAddr, copyLen); + + // Adjust the updater state + mElementStartAddr += copyLen; + mUpdaterWriter.mWritePoint += copyLen; + mUpdaterWriter.mLenWritten += copyLen; + mUpdaterWriter.mMaxLen += copyLen; + mUpdaterWriter.mContainerType = kTLVType_NotSpecified; + mUpdaterWriter.SetContainerOpen(false); + mUpdaterWriter.SetCloseContainerReserved(false); + mUpdaterReader.mReadPoint += copyLen; + mUpdaterReader.mLenRead += copyLen; + mUpdaterReader.mControlByte = kTLVControlByte_NotSpecified; + mUpdaterReader.mElemTag = AnonymousTag; + mUpdaterReader.mElemLenOrVal = 0; + mUpdaterReader.mContainerType = kTLVType_NotSpecified; + mUpdaterReader.SetContainerOpen(false); +} + +/** + * Prepares a TLVUpdater object for reading elements of a container. It also + * encodes a start of container object in the output TLV. + * + * The EnterContainer() method prepares the current TLVUpdater object to begin + * reading the member elements of a TLV container (a structure, array or path). + * For every call to EnterContainer() applications must make a corresponding + * call to ExitContainer(). + * + * When EnterContainer() is called the TLVUpdater's reader must be positioned on + * the container element. The method takes as an argument a reference to a + * TLVType value which will be used to save the context of the updater while it + * is reading the container. + * + * When the EnterContainer() method returns, the updater is positioned + * immediately @em before the first member of the container. Repeatedly calling + * Next() will advance the updater through the members of the collection until + * the end is reached, at which point the updater will return WEAVE_END_OF_TLV. + * + * Once the application has finished reading a container it can continue reading + * the elements after the container by calling the ExitContainer() method. + * + * @note This method implicitly encodes a start of container element in the + * output TLV buffer. + * + * @param[out] outerContainerType A reference to a TLVType value that will + * receive the context of the updater. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE If the TLVUpdater reader is not + * positioned on a container element. + * @retval other Any other Weave or platform error code + * returned by TLVWriter::StartContainer() + * or TLVReader::EnterContainer(). + * + */ +WEAVE_ERROR TLVUpdater::EnterContainer(TLVType& outerContainerType) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + TLVType containerType; + + VerifyOrExit(TLVTypeIsContainer(mUpdaterReader.mControlByte & kTLVTypeMask), + err = WEAVE_ERROR_INCORRECT_STATE); + + // Change the updater state + AdjustInternalWriterFreeSpace(); + + err = mUpdaterWriter.StartContainer(mUpdaterReader.GetTag(), + mUpdaterReader.GetType(), + containerType); + SuccessOrExit(err); + + err = mUpdaterReader.EnterContainer(containerType); + SuccessOrExit(err); + + outerContainerType = containerType; + +exit: + return err; +} + +/** + * Completes the reading of a TLV container element and encodes an end of TLV + * element in the output TLV. + * + * The ExitContainer() method restores the state of a TLVUpdater object after a + * call to EnterContainer(). For every call to EnterContainer() applications + * must make a corresponding call to ExitContainer(), passing the context value + * returned by the EnterContainer() method. + * + * When ExitContainer() returns, the TLVUpdater reader is positioned immediately + * before the first element that follows the container in the input TLV. From + * this point applications can call Next() to advance through any remaining + * elements. + * + * Once EnterContainer() has been called, applications can call ExitContainer() + * on the updater at any point in time, regardless of whether all elements in + * the underlying container have been read. Also, note that calling + * ExitContainer() before reading all the elements in the container, will result + * in the updated container getting truncated in the output TLV. + * + * @note Any changes made to the configuration of the updater between the calls + * to EnterContainer() and ExitContainer() are NOT undone by the call to + * ExitContainer(). For example, a change to the implicit profile id + * (@p ImplicitProfileId) will not be reversed when a container is exited. Thus + * it is the application's responsibility to adjust the configuration + * accordingly at the appropriate times. + * + * @param[in] outerContainerType The TLVType value that was returned by + * the EnterContainer() method. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended + * prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the updater encountered an invalid or + * unsupported TLV element type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the updater encountered a TLV tag in + * an invalid context. + * @retval other Any other Weave or platform error code + * returned by TLVWriter::EndContainer() or + * TLVReader::ExitContainer(). + * + */ +WEAVE_ERROR TLVUpdater::ExitContainer(TLVType outerContainerType) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + err = mUpdaterReader.ExitContainer(outerContainerType); + SuccessOrExit(err); + + // Change the updater's state + AdjustInternalWriterFreeSpace(); + + err = mUpdaterWriter.EndContainer(outerContainerType); + SuccessOrExit(err); + +exit: + return err; +} + +/** + * This is a private method that adjusts the TLVUpdater's free space count by + * accounting for the freespace from mElementStartAddr to current read point. + */ +void TLVUpdater::AdjustInternalWriterFreeSpace() +{ + const uint8_t *nextElementStart = mUpdaterReader.mReadPoint; + + if (nextElementStart != mElementStartAddr) + { + // Increase the internal writer's free space state variables + mUpdaterWriter.mRemainingLen += nextElementStart - mElementStartAddr; + mUpdaterWriter.mMaxLen += nextElementStart - mElementStartAddr; + + // Cache the start address of the next element + mElementStartAddr = nextElementStart; + } +} + +} // namespace TLV +} // namespace Weave +} // namespace nl diff --git a/src/lib/core/WeaveTLVUtilities.cpp b/src/lib/core/WeaveTLVUtilities.cpp new file mode 100644 index 00000000000000..3eb7f3d756d932 --- /dev/null +++ b/src/lib/core/WeaveTLVUtilities.cpp @@ -0,0 +1,452 @@ +/* + * + * Copyright (c) 2015-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements utility interfaces for managing and + * working with Weave TLV. + * + */ + +#include +#include +#include + +namespace nl { + +namespace Weave { + +namespace TLV { + +namespace Utilities { + +struct FindContext { + const uint64_t & mTag; + TLVReader & mReader; +}; + +/** + * Iterate through the TLV data referenced by @a aReader and invoke @a aHandler + * for each visited TLV element in the context of @a aContext. + * The iteration is aborted if @a aHandler returns anything other than #WEAVE_NO_ERROR + * + * @param[in] aReader A reference to the TLV reader containing the TLV + * data to iterate. + * @param[in] aDepth The current depth into the TLV data. + * @param[in] aHandler A callback to invoke for the current TLV element + * being visited. + * @param[inout] aContext An optional pointer to caller-provided context data. + * @param[in] aRecurse A Boolean indicating whether (true) or not (false) + * any encountered arrays or structures should be + * descended into. + * + * @retval #WEAVE_END_OF_TLV On a successful iteration to the end of a TLV encoding, + * or to the end of a TLV container. + * + * @retval The last value returned by @a aHandler, if different than #WEAVE_NO_ERROR + */ +static WEAVE_ERROR Iterate(TLVReader &aReader, size_t aDepth, IterateHandler aHandler, void *aContext, bool aRecurse) +{ + WEAVE_ERROR retval = WEAVE_NO_ERROR; + + if (aReader.GetType() == kTLVType_NotSpecified) + { + retval = aReader.Next(); + SuccessOrExit(retval); + } + + do + { + const TLVType theType = aReader.GetType(); + + retval = (aHandler)(aReader, aDepth, aContext); + SuccessOrExit(retval); + + if (aRecurse && TLVTypeIsContainer(theType)) + { + TLVType containerType; + + retval = aReader.EnterContainer(containerType); + SuccessOrExit(retval); + + retval = Iterate(aReader, aDepth + 1, aHandler, aContext, aRecurse); + if (retval != WEAVE_END_OF_TLV) + SuccessOrExit(retval); + + retval = aReader.ExitContainer(containerType); + SuccessOrExit(retval); + } + } while ((retval = aReader.Next()) == WEAVE_NO_ERROR); + +exit: + return retval; +} + +/** + * Iterate through the TLV data referenced by @a aReader and invoke @a aHandler + * for each visited TLV element in the context of @a aContext. + * The iteration is aborted if @a aHandler returns anything other than #WEAVE_NO_ERROR + * + * @param[in] aReader A reference to the TLV reader containing the TLV + * data to iterate. + * @param[in] aHandler A callback to invoke for the current TLV element + * being visited. + * @param[inout] aContext An optional pointer to caller-provided context data. + * + * @retval #WEAVE_END_OF_TLV On a successful iteration to the end of a TLV encoding, + * or to the end of a TLV container. + * + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aHandler is NULL. + * + * @retval The last value returned by @a aHandler, if different than #WEAVE_NO_ERROR + * + */ +WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext) +{ + const bool recurse = true; + WEAVE_ERROR retval; + + retval = Iterate(aReader, aHandler, aContext, recurse); + + return retval; +} + +/** + * Iterate through the TLV data referenced by @a aReader and invoke @a aHandler + * for each visited TLV element in the context of @a aContext. + * The iteration is aborted if @a aHandler returns anything other than #WEAVE_NO_ERROR + * + * @param[in] aReader A reference to the TLV reader containing the TLV + * data to iterate. + * @param[in] aHandler A callback to invoke for the current TLV element + * being visited. + * @param[inout] aContext An optional pointer to caller-provided context data. + * @param[in] aRecurse A Boolean indicating whether (true) or not (false) + * any encountered arrays or structures should be + * descended into. + * + * @retval #WEAVE_END_OF_TLV On a successful iteration to the end of a TLV encoding, + * or to the end of a TLV container. + * + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aHandler is NULL. + * + * @retval The last value returned by @a aHandler, if different than #WEAVE_NO_ERROR + * + */ +WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext, const bool aRecurse) +{ + const size_t depth = 0; + TLVReader temp; + WEAVE_ERROR retval = WEAVE_ERROR_NOT_IMPLEMENTED; + + VerifyOrExit(aHandler != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + + temp.Init(aReader); + + retval = Iterate(temp, depth, aHandler, aContext, aRecurse); + + exit: + return retval; +} + +/** + * Increment the counter when iterating through the TLV data. + * + * @param[in] aReader A reference to the TLV reader containing the TLV + * data to count the number of TLV elements. + * @param[in] aDepth The current depth into the TLV data. + * @param[inout] aContext A pointer to the handler-specific context which + * is a pointer to storage for the count value. + * + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aContext is NULL. + * + */ +static WEAVE_ERROR CountHandler(const TLVReader &aReader, size_t aDepth, void *aContext) +{ + WEAVE_ERROR retval = WEAVE_NO_ERROR; + + VerifyOrExit(aContext != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + + *static_cast(aContext) += 1; + + exit: + return retval; +} + +/** + * Count the number of TLV elements within the specified TLV reader, + * descending into arrays or structures. + * + * @param[in] aReader A read-only reference to the TLV reader for + * which to count the number of TLV elements. + * @param[inout] aCount A reference to storage for the returned count. + * This is initialized to zero (0) prior to counting + * and is set to the number of elements counted on + * success. + * + * @retval #WEAVE_NO_ERROR On success. + * + */ +WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount) +{ + const bool recurse = true; + WEAVE_ERROR retval; + + retval = Count(aReader, aCount, recurse); + + return retval; +} + +/** + * Count the number of TLV elements within the specified TLV reader, + * optionally descending into arrays or structures. + * + * @param[in] aReader A read-only reference to the TLV reader for + * which to count the number of TLV elements. + * @param[inout] aCount A reference to storage for the returned count. + * This is initialized to zero (0) prior to counting + * and is set to the number of elements counted on + * success. + * @param[in] aRecurse A Boolean indicating whether (true) or not (false) + * any encountered arrays or structures should be + * descended into. + * + * @retval #WEAVE_NO_ERROR On success. + * + */ +WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse) +{ + WEAVE_ERROR retval; + + aCount = 0; + + retval = Iterate(aReader, CountHandler, &aCount, aRecurse); + + if (retval == WEAVE_END_OF_TLV) + retval = WEAVE_NO_ERROR; + + return retval; +} + +/** + * Search for the specified tag within the provided TLV reader. + * + * @param[in] aReader A read-only reference to the TLV reader in + * which to find the specified tag. + * @param[in] aDepth The current depth into the TLV data. + * @param[inout] aContext A pointer to the handler-specific context. + * + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aContext is NULL. + * + * @retval #WEAVE_ERROR_MAX If the specified tag is found. + * + */ +static WEAVE_ERROR FindHandler(const TLVReader &aReader, size_t aDepth, void *aContext) +{ + const FindContext * theContext = static_cast(aContext); + WEAVE_ERROR retval = WEAVE_NO_ERROR; + + VerifyOrExit(aContext != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + + if (theContext->mTag == aReader.GetTag()) + { + theContext->mReader.Init(aReader); + // terminate the iteration when the specified tag is found + retval = WEAVE_ERROR_MAX; + } + + exit: + return retval; +} + +/** + * Search for the specified tag within the provided TLV reader. + * + * @param[in] aReader A read-only reference to the TLV reader in + * which to find the specified tag. + * @param[in] aTag A read-only reference to the TLV tag to find. + * @param[out] aResult A reference to storage to a TLV reader which + * will be positioned at the specified tag + * on success. + * + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified tag @a aTag was not found. + * + */ +WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult) +{ + const bool recurse = true; + WEAVE_ERROR retval; + + retval = Find(aReader, aTag, aResult, recurse); + + return retval; +} + +/** + * Search for the specified tag within the provided TLV reader, + * optionally descending into arrays or structures. + * + * @param[in] aReader A read-only reference to the TLV reader in + * which to find the specified tag. + * @param[in] aTag A read-only reference to the TLV tag to find. + * @param[out] aResult A reference to storage to a TLV reader which + * will be positioned at the specified tag + * on success. + * @param[in] aRecurse A Boolean indicating whether (true) or not (false) + * any encountered arrays or structures should be + * descended into. + * + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified tag @a aTag was not found. + * + */ +WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult, const bool aRecurse) +{ + FindContext theContext = { aTag, aResult }; + WEAVE_ERROR retval; + + retval = Iterate(aReader, FindHandler, &theContext, aRecurse); + + if (retval == WEAVE_ERROR_MAX) + retval = WEAVE_NO_ERROR; + else + retval = WEAVE_ERROR_TLV_TAG_NOT_FOUND; + + return retval; +} + +struct FindPredicateContext +{ + TLVReader &mResult; + IterateHandler mHandler; + void * mContext; + FindPredicateContext(TLVReader &inReader, IterateHandler inHandler, void *inContext); +}; + +FindPredicateContext::FindPredicateContext(TLVReader &inReader, IterateHandler inHandler, void *inContext) : + mResult(inReader), + mHandler(inHandler), + mContext(inContext) +{ +} + +static WEAVE_ERROR FindPredicateHandler(const TLVReader & aReader, size_t aDepth, void *aContext) +{ + FindPredicateContext *theContext = static_cast(aContext); + WEAVE_ERROR err; + + err = theContext->mHandler(aReader, aDepth, theContext->mContext); + + if (err == WEAVE_ERROR_MAX) + theContext->mResult.Init(aReader); + + return err; +} + +/** + * Search for the first element matching the predicate within the TLV reader + * descending into arrays or structures. The @a aPredicate is applied + * to each visited TLV element; the @a aPredicate shall return #WEAVE_ERROR_MAX + * for the matching elements, #WEAVE_NO_ERROR for non-matching elements, and any + * other value to terminate the search. + * + * @param[in] aReader A read-only reference to the TLV reader in which to find the + * element matching the predicate. + * @param[in] aPredicate A predicate to be applied to each TLV element. To + * support the code reuse, aPredicate has the + * IterateHandler type. The return value of aPredicate + * controls the search: a #WEAVE_ERROR_MAX signals that + * desired element has been found, #WEAVE_NO_ERROR + * signals that the desired element has not been found, + * and all other values signal that the saerch should be + * terminated. + * @param[in] aContext An optional pointer to caller-provided context data. + * + * @param[out] aResult A reference to storage to a TLV reader which + * will be positioned at the specified tag + * on success. + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified @a aPredicate did not locate the specified element + * + */ +WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aContext, TLVReader &aResult) +{ + const bool recurse = true; + return Find(aReader, aPredicate, aContext, aResult, recurse); +} + +/** + * Search for the first element matching the predicate within the TLV reader + * optionally descending into arrays or structures. The @a aPredicate is applied + * to each visited TLV element; the @a aPredicate shall return #WEAVE_ERROR_MAX + * for the matching elements, #WEAVE_NO_ERROR for non-matching elements, and any + * other value to terminate the search. + * + * @param[in] aReader A read-only reference to the TLV reader in which to find the + * element matching the predicate. + * @param[in] aPredicate A predicate to be applied to each TLV element. To + * support the code reuse, aPredicate has the + * @a IterateHandler type. The return value of aPredicate + * controls the search: a #WEAVE_ERROR_MAX signals that + * desired element has been found, #WEAVE_NO_ERROR + * signals that the desired element has not been found, + * and all other values signal that the saerch should be + * terminated. + * @param[in] aContext An optional pointer to caller-provided context data. + * @param[out] aResult A reference to storage to a TLV reader which + * will be positioned at the specified tag + * on success. + * @param[in] aRecurse A boolean indicating whether (true) or not (false) any + * encountered arrays or structures should be descended + * into. + * + * @retval #WEAVE_NO_ERROR On success. + * + * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified @a aPredicate did not locate the specified element + * + */ +WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aContext, TLVReader &aResult, const bool aRecurse) +{ + WEAVE_ERROR retval; + FindPredicateContext theContext(aResult, aPredicate, aContext); + + retval = Iterate(aReader, FindPredicateHandler, &theContext, aRecurse); + + if (retval == WEAVE_ERROR_MAX) + retval = WEAVE_NO_ERROR; + else + retval = WEAVE_ERROR_TLV_TAG_NOT_FOUND; + + return retval; +} + +} // namespace Utilities + +} // namespace TLV + +} // namespace Weave + +} // namespace nl diff --git a/src/lib/core/WeaveTLVUtilities.hpp b/src/lib/core/WeaveTLVUtilities.hpp new file mode 100644 index 00000000000000..1204225fa0ceac --- /dev/null +++ b/src/lib/core/WeaveTLVUtilities.hpp @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2015-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file specifies types and utility interfaces for managing and + * working with Weave TLV. + * + */ + +#ifndef WEAVETLVUTILITIES_HPP +#define WEAVETLVUTILITIES_HPP + +#include +#include + +#include +#include + +namespace nl { + +namespace Weave { + +namespace TLV { + +/** + * @namespace nl::Weave::TLV::Utilities + * + * @brief + * This namespace includes types and utility interfaces for managing and + * working with Weave TLV. + * + */ +namespace Utilities { + +typedef WEAVE_ERROR (*IterateHandler)(const TLVReader &aReader, size_t aDepth, void *aContext); + +extern WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext); +extern WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext, const bool aRecurse); + +extern WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount); +extern WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse); + +extern WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult); +extern WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult, const bool aRecurse); + +extern WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void *aContext, TLVReader &aResult); +extern WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void *aContext, TLVReader &aResult, const bool aRecurse); +} // namespace Utilities + +} // namespace TLV + +} // namespace Weave + +} // namespace nl + +#endif // WEAVETLVUTILITIES_HPP diff --git a/src/lib/core/WeaveTLVWriter.cpp b/src/lib/core/WeaveTLVWriter.cpp new file mode 100644 index 00000000000000..dc4a4b57c20018 --- /dev/null +++ b/src/lib/core/WeaveTLVWriter.cpp @@ -0,0 +1,1898 @@ +/* + * + * Copyright (c) 2013-2017 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements an encoder for the Weave TLV (Tag-Length-Value) encoding format. + * + */ + +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS +#endif +#include +#include + +#include +#include +#include +#include + +namespace nl { +namespace Weave { +namespace TLV { + +using namespace nl::Weave::Encoding; + + +/** + * @var uint32_t TLVWriter::ImplicitProfileId + * + * The profile id of tags that should be encoded in implicit form. + * + * When a writer is asked to encode a new element, if the profile id of the tag associated with the + * new element matches the value of the @p ImplicitProfileId member, the writer will encode the tag + * in implicit form, omitting the profile id in the process. + * + * By default, the @p ImplicitProfileId property is set to kProfileIdNotSpecified, which instructs + * the writer not to emit implicitly encoded tags. Applications can set @p ImplicitProfileId at any + * time to enable encoding tags in implicit form starting at the current point in the encoding. The + * appropriate profile id to set is usually dependent on the context of the application or protocol + * being spoken. + * + * @note The value of the @p ImplicitProfileId member affects the encoding of profile-specific + * tags only; the encoding of context-specific tags is unchanged. + */ + +/** + * @var void *TLVWriter::AppData + * + * A pointer field that can be used for application-specific data. + */ + +/** + * @typedef WEAVE_ERROR (*TLVWriter::GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) + * + * A function that supplies new output buffer space to a TLVWriter. + * + * Functions of this type are used to prepare new buffer space for a TLVWriter to write to. When called, + * the function is expected to return a pointer to a memory location where new data should be written, + * along with an associated maximum length. The function can supply write space either by allocating + * a new buffer to hold the data or by clearing out previously written data from an existing buffer. + * + * @param[in] writer A reference to the TLVWriter object that is requesting new buffer + * space. + * @param[in,out] bufHandle A reference to a uintptr_t value that the function can use to store + * context data between calls. This value is initialized to 0 + * prior to the first call. + * @param[in,out] bufStart A reference to a data pointer. On entry to the function, @p bufStart + * points the beginning of the current output buffer. On exit, @p bufStart + * is expected to point to the beginning of the new output buffer. + * The new pointer value can be the same as the previous value (e.g. + * if the function copied the existing data elsewhere), or it can point + * to an entirely new location. + * @param[in,out] bufLen A reference to an unsigned integer. On entry to the function, + * @p bufLen contains the number of byte of @em unused space in the + * current buffer. On exit, @p bufLen is expected to contain the maximum + * number of bytes that can be written to the new output buffer. + * + * @retval #WEAVE_NO_ERROR If the function was able to supply more buffer space for the writer. + * @retval other Other Weave or platform-specific error codes indicating that an error + * occurred preventing the function from producing additional buffer + * space. + * + */ + +/** + * @var GetNewBufferFunct TLVWriter::GetNewBuffer + * + * A pointer to a function that will supply new output buffer space to a TLVWriter. + * + * A TLVWriter object will call the GetNewBuffer function whenever an attempt is made to write data + * that exceeds the size of the current output buffer. If set to NULL (the default value), the + * writer will return a WEAVE_ERROR_NO_MEMORY if the output data overflows the current buffer. + * + * GetNewBuffer can be set by an application at any time, but is typically set when the writer + * is initialized. + * + * See the GetNewBufferFunct type definition for additional information on implementing a + * GetNewBuffer function. + */ + +/** + * @typedef WEAVE_ERROR (*TLVWriter::FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t bufLen) + * + * A function used to perform finalization of the output from a TLVWriter object. + * + * Functions of this type are called when a TLVWriter's Finalize() method is called. The function is + * expected to perform any necessary clean-up or finalization related to consuming the output of the + * writer object. Examples of this include such things as recording the final length of the encoding, + * or closing a file descriptor. + * + * @param[in] writer A reference to the TLVWriter object that is being finalized. + * @param[in,out] bufHandle A uintptr_t context value that was set by previous calls to the + * @p GetNewBuffer function. + * @param[in,out] bufStart A pointer to the beginning of the current (and final) output buffer. + * @param[in,out] bufLen The number of bytes contained in the buffer pointed to by @p bufStart. + * + * @retval #WEAVE_NO_ERROR If finalization was successful. + * @retval other Other Weave or platform-specific error codes indicating that an error + * occurred during finalization. + * + */ + +/** + * @var FinalizeBufferFunct TLVWriter::FinalizeBuffer + * + * A pointer to a function that will be called when the TLVWriter is finalized. + * + * A TLVWriter object will call the FinalizeBuffer function whenever its Finalize() method is + * called. Applications can set the function pointer at any point prior to calling Finalize(). + * By default the pointer is set to NULL, which causes the Finalize() method to forego calling + * the function. + * + * See the FinalizeBufferFunct type definition for additional information on implementing a + * FinalizeBuffer function. + */ + +/** + * Initializes a TLVWriter object to write into a single output buffer. + * + * @note Applications must call Finalize() on the writer before using the contents of the output + * buffer. + * + * @param[in] buf A pointer to the buffer into which TLV should be written. + * @param[in] maxLen The maximum number of bytes that should be written to the output buffer. + * + */ +__attribute__((noinline)) +void TLVWriter::Init(uint8_t *buf, uint32_t maxLen) +{ + mBufHandle = 0; + mBufStart = mWritePoint = buf; + mRemainingLen = maxLen; + mLenWritten = 0; + mMaxLen = maxLen; + mContainerType = kTLVType_NotSpecified; + SetContainerOpen(false); + SetCloseContainerReserved(true); + + ImplicitProfileId = kProfileIdNotSpecified; + GetNewBuffer = NULL; + FinalizeBuffer = NULL; +} + +/** + * Initializes a TLVWriter object to write into a single PacketBuffer. + * + * Writing begins immediately after the last byte of existing data in the supplied buffer. + * + * @note If a chain of buffers is given, data will only be written to the first buffer. + * + * @note Applications must call Finalize() on the writer before using the contents of the buffer. + * + * @param[in] buf A pointer to an PacketBuffer into which TLV should be written. + * @param[in] maxLen The maximum number of bytes that should be written to the output buffer. + * + */ +void TLVWriter::Init(PacketBuffer *buf, uint32_t maxLen) +{ + mBufHandle = (uintptr_t) buf; + mBufStart = mWritePoint = buf->Start() + buf->DataLength(); + mRemainingLen = buf->AvailableDataLength(); + if (mRemainingLen > maxLen) + mRemainingLen = maxLen; + mLenWritten = 0; + mMaxLen = maxLen; + mContainerType = kTLVType_NotSpecified; + SetContainerOpen(false); + SetCloseContainerReserved(true); + + ImplicitProfileId = kProfileIdNotSpecified; + GetNewBuffer = NULL; + FinalizeBuffer = FinalizePacketBuffer; +} + +/** + * Initializes a TLVWriter object to write into one or more PacketBuffers + * + * Writing begins immediately after the last byte of existing data in the specified buffer. If + * @p allowDiscontiguousBuffers is true, additional PacketBuffers will be allocated and chained to + * the supplied buffer as needed to accommodate the amount of data written. If the specified output + * buffer is already the head of a chain of buffers, output will be written to the subsequent buffers + * in the chain before any new buffers are allocated. + * + * @note Applications must call Finalize() on the writer before using the contents of the output + * buffer(s). + * + * @param[in] buf A pointer to an PacketBuffer into which TLV data should be written. + * @param[in] maxLen The maximum number of bytes that should be written to the output buffer(s). + * @param[in] allowDiscontiguousBuffers + * If true, write data to a chain of PacketBuffers, allocating new buffers as + * needed to store the data written. If false, writing will fail with + * WEAVE_ERROR_BUFFER_TOO_SMALL if the written data exceeds the space available + * in the initial output buffer. + * + */ +void TLVWriter::Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers) +{ + Init(buf, maxLen); + + if (allowDiscontiguousBuffers) + { + GetNewBuffer = GetNewPacketBuffer; + } + else + { + GetNewBuffer = NULL; + } +} + +/** + * Returns the total number of bytes written since the writer was initialized. + * + * @return Total number of bytes written since the writer was initialized. + */ +uint32_t TLVWriter::GetLengthWritten() +{ + return mLenWritten; +} + +/** + * Finish the writing of a TLV encoding. + * + * The Finalize() method completes the process of writing a TLV encoding to the underlying output + * buffer. The method must be called by the application before it uses the contents of the buffer. + * Finalize() can only be called when there are no container writers open for the current writer. + * (See @p OpenContainer()). + * + * @retval #WEAVE_NO_ERROR If the encoding was finalized successfully. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval other Other Weave or platform-specific errors returned by the configured + * FinalizeBuffer() function. + */ +WEAVE_ERROR TLVWriter::Finalize() +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + if (IsContainerOpen()) + return WEAVE_ERROR_TLV_CONTAINER_OPEN; + if (FinalizeBuffer != NULL) + err = FinalizeBuffer(*this, mBufHandle, mBufStart, mWritePoint - mBufStart); + return err; +} + +/** + * Encodes a TLV boolean value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] v The value to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::PutBoolean(uint64_t tag, bool v) +{ + return WriteElementHead((v) ? kTLVElementType_BooleanTrue : kTLVElementType_BooleanFalse, tag, 0); +} + +/** + * Encodes a TLV unsigned integer value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] v The value to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) +{ + return Put(tag, static_cast(v)); +} + +/** + * Encodes a TLV unsigned integer value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] v The value to be encoded. + * @param[in] preserveSize True if the value should be encoded in the same number of bytes as + * at the input type. False if value should be encoded in the minimum + * number of bytes necessary to represent the value. Note: Applications + * are strongly encouraged to set this parameter to false. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_UInt8, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint16_t v) +{ + return Put(tag, static_cast(v)); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint16_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_UInt16, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint32_t v) +{ + return Put(tag, static_cast(v)); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint32_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_UInt32, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint64_t v) +{ + TLVElementType elemType; + if (v <= UINT8_MAX) + elemType = kTLVElementType_UInt8; + else if (v <= UINT16_MAX) + elemType = kTLVElementType_UInt16; + else if (v <= UINT32_MAX) + elemType = kTLVElementType_UInt32; + else + elemType = kTLVElementType_UInt64; + return WriteElementHead(elemType, tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint64_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_UInt64, tag, v); + else + return Put(tag, v); +} + +/** + * Encodes a TLV signed integer value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] v The value to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) +{ + return Put(tag, static_cast(v)); +} + +/** + * Encodes a TLV signed integer value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] v The value to be encoded. + * @param[in] preserveSize True if the value should be encoded in the same number of bytes as + * at the input type. False if value should be encoded in the minimum + * number of bytes necessary to represent the value. Note: Applications + * are strongly encouraged to set this parameter to false. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_Int8, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int16_t v) +{ + return Put(tag, static_cast(v)); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int16_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_Int16, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int32_t v) +{ + return Put(tag, static_cast(v)); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int32_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_Int32, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int64_t v) +{ + TLVElementType elemType; + if (v >= INT8_MIN && v <= INT8_MAX) + elemType = kTLVElementType_Int8; + else if (v >= INT16_MIN && v <= INT16_MAX) + elemType = kTLVElementType_Int16; + else if (v >= INT32_MIN && v <= INT32_MAX) + elemType = kTLVElementType_Int32; + else + elemType = kTLVElementType_Int64; + return WriteElementHead(elemType, tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, int64_t v, bool preserveSize) +{ + if (preserveSize) + return WriteElementHead(kTLVElementType_Int64, tag, v); + else + return Put(tag, v); +} + +/** + * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, double v) + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, float v) +{ + union + { + float f; + uint32_t u32; + } cvt; + cvt.f = v; + return WriteElementHead(kTLVElementType_FloatingPointNumber32, tag, cvt.u32); +} + +/** + * Encodes a TLV floating point value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] v The value to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::Put(uint64_t tag, double v) +{ + union + { + double d; + uint64_t u64; + } cvt; + cvt.d = v; + return WriteElementHead(kTLVElementType_FloatingPointNumber64, tag, cvt.u64); +} + +/** + * Encodes a TLV byte string value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] buf A pointer to a buffer containing the bytes string to be encoded. + * @param[in] len The number of bytes to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) +{ + return WriteElementWithData(kTLVType_ByteString, tag, (const uint8_t *) buf, len); +} + +/** + * Encodes a TLV UTF8 string value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] buf A pointer to the null-terminated UTF-8 string to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::PutString(uint64_t tag, const char *buf) +{ + return PutString(tag, buf, strlen(buf)); +} + +/** + * Encodes a TLV UTF8 string value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] buf A pointer to the UTF-8 string to be encoded. + * @param[in] len The length (in bytes) of the string to be encoded. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::PutString(uint64_t tag, const char *buf, uint32_t len) +{ + return WriteElementWithData(kTLVType_UTF8String, tag, (const uint8_t *) buf, len); +} + +/** + * @brief + * Encode the string output formatted according to the format in the TLV element. + * + * PutStringF is an analog of a sprintf where the output is stored in + * a TLV element as opposed to a character buffer. When extended + * printf functionality is available, the function is able to output + * the result string into a discontinuous underlying storage. The + * implementation supports the following printf enhancements: + * + * -- The platform supplies a callback-based `vcbprintf` that provides + * the ability to call a custom callback in place of putchar. + * + * -- The platform supplies a variant of `vsnprintf` called + * `vsnprintf_ex`, that behaves exactly like vsnprintf except it + * has provisions for omitting the first `n` characters of the + * output. + * + * Note that while the callback-based function may be the simplest and + * use the least amount of code, the `vsprintf_ex` variety of + * functions will consume less stack. + * + * If neither of the above is available, but platform provides + * `malloc` the function will allocate a temporary buffer to hold the + * output. When the platform supplies neither enhancement to the + * printf family nor malloc, the output is truncated such that it fits + * in the continuous state in the current TLV storage + * + * @param[in] tag The TLV tag to be encoded with the value, or @p + * AnonymousTag if the value should be encoded without + * a tag. Tag values should be constructed with one of + * the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * + * @param[in] fmt The format string used to format the argument list. + * Follows the same syntax and rules as the format + * string for `printf` family of functions. + * + * @param[in] ... A list of arguments to be formatted in the output value + * according to fmt. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * + * @retval other If underlying calls to TLVWriter methods -- + * `WriteElementHead` or `GetNewBuffer` -- failed, their + * error is immediately forwarded up the call stack. + */ +WEAVE_ERROR TLVWriter::PutStringF(uint64_t tag, const char *fmt, ...) +{ + WEAVE_ERROR err; + va_list ap; + + va_start(ap, fmt); + + err = VPutStringF(tag, fmt, ap); + + va_end(ap); + + return err; +} + + +#if CONFIG_HAVE_VCBPRINTF +// We have a variant of the printf function that takes a callback that +// emits a single character. The callback performs a function +// identical to putchar. + +void TLVWriter::WeaveTLVWriterPutcharCB(uint8_t c, void *appState) +{ + TLVWriter *w = static_cast(appState); + w->WriteData(&c, sizeof(c)); +} +#endif + +/** + * @brief + * Encode the string output formatted according to the format in the TLV element. + * + * PutStringF is an analog of a sprintf where the output is stored in + * a TLV element as opposed to a character buffer. When extended + * printf functionality is available, the function is able to output + * the result string into a discontinuous underlying storage. The + * implementation supports the following printf enhancements: + * + * -- The platform supplies a callback-based `vcbprintf` that provides + * the ability to call a custom callback in place of putchar. + * + * -- The platform supplies a variant of `vsnprintf` called + * `vsnprintf_ex`, that behaves exactly like vsnprintf except it + * has provisions for omitting the first `n` characters of the + * output. + * + * Note that while the callback-based function may be the simplest and + * use the least amount of code, the `vsprintf_ex` variety of + * functions will consume less stack. + * + * If neither of the above is available, but platform provides + * `malloc` the function will allocate a temporary buffer to hold the + * output. When the platform supplies neither enhancement to the + * printf family nor malloc, the output is truncated such that it fits + * in the continuous state in the current TLV storage + * + * @param[in] tag The TLV tag to be encoded with the value, or @p + * AnonymousTag if the value should be encoded without + * a tag. Tag values should be constructed with one of + * the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * + * @param[in] fmt The format string used to format the argument list. + * Follows the same syntax and rules as the format + * string for `printf` family of functions. + * + * @param[in] ap A list of arguments to be formatted in the output value + * according to fmt. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * + * @retval other If underlying calls to TLVWriter methods -- + * `WriteElementHead` or `GetNewBuffer` -- failed, their + * error is immediately forwarded up the call stack. + */ +WEAVE_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) +{ + va_list aq; + size_t dataLen; + WEAVE_ERROR err = WEAVE_NO_ERROR; + TLVFieldSize lenFieldSize; +#if CONFIG_HAVE_VSNPRINTF_EX + size_t skipLen; + size_t writtenBytes; +#elif CONFIG_HAVE_VCBPRINTF +#elif HAVE_MALLOC + char *tmpBuf; +#else + size_t maxLen; +#endif + va_copy(aq, ap); + + dataLen = vsnprintf(NULL, 0, fmt, aq); + + va_end(aq); + + if (dataLen <= UINT8_MAX) + lenFieldSize = kTLVFieldSize_1Byte; + else if (dataLen <= UINT16_MAX) + lenFieldSize = kTLVFieldSize_2Byte; + else + lenFieldSize = kTLVFieldSize_4Byte; + +#if !(CONFIG_HAVE_VCBPRINTF) && !(CONFIG_HAVE_VSNPRINTF_EX) && !(HAVE_MALLOC) + // no facilities for splitting the stream across multiple buffers, + // just write however much fits in the current buffer. + // assume conservative tag length at this time (8 bytes) + maxLen = mRemainingLen - (1 + 8 + (1 << static_cast(lenFieldSize)) + 1); // 1 : control byte, 8 : tag length, stringLen + 1 for null termination + if (maxLen < dataLen) + dataLen = maxLen; +#endif + + // write length. + err = WriteElementHead((TLVElementType) (kTLVType_UTF8String | lenFieldSize), tag, dataLen); + SuccessOrExit(err); + + VerifyOrExit((mLenWritten + dataLen) <= mMaxLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + + // write data +#if CONFIG_HAVE_VSNPRINTF_EX + + skipLen = 0; + + do + { + va_copy(aq, ap); + + vsnprintf_ex(reinterpret_cast(mWritePoint), mRemainingLen, skipLen, fmt, aq); + + va_end(aq); + + writtenBytes = (mRemainingLen >= (dataLen-skipLen))? dataLen-skipLen : mRemainingLen; + skipLen += writtenBytes; + mWritePoint += writtenBytes; + mRemainingLen -= writtenBytes; + mLenWritten += writtenBytes; + if (skipLen < dataLen) + { + VerifyOrExit(GetNewBuffer != NULL, err = WEAVE_ERROR_NO_MEMORY); + + if (FinalizeBuffer != NULL) + { + err = FinalizeBuffer(*this, mBufHandle, mBufStart, mWritePoint - mBufStart); + SuccessOrExit(err); + } + + err = GetNewBuffer(*this, mBufHandle, mBufStart, mRemainingLen); + SuccessOrExit(err); + + mWritePoint = mBufStart; + } + + } while (skipLen < dataLen); + +#elif CONFIG_HAVE_VCBPRINTF + + va_copy(aq, ap); + + vcbprintf(WeaveTLVWriterPutcharCB, this, dataLen, fmt, aq); + + va_end(aq); + +#elif HAVE_MALLOC + + tmpBuf = static_cast(malloc(dataLen+1)); + VerifyOrExit(tmpBuf != NULL, err = WEAVE_ERROR_NO_MEMORY); + + va_copy(aq, ap); + + vsnprintf(tmpBuf, dataLen+1, fmt, aq); + + va_end(aq); + + err = WriteData(reinterpret_cast(tmpBuf), dataLen); + free(tmpBuf); + +#else // CONFIG_HAVE_VSNPRINTF_EX + + va_copy(aq, ap); + + vsnprintf(reinterpret_cast(mWritePoint), dataLen+1, fmt, aq); + + va_end(aq); + + mWritePoint += dataLen; + mRemainingLen -= dataLen; + mLenWritten += dataLen; + +#endif // CONFIG_HAVE_VSNPRINTF_EX + +exit: + + return err; +} + + +/** + * Encodes a TLV null value. + * + * @param[in] tag The TLV tag to be encoded with the value, or @p AnonymousTag if the + * value should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::PutNull(uint64_t tag) +{ + return WriteElementHead(kTLVElementType_Null, tag, 0); +} + +/** + * Copies a TLV element from a reader object into the writer. + * + * The CopyElement() method encodes a new TLV element whose type, tag and value are taken from a TLVReader + * object. When the method is called, the supplied reader object is expected to be positioned on the + * source TLV element. The newly encoded element will have the same type, tag and contents as the input + * container. If the supplied element is a TLV container (structure, array or path), the entire contents + * of the container will be copied. + * + * @note This method requires the supplied TVLReader object to be reading from a single, contiguous + * input buffer that contains the entirety of the underlying TLV encoding. Supplying a reader in any + * other mode has undefined behavior. + * + * @param[in] reader A reference to a TLVReader object identifying a pre-encoded TLV + * element that should be copied. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE + * If the supplied reader is not positioned on an element. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_TLV_UNDERRUN + * If the underlying TLV encoding associated with the supplied reader ended + * prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the supplied reader encountered an invalid or unsupported TLV element + * type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the supplied reader encountered a TLV tag in an invalid context, + * or if the supplied tag is invalid or inappropriate in the context in + * which the new container is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() + * function associated with the reader object. + * + */ +WEAVE_ERROR TLVWriter::CopyElement(TLVReader& reader) +{ + return CopyElement(reader.GetTag(), reader); +} + +/** + * Copies a TLV element from a reader object into the writer. + * + * The CopyElement() method encodes a new TLV element whose type and value are taken from a TLVReader + * object. When the method is called, the supplied reader object is expected to be positioned on the + * source TLV element. The newly encoded element will have the same type and contents as the input + * container, however the tag will be set to the specified argument. If the supplied element is a + * TLV container (structure, array or path), the entire contents of the container will be copied. + * + * @note This method requires the supplied TVLReader object to be reading from a single, contiguous + * input buffer that contains the entirety of the underlying TLV encoding. Supplying a reader in any + * other mode has undefined behavior. + * + * @param[in] tag The TLV tag to be encoded with the container, or @p AnonymousTag if + * the container should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] reader A reference to a TLVReader object identifying a pre-encoded TLV + * element whose type and value should be copied. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE + * If the supplied reader is not positioned on an element. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_TLV_UNDERRUN + * If the underlying TLV encoding associated with the supplied reader ended + * prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the supplied reader encountered an invalid or unsupported TLV element + * type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the supplied reader encountered a TLV tag in an invalid context, + * or if the supplied tag is invalid or inappropriate in the context in + * which the new container is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() + * function associated with the reader object. + * + */ + + +const size_t kWeaveTLVCopyChunkSize = 16; + +WEAVE_ERROR TLVWriter::CopyElement(uint64_t tag, TLVReader& reader) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + TLVElementType elemType = reader.ElementType(); + uint64_t elemLenOrVal = reader.mElemLenOrVal; + TLVReader readerHelper; // used to figure out the length of the element and read data of the element + uint32_t copyDataLen; + uint8_t chunk[kWeaveTLVCopyChunkSize]; + + VerifyOrExit(elemType != kTLVElementType_NotSpecified && elemType != kTLVElementType_EndOfContainer, err = WEAVE_ERROR_INCORRECT_STATE); + + // Initialize the helper + readerHelper.Init(reader); + + // Skip to the end of the element. + err = reader.Skip(); + SuccessOrExit(err); + + // Compute the amount of value data to copy from the reader. + copyDataLen = reader.GetLengthRead() - readerHelper.GetLengthRead(); + + // Write the head of the new element with the same type and length/value, but using the + // specified tag. + err = WriteElementHead(elemType, tag, elemLenOrVal); + SuccessOrExit(err); + + while (copyDataLen > 0) + { + uint32_t chunkSize = copyDataLen > kWeaveTLVCopyChunkSize ? kWeaveTLVCopyChunkSize : copyDataLen; + err = readerHelper.ReadData(chunk, chunkSize); + SuccessOrExit(err); + + err = WriteData(chunk, chunkSize); + SuccessOrExit(err); + + copyDataLen -= chunkSize; + } + +exit: + return err; + +} + +/** + * Initializes a new TLVWriter object for writing the members of a TLV container element. + * + * The OpenContainer() method is used to write TLV container elements (structure, arrays or paths) + * to an encoding. The method takes the type and tag (if any) of the new container, and a reference + * to a new writer object (the container writer) that will be initialized for the purpose + * of writing the container's elements. Applications write the members of the new container using + * the container writer and then call CloseContainer() to complete the container encoding. + * + * While the container writer is open, applications must not make calls on or otherwise alter the state + * of the parent writer. + * + * The container writer inherits various configuration properties from the parent writer. These are: + * + * @li The implicit profile id (ImplicitProfileId) + * @li The application data pointer (AppData) + * @li The GetNewBuffer and FinalizeBuffer function pointers + * + * @note The StartContainer() method can be used as an alternative to OpenContainer() to write a + * container element without initializing a new writer object. + * + * @param[in] tag The TLV tag to be encoded with the container, or @p AnonymousTag if + * the container should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] containerType The type of container to encode. Must be one of @p kTLVType_Structure, + * @p kTLVType_Array or @p kTLVType_Path. + * @param[out] containerWriter A reference to a TLVWriter object that will be initialized for + * writing the members of the new container element. Any data + * associated with the supplied object is overwritten. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE + * If the value specified for containerType is incorrect. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + VerifyOrExit(TLVTypeIsContainer(containerType), err = WEAVE_ERROR_WRONG_TLV_TYPE); + + if (IsCloseContainerReserved()) + { + VerifyOrExit(mMaxLen >= kEndOfContainerMarkerSize, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + mMaxLen -= kEndOfContainerMarkerSize; + } + err = WriteElementHead((TLVElementType) containerType, tag, 0); + + if (err != WEAVE_NO_ERROR) + { + // undo the space reservation, as the container is not actually open + if (IsCloseContainerReserved()) + mMaxLen += kEndOfContainerMarkerSize; + + ExitNow(); + } + + containerWriter.mBufHandle = mBufHandle; + containerWriter.mBufStart = mBufStart; + containerWriter.mWritePoint = mWritePoint; + containerWriter.mRemainingLen = mRemainingLen; + containerWriter.mLenWritten = 0; + containerWriter.mMaxLen = mMaxLen - mLenWritten; + containerWriter.mContainerType = containerType; + containerWriter.SetContainerOpen(false); + containerWriter.SetCloseContainerReserved(IsCloseContainerReserved()); + containerWriter.ImplicitProfileId = ImplicitProfileId; + containerWriter.GetNewBuffer = GetNewBuffer; + containerWriter.FinalizeBuffer = FinalizeBuffer; + + SetContainerOpen(true); + +exit: + return err; +} + +/** + * Completes the writing of a TLV container after a call to OpenContainer(). + * + * The CloseContainer() method restores the state of a parent TLVWriter object after a call to + * OpenContainer(). For every call to OpenContainer() applications must make a corresponding + * call to CloseContainer(), passing a reference to the same container writer to both methods. + * + * When CloseContainer() returns, applications may continue to use the parent writer to write + * additional TLV elements that appear after the container element. At this point the supplied + * container writer should be considered 'de-initialized' and must not be used without + * re-initialization. + * + * @param[in] containerWriter A reference to the TLVWriter object that was supplied to the + * OpenContainer() method. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE + * If the supplied container writer is not in the correct state. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If another container writer has been opened on the supplied + * container writer and not yet closed. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If completing the encoding of the container would exceed the + * limit on the maximum number of bytes specified when the writer + * was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack + * of memory. + * @retval other Other Weave or platform-specific errors returned by the + * configured GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::CloseContainer(TLVWriter& containerWriter) +{ + if (!TLVTypeIsContainer(containerWriter.mContainerType)) + return WEAVE_ERROR_INCORRECT_STATE; + + if (containerWriter.IsContainerOpen()) + return WEAVE_ERROR_TLV_CONTAINER_OPEN; + + mBufHandle = containerWriter.mBufHandle; + mBufStart = containerWriter.mBufStart; + mWritePoint = containerWriter.mWritePoint; + mRemainingLen = containerWriter.mRemainingLen; + mLenWritten += containerWriter.mLenWritten; + + if (IsCloseContainerReserved()) + mMaxLen += kEndOfContainerMarkerSize; + + SetContainerOpen(false); + + // Reset the container writer so that it can't accidentally be used again. + containerWriter.Init((uint8_t *) NULL, 0); + + return WriteElementHead(kTLVElementType_EndOfContainer, AnonymousTag, 0); +} + +/** + * Begins encoding a new TLV container element. + * + * The StartContainer() method is used to write TLV container elements (structure, arrays or paths) + * to an encoding. The method takes the type and tag (if any) of the new container, and a reference + * to a TLVType value which will be used to save the current context of the writer while it is being + * used to write the container. + * + * Once the StartContainer() method returns, the application should use the current TLVWriter object to + * write the elements of the container. When finish, the application must call the EndContainer() + * method to finish the encoding of the container. + * + * @param[in] tag The TLV tag to be encoded with the container, or @p AnonymousTag if + * the container should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] containerType The type of container to encode. Must be one of @p kTLVType_Structure, + * @p kTLVType_Array or @p kTLVType_Path. + * @param[out] outerContainerType + * A reference to a TLVType value that will receive the context of the + * writer. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE + * If the value specified for containerType is incorrect. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + VerifyOrExit(TLVTypeIsContainer(containerType), err = WEAVE_ERROR_WRONG_TLV_TYPE); + + if (IsCloseContainerReserved()) + { + VerifyOrExit(mMaxLen >= kEndOfContainerMarkerSize, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + mMaxLen -= kEndOfContainerMarkerSize; + } + + err = WriteElementHead((TLVElementType) containerType, tag, 0); + if (err != WEAVE_NO_ERROR) + { + // undo the space reservation, as the container is not actually open + if (IsCloseContainerReserved()) + mMaxLen += kEndOfContainerMarkerSize; + + ExitNow(); + } + outerContainerType = mContainerType; + mContainerType = containerType; + + SetContainerOpen(false); + +exit: + return err; +} + +/** + * Completes the encoding of a TLV container element. + * + * The EndContainer() method completes the encoding of a TLV container element and restores the state + * of a TLVWrite object after an earlier call to StartContainer(). For every call to StartContainer() + * applications must make a corresponding call to EndContainer(), passing the TLVType value returned + * by the StartContainer() call. When EndContainer() returns, the writer object can be used to write + * additional TLV elements that follow the container element. + * + * @note Any changes made to the configuration of the writer between the calls to StartContainer() + * and EndContainer() are NOT undone by the call to EndContainer(). For example, a change to the + * implicit profile id (@p ImplicitProfileId) will not be reversed when a container is ended. Thus + * it is the application's responsibility to adjust the configuration accordingly at the appropriate + * times. + * + * @param[in] outerContainerType + * The TLVType value that was returned by the StartContainer() method. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE + * If a corresponding StartContainer() call was not made. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::EndContainer(TLVType outerContainerType) +{ + if (!TLVTypeIsContainer(mContainerType)) + return WEAVE_ERROR_INCORRECT_STATE; + + mContainerType = outerContainerType; + + if (IsCloseContainerReserved()) + mMaxLen += kEndOfContainerMarkerSize; + + return WriteElementHead(kTLVElementType_EndOfContainer, AnonymousTag, 0); +} + +/** + * Encodes a TLV container element from a pre-encoded set of member elements + * + * The PutPreEncodedContainer() method encodes a new TLV container element (a structure, array or path) + * containing a set of member elements taken from a pre-encoded buffer. The input buffer is expected to + * contain zero or more full-encoded TLV elements, with tags that conform to the rules associated with + * the specified container type (e.g. structure members must have tags, while array members must not). + * + * The method encodes the entirety of the container element in one call. When PutPreEncodedContainer() + * returns, the writer object can be used to write additional TLV elements following the container element. + * + * @param[in] tag The TLV tag to be encoded with the container, or @p AnonymousTag if + * the container should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] containerType The type of container to encode. Must be one of @p kTLVType_Structure, + * @p kTLVType_Array or @p kTLVType_Path. + * @param[in] data A pointer to a buffer containing zero of more encoded TLV elements that + * will become the members of the new container. + * @param[in] dataLen The number of bytes in the @p data buffer. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_WRONG_TLV_TYPE + * If the value specified for containerType is incorrect. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the specified tag value is invalid or inappropriate in the context + * in which the value is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions. + * + */ +WEAVE_ERROR TLVWriter::PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen) +{ + if (!TLVTypeIsContainer(containerType)) + return WEAVE_ERROR_INVALID_ARGUMENT; + + WEAVE_ERROR err = WriteElementHead((TLVElementType)containerType, tag, 0); + if (err != WEAVE_NO_ERROR) + return err; + + return WriteData(data, dataLen); +} + +/** + * Copies a TLV container element from TLVReader object + * + * The CopyContainer() encodes a new TLV container element by copying a pre-encoded container element + * located at the current position of a TLVReader object. The method writes the entirety of the new + * container element in one call, copying the container's type, tag and elements from the source + * encoding. When the method returns, the writer object can be used to write additional TLV elements + * following the container element. + * + * @note This method requires the supplied TVLReader object to be reading from a single, contiguous + * input buffer that contains the entirety of the underlying TLV encoding. Supplying a reader in any + * other mode has undefined behavior. + * + * @param[in] container A reference to a TLVReader object identifying the pre-encoded TLV + * container to be copied. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE + * If the supplied reader is not positioned on a container element. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_TLV_UNDERRUN + * If the underlying TLV encoding associated with the supplied reader ended + * prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the supplied reader encountered an invalid or unsupported TLV element + * type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the supplied reader encountered a TLV tag in an invalid context, + * or if the tag associated with the source container is invalid or + * inappropriate in the context in which the new container is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() + * function associated with the reader object. + * + */ +WEAVE_ERROR TLVWriter::CopyContainer(TLVReader& container) +{ + return CopyContainer(container.GetTag(), container); +} + +/** + * Encodes a TLV container element from a pre-encoded set of member elements + * + * The CopyContainer() method encodes a new TLV container element (a structure, array or path) + * containing a set of member elements taken from a TLVReader object. When the method is called, the + * supplied reader object is expected to be positioned on a TLV container element. The newly encoded + * container will have the same type and members as the input container. The tag for the new + * container is specified as an input parameter. + * + * When the method returns, the writer object can be used to write additional TLV elements following + * the container element. + * + * @note This method requires the supplied TVLReader object to be reading from a single, contiguous + * input buffer that contains the entirety of the underlying TLV encoding. Supplying a reader in any + * other mode has undefined behavior. + * + * @param[in] tag The TLV tag to be encoded with the container, or @p AnonymousTag if + * the container should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] container A reference to a TLVReader object identifying a pre-encoded TLV + * container whose type and members should be copied. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_INCORRECT_STATE + * If the supplied reader is not positioned on a container element. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_TLV_UNDERRUN + * If the underlying TLV encoding associated with the supplied reader ended + * prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the supplied reader encountered an invalid or unsupported TLV element + * type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the supplied reader encountered a TLV tag in an invalid context, + * or if the supplied tag is invalid or inappropriate in the context in + * which the new container is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() + * function associated with the reader object. + * + */ +WEAVE_ERROR TLVWriter::CopyContainer(uint64_t tag, TLVReader& container) +{ + // NOTE: This function MUST be used with a TVLReader that is reading from a contiguous buffer. + WEAVE_ERROR err; + TLVType containerType, outerContainerType; + const uint8_t *containerStart; + + containerType = container.GetType(); + + err = container.EnterContainer(outerContainerType); + if (err != WEAVE_NO_ERROR) + return err; + + containerStart = container.GetReadPoint(); + + err = container.ExitContainer(outerContainerType); + if (err != WEAVE_NO_ERROR) + return err; + + return PutPreEncodedContainer(tag, containerType, containerStart, container.GetReadPoint() - containerStart); +} + +/** + * Encodes a TLV container element that contains member elements from a pre-encoded container + * + * The CopyContainer() method encodes a new TLV container element (a structure, array or path) + * containing a set of member elements taken from the contents of a supplied pre-encoded container. + * When the method is called, data in the supplied input buffer is parsed as a TLV container element + * an a new container is written that has the same type and members as the input container. The tag + * for the new container is specified as an input parameter. + * + * When the method returns, the writer object can be used to write additional TLV elements following + * the container element. + * + * @param[in] tag The TLV tag to be encoded with the container, or @p AnonymousTag if + * the container should be encoded without a tag. Tag values should be + * constructed with one of the tag definition functions ProfileTag(), + * ContextTag() or CommonTag(). + * @param[in] encodedContainer A buffer containing a pre-encoded TLV container whose type and members + * should be copied. + * @param[in] encodedContainerLen The length in bytes of the pre-encoded container. + * + * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * If a container writer has been opened on the current writer and not + * yet closed. + * @retval #WEAVE_ERROR_TLV_UNDERRUN + * If the encoded container ended prematurely. + * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * If the encoded container contained an invalid or unsupported TLV element type. + * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * If the encoded container contained a TLV tag in an invalid context, + * or if the supplied tag is invalid or inappropriate in the context in + * which the new container is being written. + * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * If writing the value would exceed the limit on the maximum number of + * bytes specified when the writer was initialized. + * @retval #WEAVE_ERROR_NO_MEMORY + * If an attempt to allocate an output buffer failed due to lack of + * memory. + * @retval other Other Weave or platform-specific errors returned by the configured + * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() + * function associated with the reader object. + * + */ +WEAVE_ERROR TLVWriter::CopyContainer(uint64_t tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen) +{ + WEAVE_ERROR err; + TLVReader reader; + + reader.Init(encodedContainer, encodedContainerLen); + + err = reader.Next(); + SuccessOrExit(err); + + err = PutPreEncodedContainer(tag, reader.GetType(), reader.GetReadPoint(), reader.GetRemainingLength()); + SuccessOrExit(err); + +exit: + return err; +} + +/** + * Returns the type of container within which the TLVWriter is currently writing. + * + * The GetContainerType() method returns the type of the TLV container within which the TLVWriter + * is currently writing. If the TLVWriter is not writing elements within a container (i.e. if writing + * at the outer-most level of an encoding) the method returns kTLVType_NotSpecified. + * + * @return The TLVType of the current container, or kTLVType_NotSpecified if the TLVWriter is not + * writing elements within a container. + */ +TLVType TLVWriter::GetContainerType() const +{ + return mContainerType; +} + +WEAVE_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal) +{ + uint8_t *p; + uint8_t stagingBuf[17]; // 17 = 1 control byte + 8 tag bytes + 8 length/value bytes + + if (IsContainerOpen()) + return WEAVE_ERROR_TLV_CONTAINER_OPEN; + + uint32_t tagNum = TagNumFromTag(tag); + + if ((mRemainingLen >= sizeof(stagingBuf)) && (mMaxLen >= sizeof(stagingBuf))) + p = mWritePoint; + else + p = stagingBuf; + + if (IsSpecialTag(tag)) + { + if (tagNum < 256) + { + if (mContainerType != kTLVType_Structure && mContainerType != kTLVType_Path) + return WEAVE_ERROR_INVALID_TLV_TAG; + + Write8(p, kTLVTagControl_ContextSpecific | elemType); + Write8(p, (uint8_t) tagNum); + } + else + { + if (elemType != kTLVElementType_EndOfContainer && mContainerType != kTLVType_NotSpecified + && mContainerType != kTLVType_Array) + return WEAVE_ERROR_INVALID_TLV_TAG; + + Write8(p, kTLVTagControl_Anonymous | elemType); + } + } + else + { + uint32_t profileId = ProfileIdFromTag(tag); + + if (mContainerType != kTLVType_NotSpecified && mContainerType != kTLVType_Structure + && mContainerType != kTLVType_Path) + return WEAVE_ERROR_INVALID_TLV_TAG; + + if (profileId == kCommonProfileId) + { + if (tagNum < 65536) + { + Write8(p, kTLVTagControl_CommonProfile_2Bytes | elemType); + LittleEndian::Write16(p, (uint16_t) tagNum); + } + else + { + Write8(p, kTLVTagControl_CommonProfile_4Bytes | elemType); + LittleEndian::Write32(p, tagNum); + } + } + else if (profileId == ImplicitProfileId) + { + if (tagNum < 65536) + { + Write8(p, kTLVTagControl_ImplicitProfile_2Bytes | elemType); + LittleEndian::Write16(p, (uint16_t) tagNum); + } + else + { + Write8(p, kTLVTagControl_ImplicitProfile_4Bytes | elemType); + LittleEndian::Write32(p, tagNum); + } + } + else + { + uint16_t vendorId = (uint16_t) (profileId >> 16); + uint16_t profileNum = (uint16_t) profileId; + + if (tagNum < 65536) + { + Write8(p, kTLVTagControl_FullyQualified_6Bytes | elemType); + LittleEndian::Write16(p, vendorId); + LittleEndian::Write16(p, profileNum); + LittleEndian::Write16(p, (uint16_t) tagNum); + } + else + { + Write8(p, kTLVTagControl_FullyQualified_8Bytes | elemType); + LittleEndian::Write16(p, vendorId); + LittleEndian::Write16(p, profileNum); + LittleEndian::Write32(p, tagNum); + } + } + } + + switch (GetTLVFieldSize(elemType)) + { + case kTLVFieldSize_0Byte: + break; + case kTLVFieldSize_1Byte: + Write8(p, (uint8_t) lenOrVal); + break; + case kTLVFieldSize_2Byte: + LittleEndian::Write16(p, (uint16_t) lenOrVal); + break; + case kTLVFieldSize_4Byte: + LittleEndian::Write32(p, (uint32_t) lenOrVal); + break; + case kTLVFieldSize_8Byte: + LittleEndian::Write64(p, lenOrVal); + break; + } + + if ((mRemainingLen >= sizeof(stagingBuf)) && (mMaxLen >= sizeof(stagingBuf))) + { + uint32_t len = p - mWritePoint; + mWritePoint = p; + mRemainingLen -= len; + mLenWritten += len; + return WEAVE_NO_ERROR; + } + else + return WriteData(stagingBuf, p - stagingBuf); +} + +WEAVE_ERROR TLVWriter::WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen) +{ + TLVFieldSize lenFieldSize; + + if (dataLen <= UINT8_MAX) + lenFieldSize = kTLVFieldSize_1Byte; + else if (dataLen <= UINT16_MAX) + lenFieldSize = kTLVFieldSize_2Byte; + else + lenFieldSize = kTLVFieldSize_4Byte; + + WEAVE_ERROR err = WriteElementHead((TLVElementType) (type | lenFieldSize), tag, dataLen); + if (err != WEAVE_NO_ERROR) + return err; + + return WriteData(data, dataLen); +} + +WEAVE_ERROR TLVWriter::WriteData(const uint8_t *p, uint32_t len) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + VerifyOrExit((mLenWritten + len) <= mMaxLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + + while (len > 0) + { + if (mRemainingLen == 0) + { + VerifyOrExit(GetNewBuffer != NULL, err = WEAVE_ERROR_NO_MEMORY); + + if (FinalizeBuffer != NULL) + { + err = FinalizeBuffer(*this, mBufHandle, mBufStart, mWritePoint - mBufStart); + SuccessOrExit(err); + } + + err = GetNewBuffer(*this, mBufHandle, mBufStart, mRemainingLen); + SuccessOrExit(err); + + mWritePoint = mBufStart; + + if (mRemainingLen > (mMaxLen - mLenWritten)) + mRemainingLen = (mMaxLen - mLenWritten); + } + + uint32_t writeLen = len; + if (writeLen > mRemainingLen) + writeLen = mRemainingLen; + + memmove(mWritePoint, p, writeLen); + mWritePoint += writeLen; + mRemainingLen -= writeLen; + mLenWritten += writeLen; + p += writeLen; + len -= writeLen; + } + +exit: + return err; +} + +/** + * An implementation of a TLVWriter GetNewBuffer function for writing to a chain of PacketBuffers. + * + * The GetNewPacketBuffer() function supplies new output space to a TLVWriter by allocating a chain + * of one or more PacketBuffers as needed to store the encoding. The function is designed to be + * assigned to the TLVWriter GetNewBuffer function pointer. + * + * Note that when using the GetNewPacketBuffer with a TLVWriter, the corresponding FinalizePacketBuffer() + * function (or an equivalent) should also be used to finalize the buffer chain. + * + * See the GetNewBufferFunct type definition for additional information on the API of the + * GetNewPacketBuffer() function. + */ +WEAVE_ERROR TLVWriter::GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) +{ + PacketBuffer *buf = (PacketBuffer *) bufHandle; + + PacketBuffer *newBuf = buf->Next(); + if (newBuf == NULL) + { + newBuf = PacketBuffer::New(0); + if (newBuf != NULL) + buf->AddToEnd(newBuf); + } + + if (newBuf != NULL) + { + bufHandle = (uintptr_t) newBuf; + bufStart = newBuf->Start(); + bufLen = newBuf->MaxDataLength(); + } + else + { + bufStart = NULL; + bufLen = 0; + } + + return WEAVE_NO_ERROR; +} + +/** + * An implementation of a TLVWriter FinalizeBuffer function for writing to a chain of PacketBuffers. + * + * The FinalizePacketBuffer() function performs the necessary finalization required when using a + * TLVWriter to write to a chain of PacketBuffers. The function is designed to be used in conjunction + * with the GetNewPacketBuffer() function. + * + * See the FinalizeBufferFunct type definition for additional information on the API of the + * FinalizePacketBuffer() function. + */ +WEAVE_ERROR TLVWriter::FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen) +{ + PacketBuffer *buf = (PacketBuffer *) bufHandle; + uint8_t * endPtr = bufStart + dataLen; + + buf->SetDataLength(endPtr - buf->Start()); + + return WEAVE_NO_ERROR; +} + +} // namespace TLV +} // namespace Weave +} // namespace nl From b51c4429d57053e6cbe6633df479e0c7d1874829 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Tue, 10 Mar 2020 14:34:10 -0700 Subject: [PATCH 2/3] Rename from Weave to CHIP --- src/lib/core/CHIPTLV.h | 465 ++++++++++++++++ .../{WeaveTLVData.hpp => CHIPTLVData.hpp} | 187 ++++--- .../{WeaveTLVDebug.cpp => CHIPTLVDebug.cpp} | 61 +-- .../{WeaveTLVDebug.hpp => CHIPTLVDebug.hpp} | 21 +- .../{WeaveTLVReader.cpp => CHIPTLVReader.cpp} | 485 ++++++++-------- .../core/{WeaveTLVTags.h => CHIPTLVTags.h} | 21 +- .../core/{WeaveTLVTypes.h => CHIPTLVTypes.h} | 18 +- ...WeaveTLVUpdater.cpp => CHIPTLVUpdater.cpp} | 103 ++-- ...eTLVUtilities.cpp => CHIPTLVUtilities.cpp} | 163 +++--- ...eTLVUtilities.hpp => CHIPTLVUtilities.hpp} | 21 +- .../{WeaveTLVWriter.cpp => CHIPTLVWriter.cpp} | 517 +++++++++--------- src/lib/core/WeaveTLV.h | 470 ---------------- 12 files changed, 1245 insertions(+), 1287 deletions(-) create mode 100644 src/lib/core/CHIPTLV.h rename src/lib/core/{WeaveTLVData.hpp => CHIPTLVData.hpp} (60%) rename src/lib/core/{WeaveTLVDebug.cpp => CHIPTLVDebug.cpp} (83%) rename src/lib/core/{WeaveTLVDebug.hpp => CHIPTLVDebug.hpp} (82%) rename src/lib/core/{WeaveTLVReader.cpp => CHIPTLVReader.cpp} (76%) rename src/lib/core/{WeaveTLVTags.h => CHIPTLVTags.h} (93%) rename src/lib/core/{WeaveTLVTypes.h => CHIPTLVTypes.h} (94%) rename src/lib/core/{WeaveTLVUpdater.cpp => CHIPTLVUpdater.cpp} (85%) rename src/lib/core/{WeaveTLVUtilities.cpp => CHIPTLVUtilities.cpp} (72%) rename src/lib/core/{WeaveTLVUtilities.hpp => CHIPTLVUtilities.hpp} (85%) rename src/lib/core/{WeaveTLVWriter.cpp => CHIPTLVWriter.cpp} (82%) delete mode 100644 src/lib/core/WeaveTLV.h diff --git a/src/lib/core/CHIPTLV.h b/src/lib/core/CHIPTLV.h new file mode 100644 index 00000000000000..83284df3ff437a --- /dev/null +++ b/src/lib/core/CHIPTLV.h @@ -0,0 +1,465 @@ +/* + * + * + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file contains definitions for working with data encoded in CHIP TLV format. + * + * CHIP TLV (Tag-Length-Value) is a generalized encoding method for simple structured data. It + * shares many properties with the commonly used JSON serialization format while being considerably + * more compact over the wire. + */ + +#ifndef CHIPTLV_H_ +#define CHIPTLV_H_ + +#include +#include + +#include +#include +#include "CHIPTLVTags.h" +#include "CHIPTLVTypes.h" + +// forward declaration of the PacketBuffer class used within the header. +namespace chip { +namespace System { + +class PacketBuffer; + +} // namespace System +} // namespace chip + +/** + * @namespace chip::TLV + * + * Definitions for working with data encoded in CHIP TLV format. + * + * CHIP TLV is a generalized encoding method for simple structured data. It shares many properties + * with the commonly used JSON serialization format while being considerably more compact over the wire. + */ + +namespace chip { +namespace TLV { + +using chip::System::PacketBuffer; + +enum { + kTLVControlByte_NotSpecified = 0xFFFF +}; + +/** + * Provides a memory efficient parser for data encoded in CHIP TLV format. + * + * TLVReader implements a forward-only, “pull-style” parser for CHIP TLV data. The TLVReader + * object operates as a cursor that can be used to iterate over a sequence of TLV elements + * and interpret their contents. When positioned on an element, applications can make calls + * to the reader's Get() methods to query the current element’s type and tag, and to extract + * any associated value. The reader’s Next() method is used to advance from element to element. + * + * A TLVReader object is always positioned either before, on or after a TLV element. When first + * initialized, a TLVReader is positioned immediately before the first element of the encoding. + * To begin reading, an application must make an initial call to the Next() method to position + * the reader on the first element. When a container element is encountered--either a structure, + * an array or a path--the OpenContainer() or EnterContainer() methods can be used to iterate + * through the contents of the container. + * + * When the reader reaches the end of a TLV encoding, or the last element within a container, + * it signals the application by returning a CHIP_END_OF_TLV error from the Next() method. + * The reader will continue to return CHIP_END_OF_TLV until it is reinitialized, or the current + * container is exited (via CloseContainer() / ExitContainer()). + * + * A TLVReader object can parse data directly from a fixed input buffer, or from a chain of one + * or more PacketBuffers. Additionally, applications can supply a @p GetNextBuffer function to + * feed data to the reader from an arbitrary source, e.g. a socket or a serial port. + * + */ +class DLL_EXPORT TLVReader +{ +friend class TLVWriter; +friend class TLVUpdater; + +public: + // *** See CHIPTLVReader.cpp file for API documentation *** + + void Init(const TLVReader &aReader); + void Init(const uint8_t *data, uint32_t dataLen); + void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL); + void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers); + + CHIP_ERROR Next(void); + CHIP_ERROR Next(TLVType expectedType, uint64_t expectedTag); + + TLVType GetType(void) const; + uint64_t GetTag(void) const; + uint32_t GetLength(void) const; + uint16_t GetControlByte(void) const; + + CHIP_ERROR Get(bool& v); + CHIP_ERROR Get(int8_t& v); + CHIP_ERROR Get(int16_t& v); + CHIP_ERROR Get(int32_t& v); + CHIP_ERROR Get(int64_t& v); + CHIP_ERROR Get(uint8_t& v); + CHIP_ERROR Get(uint16_t& v); + CHIP_ERROR Get(uint32_t& v); + CHIP_ERROR Get(uint64_t& v); + CHIP_ERROR Get(float& v); + CHIP_ERROR Get(double& v); + CHIP_ERROR GetBytes(uint8_t *buf, uint32_t bufSize); + CHIP_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen); + CHIP_ERROR GetString(char *buf, uint32_t bufSize); + CHIP_ERROR DupString(char *& buf); + CHIP_ERROR GetDataPtr(const uint8_t *& data); + + CHIP_ERROR EnterContainer(TLVType& outerContainerType); + CHIP_ERROR ExitContainer(TLVType outerContainerType); + CHIP_ERROR OpenContainer(TLVReader& containerReader); + CHIP_ERROR CloseContainer(TLVReader& containerReader); + TLVType GetContainerType(void) const; + CHIP_ERROR VerifyEndOfContainer(void); + + uint32_t GetLengthRead(void) const { return mLenRead; } + uint32_t GetRemainingLength(void) const { return mMaxLen - mLenRead; } + + const uint8_t *GetReadPoint(void) const { return mReadPoint; } + uintptr_t GetBufHandle(void) const { return mBufHandle; } + + CHIP_ERROR Skip(void); + + uint32_t ImplicitProfileId; + void *AppData; + + typedef CHIP_ERROR (*GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); + GetNextBufferFunct GetNextBuffer; + +protected: + uint64_t mElemTag; + uint64_t mElemLenOrVal; + uintptr_t mBufHandle; + const uint8_t *mReadPoint; + const uint8_t *mBufEnd; + uint32_t mLenRead; + uint32_t mMaxLen; + TLVType mContainerType; + uint16_t mControlByte; + +private: + bool mContainerOpen; + +protected: + bool IsContainerOpen(void) const { return mContainerOpen; } + void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; } + + CHIP_ERROR ReadElement(void); + void ClearElementState(void); + CHIP_ERROR SkipData(void); + CHIP_ERROR SkipToEndOfContainer(void); + CHIP_ERROR VerifyElement(void); + uint64_t ReadTag(TLVTagControl tagControl, const uint8_t *& p); + CHIP_ERROR EnsureData(CHIP_ERROR noDataErr); + CHIP_ERROR ReadData(uint8_t *buf, uint32_t len); + CHIP_ERROR GetElementHeadLength(uint8_t& elemHeadBytes) const; + TLVElementType ElementType(void) const; + + static CHIP_ERROR GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); + static CHIP_ERROR FailGetNextBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); + +#if CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + static CHIP_ERROR GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen); +#endif // CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES +}; + +#if CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES +inline CHIP_ERROR TLVReader::GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, + uint32_t& bufLen) +{ + return GetNextPacketBuffer(reader, bufHandle, bufStart, bufLen); +} +#endif // CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + +/** + * Provides a memory efficient encoder for writing data in CHIP TLV format. + * + * TLVWriter implements a forward-only, stream-style encoder for CHIP TLV data. Applications + * write data to an encoding by calling one of the writer's Put() methods, passing associated + * tag and value information as necessary. Similarly applications can encode TLV container types + * (structures, arrays or paths) by calling the writer's OpenContainer() or EnterContainer() + * methods. + * + * A TLVWriter object can write data directly to a fixed output buffer, or to a chain of one or + * more PacketBuffer objects. Additionally, applications can supply their own @p GetNewBuffer and + * @p FinalizeBuffer functions to direct output to an arbitrary destination, e.g. a socket or an + * event queue. + * + */ +class DLL_EXPORT TLVWriter +{ +friend class TLVUpdater; +public: + // *** See CHIPTLVWriter.cpp file for API documentation *** + + void Init(uint8_t *buf, uint32_t maxLen); + void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL); + void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers); + + CHIP_ERROR Finalize(void); + + CHIP_ERROR Put(uint64_t tag, int8_t v); + CHIP_ERROR Put(uint64_t tag, int8_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, int16_t v); + CHIP_ERROR Put(uint64_t tag, int16_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, int32_t v); + CHIP_ERROR Put(uint64_t tag, int32_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, int64_t v); + CHIP_ERROR Put(uint64_t tag, int64_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, uint8_t v); + CHIP_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, uint16_t v); + CHIP_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, uint32_t v); + CHIP_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, uint64_t v); + CHIP_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize); + CHIP_ERROR Put(uint64_t tag, float v); + CHIP_ERROR Put(uint64_t tag, double v); + CHIP_ERROR PutBoolean(uint64_t tag, bool v); + CHIP_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len); + CHIP_ERROR PutString(uint64_t tag, const char *buf); + CHIP_ERROR PutString(uint64_t tag, const char *buf, uint32_t len); + CHIP_ERROR PutStringF(uint64_t tag, const char *fmt, ...); + CHIP_ERROR VPutStringF(uint64_t tag, const char *fmt, va_list ap); + CHIP_ERROR PutNull(uint64_t tag); + CHIP_ERROR CopyElement(TLVReader& reader); + CHIP_ERROR CopyElement(uint64_t tag, TLVReader& reader); + + CHIP_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType); + CHIP_ERROR EndContainer(TLVType outerContainerType); + CHIP_ERROR OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter); + CHIP_ERROR CloseContainer(TLVWriter& containerWriter); + CHIP_ERROR PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen); + CHIP_ERROR CopyContainer(TLVReader& container); + CHIP_ERROR CopyContainer(uint64_t tag, TLVReader& container); + CHIP_ERROR CopyContainer(uint64_t tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen); + TLVType GetContainerType(void) const; + + uint32_t GetLengthWritten(void); + + uint32_t ImplicitProfileId; + void *AppData; + + typedef CHIP_ERROR (*GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, + uint32_t& bufLen); + GetNewBufferFunct GetNewBuffer; + + typedef CHIP_ERROR (*FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, + uint32_t bufLen); + FinalizeBufferFunct FinalizeBuffer; + + // Implementations of GetNewBufferFunct/FinalizeBufferFunct that support writing into one or more + // PacketBuffers. + static CHIP_ERROR GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen); + static CHIP_ERROR FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen); + +#if CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + static CHIP_ERROR GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen); + static CHIP_ERROR FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen); +#endif // CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + +protected: + uintptr_t mBufHandle; + uint8_t *mBufStart; + uint8_t *mWritePoint; + uint32_t mRemainingLen; + uint32_t mLenWritten; + uint32_t mMaxLen; + TLVType mContainerType; + +private: + bool mContainerOpen; + bool mCloseContainerReserved; + +protected: + bool IsContainerOpen(void) const { return mContainerOpen; } + void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; } + + enum { + kEndOfContainerMarkerSize = 1, /**< Size of the EndOfContainer marker, used in reserving space. */ + }; + + /** + * @brief + * Determine whether the container should reserve space for the + * CloseContainer symbol at the point of starting / opening the + * container. + */ + bool IsCloseContainerReserved(void) const { return mCloseContainerReserved; } + + /** + * @brief + * Set whether the container should reserve the space for the + * CloseContainer symbol at the point of starting / opening the + * container. + */ + void SetCloseContainerReserved(bool aCloseContainerReserved) { mCloseContainerReserved = aCloseContainerReserved; } + +#if CONFIG_HAVE_VCBPRINTF + static void CHIPTLVWriterPutcharCB(uint8_t c, void *appState); +#endif + CHIP_ERROR WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal); + CHIP_ERROR WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen); + CHIP_ERROR WriteData(const uint8_t *p, uint32_t len); +}; + +#if CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES +inline CHIP_ERROR TLVWriter::GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) +{ + return GetNewPacketBuffer(writer, bufHandle, bufStart, bufLen); +} + +inline CHIP_ERROR TLVWriter::FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen) +{ + return FinalizePacketBuffer(writer, bufHandle, bufStart, dataLen); +} +#endif // CHIP_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES + +/** + * Provides a unified Reader/Writer interface for editing/adding/deleting elements in TLV encoding. + * + * The TLVUpdater is a union of the TLVReader and TLVWriter objects and provides interface methods + * for editing/deleting data in an encoding as well as adding new elements to the TLV encoding. The + * TLVUpdater object essentially acts like two cursors, one for reading existing encoding and + * another for writing (either for copying over existing data or writing new data). + * + * Semantically, the TLVUpdater object functions like a union of the TLVReader and TLVWriter. The + * TLVUpdater methods have more or less similar meanings as similarly named counterparts in + * TLVReader/TLVWriter. Where there are differences in the semantics, the differences are clearly + * documented in the function's comment section in CHIPTLVUpdater.cpp. + * + * One particularly important note about the TLVUpdater's PutBytes() and PutString() methods is that + * it can leave the encoding in a corrupt state with only the element header written when an + * overflow occurs. Applications can call GetRemainingFreeLength() to make sure there is + * @em approximately enough free space to write the encoding. Note that GetRemainingFreeLength() + * only tells you the available free bytes and there is @em no way for the application to know the + * length of encoded data that gets written. In the event of an overflow, both PutBytes() and + * PutString() will return CHIP_ERROR_BUFFER_TOO_SMALL to the caller. + * + * Also, note that Next() method is overloaded to both skip the current element and also advance the + * internal reader to the next element. Because skipping already encoded elements requires changing + * the internal writer's free space state variables to account for the new freed space (made + * available by skipping), the application is expected to call Next() on the updater after a Get() + * method whose value it doesn't wish to write back (which is equivalent to skipping the current + * element). + * + * @note The application is expected to use the TLVUpdater object atomically from the time it calls + * Init() till it calls Finalize(). The same buffer should NOT be used with other TLVWriter objects. + * + * @note The TLVUpdater currently only supports single static buffers. Support for chain of buffers + * (PacketBuffer) is NOT supported. + */ +class DLL_EXPORT TLVUpdater +{ +public: + CHIP_ERROR Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen); + CHIP_ERROR Init(TLVReader& aReader, uint32_t freeLen); + CHIP_ERROR Finalize(void) { return mUpdaterWriter.Finalize(); } + + // Common methods + void SetImplicitProfileId(uint32_t profileId); + uint32_t GetImplicitProfileId(void) { return mUpdaterReader.ImplicitProfileId; } + CHIP_ERROR Move(void); + void MoveUntilEnd(void); + CHIP_ERROR EnterContainer(TLVType& outerContainerType); + CHIP_ERROR ExitContainer(TLVType outerContainerType); + void GetReader(TLVReader& containerReader) { containerReader = mUpdaterReader; } + + // Reader methods + CHIP_ERROR Next(void); + + CHIP_ERROR Get(bool& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(int8_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(int16_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(int32_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(int64_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(uint8_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(uint16_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(uint32_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(uint64_t& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(float& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR Get(double& v) { return mUpdaterReader.Get(v); } + CHIP_ERROR GetBytes(uint8_t *buf, uint32_t bufSize) { return mUpdaterReader.GetBytes(buf, bufSize); } + CHIP_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen) { return mUpdaterReader.DupBytes(buf, dataLen); } + CHIP_ERROR GetString(char *buf, uint32_t bufSize) { return mUpdaterReader.GetString(buf, bufSize); } + CHIP_ERROR DupString(char *& buf) { return mUpdaterReader.DupString(buf); } + + TLVType GetType(void) const { return mUpdaterReader.GetType(); } + uint64_t GetTag(void) const { return mUpdaterReader.GetTag(); } + uint32_t GetLength(void) const { return mUpdaterReader.GetLength(); } + CHIP_ERROR GetDataPtr(const uint8_t *& data) { return mUpdaterReader.GetDataPtr(data); } + CHIP_ERROR VerifyEndOfContainer(void) { return mUpdaterReader.VerifyEndOfContainer(); } + TLVType GetContainerType(void) const { return mUpdaterReader.GetContainerType(); } + uint32_t GetLengthRead(void) const { return mUpdaterReader.GetLengthRead(); } + uint32_t GetRemainingLength(void) const { return mUpdaterReader.GetRemainingLength(); } + + // Writer methods + CHIP_ERROR Put(uint64_t tag, int8_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, int16_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, int32_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, int64_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, uint8_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, uint16_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, uint32_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, uint64_t v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, int8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, int16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, int32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, int64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } + CHIP_ERROR Put(uint64_t tag, float v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR Put(uint64_t tag, double v) { return mUpdaterWriter.Put(tag, v); } + CHIP_ERROR PutBoolean(uint64_t tag, bool v) { return mUpdaterWriter.PutBoolean(tag, v); } + CHIP_ERROR PutNull(uint64_t tag) { return mUpdaterWriter.PutNull(tag); } + CHIP_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) { return mUpdaterWriter.PutBytes(tag, buf, len); } + CHIP_ERROR PutString(uint64_t tag, const char *buf) { return mUpdaterWriter.PutString(tag, buf); } + CHIP_ERROR PutString(uint64_t tag, const char *buf, uint32_t len) { return mUpdaterWriter.PutString(tag, buf, len); } + CHIP_ERROR CopyElement(TLVReader& reader) { return mUpdaterWriter.CopyElement(reader); } + CHIP_ERROR CopyElement(uint64_t tag, TLVReader& reader) { return mUpdaterWriter.CopyElement(tag, reader); } + CHIP_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) { return mUpdaterWriter.StartContainer(tag, containerType, outerContainerType); } + CHIP_ERROR EndContainer(TLVType outerContainerType) { return mUpdaterWriter.EndContainer(outerContainerType); } + uint32_t GetLengthWritten(void) { return mUpdaterWriter.GetLengthWritten(); } + uint32_t GetRemainingFreeLength(void) { return mUpdaterWriter.mRemainingLen; } + +private: + void AdjustInternalWriterFreeSpace(void); + +private: + TLVWriter mUpdaterWriter; + TLVReader mUpdaterReader; + const uint8_t * mElementStartAddr; +}; + +} // namespace TLV +} // namespace chip + +#endif /* CHIPTLV_H_ */ diff --git a/src/lib/core/WeaveTLVData.hpp b/src/lib/core/CHIPTLVData.hpp similarity index 60% rename from src/lib/core/WeaveTLVData.hpp rename to src/lib/core/CHIPTLVData.hpp index d6c7643d710204..e306d1666b7687 100644 --- a/src/lib/core/WeaveTLVData.hpp +++ b/src/lib/core/CHIPTLVData.hpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2015-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +17,7 @@ /** * @file - * This file contains macros to create static Weave TLV data. + * This file contains macros to create static CHIP TLV data. * * These macros are designed to be used in statically initializing a byte array * containing various TLV elements. TLVWriter can achieve similar functionality @@ -31,369 +30,369 @@ #define WEAVETLVDATA_H_ #include -#include +#include /* * @brief Integral truncate L to the least significant 32-bit * * @note Integral truncate would take the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_GetLower32From64(v) ((uint32_t)(((uint64_t)(v) >> 0) & 0xFFFFFFFFUL)) +#define CHIPTLV_GetLower32From64(v) ((uint32_t)(((uint64_t)(v) >> 0) & 0xFFFFFFFFUL)) /* * @brief Integral truncate argument X to the next least significant 32-bit * * @note Right bit shift gets rid of the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_GetUpper32From64(v) ((uint32_t)(((uint64_t)(v) >> 32) & 0xFFFFFFFFUL)) +#define CHIPTLV_GetUpper32From64(v) ((uint32_t)(((uint64_t)(v) >> 32) & 0xFFFFFFFFUL)) /* * @brief Integral truncate L to the least significant 16-bit * * @note Integral truncate would take the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_GetLower16From32(v) ((uint16_t)(((uint32_t)(v) >> 0) & 0xFFFFU)) +#define CHIPTLV_GetLower16From32(v) ((uint16_t)(((uint32_t)(v) >> 0) & 0xFFFFU)) /* * @brief Integral truncate argument X to the next least significant 16-bit * * @note Right bit shift gets rid of the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_GetUpper16From32(v) ((uint16_t)(((uint32_t)(v) >> 16) & 0xFFFFU)) +#define CHIPTLV_GetUpper16From32(v) ((uint16_t)(((uint32_t)(v) >> 16) & 0xFFFFU)) /* * @brief Integral truncate L to the least significant 8-bit * * @note Integral truncate would take the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_GetLower8From16(v) ((uint8_t)(((uint16_t)(v) >> 0) & 0xFFU)) +#define CHIPTLV_GetLower8From16(v) ((uint8_t)(((uint16_t)(v) >> 0) & 0xFFU)) /* * @brief Integral truncate argument X to the next least significant 8-bit * * @note Right bit shift gets rid of the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_GetUpper8From16(v) ((uint8_t)(((uint16_t)(v) >> 8) & 0xFFU)) +#define CHIPTLV_GetUpper8From16(v) ((uint8_t)(((uint16_t)(v) >> 8) & 0xFFU)) /* * @brief Integral truncate argument v to 8-bit * * @note Integral truncate would take the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_Serialize8(v) ((uint8_t)(v)) +#define CHIPTLV_Serialize8(v) ((uint8_t)(v)) /* - * @brief Integral truncate argument v to 16-bit, and then serialize it using Weave standard Little Endian order + * @brief Integral truncate argument v to 16-bit, and then serialize it using CHIP standard Little Endian order * * @note Integral truncate would preserve the least significant bits, regardless of hardware endianness. * Right bit shift gets rid of the least significant bits, regardless of hardware endianness. */ -#define nlWeaveTLV_Serialize16(v) nlWeaveTLV_GetLower8From16(v), nlWeaveTLV_GetUpper8From16(v) +#define CHIPTLV_Serialize16(v) CHIPTLV_GetLower8From16(v), CHIPTLV_GetUpper8From16(v) /* - * @brief Integral truncate argument v to 32-bit, and then serialize it using Weave standard Little Endian order + * @brief Integral truncate argument v to 32-bit, and then serialize it using CHIP standard Little Endian order */ -#define nlWeaveTLV_Serialize32(v) nlWeaveTLV_Serialize16(nlWeaveTLV_GetLower16From32(v)), nlWeaveTLV_Serialize16(nlWeaveTLV_GetUpper16From32(v)) +#define CHIPTLV_Serialize32(v) CHIPTLV_Serialize16(CHIPTLV_GetLower16From32(v)), CHIPTLV_Serialize16(CHIPTLV_GetUpper16From32(v)) /* - * @brief Integral truncate argument v to 64-bit, and then serialize it using Weave standard Little Endian order + * @brief Integral truncate argument v to 64-bit, and then serialize it using CHIP standard Little Endian order */ -#define nlWeaveTLV_Serialize64(v) nlWeaveTLV_Serialize32(nlWeaveTLV_GetLower32From64(v)), nlWeaveTLV_Serialize32(nlWeaveTLV_GetUpper32From64(v)) +#define CHIPTLV_Serialize64(v) CHIPTLV_Serialize32(CHIPTLV_GetLower32From64(v)), CHIPTLV_Serialize32(CHIPTLV_GetUpper32From64(v)) /* * @brief Specifies an anonymous TLV element, which doesn't have any tag */ -#define nlWeaveTLV_TAG_ANONYMOUS nl::Weave::TLV::kTLVTagControl_Anonymous +#define CHIPTLV_TAG_ANONYMOUS CHIP::TLV::kTLVTagControl_Anonymous /* * @brief Specifies a TLV element with a context-specific tag * @param Tag The context-specific tag for this TLV element. Would be truncated to 8 bits. */ -#define nlWeaveTLV_TAG_CONTEXT_SPECIFIC(Tag) nl::Weave::TLV::kTLVTagControl_ContextSpecific, nlWeaveTLV_Serialize8(Tag) +#define CHIPTLV_TAG_CONTEXT_SPECIFIC(Tag) CHIP::TLV::kTLVTagControl_ContextSpecific, CHIPTLV_Serialize8(Tag) /* * @brief Specifies a TLV element with a Common Profile tag * @param Tag The tag for this TLV element, defined under Common Profile. * Would be truncated to 16 bites. */ -#define nlWeaveTLV_TAG_COMMON_PROFILE_2Bytes(Tag) \ - nl::Weave::TLV::kTLVTagControl_CommonProfile_2Bytes, nlWeaveTLV_Serialize16(Tag) +#define CHIPTLV_TAG_COMMON_PROFILE_2Bytes(Tag) \ + CHIP::TLV::kTLVTagControl_CommonProfile_2Bytes, CHIPTLV_Serialize16(Tag) /* * @brief Specifies a TLV element with a Common Profile tag * @param Tag The tag for this TLV element, defined under Common Profile. * Would be truncated to 32 bites. */ -#define nlWeaveTLV_TAG_COMMON_PROFILE_4Bytes(Tag) \ - nl::Weave::TLV::kTLVTagControl_CommonProfile_4Bytes, nlWeaveTLV_Serialize32(Tag) +#define CHIPTLV_TAG_COMMON_PROFILE_4Bytes(Tag) \ + CHIP::TLV::kTLVTagControl_CommonProfile_4Bytes, CHIPTLV_Serialize32(Tag) /* * @brief Specifies a TLV element with an Implicit Profile tag * @param Tag The tag for this TLV element, defined under the current implicit profile. * Would be truncated to 16 bits. */ -#define nlWeaveTLV_TAG_IMPLICIT_PROFILE_2Bytes(Tag) \ - nl::Weave::TLV::kTLVTagControl_ImplicitProfile_2Bytes, nlWeaveTLV_Serialize16(Tag) +#define CHIPTLV_TAG_IMPLICIT_PROFILE_2Bytes(Tag) \ + CHIP::TLV::kTLVTagControl_ImplicitProfile_2Bytes, CHIPTLV_Serialize16(Tag) /* * @brief Specifies a TLV element with an Implicit Profile tag * @param Tag The tag for this TLV element, defined under the current implicit profile. * Would be truncated to 32 bits. */ -#define nlWeaveTLV_TAG_IMPLICIT_PROFILE_4Bytes(Tag) \ - nl::Weave::TLV::kTLVTagControl_ImplicitProfile_4Bytes, nlWeaveTLV_Serialize32(Tag) +#define CHIPTLV_TAG_IMPLICIT_PROFILE_4Bytes(Tag) \ + CHIP::TLV::kTLVTagControl_ImplicitProfile_4Bytes, CHIPTLV_Serialize32(Tag) /* * @brief Specifies a TLV element with a Fully Qualified tag - * @param ProfileId {Vendor ID, Profile Number}, as in #WeaveProfileId + * @param ProfileId {Vendor ID, Profile Number}, as in #CHIPProfileId * @param Tag The tag for this TLV element, defined under ProfileId. * Would be truncated to 16 bits. */ -#define nlWeaveTLV_TAG_FULLY_QUALIFIED_6Bytes(ProfileId, Tag) \ - nl::Weave::TLV::kTLVTagControl_FullyQualified_6Bytes, nlWeaveTLV_Serialize16(ProfileId >> 16), nlWeaveTLV_Serialize16(ProfileId), nlWeaveTLV_Serialize16(Tag) +#define CHIPTLV_TAG_FULLY_QUALIFIED_6Bytes(ProfileId, Tag) \ + CHIP::TLV::kTLVTagControl_FullyQualified_6Bytes, CHIPTLV_Serialize16(ProfileId >> 16), CHIPTLV_Serialize16(ProfileId), CHIPTLV_Serialize16(Tag) /* * @brief Specifies a TLV element with a Fully Qualified tag - * @param ProfileId {Vendor ID, Profile Number}, as in #WeaveProfileId + * @param ProfileId {Vendor ID, Profile Number}, as in #CHIPProfileId * @param Tag The tag for this TLV element, defined under ProfileId. * Would be truncated to 32 bits. */ -#define nlWeaveTLV_TAG_FULLY_QUALIFIED_8Bytes(ProfileId, Tag) \ - nl::Weave::TLV::kTLVTagControl_FullyQualified_8Bytes, nlWeaveTLV_Serialize16(ProfileId >> 16), nlWeaveTLV_Serialize16(ProfileId), nlWeaveTLV_Serialize32(Tag) +#define CHIPTLV_TAG_FULLY_QUALIFIED_8Bytes(ProfileId, Tag) \ + CHIP::TLV::kTLVTagControl_FullyQualified_8Bytes, CHIPTLV_Serialize16(ProfileId >> 16), CHIPTLV_Serialize16(ProfileId), CHIPTLV_Serialize32(Tag) /* * @brief Specifies a NULL TLV element, which has just the tag but no value - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ */ -#define nlWeaveTLV_NULL(TagSpec) nl::Weave::TLV::kTLVElementType_Null | TagSpec +#define CHIPTLV_NULL(TagSpec) CHIP::TLV::kTLVElementType_Null | TagSpec /* * @brief Specifies a Structure TLV element, marking the beginning of a Structure - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ */ -#define nlWeaveTLV_STRUCTURE(TagSpec) nl::Weave::TLV::kTLVElementType_Structure | TagSpec +#define CHIPTLV_STRUCTURE(TagSpec) CHIP::TLV::kTLVElementType_Structure | TagSpec /* * @brief Specifies a Array TLV element, marking the beginning of an Array - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ */ -#define nlWeaveTLV_ARRAY(TagSpec) nl::Weave::TLV::kTLVElementType_Array | TagSpec +#define CHIPTLV_ARRAY(TagSpec) CHIP::TLV::kTLVElementType_Array | TagSpec /* * @brief Specifies a Path TLV element, marking the beginning of a Path - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ */ -#define nlWeaveTLV_PATH(TagSpec) nl::Weave::TLV::kTLVElementType_Path | TagSpec +#define CHIPTLV_PATH(TagSpec) CHIP::TLV::kTLVElementType_Path | TagSpec /* * @brief Specifies a Boolean TLV element, which can be either true or false - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Should be either true or false */ -#define nlWeaveTLV_BOOL(TagSpec, Value) \ - ((Value) ? nl::Weave::TLV::kTLVElementType_BooleanTrue : nl::Weave::TLV::kTLVElementType_BooleanFalse) | TagSpec +#define CHIPTLV_BOOL(TagSpec, Value) \ + ((Value) ? CHIP::TLV::kTLVElementType_BooleanTrue : CHIP::TLV::kTLVElementType_BooleanFalse) | TagSpec /** * @brief * Specifies a Single Precision Floating Point TLV element, marking the beginning of 32-bit data * - * @param TagSpec Should be filled with macros beginning with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros beginning with CHIPTLV_TAG_ * * @param ... Bytes representing the floating point value to serialize */ -#define nlWeaveTLV_FLOAT32(TagSpec, ...) \ - nl::Weave::TLV::kTLVElementType_FloatingPointNumber32 | TagSpec, ## __VA_ARGS__ +#define CHIPTLV_FLOAT32(TagSpec, ...) \ + CHIP::TLV::kTLVElementType_FloatingPointNumber32 | TagSpec, ## __VA_ARGS__ /** * @brief * Specifies a Double Precision Floating Point TLV element, marking the beginning of 64-bit data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param ... Bytes representing the floating point value to serialize */ -#define nlWeaveTLV_FLOAT64(TagSpec, ...) \ - nl::Weave::TLV::kTLVElementType_FloatingPointNumber64 | TagSpec, ## __VA_ARGS__ +#define CHIPTLV_FLOAT64(TagSpec, ...) \ + CHIP::TLV::kTLVElementType_FloatingPointNumber64 | TagSpec, ## __VA_ARGS__ /* * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path */ -#define nlWeaveTLV_END_OF_CONTAINER nl::Weave::TLV::kTLVElementType_EndOfContainer | nl::Weave::TLV::kTLVTagControl_Anonymous +#define CHIPTLV_END_OF_CONTAINER CHIP::TLV::kTLVElementType_EndOfContainer | CHIP::TLV::kTLVTagControl_Anonymous /* * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path */ -#define nlWeaveTLV_END_OF_STRUCTURE nlWeaveTLV_END_OF_CONTAINER +#define CHIPTLV_END_OF_STRUCTURE CHIPTLV_END_OF_CONTAINER /* * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path */ -#define nlWeaveTLV_END_OF_ARRAY nlWeaveTLV_END_OF_CONTAINER +#define CHIPTLV_END_OF_ARRAY CHIPTLV_END_OF_CONTAINER /* * @brief Specifies a EndOfContainer TLV element, marking the end of a Structure, Array, or Path */ -#define nlWeaveTLV_END_OF_PATH nlWeaveTLV_END_OF_CONTAINER +#define CHIPTLV_END_OF_PATH CHIPTLV_END_OF_CONTAINER /* * @brief Specifies an 8-bit Signed Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to int8_t, and then serialized */ -#define nlWeaveTLV_INT8(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int8 | TagSpec, nlWeaveTLV_Serialize8(int8_t(Value)) +#define CHIPTLV_INT8(TagSpec, Value) CHIP::TLV::kTLVElementType_Int8 | TagSpec, CHIPTLV_Serialize8(int8_t(Value)) /* * @brief Specifies a 16-bit Signed Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to int16_t, and then serialized */ -#define nlWeaveTLV_INT16(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int16 | TagSpec, nlWeaveTLV_Serialize16(int16_t(Value)) +#define CHIPTLV_INT16(TagSpec, Value) CHIP::TLV::kTLVElementType_Int16 | TagSpec, CHIPTLV_Serialize16(int16_t(Value)) /* * @brief Specifies a 32-bit Signed Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to int32_t, and then serialized */ -#define nlWeaveTLV_INT32(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int32 | TagSpec, nlWeaveTLV_Serialize32(int32_t(Value)) +#define CHIPTLV_INT32(TagSpec, Value) CHIP::TLV::kTLVElementType_Int32 | TagSpec, CHIPTLV_Serialize32(int32_t(Value)) /* * @brief Specifies a 32-bit Signed Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to int64_t, and then serialized */ -#define nlWeaveTLV_INT64(TagSpec, Value) nl::Weave::TLV::kTLVElementType_Int64 | TagSpec, nlWeaveTLV_Serialize64(int64_t(Value)) +#define CHIPTLV_INT64(TagSpec, Value) CHIP::TLV::kTLVElementType_Int64 | TagSpec, CHIPTLV_Serialize64(int64_t(Value)) /* * @brief Specifies an 8-bit Unsigned Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to (uint8_t), and then serialized */ -#define nlWeaveTLV_UINT8(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt8 | TagSpec, nlWeaveTLV_Serialize8((uint8_t)(Value)) +#define CHIPTLV_UINT8(TagSpec, Value) CHIP::TLV::kTLVElementType_UInt8 | TagSpec, CHIPTLV_Serialize8((uint8_t)(Value)) /* * @brief Specifies a 16-bit Unsigned Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to (uint16_t), and then serialized */ -#define nlWeaveTLV_UINT16(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt16 | TagSpec, nlWeaveTLV_Serialize16((uint16_t)(Value)) +#define CHIPTLV_UINT16(TagSpec, Value) CHIP::TLV::kTLVElementType_UInt16 | TagSpec, CHIPTLV_Serialize16((uint16_t)(Value)) /* * @brief Specifies a 32-bit Unsigned Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to (uint32_t), and then serialized */ -#define nlWeaveTLV_UINT32(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt32 | TagSpec, nlWeaveTLV_Serialize32((uint32_t)(Value)) +#define CHIPTLV_UINT32(TagSpec, Value) CHIP::TLV::kTLVElementType_UInt32 | TagSpec, CHIPTLV_Serialize32((uint32_t)(Value)) /* * @brief Specifies a 64-bit Unsigned Integer TLV element - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * @param Value Would be first converted to (uint64_t), and then serialized */ -#define nlWeaveTLV_UINT64(TagSpec, Value) nl::Weave::TLV::kTLVElementType_UInt64 | TagSpec, nlWeaveTLV_Serialize64((uint64_t)(Value)) +#define CHIPTLV_UINT64(TagSpec, Value) CHIP::TLV::kTLVElementType_UInt64 | TagSpec, CHIPTLV_Serialize64((uint64_t)(Value)) /** * @brief * Specifies an UTF8 String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x100 * * @param ... Bytes representing the string characters to serialize */ -#define nlWeaveTLV_UTF8_STRING_1ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_UTF8String_1ByteLength | TagSpec, nlWeaveTLV_Serialize8((uint8_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_UTF8_STRING_1ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_UTF8String_1ByteLength | TagSpec, CHIPTLV_Serialize8((uint8_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies an UTF8 String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x10000 * * @param ... Bytes representing the string characters to serialize */ -#define nlWeaveTLV_UTF8_STRING_2ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_UTF8String_2ByteLength | TagSpec, nlWeaveTLV_Serialize16((uint16_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_UTF8_STRING_2ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_UTF8String_2ByteLength | TagSpec, CHIPTLV_Serialize16((uint16_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies an UTF8 String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x100000000 * * @param ... Bytes representing the string characters to serialize */ -#define nlWeaveTLV_UTF8_STRING_4ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_UTF8String_4ByteLength | TagSpec, nlWeaveTLV_Serialize32((uint32_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_UTF8_STRING_4ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_UTF8String_4ByteLength | TagSpec, CHIPTLV_Serialize32((uint32_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies an UTF8 String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x10000000000000000 * * @param ... Bytes representing the string characters to serialize */ -#define nlWeaveTLV_UTF8_STRING_8ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_UTF8String_8ByteLength | TagSpec, nlWeaveTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_UTF8_STRING_8ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_UTF8String_8ByteLength | TagSpec, CHIPTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies a BYTE String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x100 * * @param ... Bytes to serialize */ -#define nlWeaveTLV_BYTE_STRING_1ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_ByteString_1ByteLength | TagSpec, nlWeaveTLV_Serialize8((uint8_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_BYTE_STRING_1ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_ByteString_1ByteLength | TagSpec, CHIPTLV_Serialize8((uint8_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies a BYTE String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x10000 * * @param ... Bytes to serialize */ -#define nlWeaveTLV_BYTE_STRING_2ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_ByteString_2ByteLength | TagSpec, nlWeaveTLV_Serialize16((uint16_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_BYTE_STRING_2ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_ByteString_2ByteLength | TagSpec, CHIPTLV_Serialize16((uint16_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies a BYTE String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x100000000 * * @param ... Bytes to serialize */ -#define nlWeaveTLV_BYTE_STRING_4ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_ByteString_4ByteLength | TagSpec, nlWeaveTLV_Serialize32((uint32_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_BYTE_STRING_4ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_ByteString_4ByteLength | TagSpec, CHIPTLV_Serialize32((uint32_t)(StringLength)), ## __VA_ARGS__ /** * @brief * Specifies a BYTE String TLV element, marking the beginning of String data * - * @param TagSpec Should be filled with macros begin with nlWeaveTLV_TAG_ + * @param TagSpec Should be filled with macros begin with CHIPTLV_TAG_ * * @param StringLength Number of bytes in this string, must be less than 0x10000000000000000 * * @param ... Bytes to serialize */ -#define nlWeaveTLV_BYTE_STRING_8ByteLength(TagSpec, StringLength, ...) \ - nl::Weave::TLV::kTLVElementType_ByteString_8ByteLength | TagSpec, nlWeaveTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ +#define CHIPTLV_BYTE_STRING_8ByteLength(TagSpec, StringLength, ...) \ + CHIP::TLV::kTLVElementType_ByteString_8ByteLength | TagSpec, CHIPTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ #endif /* WEAVETLVDATA_H_ */ diff --git a/src/lib/core/WeaveTLVDebug.cpp b/src/lib/core/CHIPTLVDebug.cpp similarity index 83% rename from src/lib/core/WeaveTLVDebug.cpp rename to src/lib/core/CHIPTLVDebug.cpp index b5c12103b2815f..8bf621636b2bb3 100644 --- a/src/lib/core/WeaveTLVDebug.cpp +++ b/src/lib/core/CHIPTLVDebug.cpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2015-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +18,7 @@ /** * @file * This file implements interfaces for debugging and logging - * Weave TLV. + * CHIP TLV. * */ @@ -31,15 +30,13 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -namespace nl { - -namespace Weave { +namespace chip { namespace TLV { @@ -63,7 +60,7 @@ static void DumpHandler(DumpWriter aWriter, const char *aIndent, const TLVReader const uint64_t tag = aReader.GetTag(); const uint32_t len = aReader.GetLength(); const uint8_t *strbuf = NULL; - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; TLVReader temp; TLVTagControl tagControl; @@ -114,40 +111,40 @@ static void DumpHandler(DumpWriter aWriter, const char *aIndent, const TLVReader case kTLVType_SignedInteger: int64_t sVal; err = temp.Get(sVal); - VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_SignedInteger")); + VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_SignedInteger")); aWriter("%" PRIi64, sVal); break; case kTLVType_UnsignedInteger: uint64_t uVal; err = temp.Get(uVal); - VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_UnsignedInteger")); + VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_UnsignedInteger")); aWriter("%" PRIu64, uVal); break; case kTLVType_Boolean: bool bVal; err = temp.Get(bVal); - VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_Boolean")); + VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_Boolean")); aWriter("%s", bVal ? "true" : "false"); break; case kTLVType_FloatingPointNumber: double fpVal; err = temp.Get(fpVal); - VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_FloatingPointNumber")); + VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_FloatingPointNumber")); aWriter("%lf", fpVal); break; case kTLVType_UTF8String: err = temp.GetDataPtr(strbuf); - VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_UTF8String")); + VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_UTF8String")); aWriter("\"%-.*s\"", static_cast(len), strbuf); break; case kTLVType_ByteString: err = temp.GetDataPtr(strbuf); - VerifyOrExit(err == WEAVE_NO_ERROR, aWriter("Error in kTLVType_ByteString")); + VerifyOrExit(err == CHIP_NO_ERROR, aWriter("Error in kTLVType_ByteString")); aWriter("%p\n", strbuf); break; @@ -306,14 +303,14 @@ const char *DecodeType(const TLVType aType) * @param[in] aReader A read-only reference to the TLV reader containing * the TLV data to log. * - * @retval #WEAVE_NO_ERROR Unconditionally. + * @retval #CHIP_NO_ERROR Unconditionally. * */ -WEAVE_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader) +CHIP_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader) { const char * tabs = ""; const size_t depth = 0; - WEAVE_ERROR retval = WEAVE_NO_ERROR; + CHIP_ERROR retval = CHIP_NO_ERROR; DumpHandler(aWriter, tabs, aReader, depth); @@ -328,23 +325,23 @@ WEAVE_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader) * @param[in] aDepth The current depth into the TLV data. * @param[inout] aContext A pointer to the handler-specific context. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If aContext is NULL or if + * @retval #CHIP_ERROR_INVALID_ARGUMENT If aContext is NULL or if * aContext->mWriter is NULL. * */ -WEAVE_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext) +CHIP_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext) { static const char indent[] = " "; - WEAVE_ERROR retval = WEAVE_NO_ERROR; + CHIP_ERROR retval = CHIP_NO_ERROR; DumpContext * context; - VerifyOrExit(aContext != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(aContext != NULL, retval = CHIP_ERROR_INVALID_ARGUMENT); context = static_cast(aContext); - VerifyOrExit(context->mWriter != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(context->mWriter != NULL, retval = CHIP_ERROR_INVALID_ARGUMENT); DumpHandler(context->mWriter, indent, @@ -364,14 +361,14 @@ WEAVE_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext) * * @param[in] aWriter A dump writer to log the TLV data of the TLV reader. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * */ -WEAVE_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter) +CHIP_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter) { void * context = NULL; DumpContext dumpContext = { aWriter, context }; - WEAVE_ERROR retval; + CHIP_ERROR retval; retval = Utilities::Iterate(aReader, DumpHandler, &dumpContext); @@ -382,6 +379,4 @@ WEAVE_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter) } // namespace TLV -} // namespace Weave - -} // namespace nl +} // namespace chip diff --git a/src/lib/core/WeaveTLVDebug.hpp b/src/lib/core/CHIPTLVDebug.hpp similarity index 82% rename from src/lib/core/WeaveTLVDebug.hpp rename to src/lib/core/CHIPTLVDebug.hpp index 2e575ef9c97be0..44bf3c8873d039 100644 --- a/src/lib/core/WeaveTLVDebug.hpp +++ b/src/lib/core/CHIPTLVDebug.hpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2015-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +18,7 @@ /** * @file * This file defines types and interfaces for debugging and - * logging Weave TLV. + * logging CHIP TLV. * */ @@ -29,21 +28,19 @@ #include #include -#include -#include +#include +#include -namespace nl { - -namespace Weave { +namespace CHIP { namespace TLV { /** - * @namespace nl::Weave::TLV::Debug + * @namespace CHIP::TLV::Debug * * @brief * This namespace includes types and interfaces for debugging and - * logging Weave TLV. + * logging CHIP TLV. * */ namespace Debug { @@ -69,8 +66,6 @@ extern WEAVE_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter); } // namespace TLV -} // namespace Weave - -} // namespace nl +} // namespace CHIP #endif // WEAVETLVDEBUG_HPP diff --git a/src/lib/core/WeaveTLVReader.cpp b/src/lib/core/CHIPTLVReader.cpp similarity index 76% rename from src/lib/core/WeaveTLVReader.cpp rename to src/lib/core/CHIPTLVReader.cpp index 4d06134a1b6d96..a3f847e07e2b11 100644 --- a/src/lib/core/WeaveTLVReader.cpp +++ b/src/lib/core/CHIPTLVReader.cpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2013-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,22 +17,21 @@ /** * @file - * This file implements a parser for the Weave TLV (Tag-Length-Value) encoding format. + * This file implements a parser for the CHIP TLV (Tag-Length-Value) encoding format. * */ #include -#include -#include -#include -#include +#include +#include +#include +#include -namespace nl { -namespace Weave { +namespace chip { namespace TLV { -using namespace nl::Weave::Encoding; +using namespace chip::Encoding; static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 }; @@ -83,7 +81,7 @@ static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 }; * on the context of the application or protocol being spoken. * * If an implicitly-encoded tag is encountered while @p ImplicitProfileId is set to - * kProfileIdNotSpecified, the reader will return a #WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG error. + * kProfileIdNotSpecified, the reader will return a #CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG error. */ /** @@ -93,7 +91,7 @@ static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 }; */ /** - * @typedef WEAVE_ERROR (*TLVReader::GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, uint32_t& bufLen) + * @typedef CHIP_ERROR (*TLVReader::GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, uint32_t& bufLen) * * A function that can be used to retrieve additional TLV data to be parsed. * @@ -116,9 +114,9 @@ static const uint8_t sTagSizes[] = { 0, 1, 2, 4, 2, 4, 6, 8 }; * input TLV data has been reached, the function should set this value * to 0. * - * @retval #WEAVE_NO_ERROR If the function successfully produced more TLV data, or the end of + * @retval #CHIP_NO_ERROR If the function successfully produced more TLV data, or the end of * the input data was reached (@p bufLen should be set to 0 in this case). - * @retval other Other Weave or platform-specific error codes indicating that an error + * @retval other Other CHIP or platform-specific error codes indicating that an error * occurred preventing the function from producing the requested data. * */ @@ -336,12 +334,12 @@ uint32_t TLVReader::GetLength() const * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV boolean type, or the + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV boolean type, or the * reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(bool& v) +CHIP_ERROR TLVReader::Get(bool& v) { TLVElementType elemType = ElementType(); if (elemType == kTLVElementType_BooleanFalse) @@ -349,8 +347,8 @@ WEAVE_ERROR TLVReader::Get(bool& v) else if (elemType == kTLVElementType_BooleanTrue) v = true; else - return WEAVE_ERROR_WRONG_TLV_TYPE; - return WEAVE_NO_ERROR; + return CHIP_ERROR_WRONG_TLV_TYPE; + return CHIP_NO_ERROR; } /** @@ -361,15 +359,15 @@ WEAVE_ERROR TLVReader::Get(bool& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(int8_t& v) +CHIP_ERROR TLVReader::Get(int8_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -382,15 +380,15 @@ WEAVE_ERROR TLVReader::Get(int8_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(int16_t& v) +CHIP_ERROR TLVReader::Get(int16_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -403,15 +401,15 @@ WEAVE_ERROR TLVReader::Get(int16_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(int32_t& v) +CHIP_ERROR TLVReader::Get(int32_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -424,15 +422,15 @@ WEAVE_ERROR TLVReader::Get(int32_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(int64_t& v) +CHIP_ERROR TLVReader::Get(int64_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -446,15 +444,15 @@ WEAVE_ERROR TLVReader::Get(int64_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(uint8_t& v) +CHIP_ERROR TLVReader::Get(uint8_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -468,15 +466,15 @@ WEAVE_ERROR TLVReader::Get(uint8_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(uint16_t& v) +CHIP_ERROR TLVReader::Get(uint16_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -490,15 +488,15 @@ WEAVE_ERROR TLVReader::Get(uint16_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(uint32_t& v) +CHIP_ERROR TLVReader::Get(uint32_t& v) { uint64_t v64 = 0; - WEAVE_ERROR err = Get(v64); + CHIP_ERROR err = Get(v64); v = v64; return err; } @@ -510,12 +508,12 @@ WEAVE_ERROR TLVReader::Get(uint32_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV integer type (signed or * unsigned), or the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(uint64_t& v) +CHIP_ERROR TLVReader::Get(uint64_t& v) { switch (ElementType()) { @@ -536,9 +534,9 @@ WEAVE_ERROR TLVReader::Get(uint64_t& v) v = mElemLenOrVal; break; default: - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -546,12 +544,12 @@ WEAVE_ERROR TLVReader::Get(uint64_t& v) * * @param[out] v Receives the value associated with current TLV element. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV floating point type, or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV floating point type, or * the reader is not positioned on an element. * */ -WEAVE_ERROR TLVReader::Get(double& v) +CHIP_ERROR TLVReader::Get(double& v) { switch (ElementType()) { @@ -578,9 +576,9 @@ WEAVE_ERROR TLVReader::Get(double& v) break; } default: - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -593,33 +591,33 @@ WEAVE_ERROR TLVReader::Get(double& v) * @param[in] buf A pointer to a buffer to receive the string data. * @param[in] bufSize The size in bytes of the buffer pointed to by @p buf. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or * the reader is not positioned on an element. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If the supplied buffer is too small to hold the data associated * with the current element. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::GetBytes(uint8_t *buf, uint32_t bufSize) +CHIP_ERROR TLVReader::GetBytes(uint8_t *buf, uint32_t bufSize) { if (!TLVTypeIsString(ElementType())) - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; if (mElemLenOrVal > bufSize) - return WEAVE_ERROR_BUFFER_TOO_SMALL; + return CHIP_ERROR_BUFFER_TOO_SMALL; - WEAVE_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal); - if (err != WEAVE_NO_ERROR) + CHIP_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal); + if (err != CHIP_NO_ERROR) return err; mElemLenOrVal = 0; - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -632,25 +630,25 @@ WEAVE_ERROR TLVReader::GetBytes(uint8_t *buf, uint32_t bufSize) * @param[in] buf A pointer to a buffer to receive the byte string data. * @param[in] bufSize The size in bytes of the buffer pointed to by @p buf. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or * the reader is not positioned on an element. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If the supplied buffer is too small to hold the data associated * with the current element. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::GetString(char *buf, uint32_t bufSize) +CHIP_ERROR TLVReader::GetString(char *buf, uint32_t bufSize) { if (!TLVTypeIsString(ElementType())) - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; if ((mElemLenOrVal + 1) > bufSize) - return WEAVE_ERROR_BUFFER_TOO_SMALL; + return CHIP_ERROR_BUFFER_TOO_SMALL; buf[mElemLenOrVal] = 0; @@ -671,30 +669,30 @@ WEAVE_ERROR TLVReader::GetString(char *buf, uint32_t bufSize) * @param[out] dataLen A reference to storage for the size, in bytes, of @p buf on * success. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or * the reader is not positioned on an element. - * @retval #WEAVE_ERROR_NO_MEMORY If memory could not be allocated for the output buffer. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE + * @retval #CHIP_ERROR_NO_MEMORY If memory could not be allocated for the output buffer. + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE * If the target platform does not support malloc() and free(). - * @retval other Other Weave or platform error codes returned by the configured + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer * is non-NULL. * */ -WEAVE_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t& dataLen) +CHIP_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t& dataLen) { #if HAVE_MALLOC && HAVE_FREE if (!TLVTypeIsString(ElementType())) - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; buf = (uint8_t *) malloc(mElemLenOrVal); if (buf == NULL) - return WEAVE_ERROR_NO_MEMORY; + return CHIP_ERROR_NO_MEMORY; - WEAVE_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal); - if (err != WEAVE_NO_ERROR) + CHIP_ERROR err = ReadData(buf, (uint32_t) mElemLenOrVal); + if (err != CHIP_NO_ERROR) { free(buf); return err; @@ -703,9 +701,9 @@ WEAVE_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t& dataLen) dataLen = mElemLenOrVal; mElemLenOrVal = 0; - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; #else - return WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE; + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; #endif // HAVE_MALLOC && HAVE_FREE } @@ -720,30 +718,30 @@ WEAVE_ERROR TLVReader::DupBytes(uint8_t *& buf, uint32_t& dataLen) * @param[out] buf A reference to a pointer to which a heap-allocated buffer of * will be assigned on success. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or * the reader is not positioned on an element. - * @retval #WEAVE_ERROR_NO_MEMORY If memory could not be allocated for the output buffer. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE + * @retval #CHIP_ERROR_NO_MEMORY If memory could not be allocated for the output buffer. + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE * If the target platform does not support malloc() and free(). - * @retval other Other Weave or platform error codes returned by the configured + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer * is non-NULL. * */ -WEAVE_ERROR TLVReader::DupString(char *& buf) +CHIP_ERROR TLVReader::DupString(char *& buf) { #if HAVE_MALLOC && HAVE_FREE if (!TLVTypeIsString(ElementType())) - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; buf = (char *) malloc(mElemLenOrVal + 1); if (buf == NULL) - return WEAVE_ERROR_NO_MEMORY; + return CHIP_ERROR_NO_MEMORY; - WEAVE_ERROR err = ReadData((uint8_t *) buf, (uint32_t) mElemLenOrVal); - if (err != WEAVE_NO_ERROR) + CHIP_ERROR err = ReadData((uint8_t *) buf, (uint32_t) mElemLenOrVal); + if (err != CHIP_NO_ERROR) { free(buf); return err; @@ -754,7 +752,7 @@ WEAVE_ERROR TLVReader::DupString(char *& buf) return err; #else - return WEAVE_ERROR_UNSUPPORTED_WEAVE_FEATURE; + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; #endif // HAVE_MALLOC && HAVE_FREE } @@ -763,32 +761,32 @@ WEAVE_ERROR TLVReader::DupString(char *& buf) * * This method returns a direct pointer the encoded string value within the underlying input buffer. * To succeed, the method requires that the entirety of the string value be present in a single buffer. - * Otherwise the method returns #WEAVE_ERROR_TLV_UNDERRUN. This makes the method of limited use when + * Otherwise the method returns #CHIP_ERROR_TLV_UNDERRUN. This makes the method of limited use when * reading data from multiple discontiguous buffers. * * @param[out] data A reference to a const pointer that will receive a pointer to * the underlying string data. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or the + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the current element is not a TLV byte or UTF8 string, or the * reader is not positioned on an element. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely or the value + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely or the value * of the current string element is not contained within a single * contiguous buffer. - * @retval other Other Weave or platform error codes returned by the configured + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::GetDataPtr(const uint8_t *& data) +CHIP_ERROR TLVReader::GetDataPtr(const uint8_t *& data) { - WEAVE_ERROR err; + CHIP_ERROR err; if (!TLVTypeIsString(ElementType())) - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; - err = EnsureData(WEAVE_ERROR_TLV_UNDERRUN); - if (err != WEAVE_NO_ERROR) + err = EnsureData(CHIP_ERROR_TLV_UNDERRUN); + if (err != CHIP_NO_ERROR) return err; uint32_t remainingLen = mBufEnd - mReadPoint; @@ -796,11 +794,11 @@ WEAVE_ERROR TLVReader::GetDataPtr(const uint8_t *& data) // Verify that the entirety of the data is available in the buffer. // Note that this may not be possible if the reader is reading from a chain of buffers. if (remainingLen < (uint32_t)mElemLenOrVal) - return WEAVE_ERROR_TLV_UNDERRUN; + return CHIP_ERROR_TLV_UNDERRUN; data = mReadPoint; - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -815,7 +813,7 @@ WEAVE_ERROR TLVReader::GetDataPtr(const uint8_t *& data) * * When the OpenContainer() method returns, the container reader is positioned immediately before the * first member of the container. Calling Next() on the container reader will advance through the members - * of the collection until the end is reached, at which point the reader will return WEAVE_END_OF_TLV. + * of the collection until the end is reached, at which point the reader will return CHIP_END_OF_TLV. * * While the container reader is open, applications must not make calls on or otherwise alter the state * of the parent reader. Once an application has finished using the container reader it must close it @@ -837,15 +835,15 @@ WEAVE_ERROR TLVReader::GetDataPtr(const uint8_t *& data) * reading the members of the current container element. Any data * associated with the supplied object is overwritten. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE If the current element is not positioned on a container element. + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE If the current element is not positioned on a container element. * */ -WEAVE_ERROR TLVReader::OpenContainer(TLVReader& containerReader) +CHIP_ERROR TLVReader::OpenContainer(TLVReader& containerReader) { TLVElementType elemType = ElementType(); if (!TLVTypeIsContainer(elemType)) - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; containerReader.mBufHandle = mBufHandle; containerReader.mReadPoint = mReadPoint; @@ -861,7 +859,7 @@ WEAVE_ERROR TLVReader::OpenContainer(TLVReader& containerReader) SetContainerOpen(true); - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -883,32 +881,32 @@ WEAVE_ERROR TLVReader::OpenContainer(TLVReader& containerReader) * @param[in] containerReader A reference to the TLVReader object that was supplied to the * OpenContainer() method. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if * the container reader does not match the one passed to the * OpenContainer() method. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the reader encountered an invalid or unsupported TLV * element type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::CloseContainer(TLVReader& containerReader) +CHIP_ERROR TLVReader::CloseContainer(TLVReader& containerReader) { - WEAVE_ERROR err; + CHIP_ERROR err; if (!IsContainerOpen()) - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; if ((TLVElementType) containerReader.mContainerType != ElementType()) - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; err = containerReader.SkipToEndOfContainer(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; mBufHandle = containerReader.mBufHandle; @@ -918,7 +916,7 @@ WEAVE_ERROR TLVReader::CloseContainer(TLVReader& containerReader) mMaxLen = containerReader.mMaxLen; ClearElementState(); - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -934,7 +932,7 @@ WEAVE_ERROR TLVReader::CloseContainer(TLVReader& containerReader) * * When the EnterContainer() method returns, the reader is positioned immediately @em before the * first member of the container. Repeatedly calling Next() will advance the reader through the members - * of the collection until the end is reached, at which point the reader will return WEAVE_END_OF_TLV. + * of the collection until the end is reached, at which point the reader will return CHIP_END_OF_TLV. * * Once the application has finished reading a container it can continue reading the elements after * the container by calling the ExitContainer() method. @@ -942,15 +940,15 @@ WEAVE_ERROR TLVReader::CloseContainer(TLVReader& containerReader) * @param[out] outerContainerType A reference to a TLVType value that will receive the context * of the reader. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE If the current element is not positioned on a container element. + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE If the current element is not positioned on a container element. * */ -WEAVE_ERROR TLVReader::EnterContainer(TLVType& outerContainerType) +CHIP_ERROR TLVReader::EnterContainer(TLVType& outerContainerType) { TLVElementType elemType = ElementType(); if (!TLVTypeIsContainer(elemType)) - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; outerContainerType = mContainerType; mContainerType = (TLVType) elemType; @@ -958,7 +956,7 @@ WEAVE_ERROR TLVReader::EnterContainer(TLVType& outerContainerType) ClearElementState(); SetContainerOpen(false); - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -984,31 +982,31 @@ WEAVE_ERROR TLVReader::EnterContainer(TLVType& outerContainerType) * * @param[in] outerContainerType The TLVType value that was returned by the EnterContainer() method. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE If OpenContainer() has not been called on the reader, or if * the container reader does not match the one passed to the * OpenContainer() method. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the reader encountered an invalid or unsupported TLV element type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::ExitContainer(TLVType outerContainerType) +CHIP_ERROR TLVReader::ExitContainer(TLVType outerContainerType) { - WEAVE_ERROR err; + CHIP_ERROR err; err = SkipToEndOfContainer(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; mContainerType = outerContainerType; ClearElementState(); - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -1016,31 +1014,31 @@ WEAVE_ERROR TLVReader::ExitContainer(TLVType outerContainerType) * * The VerifyEndOfContainer() method verifies that there are no further TLV elements to be read * within the current TLV container. This is a convenience method that is equivalent to calling - * Next() and checking for a return value of WEAVE_END_OF_TLV. + * Next() and checking for a return value of CHIP_END_OF_TLV. * * @note When there are more TLV elements in the collection, this method will change the position * of the reader. * - * @retval #WEAVE_NO_ERROR If there are no further TLV elements to be read. - * @retval #WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT + * @retval #CHIP_NO_ERROR If there are no further TLV elements to be read. + * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT * If another TLV element was found in the collection. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the reader encountered an invalid or unsupported TLV element * type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::VerifyEndOfContainer() +CHIP_ERROR TLVReader::VerifyEndOfContainer() { - WEAVE_ERROR err = Next(); - if (err == WEAVE_END_OF_TLV) - return WEAVE_NO_ERROR; - if (err == WEAVE_NO_ERROR) - return WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT; + CHIP_ERROR err = Next(); + if (err == CHIP_END_OF_TLV) + return CHIP_NO_ERROR; + if (err == CHIP_NO_ERROR) + return CHIP_ERROR_UNEXPECTED_TLV_ELEMENT; return err; } @@ -1074,41 +1072,41 @@ TLVType TLVReader::GetContainerType() const * after the container. * * When there are no further elements within a particular containment context the Next() method will - * return a #WEAVE_END_OF_TLV error and the position of the reader will remain unchanged. + * return a #CHIP_END_OF_TLV error and the position of the reader will remain unchanged. * - * @retval #WEAVE_NO_ERROR If the reader was successfully positioned on a new element. - * @retval #WEAVE_END_OF_TLV If no further elements are available. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #CHIP_END_OF_TLV If no further elements are available. + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the reader encountered an invalid or unsupported TLV element * type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval #WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval #CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG * If the reader encountered a implicitly-encoded TLV tag for which * the corresponding profile id is unknown. - * @retval other Other Weave or platform error codes returned by the configured + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::Next() +CHIP_ERROR TLVReader::Next() { - WEAVE_ERROR err; + CHIP_ERROR err; TLVElementType elemType = ElementType(); err = Skip(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; err = ReadElement(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; elemType = ElementType(); if (elemType == kTLVElementType_EndOfContainer) - return WEAVE_END_OF_TLV; + return CHIP_END_OF_TLV; - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -1122,33 +1120,33 @@ WEAVE_ERROR TLVReader::Next() * @param[in] expectedType The expected data type for the next element. * @param[in] expectedTag The expected tag for the next element. * - * @retval #WEAVE_NO_ERROR If the reader was successfully positioned on a new element. - * @retval #WEAVE_END_OF_TLV If no further elements are available. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE If the type of the new element does not match the value + * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #CHIP_END_OF_TLV If no further elements are available. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE If the type of the new element does not match the value * of the @p expectedType argument. - * @retval #WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT + * @retval #CHIP_ERROR_UNEXPECTED_TLV_ELEMENT * If the tag associated with the new element does not match the * value of the @p expectedTag argument. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the reader encountered an invalid or unsupported TLV * element type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::Next(TLVType expectedType, uint64_t expectedTag) +CHIP_ERROR TLVReader::Next(TLVType expectedType, uint64_t expectedTag) { - WEAVE_ERROR err = Next(); - if (err != WEAVE_NO_ERROR) + CHIP_ERROR err = Next(); + if (err != CHIP_NO_ERROR) return err; if (GetType() != expectedType) - return WEAVE_ERROR_WRONG_TLV_TYPE; + return CHIP_ERROR_WRONG_TLV_TYPE; if (mElemTag != expectedTag) - return WEAVE_ERROR_UNEXPECTED_TLV_ELEMENT; - return WEAVE_NO_ERROR; + return CHIP_ERROR_UNEXPECTED_TLV_ELEMENT; + return CHIP_NO_ERROR; } /** @@ -1160,47 +1158,47 @@ WEAVE_ERROR TLVReader::Next(TLVType expectedType, uint64_t expectedTag) * container will be skipped. If the reader is not positioned on any element, its position remains * unchanged. * - * @retval #WEAVE_NO_ERROR If the reader was successfully positioned on a new element. - * @retval #WEAVE_END_OF_TLV If no further elements are available. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_NO_ERROR If the reader was successfully positioned on a new element. + * @retval #CHIP_END_OF_TLV If no further elements are available. + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended prematurely. + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the reader encountered an invalid or unsupported TLV * element type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. - * @retval other Other Weave or platform error codes returned by the configured + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the reader encountered a TLV tag in an invalid context. + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. * */ -WEAVE_ERROR TLVReader::Skip() +CHIP_ERROR TLVReader::Skip() { - WEAVE_ERROR err; + CHIP_ERROR err; TLVElementType elemType = ElementType(); if (elemType == kTLVElementType_EndOfContainer) - return WEAVE_END_OF_TLV; + return CHIP_END_OF_TLV; if (TLVTypeIsContainer(elemType)) { TLVType outerContainerType; err = EnterContainer(outerContainerType); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; err = ExitContainer(outerContainerType); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; } else { err = SkipData(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; ClearElementState(); } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -1219,30 +1217,30 @@ void TLVReader::ClearElementState(void) * Skip any data contained in the current TLV by reading over it without * a destination buffer. * - * @retval #WEAVE_NO_ERROR If the reader was successfully positioned at the end of the + * @retval #CHIP_NO_ERROR If the reader was successfully positioned at the end of the * data. - * @retval other Other Weave or platform error codes returned by the configured + * @retval other Other CHIP or platform error codes returned by the configured * GetNextBuffer() function. Only possible when GetNextBuffer is * non-NULL. */ -WEAVE_ERROR TLVReader::SkipData(void) +CHIP_ERROR TLVReader::SkipData(void) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; TLVElementType elemType = ElementType(); if (TLVTypeHasLength(elemType)) { err = ReadData(NULL, mElemLenOrVal); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; } return err; } -WEAVE_ERROR TLVReader::SkipToEndOfContainer() +CHIP_ERROR TLVReader::SkipToEndOfContainer() { - WEAVE_ERROR err; + CHIP_ERROR err; TLVType outerContainerType = mContainerType; uint32_t nestLevel = 0; @@ -1259,7 +1257,7 @@ WEAVE_ERROR TLVReader::SkipToEndOfContainer() if (elemType == kTLVElementType_EndOfContainer) { if (nestLevel == 0) - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; nestLevel--; mContainerType = (nestLevel == 0) ? outerContainerType : kTLVType_UnknownContainer; @@ -1272,25 +1270,25 @@ WEAVE_ERROR TLVReader::SkipToEndOfContainer() } err = SkipData(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; err = ReadElement(); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; } } -WEAVE_ERROR TLVReader::ReadElement() +CHIP_ERROR TLVReader::ReadElement() { - WEAVE_ERROR err; + CHIP_ERROR err; uint8_t stagingBuf[17]; // 17 = 1 control byte + 8 tag bytes + 8 length/value bytes const uint8_t *p; TLVElementType elemType; - // Make sure we have input data. Return WEAVE_END_OF_TLV if no more data is available. - err = EnsureData(WEAVE_END_OF_TLV); - if (err != WEAVE_NO_ERROR) + // Make sure we have input data. Return CHIP_END_OF_TLV if no more data is available. + err = EnsureData(CHIP_END_OF_TLV); + if (err != CHIP_NO_ERROR) return err; // Get the element's control byte. @@ -1299,7 +1297,7 @@ WEAVE_ERROR TLVReader::ReadElement() // Extract the element type from the control byte. Fail if it's invalid. elemType = ElementType(); if (!IsValidTLVType(elemType)) - return WEAVE_ERROR_INVALID_TLV_ELEMENT; + return CHIP_ERROR_INVALID_TLV_ELEMENT; // Extract the tag control from the control byte. TLVTagControl tagControl = (TLVTagControl)(mControlByte & kTLVTagControlMask); @@ -1322,7 +1320,7 @@ WEAVE_ERROR TLVReader::ReadElement() if (elemHeadBytes > (mBufEnd - mReadPoint)) { err = ReadData(stagingBuf, elemHeadBytes); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; p = stagingBuf; } @@ -1362,38 +1360,38 @@ WEAVE_ERROR TLVReader::ReadElement() return VerifyElement(); } -WEAVE_ERROR TLVReader::VerifyElement() +CHIP_ERROR TLVReader::VerifyElement() { if (ElementType() == kTLVElementType_EndOfContainer) { if (mContainerType == kTLVType_NotSpecified) - return WEAVE_ERROR_INVALID_TLV_ELEMENT; + return CHIP_ERROR_INVALID_TLV_ELEMENT; if (mElemTag != AnonymousTag) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; } else { if (mElemTag == UnknownImplicitTag) - return WEAVE_ERROR_UNKNOWN_IMPLICIT_TLV_TAG; + return CHIP_ERROR_UNKNOWN_IMPLICIT_TLV_TAG; switch (mContainerType) { case kTLVType_NotSpecified: if (IsContextTag(mElemTag)) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; break; case kTLVType_Structure: case kTLVType_Path: if (mElemTag == AnonymousTag) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; break; case kTLVType_Array: if (mElemTag != AnonymousTag) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; break; case kTLVType_UnknownContainer: break; default: - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; } } @@ -1409,10 +1407,10 @@ WEAVE_ERROR TLVReader::VerifyElement() { uint32_t overallLenRemaining = mMaxLen - mLenRead; if (overallLenRemaining < (uint32_t)mElemLenOrVal) - return WEAVE_ERROR_TLV_UNDERRUN; + return CHIP_ERROR_TLV_UNDERRUN; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } uint64_t TLVReader::ReadTag(TLVTagControl tagControl, const uint8_t *& p) @@ -1450,14 +1448,14 @@ uint64_t TLVReader::ReadTag(TLVTagControl tagControl, const uint8_t *& p) } } -WEAVE_ERROR TLVReader::ReadData(uint8_t *buf, uint32_t len) +CHIP_ERROR TLVReader::ReadData(uint8_t *buf, uint32_t len) { - WEAVE_ERROR err; + CHIP_ERROR err; while (len > 0) { - err = EnsureData(WEAVE_ERROR_TLV_UNDERRUN); - if (err != WEAVE_NO_ERROR) + err = EnsureData(CHIP_ERROR_TLV_UNDERRUN); + if (err != CHIP_NO_ERROR) return err; uint32_t remainingLen = mBufEnd - mReadPoint; @@ -1476,12 +1474,12 @@ WEAVE_ERROR TLVReader::ReadData(uint8_t *buf, uint32_t len) len -= readLen; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } -WEAVE_ERROR TLVReader::EnsureData(WEAVE_ERROR noDataErr) +CHIP_ERROR TLVReader::EnsureData(CHIP_ERROR noDataErr) { - WEAVE_ERROR err; + CHIP_ERROR err; if (mReadPoint == mBufEnd) { @@ -1493,7 +1491,7 @@ WEAVE_ERROR TLVReader::EnsureData(WEAVE_ERROR noDataErr) uint32_t bufLen; err = GetNextBuffer(*this, mBufHandle, mReadPoint, bufLen); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; if (bufLen == 0) return noDataErr; @@ -1507,15 +1505,15 @@ WEAVE_ERROR TLVReader::EnsureData(WEAVE_ERROR noDataErr) mBufEnd = mReadPoint + bufLen; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** * This is a private method used to compute the length of a TLV element head. */ -WEAVE_ERROR TLVReader::GetElementHeadLength(uint8_t& elemHeadBytes) const +CHIP_ERROR TLVReader::GetElementHeadLength(uint8_t& elemHeadBytes) const { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; uint8_t tagBytes; uint8_t valOrLenBytes; TLVTagControl tagControl; @@ -1523,7 +1521,7 @@ WEAVE_ERROR TLVReader::GetElementHeadLength(uint8_t& elemHeadBytes) const TLVElementType elemType = ElementType(); // Verify element is of valid TLVType. - VerifyOrExit(IsValidTLVType(elemType), err = WEAVE_ERROR_INVALID_TLV_ELEMENT); + VerifyOrExit(IsValidTLVType(elemType), err = CHIP_ERROR_INVALID_TLV_ELEMENT); // Extract the tag control from the control byte. tagControl = (TLVTagControl)(mControlByte & kTLVTagControlMask); @@ -1558,7 +1556,7 @@ TLVElementType TLVReader::ElementType() const return (TLVElementType) (mControlByte & kTLVTypeMask); } -WEAVE_ERROR TLVReader::GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, +CHIP_ERROR TLVReader::GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, uint32_t& bufLen) { PacketBuffer *& buf = (PacketBuffer *&) bufHandle; @@ -1576,9 +1574,8 @@ WEAVE_ERROR TLVReader::GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHand bufLen = 0; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } } // namespace TLV -} // namespace Weave -} // namespace nl +} // namespace chip diff --git a/src/lib/core/WeaveTLVTags.h b/src/lib/core/CHIPTLVTags.h similarity index 93% rename from src/lib/core/WeaveTLVTags.h rename to src/lib/core/CHIPTLVTags.h index 2d036830136acd..0c4ac80e3e99ec 100644 --- a/src/lib/core/WeaveTLVTags.h +++ b/src/lib/core/CHIPTLVTags.h @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2013-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,26 +17,25 @@ /** * @file - * This file contains definitions for working with Weave TLV tags. + * This file contains definitions for working with CHIP TLV tags. * */ -#ifndef WEAVETLVTAGS_H_ -#define WEAVETLVTAGS_H_ +#ifndef CHIPTLVTAGS_H_ +#define CHIPTLVTAGS_H_ -namespace nl { -namespace Weave { +namespace chip { namespace TLV { enum TLVCommonProfiles { /** * Used to indicate the absence of a profile id in a variable or member. - * This is essentially the same as kWeaveProfile_NotSpecified defined in WeaveProfiles.h + * This is essentially the same as kCHIPProfile_NotSpecified defined in CHIPProfiles.h */ kProfileIdNotSpecified = 0xFFFFFFFF, - // TODO: Replace with nl::Weave::Profiles::kWeaveProfile_Common + // TODO: Replace with chip::Profiles::kCHIPProfile_Common kCommonProfileId = 0 }; @@ -184,7 +182,6 @@ inline bool IsContextTag(uint64_t tag) { return (tag & kProfileIdMask) == kSpeci inline bool IsSpecialTag(uint64_t tag) { return (tag & kProfileIdMask) == kSpecialTagMarker; } } // namespace TLV -} // namespace Weave -} // namespace nl +} // namespace chip -#endif /* WEAVETLVTAGS_H_ */ +#endif /* CHIPTLVTAGS_H_ */ diff --git a/src/lib/core/WeaveTLVTypes.h b/src/lib/core/CHIPTLVTypes.h similarity index 94% rename from src/lib/core/WeaveTLVTypes.h rename to src/lib/core/CHIPTLVTypes.h index 856bd40f23b2a5..da80fd41f3f40b 100644 --- a/src/lib/core/WeaveTLVTypes.h +++ b/src/lib/core/CHIPTLVTypes.h @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2013-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,15 +17,14 @@ /** * @file - * This file contains definitions for working with Weave TLV types. + * This file contains definitions for working with CHIP TLV types. * */ -#ifndef WEAVETLVTYPES_H_ -#define WEAVETLVTYPES_H_ +#ifndef CHIPTLVTYPES_H_ +#define CHIPTLVTYPES_H_ -namespace nl { -namespace Weave { +namespace chip { namespace TLV { /** @@ -164,9 +162,7 @@ inline uint8_t TLVFieldSizeToBytes(TLVFieldSize fieldSize) } } // namespace TLV -} // namespace Weave -} // namespace nl +} // namespace chip - -#endif /* WEAVETLVTYPES_H_ */ +#endif /* CHIPTLVTYPES_H_ */ diff --git a/src/lib/core/WeaveTLVUpdater.cpp b/src/lib/core/CHIPTLVUpdater.cpp similarity index 85% rename from src/lib/core/WeaveTLVUpdater.cpp rename to src/lib/core/CHIPTLVUpdater.cpp index be83aec45a7a30..5c569ab77d9424 100644 --- a/src/lib/core/WeaveTLVUpdater.cpp +++ b/src/lib/core/CHIPTLVUpdater.cpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2015-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,21 +17,20 @@ /** * @file - * This file implements an updating encoder for the Weave TLV + * This file implements an updating encoder for the CHIP TLV * (Tag-Length-Value) encoding format. * */ -#include -#include -#include -#include +#include +#include +#include +#include -namespace nl { -namespace Weave { +namespace chip { namespace TLV { -using namespace nl::Weave::Encoding; +using namespace chip::Encoding; /** * Initialize a TLVUpdater object to edit a single input buffer. @@ -48,19 +46,19 @@ using namespace nl::Weave::Encoding; * @param[in] dataLen The length of the TLV data in the buffer. * @param[in] maxLen The total length of the buffer. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If the buffer address is invalid. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL If the buffer is too small. + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INVALID_ARGUMENT If the buffer address is invalid. + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL If the buffer is too small. * */ -WEAVE_ERROR TLVUpdater::Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen) +CHIP_ERROR TLVUpdater::Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; uint32_t freeLen; - VerifyOrExit(buf != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(buf != NULL, err = CHIP_ERROR_INVALID_ARGUMENT); - VerifyOrExit(maxLen >= dataLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + VerifyOrExit(maxLen >= dataLen, err = CHIP_ERROR_BUFFER_TOO_SMALL); // memmove the buffer data to end of the buffer freeLen = maxLen - dataLen; @@ -103,23 +101,23 @@ WEAVE_ERROR TLVUpdater::Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen) * @param[in] freeLen The length of free space (in bytes) available * in the pre-encoded data buffer. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If the buffer address is invalid. - * @retval #WEAVE_ERROR_NOT_IMPLEMENTED If reader was initialized on a chain + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INVALID_ARGUMENT If the buffer address is invalid. + * @retval #CHIP_ERROR_NOT_IMPLEMENTED If reader was initialized on a chain * of buffers. */ -WEAVE_ERROR TLVUpdater::Init(TLVReader& aReader, uint32_t freeLen) +CHIP_ERROR TLVUpdater::Init(TLVReader& aReader, uint32_t freeLen) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; uint8_t *buf = const_cast(aReader.GetReadPoint()); uint32_t remainingDataLen = aReader.GetRemainingLength(); uint32_t readDataLen = aReader.GetLengthRead(); // TLVUpdater does not support chain of buffers yet - VerifyOrExit(aReader.mBufHandle == 0, err = WEAVE_ERROR_NOT_IMPLEMENTED); + VerifyOrExit(aReader.mBufHandle == 0, err = CHIP_ERROR_NOT_IMPLEMENTED); // TLVReader should point to a non-NULL buffer - VerifyOrExit(buf != NULL, err = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(buf != NULL, err = CHIP_ERROR_INVALID_ARGUMENT); // If reader is already on an element, reset it to start of element if (aReader.ElementType() != kTLVElementType_NotSpecified) @@ -216,7 +214,7 @@ void TLVUpdater::SetImplicitProfileId(uint32_t profileId) * container. * * When there are no further elements within a particular containment context - * the Next() method will return a #WEAVE_END_OF_TLV error and the position of + * the Next() method will return a #CHIP_END_OF_TLV error and the position of * the reader will remain unchanged. * * @note The Next() method implicitly skips the current element. Hence, the @@ -232,20 +230,20 @@ void TLVUpdater::SetImplicitProfileId(uint32_t profileId) * fixed schemas and know where the container end is cannot just add new * elements at the end, because the TLVUpdater writer's state will not reflect * the correct free space available for the Put() operation. Hence, applications - * must call Next() (and possibly also test for WEAVE_END_OF_TLV) before adding + * must call Next() (and possibly also test for CHIP_END_OF_TLV) before adding * elements at the end of a container. * - * @retval #WEAVE_NO_ERROR If the TLVUpdater reader was + * @retval #CHIP_NO_ERROR If the TLVUpdater reader was * successfully positioned on a new * element. - * @retval other Returns the Weave or platform error + * @retval other Returns the CHIP or platform error * codes returned by the TLVReader::Skip() * and TLVReader::Next() method. * */ -WEAVE_ERROR TLVUpdater::Next() +CHIP_ERROR TLVUpdater::Next() { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; // Skip current element if the reader is already positioned on an element err = mUpdaterReader.Skip(); @@ -272,29 +270,29 @@ WEAVE_ERROR TLVUpdater::Next() * container will be copied. If the reader is not positioned on any element, * nothing changes on calling this method. * - * @retval #WEAVE_NO_ERROR If the TLVUpdater reader was + * @retval #CHIP_NO_ERROR If the TLVUpdater reader was * successfully positioned on a new * element. - * @retval #WEAVE_END_OF_TLV If the TLVUpdater's reader is pointing + * @retval #CHIP_END_OF_TLV If the TLVUpdater's reader is pointing * to end of container. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the TLVIpdater's reader is not * positioned on a valid TLV element. * @retval other Returns other error codes returned by * TLVReader::Skip() method. * */ -WEAVE_ERROR TLVUpdater::Move() +CHIP_ERROR TLVUpdater::Move() { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t *elementEnd; uint32_t copyLen; VerifyOrExit((mUpdaterReader.mControlByte & kTLVTypeMask) != kTLVElementType_EndOfContainer, - err = WEAVE_END_OF_TLV); + err = CHIP_END_OF_TLV); VerifyOrExit(mUpdaterReader.GetType() != kTLVType_NotSpecified, - err = WEAVE_ERROR_INVALID_TLV_ELEMENT); + err = CHIP_ERROR_INVALID_TLV_ELEMENT); // Skip to the end of the element err = mUpdaterReader.Skip(); @@ -377,7 +375,7 @@ void TLVUpdater::MoveUntilEnd() * When the EnterContainer() method returns, the updater is positioned * immediately @em before the first member of the container. Repeatedly calling * Next() will advance the updater through the members of the collection until - * the end is reached, at which point the updater will return WEAVE_END_OF_TLV. + * the end is reached, at which point the updater will return CHIP_END_OF_TLV. * * Once the application has finished reading a container it can continue reading * the elements after the container by calling the ExitContainer() method. @@ -388,21 +386,21 @@ void TLVUpdater::MoveUntilEnd() * @param[out] outerContainerType A reference to a TLVType value that will * receive the context of the updater. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE If the TLVUpdater reader is not + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE If the TLVUpdater reader is not * positioned on a container element. - * @retval other Any other Weave or platform error code + * @retval other Any other CHIP or platform error code * returned by TLVWriter::StartContainer() * or TLVReader::EnterContainer(). * */ -WEAVE_ERROR TLVUpdater::EnterContainer(TLVType& outerContainerType) +CHIP_ERROR TLVUpdater::EnterContainer(TLVType& outerContainerType) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; TLVType containerType; VerifyOrExit(TLVTypeIsContainer(mUpdaterReader.mControlByte & kTLVTypeMask), - err = WEAVE_ERROR_INCORRECT_STATE); + err = CHIP_ERROR_INCORRECT_STATE); // Change the updater state AdjustInternalWriterFreeSpace(); @@ -451,22 +449,22 @@ WEAVE_ERROR TLVUpdater::EnterContainer(TLVType& outerContainerType) * @param[in] outerContainerType The TLVType value that was returned by * the EnterContainer() method. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_UNDERRUN If the underlying TLV encoding ended * prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the updater encountered an invalid or * unsupported TLV element type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG If the updater encountered a TLV tag in + * @retval #CHIP_ERROR_INVALID_TLV_TAG If the updater encountered a TLV tag in * an invalid context. - * @retval other Any other Weave or platform error code + * @retval other Any other CHIP or platform error code * returned by TLVWriter::EndContainer() or * TLVReader::ExitContainer(). * */ -WEAVE_ERROR TLVUpdater::ExitContainer(TLVType outerContainerType) +CHIP_ERROR TLVUpdater::ExitContainer(TLVType outerContainerType) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; err = mUpdaterReader.ExitContainer(outerContainerType); SuccessOrExit(err); @@ -501,5 +499,4 @@ void TLVUpdater::AdjustInternalWriterFreeSpace() } } // namespace TLV -} // namespace Weave -} // namespace nl +} // namespace chip diff --git a/src/lib/core/WeaveTLVUtilities.cpp b/src/lib/core/CHIPTLVUtilities.cpp similarity index 72% rename from src/lib/core/WeaveTLVUtilities.cpp rename to src/lib/core/CHIPTLVUtilities.cpp index 3eb7f3d756d932..80f229f2ac06ea 100644 --- a/src/lib/core/WeaveTLVUtilities.cpp +++ b/src/lib/core/CHIPTLVUtilities.cpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2015-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,17 +18,15 @@ /** * @file * This file implements utility interfaces for managing and - * working with Weave TLV. + * working with CHIP TLV. * */ -#include -#include -#include +#include +#include +#include -namespace nl { - -namespace Weave { +namespace chip { namespace TLV { @@ -43,7 +40,7 @@ struct FindContext { /** * Iterate through the TLV data referenced by @a aReader and invoke @a aHandler * for each visited TLV element in the context of @a aContext. - * The iteration is aborted if @a aHandler returns anything other than #WEAVE_NO_ERROR + * The iteration is aborted if @a aHandler returns anything other than #CHIP_NO_ERROR * * @param[in] aReader A reference to the TLV reader containing the TLV * data to iterate. @@ -55,14 +52,14 @@ struct FindContext { * any encountered arrays or structures should be * descended into. * - * @retval #WEAVE_END_OF_TLV On a successful iteration to the end of a TLV encoding, + * @retval #CHIP_END_OF_TLV On a successful iteration to the end of a TLV encoding, * or to the end of a TLV container. * - * @retval The last value returned by @a aHandler, if different than #WEAVE_NO_ERROR + * @retval The last value returned by @a aHandler, if different than #CHIP_NO_ERROR */ -static WEAVE_ERROR Iterate(TLVReader &aReader, size_t aDepth, IterateHandler aHandler, void *aContext, bool aRecurse) +static CHIP_ERROR Iterate(TLVReader &aReader, size_t aDepth, IterateHandler aHandler, void *aContext, bool aRecurse) { - WEAVE_ERROR retval = WEAVE_NO_ERROR; + CHIP_ERROR retval = CHIP_NO_ERROR; if (aReader.GetType() == kTLVType_NotSpecified) { @@ -85,13 +82,13 @@ static WEAVE_ERROR Iterate(TLVReader &aReader, size_t aDepth, IterateHandler aHa SuccessOrExit(retval); retval = Iterate(aReader, aDepth + 1, aHandler, aContext, aRecurse); - if (retval != WEAVE_END_OF_TLV) + if (retval != CHIP_END_OF_TLV) SuccessOrExit(retval); retval = aReader.ExitContainer(containerType); SuccessOrExit(retval); } - } while ((retval = aReader.Next()) == WEAVE_NO_ERROR); + } while ((retval = aReader.Next()) == CHIP_NO_ERROR); exit: return retval; @@ -100,7 +97,7 @@ static WEAVE_ERROR Iterate(TLVReader &aReader, size_t aDepth, IterateHandler aHa /** * Iterate through the TLV data referenced by @a aReader and invoke @a aHandler * for each visited TLV element in the context of @a aContext. - * The iteration is aborted if @a aHandler returns anything other than #WEAVE_NO_ERROR + * The iteration is aborted if @a aHandler returns anything other than #CHIP_NO_ERROR * * @param[in] aReader A reference to the TLV reader containing the TLV * data to iterate. @@ -108,18 +105,18 @@ static WEAVE_ERROR Iterate(TLVReader &aReader, size_t aDepth, IterateHandler aHa * being visited. * @param[inout] aContext An optional pointer to caller-provided context data. * - * @retval #WEAVE_END_OF_TLV On a successful iteration to the end of a TLV encoding, + * @retval #CHIP_END_OF_TLV On a successful iteration to the end of a TLV encoding, * or to the end of a TLV container. * - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aHandler is NULL. + * @retval #CHIP_ERROR_INVALID_ARGUMENT If @a aHandler is NULL. * - * @retval The last value returned by @a aHandler, if different than #WEAVE_NO_ERROR + * @retval The last value returned by @a aHandler, if different than #CHIP_NO_ERROR * */ -WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext) +CHIP_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext) { const bool recurse = true; - WEAVE_ERROR retval; + CHIP_ERROR retval; retval = Iterate(aReader, aHandler, aContext, recurse); @@ -129,7 +126,7 @@ WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aCo /** * Iterate through the TLV data referenced by @a aReader and invoke @a aHandler * for each visited TLV element in the context of @a aContext. - * The iteration is aborted if @a aHandler returns anything other than #WEAVE_NO_ERROR + * The iteration is aborted if @a aHandler returns anything other than #CHIP_NO_ERROR * * @param[in] aReader A reference to the TLV reader containing the TLV * data to iterate. @@ -140,21 +137,21 @@ WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aCo * any encountered arrays or structures should be * descended into. * - * @retval #WEAVE_END_OF_TLV On a successful iteration to the end of a TLV encoding, + * @retval #CHIP_END_OF_TLV On a successful iteration to the end of a TLV encoding, * or to the end of a TLV container. * - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aHandler is NULL. + * @retval #CHIP_ERROR_INVALID_ARGUMENT If @a aHandler is NULL. * - * @retval The last value returned by @a aHandler, if different than #WEAVE_NO_ERROR + * @retval The last value returned by @a aHandler, if different than #CHIP_NO_ERROR * */ -WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext, const bool aRecurse) +CHIP_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext, const bool aRecurse) { const size_t depth = 0; TLVReader temp; - WEAVE_ERROR retval = WEAVE_ERROR_NOT_IMPLEMENTED; + CHIP_ERROR retval = CHIP_ERROR_NOT_IMPLEMENTED; - VerifyOrExit(aHandler != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(aHandler != NULL, retval = CHIP_ERROR_INVALID_ARGUMENT); temp.Init(aReader); @@ -173,16 +170,16 @@ WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aCo * @param[inout] aContext A pointer to the handler-specific context which * is a pointer to storage for the count value. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aContext is NULL. + * @retval #CHIP_ERROR_INVALID_ARGUMENT If @a aContext is NULL. * */ -static WEAVE_ERROR CountHandler(const TLVReader &aReader, size_t aDepth, void *aContext) +static CHIP_ERROR CountHandler(const TLVReader &aReader, size_t aDepth, void *aContext) { - WEAVE_ERROR retval = WEAVE_NO_ERROR; + CHIP_ERROR retval = CHIP_NO_ERROR; - VerifyOrExit(aContext != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(aContext != NULL, retval = CHIP_ERROR_INVALID_ARGUMENT); *static_cast(aContext) += 1; @@ -201,13 +198,13 @@ static WEAVE_ERROR CountHandler(const TLVReader &aReader, size_t aDepth, void *a * and is set to the number of elements counted on * success. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * */ -WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount) +CHIP_ERROR Count(const TLVReader &aReader, size_t &aCount) { const bool recurse = true; - WEAVE_ERROR retval; + CHIP_ERROR retval; retval = Count(aReader, aCount, recurse); @@ -228,19 +225,19 @@ WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount) * any encountered arrays or structures should be * descended into. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * */ -WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse) +CHIP_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse) { - WEAVE_ERROR retval; + CHIP_ERROR retval; aCount = 0; retval = Iterate(aReader, CountHandler, &aCount, aRecurse); - if (retval == WEAVE_END_OF_TLV) - retval = WEAVE_NO_ERROR; + if (retval == CHIP_END_OF_TLV) + retval = CHIP_NO_ERROR; return retval; } @@ -253,25 +250,25 @@ WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse) * @param[in] aDepth The current depth into the TLV data. * @param[inout] aContext A pointer to the handler-specific context. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_INVALID_ARGUMENT If @a aContext is NULL. + * @retval #CHIP_ERROR_INVALID_ARGUMENT If @a aContext is NULL. * - * @retval #WEAVE_ERROR_MAX If the specified tag is found. + * @retval #CHIP_ERROR_MAX If the specified tag is found. * */ -static WEAVE_ERROR FindHandler(const TLVReader &aReader, size_t aDepth, void *aContext) +static CHIP_ERROR FindHandler(const TLVReader &aReader, size_t aDepth, void *aContext) { const FindContext * theContext = static_cast(aContext); - WEAVE_ERROR retval = WEAVE_NO_ERROR; + CHIP_ERROR retval = CHIP_NO_ERROR; - VerifyOrExit(aContext != NULL, retval = WEAVE_ERROR_INVALID_ARGUMENT); + VerifyOrExit(aContext != NULL, retval = CHIP_ERROR_INVALID_ARGUMENT); if (theContext->mTag == aReader.GetTag()) { theContext->mReader.Init(aReader); // terminate the iteration when the specified tag is found - retval = WEAVE_ERROR_MAX; + retval = CHIP_ERROR_MAX; } exit: @@ -288,15 +285,15 @@ static WEAVE_ERROR FindHandler(const TLVReader &aReader, size_t aDepth, void *aC * will be positioned at the specified tag * on success. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified tag @a aTag was not found. + * @retval #CHIP_ERROR_TLV_TAG_NOT_FOUND If the specified tag @a aTag was not found. * */ -WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult) +CHIP_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult) { const bool recurse = true; - WEAVE_ERROR retval; + CHIP_ERROR retval; retval = Find(aReader, aTag, aResult, recurse); @@ -317,22 +314,22 @@ WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aRes * any encountered arrays or structures should be * descended into. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified tag @a aTag was not found. + * @retval #CHIP_ERROR_TLV_TAG_NOT_FOUND If the specified tag @a aTag was not found. * */ -WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult, const bool aRecurse) +CHIP_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult, const bool aRecurse) { FindContext theContext = { aTag, aResult }; - WEAVE_ERROR retval; + CHIP_ERROR retval; retval = Iterate(aReader, FindHandler, &theContext, aRecurse); - if (retval == WEAVE_ERROR_MAX) - retval = WEAVE_NO_ERROR; + if (retval == CHIP_ERROR_MAX) + retval = CHIP_NO_ERROR; else - retval = WEAVE_ERROR_TLV_TAG_NOT_FOUND; + retval = CHIP_ERROR_TLV_TAG_NOT_FOUND; return retval; } @@ -352,14 +349,14 @@ FindPredicateContext::FindPredicateContext(TLVReader &inReader, IterateHandler i { } -static WEAVE_ERROR FindPredicateHandler(const TLVReader & aReader, size_t aDepth, void *aContext) +static CHIP_ERROR FindPredicateHandler(const TLVReader & aReader, size_t aDepth, void *aContext) { FindPredicateContext *theContext = static_cast(aContext); - WEAVE_ERROR err; + CHIP_ERROR err; err = theContext->mHandler(aReader, aDepth, theContext->mContext); - if (err == WEAVE_ERROR_MAX) + if (err == CHIP_ERROR_MAX) theContext->mResult.Init(aReader); return err; @@ -368,8 +365,8 @@ static WEAVE_ERROR FindPredicateHandler(const TLVReader & aReader, size_t aDepth /** * Search for the first element matching the predicate within the TLV reader * descending into arrays or structures. The @a aPredicate is applied - * to each visited TLV element; the @a aPredicate shall return #WEAVE_ERROR_MAX - * for the matching elements, #WEAVE_NO_ERROR for non-matching elements, and any + * to each visited TLV element; the @a aPredicate shall return #CHIP_ERROR_MAX + * for the matching elements, #CHIP_NO_ERROR for non-matching elements, and any * other value to terminate the search. * * @param[in] aReader A read-only reference to the TLV reader in which to find the @@ -377,8 +374,8 @@ static WEAVE_ERROR FindPredicateHandler(const TLVReader & aReader, size_t aDepth * @param[in] aPredicate A predicate to be applied to each TLV element. To * support the code reuse, aPredicate has the * IterateHandler type. The return value of aPredicate - * controls the search: a #WEAVE_ERROR_MAX signals that - * desired element has been found, #WEAVE_NO_ERROR + * controls the search: a #CHIP_ERROR_MAX signals that + * desired element has been found, #CHIP_NO_ERROR * signals that the desired element has not been found, * and all other values signal that the saerch should be * terminated. @@ -387,12 +384,12 @@ static WEAVE_ERROR FindPredicateHandler(const TLVReader & aReader, size_t aDepth * @param[out] aResult A reference to storage to a TLV reader which * will be positioned at the specified tag * on success. - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified @a aPredicate did not locate the specified element + * @retval #CHIP_ERROR_TLV_TAG_NOT_FOUND If the specified @a aPredicate did not locate the specified element * */ -WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aContext, TLVReader &aResult) +CHIP_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aContext, TLVReader &aResult) { const bool recurse = true; return Find(aReader, aPredicate, aContext, aResult, recurse); @@ -401,8 +398,8 @@ WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aCon /** * Search for the first element matching the predicate within the TLV reader * optionally descending into arrays or structures. The @a aPredicate is applied - * to each visited TLV element; the @a aPredicate shall return #WEAVE_ERROR_MAX - * for the matching elements, #WEAVE_NO_ERROR for non-matching elements, and any + * to each visited TLV element; the @a aPredicate shall return #CHIP_ERROR_MAX + * for the matching elements, #CHIP_NO_ERROR for non-matching elements, and any * other value to terminate the search. * * @param[in] aReader A read-only reference to the TLV reader in which to find the @@ -410,8 +407,8 @@ WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aCon * @param[in] aPredicate A predicate to be applied to each TLV element. To * support the code reuse, aPredicate has the * @a IterateHandler type. The return value of aPredicate - * controls the search: a #WEAVE_ERROR_MAX signals that - * desired element has been found, #WEAVE_NO_ERROR + * controls the search: a #CHIP_ERROR_MAX signals that + * desired element has been found, #CHIP_NO_ERROR * signals that the desired element has not been found, * and all other values signal that the saerch should be * terminated. @@ -423,22 +420,22 @@ WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aCon * encountered arrays or structures should be descended * into. * - * @retval #WEAVE_NO_ERROR On success. + * @retval #CHIP_NO_ERROR On success. * - * @retval #WEAVE_ERROR_TLV_TAG_NOT_FOUND If the specified @a aPredicate did not locate the specified element + * @retval #CHIP_ERROR_TLV_TAG_NOT_FOUND If the specified @a aPredicate did not locate the specified element * */ -WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aContext, TLVReader &aResult, const bool aRecurse) +CHIP_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aContext, TLVReader &aResult, const bool aRecurse) { - WEAVE_ERROR retval; + CHIP_ERROR retval; FindPredicateContext theContext(aResult, aPredicate, aContext); retval = Iterate(aReader, FindPredicateHandler, &theContext, aRecurse); - if (retval == WEAVE_ERROR_MAX) - retval = WEAVE_NO_ERROR; + if (retval == CHIP_ERROR_MAX) + retval = CHIP_NO_ERROR; else - retval = WEAVE_ERROR_TLV_TAG_NOT_FOUND; + retval = CHIP_ERROR_TLV_TAG_NOT_FOUND; return retval; } @@ -447,6 +444,4 @@ WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aPredicate, void *aCon } // namespace TLV -} // namespace Weave - -} // namespace nl +} // namespace chip diff --git a/src/lib/core/WeaveTLVUtilities.hpp b/src/lib/core/CHIPTLVUtilities.hpp similarity index 85% rename from src/lib/core/WeaveTLVUtilities.hpp rename to src/lib/core/CHIPTLVUtilities.hpp index 1204225fa0ceac..03dfce7c27984b 100644 --- a/src/lib/core/WeaveTLVUtilities.hpp +++ b/src/lib/core/CHIPTLVUtilities.hpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2015-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +18,7 @@ /** * @file * This file specifies types and utility interfaces for managing and - * working with Weave TLV. + * working with CHIP TLV. * */ @@ -29,21 +28,19 @@ #include #include -#include -#include +#include +#include -namespace nl { - -namespace Weave { +namespace CHIP { namespace TLV { /** - * @namespace nl::Weave::TLV::Utilities + * @namespace CHIP::TLV::Utilities * * @brief * This namespace includes types and utility interfaces for managing and - * working with Weave TLV. + * working with CHIP TLV. * */ namespace Utilities { @@ -65,8 +62,6 @@ extern WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void } // namespace TLV -} // namespace Weave - -} // namespace nl +} // namespace CHIP #endif // WEAVETLVUTILITIES_HPP diff --git a/src/lib/core/WeaveTLVWriter.cpp b/src/lib/core/CHIPTLVWriter.cpp similarity index 82% rename from src/lib/core/WeaveTLVWriter.cpp rename to src/lib/core/CHIPTLVWriter.cpp index dc4a4b57c20018..6c19977dd67769 100644 --- a/src/lib/core/WeaveTLVWriter.cpp +++ b/src/lib/core/CHIPTLVWriter.cpp @@ -1,7 +1,6 @@ /* * - * Copyright (c) 2013-2017 Nest Labs, Inc. - * All rights reserved. + * * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +17,7 @@ /** * @file - * This file implements an encoder for the Weave TLV (Tag-Length-Value) encoding format. + * This file implements an encoder for the CHIP TLV (Tag-Length-Value) encoding format. * */ @@ -28,16 +27,15 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include -namespace nl { -namespace Weave { +namespace chip { namespace TLV { -using namespace nl::Weave::Encoding; +using namespace chip::Encoding; /** @@ -66,7 +64,7 @@ using namespace nl::Weave::Encoding; */ /** - * @typedef WEAVE_ERROR (*TLVWriter::GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) + * @typedef CHIP_ERROR (*TLVWriter::GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) * * A function that supplies new output buffer space to a TLVWriter. * @@ -91,8 +89,8 @@ using namespace nl::Weave::Encoding; * current buffer. On exit, @p bufLen is expected to contain the maximum * number of bytes that can be written to the new output buffer. * - * @retval #WEAVE_NO_ERROR If the function was able to supply more buffer space for the writer. - * @retval other Other Weave or platform-specific error codes indicating that an error + * @retval #CHIP_NO_ERROR If the function was able to supply more buffer space for the writer. + * @retval other Other CHIP or platform-specific error codes indicating that an error * occurred preventing the function from producing additional buffer * space. * @@ -105,7 +103,7 @@ using namespace nl::Weave::Encoding; * * A TLVWriter object will call the GetNewBuffer function whenever an attempt is made to write data * that exceeds the size of the current output buffer. If set to NULL (the default value), the - * writer will return a WEAVE_ERROR_NO_MEMORY if the output data overflows the current buffer. + * writer will return a CHIP_ERROR_NO_MEMORY if the output data overflows the current buffer. * * GetNewBuffer can be set by an application at any time, but is typically set when the writer * is initialized. @@ -115,7 +113,7 @@ using namespace nl::Weave::Encoding; */ /** - * @typedef WEAVE_ERROR (*TLVWriter::FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t bufLen) + * @typedef CHIP_ERROR (*TLVWriter::FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t bufLen) * * A function used to perform finalization of the output from a TLVWriter object. * @@ -130,8 +128,8 @@ using namespace nl::Weave::Encoding; * @param[in,out] bufStart A pointer to the beginning of the current (and final) output buffer. * @param[in,out] bufLen The number of bytes contained in the buffer pointed to by @p bufStart. * - * @retval #WEAVE_NO_ERROR If finalization was successful. - * @retval other Other Weave or platform-specific error codes indicating that an error + * @retval #CHIP_NO_ERROR If finalization was successful. + * @retval other Other CHIP or platform-specific error codes indicating that an error * occurred during finalization. * */ @@ -225,7 +223,7 @@ void TLVWriter::Init(PacketBuffer *buf, uint32_t maxLen) * @param[in] allowDiscontiguousBuffers * If true, write data to a chain of PacketBuffers, allocating new buffers as * needed to store the data written. If false, writing will fail with - * WEAVE_ERROR_BUFFER_TOO_SMALL if the written data exceeds the space available + * CHIP_ERROR_BUFFER_TOO_SMALL if the written data exceeds the space available * in the initial output buffer. * */ @@ -261,18 +259,18 @@ uint32_t TLVWriter::GetLengthWritten() * Finalize() can only be called when there are no container writers open for the current writer. * (See @p OpenContainer()). * - * @retval #WEAVE_NO_ERROR If the encoding was finalized successfully. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the encoding was finalized successfully. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * FinalizeBuffer() function. */ -WEAVE_ERROR TLVWriter::Finalize() +CHIP_ERROR TLVWriter::Finalize() { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; if (IsContainerOpen()) - return WEAVE_ERROR_TLV_CONTAINER_OPEN; + return CHIP_ERROR_TLV_CONTAINER_OPEN; if (FinalizeBuffer != NULL) err = FinalizeBuffer(*this, mBufHandle, mBufStart, mWritePoint - mBufStart); return err; @@ -287,24 +285,24 @@ WEAVE_ERROR TLVWriter::Finalize() * ContextTag() or CommonTag(). * @param[in] v The value to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::PutBoolean(uint64_t tag, bool v) +CHIP_ERROR TLVWriter::PutBoolean(uint64_t tag, bool v) { return WriteElementHead((v) ? kTLVElementType_BooleanTrue : kTLVElementType_BooleanFalse, tag, 0); } @@ -318,24 +316,24 @@ WEAVE_ERROR TLVWriter::PutBoolean(uint64_t tag, bool v) * ContextTag() or CommonTag(). * @param[in] v The value to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) { return Put(tag, static_cast(v)); } @@ -353,24 +351,24 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) * number of bytes necessary to represent the value. Note: Applications * are strongly encouraged to set this parameter to false. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_UInt8, tag, v); @@ -379,17 +377,17 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint16_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint16_t v) { return Put(tag, static_cast(v)); } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint16_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint16_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_UInt16, tag, v); @@ -398,17 +396,17 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint16_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint32_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint32_t v) { return Put(tag, static_cast(v)); } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint32_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint32_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_UInt32, tag, v); @@ -417,9 +415,9 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint32_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint64_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint64_t v) { TLVElementType elemType; if (v <= UINT8_MAX) @@ -434,9 +432,9 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint64_t v) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, uint8_t v, bool preserveSize) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint64_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, uint64_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_UInt64, tag, v); @@ -453,24 +451,24 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, uint64_t v, bool preserveSize) * ContextTag() or CommonTag(). * @param[in] v The value to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v) { return Put(tag, static_cast(v)); } @@ -488,24 +486,24 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) * number of bytes necessary to represent the value. Note: Applications * are strongly encouraged to set this parameter to false. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_Int8, tag, v); @@ -514,17 +512,17 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int16_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int16_t v) { return Put(tag, static_cast(v)); } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int16_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int16_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_Int16, tag, v); @@ -533,17 +531,17 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, int16_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int32_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int32_t v) { return Put(tag, static_cast(v)); } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int32_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int32_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_Int32, tag, v); @@ -552,9 +550,9 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, int32_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int64_t v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int64_t v) { TLVElementType elemType; if (v >= INT8_MIN && v <= INT8_MAX) @@ -569,9 +567,9 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, int64_t v) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, int8_t v, bool preserveSize) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, int64_t v, bool preserveSize) +CHIP_ERROR TLVWriter::Put(uint64_t tag, int64_t v, bool preserveSize) { if (preserveSize) return WriteElementHead(kTLVElementType_Int64, tag, v); @@ -580,9 +578,9 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, int64_t v, bool preserveSize) } /** - * @overload WEAVE_ERROR TLVWriter::Put(uint64_t tag, double v) + * @overload CHIP_ERROR TLVWriter::Put(uint64_t tag, double v) */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, float v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, float v) { union { @@ -602,24 +600,24 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, float v) * ContextTag() or CommonTag(). * @param[in] v The value to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::Put(uint64_t tag, double v) +CHIP_ERROR TLVWriter::Put(uint64_t tag, double v) { union { @@ -640,24 +638,24 @@ WEAVE_ERROR TLVWriter::Put(uint64_t tag, double v) * @param[in] buf A pointer to a buffer containing the bytes string to be encoded. * @param[in] len The number of bytes to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) +CHIP_ERROR TLVWriter::PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) { return WriteElementWithData(kTLVType_ByteString, tag, (const uint8_t *) buf, len); } @@ -671,24 +669,24 @@ WEAVE_ERROR TLVWriter::PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) * ContextTag() or CommonTag(). * @param[in] buf A pointer to the null-terminated UTF-8 string to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::PutString(uint64_t tag, const char *buf) +CHIP_ERROR TLVWriter::PutString(uint64_t tag, const char *buf) { return PutString(tag, buf, strlen(buf)); } @@ -703,24 +701,24 @@ WEAVE_ERROR TLVWriter::PutString(uint64_t tag, const char *buf) * @param[in] buf A pointer to the UTF-8 string to be encoded. * @param[in] len The length (in bytes) of the string to be encoded. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::PutString(uint64_t tag, const char *buf, uint32_t len) +CHIP_ERROR TLVWriter::PutString(uint64_t tag, const char *buf, uint32_t len) { return WriteElementWithData(kTLVType_UTF8String, tag, (const uint8_t *) buf, len); } @@ -766,15 +764,15 @@ WEAVE_ERROR TLVWriter::PutString(uint64_t tag, const char *buf, uint32_t len) * @param[in] ... A list of arguments to be formatted in the output value * according to fmt. * - * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #CHIP_NO_ERROR If the method succeeded. * * @retval other If underlying calls to TLVWriter methods -- * `WriteElementHead` or `GetNewBuffer` -- failed, their * error is immediately forwarded up the call stack. */ -WEAVE_ERROR TLVWriter::PutStringF(uint64_t tag, const char *fmt, ...) +CHIP_ERROR TLVWriter::PutStringF(uint64_t tag, const char *fmt, ...) { - WEAVE_ERROR err; + CHIP_ERROR err; va_list ap; va_start(ap, fmt); @@ -792,7 +790,7 @@ WEAVE_ERROR TLVWriter::PutStringF(uint64_t tag, const char *fmt, ...) // emits a single character. The callback performs a function // identical to putchar. -void TLVWriter::WeaveTLVWriterPutcharCB(uint8_t c, void *appState) +void TLVWriter::CHIPTLVWriterPutcharCB(uint8_t c, void *appState) { TLVWriter *w = static_cast(appState); w->WriteData(&c, sizeof(c)); @@ -840,17 +838,17 @@ void TLVWriter::WeaveTLVWriterPutcharCB(uint8_t c, void *appState) * @param[in] ap A list of arguments to be formatted in the output value * according to fmt. * - * @retval #WEAVE_NO_ERROR If the method succeeded. + * @retval #CHIP_NO_ERROR If the method succeeded. * * @retval other If underlying calls to TLVWriter methods -- * `WriteElementHead` or `GetNewBuffer` -- failed, their * error is immediately forwarded up the call stack. */ -WEAVE_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) +CHIP_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) { va_list aq; size_t dataLen; - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; TLVFieldSize lenFieldSize; #if CONFIG_HAVE_VSNPRINTF_EX size_t skipLen; @@ -887,7 +885,7 @@ WEAVE_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) err = WriteElementHead((TLVElementType) (kTLVType_UTF8String | lenFieldSize), tag, dataLen); SuccessOrExit(err); - VerifyOrExit((mLenWritten + dataLen) <= mMaxLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + VerifyOrExit((mLenWritten + dataLen) <= mMaxLen, err = CHIP_ERROR_BUFFER_TOO_SMALL); // write data #if CONFIG_HAVE_VSNPRINTF_EX @@ -909,7 +907,7 @@ WEAVE_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) mLenWritten += writtenBytes; if (skipLen < dataLen) { - VerifyOrExit(GetNewBuffer != NULL, err = WEAVE_ERROR_NO_MEMORY); + VerifyOrExit(GetNewBuffer != NULL, err = CHIP_ERROR_NO_MEMORY); if (FinalizeBuffer != NULL) { @@ -929,14 +927,14 @@ WEAVE_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) va_copy(aq, ap); - vcbprintf(WeaveTLVWriterPutcharCB, this, dataLen, fmt, aq); + vcbprintf(CHIPTLVWriterPutcharCB, this, dataLen, fmt, aq); va_end(aq); #elif HAVE_MALLOC tmpBuf = static_cast(malloc(dataLen+1)); - VerifyOrExit(tmpBuf != NULL, err = WEAVE_ERROR_NO_MEMORY); + VerifyOrExit(tmpBuf != NULL, err = CHIP_ERROR_NO_MEMORY); va_copy(aq, ap); @@ -975,24 +973,24 @@ WEAVE_ERROR TLVWriter::VPutStringF(uint64_t tag, const char *fmt, va_list ap) * constructed with one of the tag definition functions ProfileTag(), * ContextTag() or CommonTag(). * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::PutNull(uint64_t tag) +CHIP_ERROR TLVWriter::PutNull(uint64_t tag) { return WriteElementHead(kTLVElementType_Null, tag, 0); } @@ -1013,34 +1011,34 @@ WEAVE_ERROR TLVWriter::PutNull(uint64_t tag) * @param[in] reader A reference to a TLVReader object identifying a pre-encoded TLV * element that should be copied. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE * If the supplied reader is not positioned on an element. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_TLV_UNDERRUN + * @retval #CHIP_ERROR_TLV_UNDERRUN * If the underlying TLV encoding associated with the supplied reader ended * prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the supplied reader encountered an invalid or unsupported TLV element * type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the supplied reader encountered a TLV tag in an invalid context, * or if the supplied tag is invalid or inappropriate in the context in * which the new container is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() * function associated with the reader object. * */ -WEAVE_ERROR TLVWriter::CopyElement(TLVReader& reader) +CHIP_ERROR TLVWriter::CopyElement(TLVReader& reader) { return CopyElement(reader.GetTag(), reader); } @@ -1065,47 +1063,47 @@ WEAVE_ERROR TLVWriter::CopyElement(TLVReader& reader) * @param[in] reader A reference to a TLVReader object identifying a pre-encoded TLV * element whose type and value should be copied. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE * If the supplied reader is not positioned on an element. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_TLV_UNDERRUN + * @retval #CHIP_ERROR_TLV_UNDERRUN * If the underlying TLV encoding associated with the supplied reader ended * prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the supplied reader encountered an invalid or unsupported TLV element * type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the supplied reader encountered a TLV tag in an invalid context, * or if the supplied tag is invalid or inappropriate in the context in * which the new container is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() * function associated with the reader object. * */ -const size_t kWeaveTLVCopyChunkSize = 16; +const size_t kCHIPTLVCopyChunkSize = 16; -WEAVE_ERROR TLVWriter::CopyElement(uint64_t tag, TLVReader& reader) +CHIP_ERROR TLVWriter::CopyElement(uint64_t tag, TLVReader& reader) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; TLVElementType elemType = reader.ElementType(); uint64_t elemLenOrVal = reader.mElemLenOrVal; TLVReader readerHelper; // used to figure out the length of the element and read data of the element uint32_t copyDataLen; - uint8_t chunk[kWeaveTLVCopyChunkSize]; + uint8_t chunk[kCHIPTLVCopyChunkSize]; - VerifyOrExit(elemType != kTLVElementType_NotSpecified && elemType != kTLVElementType_EndOfContainer, err = WEAVE_ERROR_INCORRECT_STATE); + VerifyOrExit(elemType != kTLVElementType_NotSpecified && elemType != kTLVElementType_EndOfContainer, err = CHIP_ERROR_INCORRECT_STATE); // Initialize the helper readerHelper.Init(reader); @@ -1124,7 +1122,7 @@ WEAVE_ERROR TLVWriter::CopyElement(uint64_t tag, TLVReader& reader) while (copyDataLen > 0) { - uint32_t chunkSize = copyDataLen > kWeaveTLVCopyChunkSize ? kWeaveTLVCopyChunkSize : copyDataLen; + uint32_t chunkSize = copyDataLen > kCHIPTLVCopyChunkSize ? kCHIPTLVCopyChunkSize : copyDataLen; err = readerHelper.ReadData(chunk, chunkSize); SuccessOrExit(err); @@ -1170,39 +1168,39 @@ WEAVE_ERROR TLVWriter::CopyElement(uint64_t tag, TLVReader& reader) * writing the members of the new container element. Any data * associated with the supplied object is overwritten. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE * If the value specified for containerType is incorrect. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter) +CHIP_ERROR TLVWriter::OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(TLVTypeIsContainer(containerType), err = WEAVE_ERROR_WRONG_TLV_TYPE); + VerifyOrExit(TLVTypeIsContainer(containerType), err = CHIP_ERROR_WRONG_TLV_TYPE); if (IsCloseContainerReserved()) { - VerifyOrExit(mMaxLen >= kEndOfContainerMarkerSize, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + VerifyOrExit(mMaxLen >= kEndOfContainerMarkerSize, err = CHIP_ERROR_BUFFER_TOO_SMALL); mMaxLen -= kEndOfContainerMarkerSize; } err = WriteElementHead((TLVElementType) containerType, tag, 0); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) { // undo the space reservation, as the container is not actually open if (IsCloseContainerReserved()) @@ -1245,30 +1243,30 @@ WEAVE_ERROR TLVWriter::OpenContainer(uint64_t tag, TLVType containerType, TLVWri * @param[in] containerWriter A reference to the TLVWriter object that was supplied to the * OpenContainer() method. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE * If the supplied container writer is not in the correct state. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If another container writer has been opened on the supplied * container writer and not yet closed. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If completing the encoding of the container would exceed the * limit on the maximum number of bytes specified when the writer * was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack * of memory. - * @retval other Other Weave or platform-specific errors returned by the + * @retval other Other CHIP or platform-specific errors returned by the * configured GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::CloseContainer(TLVWriter& containerWriter) +CHIP_ERROR TLVWriter::CloseContainer(TLVWriter& containerWriter) { if (!TLVTypeIsContainer(containerWriter.mContainerType)) - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; if (containerWriter.IsContainerOpen()) - return WEAVE_ERROR_TLV_CONTAINER_OPEN; + return CHIP_ERROR_TLV_CONTAINER_OPEN; mBufHandle = containerWriter.mBufHandle; mBufStart = containerWriter.mBufStart; @@ -1309,39 +1307,39 @@ WEAVE_ERROR TLVWriter::CloseContainer(TLVWriter& containerWriter) * A reference to a TLVType value that will receive the context of the * writer. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE * If the value specified for containerType is incorrect. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) +CHIP_ERROR TLVWriter::StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit(TLVTypeIsContainer(containerType), err = WEAVE_ERROR_WRONG_TLV_TYPE); + VerifyOrExit(TLVTypeIsContainer(containerType), err = CHIP_ERROR_WRONG_TLV_TYPE); if (IsCloseContainerReserved()) { - VerifyOrExit(mMaxLen >= kEndOfContainerMarkerSize, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + VerifyOrExit(mMaxLen >= kEndOfContainerMarkerSize, err = CHIP_ERROR_BUFFER_TOO_SMALL); mMaxLen -= kEndOfContainerMarkerSize; } err = WriteElementHead((TLVElementType) containerType, tag, 0); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) { // undo the space reservation, as the container is not actually open if (IsCloseContainerReserved()) @@ -1376,26 +1374,26 @@ WEAVE_ERROR TLVWriter::StartContainer(uint64_t tag, TLVType containerType, TLVTy * @param[in] outerContainerType * The TLVType value that was returned by the StartContainer() method. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE * If a corresponding StartContainer() call was not made. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::EndContainer(TLVType outerContainerType) +CHIP_ERROR TLVWriter::EndContainer(TLVType outerContainerType) { if (!TLVTypeIsContainer(mContainerType)) - return WEAVE_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INCORRECT_STATE; mContainerType = outerContainerType; @@ -1426,32 +1424,32 @@ WEAVE_ERROR TLVWriter::EndContainer(TLVType outerContainerType) * will become the members of the new container. * @param[in] dataLen The number of bytes in the @p data buffer. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_WRONG_TLV_TYPE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_WRONG_TLV_TYPE * If the value specified for containerType is incorrect. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the specified tag value is invalid or inappropriate in the context * in which the value is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions. * */ -WEAVE_ERROR TLVWriter::PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen) +CHIP_ERROR TLVWriter::PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen) { if (!TLVTypeIsContainer(containerType)) - return WEAVE_ERROR_INVALID_ARGUMENT; + return CHIP_ERROR_INVALID_ARGUMENT; - WEAVE_ERROR err = WriteElementHead((TLVElementType)containerType, tag, 0); - if (err != WEAVE_NO_ERROR) + CHIP_ERROR err = WriteElementHead((TLVElementType)containerType, tag, 0); + if (err != CHIP_NO_ERROR) return err; return WriteData(data, dataLen); @@ -1473,34 +1471,34 @@ WEAVE_ERROR TLVWriter::PutPreEncodedContainer(uint64_t tag, TLVType containerTyp * @param[in] container A reference to a TLVReader object identifying the pre-encoded TLV * container to be copied. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE * If the supplied reader is not positioned on a container element. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_TLV_UNDERRUN + * @retval #CHIP_ERROR_TLV_UNDERRUN * If the underlying TLV encoding associated with the supplied reader ended * prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the supplied reader encountered an invalid or unsupported TLV element * type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the supplied reader encountered a TLV tag in an invalid context, * or if the tag associated with the source container is invalid or * inappropriate in the context in which the new container is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() * function associated with the reader object. * */ -WEAVE_ERROR TLVWriter::CopyContainer(TLVReader& container) +CHIP_ERROR TLVWriter::CopyContainer(TLVReader& container) { return CopyContainer(container.GetTag(), container); } @@ -1528,50 +1526,50 @@ WEAVE_ERROR TLVWriter::CopyContainer(TLVReader& container) * @param[in] container A reference to a TLVReader object identifying a pre-encoded TLV * container whose type and members should be copied. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_INCORRECT_STATE + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_INCORRECT_STATE * If the supplied reader is not positioned on a container element. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_TLV_UNDERRUN + * @retval #CHIP_ERROR_TLV_UNDERRUN * If the underlying TLV encoding associated with the supplied reader ended * prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the supplied reader encountered an invalid or unsupported TLV element * type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the supplied reader encountered a TLV tag in an invalid context, * or if the supplied tag is invalid or inappropriate in the context in * which the new container is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() * function associated with the reader object. * */ -WEAVE_ERROR TLVWriter::CopyContainer(uint64_t tag, TLVReader& container) +CHIP_ERROR TLVWriter::CopyContainer(uint64_t tag, TLVReader& container) { // NOTE: This function MUST be used with a TVLReader that is reading from a contiguous buffer. - WEAVE_ERROR err; + CHIP_ERROR err; TLVType containerType, outerContainerType; const uint8_t *containerStart; containerType = container.GetType(); err = container.EnterContainer(outerContainerType); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; containerStart = container.GetReadPoint(); err = container.ExitContainer(outerContainerType); - if (err != WEAVE_NO_ERROR) + if (err != CHIP_NO_ERROR) return err; return PutPreEncodedContainer(tag, containerType, containerStart, container.GetReadPoint() - containerStart); @@ -1597,32 +1595,32 @@ WEAVE_ERROR TLVWriter::CopyContainer(uint64_t tag, TLVReader& container) * should be copied. * @param[in] encodedContainerLen The length in bytes of the pre-encoded container. * - * @retval #WEAVE_NO_ERROR If the method succeeded. - * @retval #WEAVE_ERROR_TLV_CONTAINER_OPEN + * @retval #CHIP_NO_ERROR If the method succeeded. + * @retval #CHIP_ERROR_TLV_CONTAINER_OPEN * If a container writer has been opened on the current writer and not * yet closed. - * @retval #WEAVE_ERROR_TLV_UNDERRUN + * @retval #CHIP_ERROR_TLV_UNDERRUN * If the encoded container ended prematurely. - * @retval #WEAVE_ERROR_INVALID_TLV_ELEMENT + * @retval #CHIP_ERROR_INVALID_TLV_ELEMENT * If the encoded container contained an invalid or unsupported TLV element type. - * @retval #WEAVE_ERROR_INVALID_TLV_TAG + * @retval #CHIP_ERROR_INVALID_TLV_TAG * If the encoded container contained a TLV tag in an invalid context, * or if the supplied tag is invalid or inappropriate in the context in * which the new container is being written. - * @retval #WEAVE_ERROR_BUFFER_TOO_SMALL + * @retval #CHIP_ERROR_BUFFER_TOO_SMALL * If writing the value would exceed the limit on the maximum number of * bytes specified when the writer was initialized. - * @retval #WEAVE_ERROR_NO_MEMORY + * @retval #CHIP_ERROR_NO_MEMORY * If an attempt to allocate an output buffer failed due to lack of * memory. - * @retval other Other Weave or platform-specific errors returned by the configured + * @retval other Other CHIP or platform-specific errors returned by the configured * GetNewBuffer() or FinalizeBuffer() functions, or by the GetNextBuffer() * function associated with the reader object. * */ -WEAVE_ERROR TLVWriter::CopyContainer(uint64_t tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen) +CHIP_ERROR TLVWriter::CopyContainer(uint64_t tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen) { - WEAVE_ERROR err; + CHIP_ERROR err; TLVReader reader; reader.Init(encodedContainer, encodedContainerLen); @@ -1652,13 +1650,13 @@ TLVType TLVWriter::GetContainerType() const return mContainerType; } -WEAVE_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal) +CHIP_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal) { uint8_t *p; uint8_t stagingBuf[17]; // 17 = 1 control byte + 8 tag bytes + 8 length/value bytes if (IsContainerOpen()) - return WEAVE_ERROR_TLV_CONTAINER_OPEN; + return CHIP_ERROR_TLV_CONTAINER_OPEN; uint32_t tagNum = TagNumFromTag(tag); @@ -1672,7 +1670,7 @@ WEAVE_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, u if (tagNum < 256) { if (mContainerType != kTLVType_Structure && mContainerType != kTLVType_Path) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; Write8(p, kTLVTagControl_ContextSpecific | elemType); Write8(p, (uint8_t) tagNum); @@ -1681,7 +1679,7 @@ WEAVE_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, u { if (elemType != kTLVElementType_EndOfContainer && mContainerType != kTLVType_NotSpecified && mContainerType != kTLVType_Array) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; Write8(p, kTLVTagControl_Anonymous | elemType); } @@ -1692,7 +1690,7 @@ WEAVE_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, u if (mContainerType != kTLVType_NotSpecified && mContainerType != kTLVType_Structure && mContainerType != kTLVType_Path) - return WEAVE_ERROR_INVALID_TLV_TAG; + return CHIP_ERROR_INVALID_TLV_TAG; if (profileId == kCommonProfileId) { @@ -1766,13 +1764,13 @@ WEAVE_ERROR TLVWriter::WriteElementHead(TLVElementType elemType, uint64_t tag, u mWritePoint = p; mRemainingLen -= len; mLenWritten += len; - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } else return WriteData(stagingBuf, p - stagingBuf); } -WEAVE_ERROR TLVWriter::WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen) +CHIP_ERROR TLVWriter::WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen) { TLVFieldSize lenFieldSize; @@ -1783,24 +1781,24 @@ WEAVE_ERROR TLVWriter::WriteElementWithData(TLVType type, uint64_t tag, const ui else lenFieldSize = kTLVFieldSize_4Byte; - WEAVE_ERROR err = WriteElementHead((TLVElementType) (type | lenFieldSize), tag, dataLen); - if (err != WEAVE_NO_ERROR) + CHIP_ERROR err = WriteElementHead((TLVElementType) (type | lenFieldSize), tag, dataLen); + if (err != CHIP_NO_ERROR) return err; return WriteData(data, dataLen); } -WEAVE_ERROR TLVWriter::WriteData(const uint8_t *p, uint32_t len) +CHIP_ERROR TLVWriter::WriteData(const uint8_t *p, uint32_t len) { - WEAVE_ERROR err = WEAVE_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; - VerifyOrExit((mLenWritten + len) <= mMaxLen, err = WEAVE_ERROR_BUFFER_TOO_SMALL); + VerifyOrExit((mLenWritten + len) <= mMaxLen, err = CHIP_ERROR_BUFFER_TOO_SMALL); while (len > 0) { if (mRemainingLen == 0) { - VerifyOrExit(GetNewBuffer != NULL, err = WEAVE_ERROR_NO_MEMORY); + VerifyOrExit(GetNewBuffer != NULL, err = CHIP_ERROR_NO_MEMORY); if (FinalizeBuffer != NULL) { @@ -1846,7 +1844,7 @@ WEAVE_ERROR TLVWriter::WriteData(const uint8_t *p, uint32_t len) * See the GetNewBufferFunct type definition for additional information on the API of the * GetNewPacketBuffer() function. */ -WEAVE_ERROR TLVWriter::GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) +CHIP_ERROR TLVWriter::GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) { PacketBuffer *buf = (PacketBuffer *) bufHandle; @@ -1870,7 +1868,7 @@ WEAVE_ERROR TLVWriter::GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandl bufLen = 0; } - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } /** @@ -1883,16 +1881,15 @@ WEAVE_ERROR TLVWriter::GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandl * See the FinalizeBufferFunct type definition for additional information on the API of the * FinalizePacketBuffer() function. */ -WEAVE_ERROR TLVWriter::FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen) +CHIP_ERROR TLVWriter::FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen) { PacketBuffer *buf = (PacketBuffer *) bufHandle; uint8_t * endPtr = bufStart + dataLen; buf->SetDataLength(endPtr - buf->Start()); - return WEAVE_NO_ERROR; + return CHIP_NO_ERROR; } } // namespace TLV -} // namespace Weave -} // namespace nl +} // namespace chip diff --git a/src/lib/core/WeaveTLV.h b/src/lib/core/WeaveTLV.h deleted file mode 100644 index 04fbdd5f8e8fa9..00000000000000 --- a/src/lib/core/WeaveTLV.h +++ /dev/null @@ -1,470 +0,0 @@ -/* - * - * Copyright (c) 2013-2017 Nest Labs, Inc. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * This file contains definitions for working with data encoded in Weave TLV format. - * - * Weave TLV (Tag-Length-Value) is a generalized encoding method for simple structured data. It - * shares many properties with the commonly used JSON serialization format while being considerably - * more compact over the wire. - */ - -#ifndef WEAVETLV_H_ -#define WEAVETLV_H_ - -#include -#include - -#include -#include -#include "WeaveTLVTags.h" -#include "WeaveTLVTypes.h" - -// forward declaration of the PacketBuffer class used within the header. -namespace nl { -namespace Weave { -namespace System { - -class PacketBuffer; - -} // namespace System -} // namespace Weave -} // namespace nl - -/** - * @namespace nl::Weave::TLV - * - * Definitions for working with data encoded in Weave TLV format. - * - * Weave TLV is a generalized encoding method for simple structured data. It shares many properties - * with the commonly used JSON serialization format while being considerably more compact over the wire. - */ - -namespace nl { -namespace Weave { -namespace TLV { - -using nl::Weave::System::PacketBuffer; - -enum { - kTLVControlByte_NotSpecified = 0xFFFF -}; - -/** - * Provides a memory efficient parser for data encoded in Weave TLV format. - * - * TLVReader implements a forward-only, “pull-style” parser for Weave TLV data. The TLVReader - * object operates as a cursor that can be used to iterate over a sequence of TLV elements - * and interpret their contents. When positioned on an element, applications can make calls - * to the reader's Get() methods to query the current element’s type and tag, and to extract - * any associated value. The reader’s Next() method is used to advance from element to element. - * - * A TLVReader object is always positioned either before, on or after a TLV element. When first - * initialized, a TLVReader is positioned immediately before the first element of the encoding. - * To begin reading, an application must make an initial call to the Next() method to position - * the reader on the first element. When a container element is encountered--either a structure, - * an array or a path--the OpenContainer() or EnterContainer() methods can be used to iterate - * through the contents of the container. - * - * When the reader reaches the end of a TLV encoding, or the last element within a container, - * it signals the application by returning a WEAVE_END_OF_TLV error from the Next() method. - * The reader will continue to return WEAVE_END_OF_TLV until it is reinitialized, or the current - * container is exited (via CloseContainer() / ExitContainer()). - * - * A TLVReader object can parse data directly from a fixed input buffer, or from a chain of one - * or more PacketBuffers. Additionally, applications can supply a @p GetNextBuffer function to - * feed data to the reader from an arbitrary source, e.g. a socket or a serial port. - * - */ -class NL_DLL_EXPORT TLVReader -{ -friend class TLVWriter; -friend class TLVUpdater; - -public: - // *** See WeaveTLVReader.cpp file for API documentation *** - - void Init(const TLVReader &aReader); - void Init(const uint8_t *data, uint32_t dataLen); - void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL); - void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers); - - WEAVE_ERROR Next(void); - WEAVE_ERROR Next(TLVType expectedType, uint64_t expectedTag); - - TLVType GetType(void) const; - uint64_t GetTag(void) const; - uint32_t GetLength(void) const; - uint16_t GetControlByte(void) const; - - WEAVE_ERROR Get(bool& v); - WEAVE_ERROR Get(int8_t& v); - WEAVE_ERROR Get(int16_t& v); - WEAVE_ERROR Get(int32_t& v); - WEAVE_ERROR Get(int64_t& v); - WEAVE_ERROR Get(uint8_t& v); - WEAVE_ERROR Get(uint16_t& v); - WEAVE_ERROR Get(uint32_t& v); - WEAVE_ERROR Get(uint64_t& v); - WEAVE_ERROR Get(float& v); - WEAVE_ERROR Get(double& v); - WEAVE_ERROR GetBytes(uint8_t *buf, uint32_t bufSize); - WEAVE_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen); - WEAVE_ERROR GetString(char *buf, uint32_t bufSize); - WEAVE_ERROR DupString(char *& buf); - WEAVE_ERROR GetDataPtr(const uint8_t *& data); - - WEAVE_ERROR EnterContainer(TLVType& outerContainerType); - WEAVE_ERROR ExitContainer(TLVType outerContainerType); - WEAVE_ERROR OpenContainer(TLVReader& containerReader); - WEAVE_ERROR CloseContainer(TLVReader& containerReader); - TLVType GetContainerType(void) const; - WEAVE_ERROR VerifyEndOfContainer(void); - - uint32_t GetLengthRead(void) const { return mLenRead; } - uint32_t GetRemainingLength(void) const { return mMaxLen - mLenRead; } - - const uint8_t *GetReadPoint(void) const { return mReadPoint; } - uintptr_t GetBufHandle(void) const { return mBufHandle; } - - WEAVE_ERROR Skip(void); - - uint32_t ImplicitProfileId; - void *AppData; - - typedef WEAVE_ERROR (*GetNextBufferFunct)(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, - uint32_t& bufLen); - GetNextBufferFunct GetNextBuffer; - -protected: - uint64_t mElemTag; - uint64_t mElemLenOrVal; - uintptr_t mBufHandle; - const uint8_t *mReadPoint; - const uint8_t *mBufEnd; - uint32_t mLenRead; - uint32_t mMaxLen; - TLVType mContainerType; - uint16_t mControlByte; - -private: - bool mContainerOpen; - -protected: - bool IsContainerOpen(void) const { return mContainerOpen; } - void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; } - - WEAVE_ERROR ReadElement(void); - void ClearElementState(void); - WEAVE_ERROR SkipData(void); - WEAVE_ERROR SkipToEndOfContainer(void); - WEAVE_ERROR VerifyElement(void); - uint64_t ReadTag(TLVTagControl tagControl, const uint8_t *& p); - WEAVE_ERROR EnsureData(WEAVE_ERROR noDataErr); - WEAVE_ERROR ReadData(uint8_t *buf, uint32_t len); - WEAVE_ERROR GetElementHeadLength(uint8_t& elemHeadBytes) const; - TLVElementType ElementType(void) const; - - static WEAVE_ERROR GetNextPacketBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, - uint32_t& bufLen); - static WEAVE_ERROR FailGetNextBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, - uint32_t& bufLen); - -#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES - static WEAVE_ERROR GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, - uint32_t& bufLen); -#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES -}; - -#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES -inline WEAVE_ERROR TLVReader::GetNextInetBuffer(TLVReader& reader, uintptr_t& bufHandle, const uint8_t *& bufStart, - uint32_t& bufLen) -{ - return GetNextPacketBuffer(reader, bufHandle, bufStart, bufLen); -} -#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES - -/** - * Provides a memory efficient encoder for writing data in Weave TLV format. - * - * TLVWriter implements a forward-only, stream-style encoder for Weave TLV data. Applications - * write data to an encoding by calling one of the writer's Put() methods, passing associated - * tag and value information as necessary. Similarly applications can encode TLV container types - * (structures, arrays or paths) by calling the writer's OpenContainer() or EnterContainer() - * methods. - * - * A TLVWriter object can write data directly to a fixed output buffer, or to a chain of one or - * more PacketBuffer objects. Additionally, applications can supply their own @p GetNewBuffer and - * @p FinalizeBuffer functions to direct output to an arbitrary destination, e.g. a socket or an - * event queue. - * - */ -class NL_DLL_EXPORT TLVWriter -{ -friend class TLVUpdater; -public: - // *** See WeaveTLVWriter.cpp file for API documentation *** - - void Init(uint8_t *buf, uint32_t maxLen); - void Init(PacketBuffer *buf, uint32_t maxLen = 0xFFFFFFFFUL); - void Init(PacketBuffer *buf, uint32_t maxLen, bool allowDiscontiguousBuffers); - - WEAVE_ERROR Finalize(void); - - WEAVE_ERROR Put(uint64_t tag, int8_t v); - WEAVE_ERROR Put(uint64_t tag, int8_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, int16_t v); - WEAVE_ERROR Put(uint64_t tag, int16_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, int32_t v); - WEAVE_ERROR Put(uint64_t tag, int32_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, int64_t v); - WEAVE_ERROR Put(uint64_t tag, int64_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, uint8_t v); - WEAVE_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, uint16_t v); - WEAVE_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, uint32_t v); - WEAVE_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, uint64_t v); - WEAVE_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize); - WEAVE_ERROR Put(uint64_t tag, float v); - WEAVE_ERROR Put(uint64_t tag, double v); - WEAVE_ERROR PutBoolean(uint64_t tag, bool v); - WEAVE_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len); - WEAVE_ERROR PutString(uint64_t tag, const char *buf); - WEAVE_ERROR PutString(uint64_t tag, const char *buf, uint32_t len); - WEAVE_ERROR PutStringF(uint64_t tag, const char *fmt, ...); - WEAVE_ERROR VPutStringF(uint64_t tag, const char *fmt, va_list ap); - WEAVE_ERROR PutNull(uint64_t tag); - WEAVE_ERROR CopyElement(TLVReader& reader); - WEAVE_ERROR CopyElement(uint64_t tag, TLVReader& reader); - - WEAVE_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType); - WEAVE_ERROR EndContainer(TLVType outerContainerType); - WEAVE_ERROR OpenContainer(uint64_t tag, TLVType containerType, TLVWriter& containerWriter); - WEAVE_ERROR CloseContainer(TLVWriter& containerWriter); - WEAVE_ERROR PutPreEncodedContainer(uint64_t tag, TLVType containerType, const uint8_t *data, uint32_t dataLen); - WEAVE_ERROR CopyContainer(TLVReader& container); - WEAVE_ERROR CopyContainer(uint64_t tag, TLVReader& container); - WEAVE_ERROR CopyContainer(uint64_t tag, const uint8_t * encodedContainer, uint16_t encodedContainerLen); - TLVType GetContainerType(void) const; - - uint32_t GetLengthWritten(void); - - uint32_t ImplicitProfileId; - void *AppData; - - typedef WEAVE_ERROR (*GetNewBufferFunct)(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, - uint32_t& bufLen); - GetNewBufferFunct GetNewBuffer; - - typedef WEAVE_ERROR (*FinalizeBufferFunct)(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, - uint32_t bufLen); - FinalizeBufferFunct FinalizeBuffer; - - // Implementations of GetNewBufferFunct/FinalizeBufferFunct that support writing into one or more - // PacketBuffers. - static WEAVE_ERROR GetNewPacketBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen); - static WEAVE_ERROR FinalizePacketBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen); - -#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES - static WEAVE_ERROR GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen); - static WEAVE_ERROR FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen); -#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES - -protected: - uintptr_t mBufHandle; - uint8_t *mBufStart; - uint8_t *mWritePoint; - uint32_t mRemainingLen; - uint32_t mLenWritten; - uint32_t mMaxLen; - TLVType mContainerType; - -private: - bool mContainerOpen; - bool mCloseContainerReserved; - -protected: - bool IsContainerOpen(void) const { return mContainerOpen; } - void SetContainerOpen(bool aContainerOpen) { mContainerOpen = aContainerOpen; } - - enum { - kEndOfContainerMarkerSize = 1, /**< Size of the EndOfContainer marker, used in reserving space. */ - }; - - /** - * @brief - * Determine whether the container should reserve space for the - * CloseContainer symbol at the point of starting / opening the - * container. - */ - bool IsCloseContainerReserved(void) const { return mCloseContainerReserved; } - - /** - * @brief - * Set whether the container should reserve the space for the - * CloseContainer symbol at the point of starting / opening the - * container. - */ - void SetCloseContainerReserved(bool aCloseContainerReserved) { mCloseContainerReserved = aCloseContainerReserved; } - -#if CONFIG_HAVE_VCBPRINTF - static void WeaveTLVWriterPutcharCB(uint8_t c, void *appState); -#endif - WEAVE_ERROR WriteElementHead(TLVElementType elemType, uint64_t tag, uint64_t lenOrVal); - WEAVE_ERROR WriteElementWithData(TLVType type, uint64_t tag, const uint8_t *data, uint32_t dataLen); - WEAVE_ERROR WriteData(const uint8_t *p, uint32_t len); -}; - -#if WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES -inline WEAVE_ERROR TLVWriter::GetNewInetBuffer(TLVWriter& writer, uintptr_t& bufHandle, uint8_t *& bufStart, uint32_t& bufLen) -{ - return GetNewPacketBuffer(writer, bufHandle, bufStart, bufLen); -} - -inline WEAVE_ERROR TLVWriter::FinalizeInetBuffer(TLVWriter& writer, uintptr_t bufHandle, uint8_t *bufStart, uint32_t dataLen) -{ - return FinalizePacketBuffer(writer, bufHandle, bufStart, dataLen); -} -#endif // WEAVE_CONFIG_PROVIDE_OBSOLESCENT_INTERFACES - -/** - * Provides a unified Reader/Writer interface for editing/adding/deleting elements in TLV encoding. - * - * The TLVUpdater is a union of the TLVReader and TLVWriter objects and provides interface methods - * for editing/deleting data in an encoding as well as adding new elements to the TLV encoding. The - * TLVUpdater object essentially acts like two cursors, one for reading existing encoding and - * another for writing (either for copying over existing data or writing new data). - * - * Semantically, the TLVUpdater object functions like a union of the TLVReader and TLVWriter. The - * TLVUpdater methods have more or less similar meanings as similarly named counterparts in - * TLVReader/TLVWriter. Where there are differences in the semantics, the differences are clearly - * documented in the function's comment section in WeaveTLVUpdater.cpp. - * - * One particularly important note about the TLVUpdater's PutBytes() and PutString() methods is that - * it can leave the encoding in a corrupt state with only the element header written when an - * overflow occurs. Applications can call GetRemainingFreeLength() to make sure there is - * @em approximately enough free space to write the encoding. Note that GetRemainingFreeLength() - * only tells you the available free bytes and there is @em no way for the application to know the - * length of encoded data that gets written. In the event of an overflow, both PutBytes() and - * PutString() will return WEAVE_ERROR_BUFFER_TOO_SMALL to the caller. - * - * Also, note that Next() method is overloaded to both skip the current element and also advance the - * internal reader to the next element. Because skipping already encoded elements requires changing - * the internal writer's free space state variables to account for the new freed space (made - * available by skipping), the application is expected to call Next() on the updater after a Get() - * method whose value it doesn't wish to write back (which is equivalent to skipping the current - * element). - * - * @note The application is expected to use the TLVUpdater object atomically from the time it calls - * Init() till it calls Finalize(). The same buffer should NOT be used with other TLVWriter objects. - * - * @note The TLVUpdater currently only supports single static buffers. Support for chain of buffers - * (PacketBuffer) is NOT supported. - */ -class NL_DLL_EXPORT TLVUpdater -{ -public: - WEAVE_ERROR Init(uint8_t *buf, uint32_t dataLen, uint32_t maxLen); - WEAVE_ERROR Init(TLVReader& aReader, uint32_t freeLen); - WEAVE_ERROR Finalize(void) { return mUpdaterWriter.Finalize(); } - - // Common methods - void SetImplicitProfileId(uint32_t profileId); - uint32_t GetImplicitProfileId(void) { return mUpdaterReader.ImplicitProfileId; } - WEAVE_ERROR Move(void); - void MoveUntilEnd(void); - WEAVE_ERROR EnterContainer(TLVType& outerContainerType); - WEAVE_ERROR ExitContainer(TLVType outerContainerType); - void GetReader(TLVReader& containerReader) { containerReader = mUpdaterReader; } - - // Reader methods - WEAVE_ERROR Next(void); - - WEAVE_ERROR Get(bool& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(int8_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(int16_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(int32_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(int64_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(uint8_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(uint16_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(uint32_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(uint64_t& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(float& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR Get(double& v) { return mUpdaterReader.Get(v); } - WEAVE_ERROR GetBytes(uint8_t *buf, uint32_t bufSize) { return mUpdaterReader.GetBytes(buf, bufSize); } - WEAVE_ERROR DupBytes(uint8_t *& buf, uint32_t& dataLen) { return mUpdaterReader.DupBytes(buf, dataLen); } - WEAVE_ERROR GetString(char *buf, uint32_t bufSize) { return mUpdaterReader.GetString(buf, bufSize); } - WEAVE_ERROR DupString(char *& buf) { return mUpdaterReader.DupString(buf); } - - TLVType GetType(void) const { return mUpdaterReader.GetType(); } - uint64_t GetTag(void) const { return mUpdaterReader.GetTag(); } - uint32_t GetLength(void) const { return mUpdaterReader.GetLength(); } - WEAVE_ERROR GetDataPtr(const uint8_t *& data) { return mUpdaterReader.GetDataPtr(data); } - WEAVE_ERROR VerifyEndOfContainer(void) { return mUpdaterReader.VerifyEndOfContainer(); } - TLVType GetContainerType(void) const { return mUpdaterReader.GetContainerType(); } - uint32_t GetLengthRead(void) const { return mUpdaterReader.GetLengthRead(); } - uint32_t GetRemainingLength(void) const { return mUpdaterReader.GetRemainingLength(); } - - // Writer methods - WEAVE_ERROR Put(uint64_t tag, int8_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, int16_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, int32_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, int64_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, uint8_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, uint16_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, uint32_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, uint64_t v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, int8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, int16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, int32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, int64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, uint8_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, uint16_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, uint32_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, uint64_t v, bool preserveSize) { return mUpdaterWriter.Put(tag, v, preserveSize); } - WEAVE_ERROR Put(uint64_t tag, float v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR Put(uint64_t tag, double v) { return mUpdaterWriter.Put(tag, v); } - WEAVE_ERROR PutBoolean(uint64_t tag, bool v) { return mUpdaterWriter.PutBoolean(tag, v); } - WEAVE_ERROR PutNull(uint64_t tag) { return mUpdaterWriter.PutNull(tag); } - WEAVE_ERROR PutBytes(uint64_t tag, const uint8_t *buf, uint32_t len) { return mUpdaterWriter.PutBytes(tag, buf, len); } - WEAVE_ERROR PutString(uint64_t tag, const char *buf) { return mUpdaterWriter.PutString(tag, buf); } - WEAVE_ERROR PutString(uint64_t tag, const char *buf, uint32_t len) { return mUpdaterWriter.PutString(tag, buf, len); } - WEAVE_ERROR CopyElement(TLVReader& reader) { return mUpdaterWriter.CopyElement(reader); } - WEAVE_ERROR CopyElement(uint64_t tag, TLVReader& reader) { return mUpdaterWriter.CopyElement(tag, reader); } - WEAVE_ERROR StartContainer(uint64_t tag, TLVType containerType, TLVType& outerContainerType) { return mUpdaterWriter.StartContainer(tag, containerType, outerContainerType); } - WEAVE_ERROR EndContainer(TLVType outerContainerType) { return mUpdaterWriter.EndContainer(outerContainerType); } - uint32_t GetLengthWritten(void) { return mUpdaterWriter.GetLengthWritten(); } - uint32_t GetRemainingFreeLength(void) { return mUpdaterWriter.mRemainingLen; } - -private: - void AdjustInternalWriterFreeSpace(void); - -private: - TLVWriter mUpdaterWriter; - TLVReader mUpdaterReader; - const uint8_t * mElementStartAddr; -}; - -} // namespace TLV -} // namespace Weave -} // namespace nl - -#endif /* WEAVETLV_H_ */ From c8beb25b773df9b191c3f81f5cf0601c89433c49 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Tue, 10 Mar 2020 15:17:10 -0700 Subject: [PATCH 3/3] Add CHIP TLV to libcore --- src/lib/core/CHIPTLVData.hpp | 6 +++--- src/lib/core/CHIPTLVDebug.hpp | 18 +++++++++--------- src/lib/core/CHIPTLVReader.cpp | 1 + src/lib/core/CHIPTLVUtilities.hpp | 30 +++++++++++++++--------------- src/lib/core/CHIPTLVWriter.cpp | 1 + src/lib/core/Makefile | 21 +++++++++++++++------ 6 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/lib/core/CHIPTLVData.hpp b/src/lib/core/CHIPTLVData.hpp index e306d1666b7687..0105f82513aa79 100644 --- a/src/lib/core/CHIPTLVData.hpp +++ b/src/lib/core/CHIPTLVData.hpp @@ -26,8 +26,8 @@ */ -#ifndef WEAVETLVDATA_H_ -#define WEAVETLVDATA_H_ +#ifndef CHIPTLVDATA_H_ +#define CHIPTLVDATA_H_ #include #include @@ -395,4 +395,4 @@ #define CHIPTLV_BYTE_STRING_8ByteLength(TagSpec, StringLength, ...) \ CHIP::TLV::kTLVElementType_ByteString_8ByteLength | TagSpec, CHIPTLV_Serialize64((uint64_t)(StringLength)), ## __VA_ARGS__ -#endif /* WEAVETLVDATA_H_ */ +#endif /* CHIPTLVDATA_H_ */ diff --git a/src/lib/core/CHIPTLVDebug.hpp b/src/lib/core/CHIPTLVDebug.hpp index 44bf3c8873d039..42f12c1e18f4ff 100644 --- a/src/lib/core/CHIPTLVDebug.hpp +++ b/src/lib/core/CHIPTLVDebug.hpp @@ -22,8 +22,8 @@ * */ -#ifndef WEAVETLVDEBUG_HPP -#define WEAVETLVDEBUG_HPP +#ifndef CHIPTLVDEBUG_HPP +#define CHIPTLVDEBUG_HPP #include #include @@ -31,12 +31,12 @@ #include #include -namespace CHIP { +namespace chip { namespace TLV { /** - * @namespace CHIP::TLV::Debug + * @namespace chip::TLV::Debug * * @brief * This namespace includes types and interfaces for debugging and @@ -56,16 +56,16 @@ extern const char *DecodeType(const TLVType aType); extern const char *DecodeTagControl(const TLVTagControl aTagControl); -extern WEAVE_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader); +extern CHIP_ERROR DumpIterator(DumpWriter aWriter, const TLVReader &aReader); -extern WEAVE_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext); +extern CHIP_ERROR DumpHandler(const TLVReader &aReader, size_t aDepth, void *aContext); -extern WEAVE_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter); +extern CHIP_ERROR Dump(const TLVReader &aReader, DumpWriter aWriter); } // namespace Debug } // namespace TLV -} // namespace CHIP +} // namespace chip -#endif // WEAVETLVDEBUG_HPP +#endif // CHIPTLVDEBUG_HPP diff --git a/src/lib/core/CHIPTLVReader.cpp b/src/lib/core/CHIPTLVReader.cpp index a3f847e07e2b11..1f39469e436285 100644 --- a/src/lib/core/CHIPTLVReader.cpp +++ b/src/lib/core/CHIPTLVReader.cpp @@ -27,6 +27,7 @@ #include #include #include +#include namespace chip { namespace TLV { diff --git a/src/lib/core/CHIPTLVUtilities.hpp b/src/lib/core/CHIPTLVUtilities.hpp index 03dfce7c27984b..05d05d1775e740 100644 --- a/src/lib/core/CHIPTLVUtilities.hpp +++ b/src/lib/core/CHIPTLVUtilities.hpp @@ -22,8 +22,8 @@ * */ -#ifndef WEAVETLVUTILITIES_HPP -#define WEAVETLVUTILITIES_HPP +#ifndef CHIPTLVUTILITIES_HPP +#define CHIPTLVUTILITIES_HPP #include #include @@ -31,12 +31,12 @@ #include #include -namespace CHIP { +namespace chip { namespace TLV { /** - * @namespace CHIP::TLV::Utilities + * @namespace chip::TLV::Utilities * * @brief * This namespace includes types and utility interfaces for managing and @@ -45,23 +45,23 @@ namespace TLV { */ namespace Utilities { -typedef WEAVE_ERROR (*IterateHandler)(const TLVReader &aReader, size_t aDepth, void *aContext); +typedef CHIP_ERROR (*IterateHandler)(const TLVReader &aReader, size_t aDepth, void *aContext); -extern WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext); -extern WEAVE_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext, const bool aRecurse); +extern CHIP_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext); +extern CHIP_ERROR Iterate(const TLVReader &aReader, IterateHandler aHandler, void *aContext, const bool aRecurse); -extern WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount); -extern WEAVE_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse); +extern CHIP_ERROR Count(const TLVReader &aReader, size_t &aCount); +extern CHIP_ERROR Count(const TLVReader &aReader, size_t &aCount, const bool aRecurse); -extern WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult); -extern WEAVE_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult, const bool aRecurse); +extern CHIP_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult); +extern CHIP_ERROR Find(const TLVReader &aReader, const uint64_t &aTag, TLVReader &aResult, const bool aRecurse); -extern WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void *aContext, TLVReader &aResult); -extern WEAVE_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void *aContext, TLVReader &aResult, const bool aRecurse); +extern CHIP_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void *aContext, TLVReader &aResult); +extern CHIP_ERROR Find(const TLVReader &aReader, IterateHandler aHandler, void *aContext, TLVReader &aResult, const bool aRecurse); } // namespace Utilities } // namespace TLV -} // namespace CHIP +} // namespace chip -#endif // WEAVETLVUTILITIES_HPP +#endif // CHIPTLVUTILITIES_HPP diff --git a/src/lib/core/CHIPTLVWriter.cpp b/src/lib/core/CHIPTLVWriter.cpp index 6c19977dd67769..b824064527a389 100644 --- a/src/lib/core/CHIPTLVWriter.cpp +++ b/src/lib/core/CHIPTLVWriter.cpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace chip { namespace TLV { diff --git a/src/lib/core/Makefile b/src/lib/core/Makefile index 82b1f618acfb8e..cf44cc39202359 100644 --- a/src/lib/core/Makefile +++ b/src/lib/core/Makefile @@ -8,15 +8,24 @@ all: libcore.a run_tests include $(TOP_DIR)/.yams/cpp_rules.min Module_Includes = \ - -I. \ - -I$(TOP_DIR)/src/include \ - -I$(TOP_DIR)/src/lib/ \ - -I$(TOP_DIR)/src/system \ - -I$(TOP_DIR)/build/config/standalone/ + -I. \ + -I$(TOP_DIR)/src \ + -I$(TOP_DIR)/src/include \ + -I$(TOP_DIR)/src/lib/ \ + -I$(TOP_DIR)/src/system \ + -I$(TOP_DIR)/build/config/standalone/ \ + -I$(TOP_DIR)/third_party/nlio/repo/include \ + -I$(TOP_DIR)/third_party/nlassert/repo/include \ Module_Test_Includes = $(Module_Includes) -CPP_Files = CHIPError.cpp +CPP_Files = \ + CHIPError.cpp \ + CHIPTLVWriter.cpp \ + CHIPTLVReader.cpp \ + CHIPTLVUtilities.cpp \ + CHIPTLVUpdater.cpp \ + CHIPTLVDebug.cpp \ libcore.a: $(CPP_Objects) ar rvs $@ $^