From bab5c2600497a7f4462a8a54a5af9ce649c29d52 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Mon, 19 Dec 2016 09:05:25 -0800 Subject: [PATCH] Unify base TLV implementation. (#1087) --- etc/visual-studio/libopenthread.vcxproj | 8 +- .../libopenthread.vcxproj.filters | 24 +- etc/visual-studio/libopenthread_k.vcxproj | 8 +- .../libopenthread_k.vcxproj.filters | 22 +- src/core/Makefile.am | 8 +- .../{thread/mle_tlvs.cpp => common/tlvs.cpp} | 43 +++- src/core/common/tlvs.hpp | 212 ++++++++++++++++++ .../thread_tlvs.cpp => meshcop/timestamp.cpp} | 64 +++--- src/core/meshcop/timestamp.hpp | 147 ++++++++++++ src/core/meshcop/tlvs.cpp | 143 ------------ src/core/meshcop/tlvs.hpp | 187 ++------------- src/core/thread/mle_tlvs.hpp | 34 +-- src/core/thread/network_diagnostic_tlvs.cpp | 86 ------- src/core/thread/network_diagnostic_tlvs.hpp | 37 +-- src/core/thread/thread_tlvs.hpp | 28 +-- 15 files changed, 507 insertions(+), 544 deletions(-) rename src/core/{thread/mle_tlvs.cpp => common/tlvs.cpp} (73%) create mode 100644 src/core/common/tlvs.hpp rename src/core/{thread/thread_tlvs.cpp => meshcop/timestamp.cpp} (63%) create mode 100644 src/core/meshcop/timestamp.hpp delete mode 100644 src/core/meshcop/tlvs.cpp delete mode 100644 src/core/thread/network_diagnostic_tlvs.cpp diff --git a/etc/visual-studio/libopenthread.vcxproj b/etc/visual-studio/libopenthread.vcxproj index bac790528..44f603d32 100644 --- a/etc/visual-studio/libopenthread.vcxproj +++ b/etc/visual-studio/libopenthread.vcxproj @@ -65,6 +65,7 @@ + @@ -86,7 +87,7 @@ - + @@ -107,16 +108,13 @@ - - - @@ -136,6 +134,7 @@ + @@ -160,6 +159,7 @@ + diff --git a/etc/visual-studio/libopenthread.vcxproj.filters b/etc/visual-studio/libopenthread.vcxproj.filters index deb8bf5c2..4b592cc1b 100644 --- a/etc/visual-studio/libopenthread.vcxproj.filters +++ b/etc/visual-studio/libopenthread.vcxproj.filters @@ -87,6 +87,9 @@ Source Files\common + + Source Files\common + Source Files\common @@ -153,9 +156,6 @@ Source Files\thread - - Source Files\thread - Source Files\thread @@ -171,18 +171,12 @@ Source Files\thread - - Source Files\thread - Source Files\thread Source Files\thread - - Source Files\thread - Source Files\net @@ -216,15 +210,15 @@ Source Files\meshcop - - Source Files\thread - Source Files\meshcop Source Files\meshcop + + Source Files\meshcop + Source Files\crypto @@ -302,6 +296,9 @@ Header Files\common + + Header Files\common + Header Files\common @@ -464,6 +461,9 @@ Header Files\meshcop + + Header Files\thread + Header Files\thread diff --git a/etc/visual-studio/libopenthread_k.vcxproj b/etc/visual-studio/libopenthread_k.vcxproj index 04f014b23..678b8f8e3 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj +++ b/etc/visual-studio/libopenthread_k.vcxproj @@ -75,6 +75,7 @@ + @@ -95,7 +96,7 @@ - + @@ -116,16 +117,13 @@ - - - @@ -148,6 +146,7 @@ + @@ -172,6 +171,7 @@ + diff --git a/etc/visual-studio/libopenthread_k.vcxproj.filters b/etc/visual-studio/libopenthread_k.vcxproj.filters index 917167c07..078401546 100644 --- a/etc/visual-studio/libopenthread_k.vcxproj.filters +++ b/etc/visual-studio/libopenthread_k.vcxproj.filters @@ -87,6 +87,9 @@ Source Files\common + + Source Files\common + Source Files\common @@ -153,9 +156,6 @@ Source Files\thread - - Source Files\thread - Source Files\thread @@ -171,18 +171,12 @@ Source Files\thread - - Source Files\thread - Source Files\thread Source Files\thread - - Source Files\thread - Source Files\net @@ -222,8 +216,8 @@ Source Files\meshcop - - Source Files\thread + + Source Files\meshcop Source Files\crypto @@ -296,6 +290,9 @@ Header Files\common + + Header Files\common + Header Files\common @@ -452,6 +449,9 @@ Header Files\meshcop + + Header Files\thread + Header Files\thread diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 87c0327a1..1b3486354 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -49,6 +49,7 @@ SOURCES_COMMON = \ common/message.cpp \ common/tasklet.cpp \ common/timer.cpp \ + common/tlvs.cpp \ common/trickle_timer.cpp \ crypto/aes_ccm.cpp \ crypto/aes_ecb.cpp \ @@ -60,7 +61,7 @@ SOURCES_COMMON = \ mac/mac_frame.cpp \ meshcop/dataset.cpp \ meshcop/dataset_manager.cpp \ - meshcop/tlvs.cpp \ + meshcop/timestamp.cpp \ net/icmp6.cpp \ net/ip6.cpp \ net/ip6_address.cpp \ @@ -76,14 +77,11 @@ SOURCES_COMMON = \ thread/lowpan.cpp \ thread/mesh_forwarder.cpp \ thread/mle.cpp \ - thread/mle_tlvs.cpp \ thread/network_data.cpp \ thread/network_data_leader.cpp \ thread/panid_query_server.cpp \ thread/network_diagnostic.cpp \ - thread/network_diagnostic_tlvs.cpp \ thread/thread_netif.cpp \ - thread/thread_tlvs.cpp \ utils/slaac_address.cpp \ $(NULL) @@ -179,6 +177,7 @@ noinst_HEADERS = \ common/new.hpp \ common/tasklet.hpp \ common/timer.hpp \ + common/tlvs.hpp \ common/trickle_timer.hpp \ crypto/aes_ccm.hpp \ crypto/aes_ecb.hpp \ @@ -209,6 +208,7 @@ noinst_HEADERS = \ meshcop/leader_ftd.hpp \ meshcop/leader_mtd.hpp \ meshcop/panid_query_client.hpp \ + meshcop/timestamp.hpp \ meshcop/tlvs.hpp \ net/icmp6.hpp \ net/ip6.hpp \ diff --git a/src/core/thread/mle_tlvs.cpp b/src/core/common/tlvs.cpp similarity index 73% rename from src/core/thread/mle_tlvs.cpp rename to src/core/common/tlvs.cpp index 1a02e0afc..edac6149c 100644 --- a/src/core/thread/mle_tlvs.cpp +++ b/src/core/common/tlvs.cpp @@ -36,9 +36,8 @@ #include namespace Thread { -namespace Mle { -ThreadError Tlv::GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv) +ThreadError Tlv::Get(const Message &aMessage, uint8_t aType, uint16_t aMaxLength, Tlv &aTlv) { ThreadError error = kThreadError_Parse; uint16_t offset; @@ -57,7 +56,7 @@ exit: return error; } -ThreadError Tlv::GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset) +ThreadError Tlv::GetOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset) { ThreadError error = kThreadError_Parse; uint16_t offset = aMessage.GetOffset(); @@ -81,5 +80,41 @@ exit: return error; } -} // namespace Mle +ThreadError Tlv::GetValueOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset, uint16_t &aLength) +{ + ThreadError error = kThreadError_Parse; + uint16_t offset = aMessage.GetOffset(); + uint16_t end = aMessage.GetLength(); + + while (offset < end) + { + Tlv tlv; + uint16_t length; + + aMessage.Read(offset, sizeof(tlv), &tlv); + offset += sizeof(tlv); + + length = tlv.GetLength(); + + if (length == kExtendedLength) + { + aMessage.Read(offset, sizeof(length), &length); + offset += sizeof(length); + length = HostSwap16(length); + } + + if (tlv.GetType() == aType) + { + aOffset = offset; + aLength = length; + ExitNow(error = kThreadError_None); + } + + offset += length; + } + +exit: + return error; +} + } // namespace Thread diff --git a/src/core/common/tlvs.hpp b/src/core/common/tlvs.hpp new file mode 100644 index 000000000..6d6c021d2 --- /dev/null +++ b/src/core/common/tlvs.hpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for generating and processing MLE TLVs. + */ + +#ifndef TLVS_HPP_ +#define TLVS_HPP_ + +#include + +#include +#include +#include + +using Thread::Encoding::BigEndian::HostSwap16; +using Thread::Encoding::BigEndian::HostSwap32; + +namespace Thread { + +/** + * This class implements TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class Tlv +{ +public: + /** + * This method returns the Type value. + * + * @returns The Type value. + * + */ + uint8_t GetType(void) const { return mType; } + + /** + * This method sets the Type value. + * + * @param[in] aType The Type value. + * + */ + void SetType(uint8_t aType) { mType = aType; } + + /** + * This method returns the Length value. + * + * @returns The Length value. + * + */ + uint8_t GetLength(void) const { return mLength; } + + /** + * This method sets the Length value. + * + * @param[in] aLength The Length value. + * + */ + void SetLength(uint8_t aLength) { mLength = aLength; } + + /** + * This method returns the total size including Type, Length, and Value fields. + * + * @returns The total size include Type, Length, and Value fields. + * + */ + uint8_t GetSize(void) const { return sizeof(Tlv) + mLength; } + + /** + * This method returns a pointer to the Value. + * + * @returns A pointer to the value. + * + */ + uint8_t *GetValue(void) { return reinterpret_cast(this) + sizeof(Tlv); } + + /** + * This method returns a pointer to the Value. + * + * @returns A pointer to the value. + * + */ + const uint8_t *GetValue(void) const { return reinterpret_cast(this) + sizeof(Tlv); } + + /** + * This method returns a pointer to the next TLV. + * + * @returns A pointer to the next TLV. + * + */ + Tlv *GetNext(void) { + return reinterpret_cast(reinterpret_cast(this) + sizeof(*this) + mLength); + } + + /** + * This method returns a pointer to the next TLV. + * + * @returns A pointer to the next TLV. + * + */ + const Tlv *GetNext(void) const { + return reinterpret_cast(reinterpret_cast(this) + sizeof(*this) + mLength); + } + + /** + * This static method reads the requested TLV out of @p aMessage. + * + * @param[in] aMessage A reference to the message. + * @param[in] aType The Type value to search for. + * @param[in] aMaxLength Maximum number of bytes to read. + * @param[out] aTlv A reference to the TLV that will be copied to. + * + * @retval kThreadError_None Successfully copied the TLV. + * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. + * + */ + static ThreadError Get(const Message &aMessage, uint8_t aType, uint16_t aMaxLength, Tlv &aTlv); + + /** + * This static method obtains the offset of a TLV within @p aMessage. + * + * @param[in] aMessage A reference to the message. + * @param[in] aType The Type value to search for. + * @param[out] aOffset A reference to the offset of the TLV. + * + * @retval kThreadError_None Successfully copied the TLV. + * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. + * + */ + static ThreadError GetOffset(const Message &aMessage, uint8_t aType, uint16_t &aOffset); + + /** + * This static method finds the offset and length of a given TLV type. + * + * @param[in] aMessage A reference to the message. + * @param[in] aType The Type value to search for. + * @param[out] aOffset The offset where the value starts. + * @param[out] aLength The length of the value. + * + * @retval kThreadError_None Successfully found the TLV. + * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. + * + */ + static ThreadError GetValueOffset(const Message &aMesasge, uint8_t aType, uint16_t &aOffset, uint16_t &aLength); + +protected: + /** + * Length values. + * + */ + enum + { + kExtendedLength = 255, ///< Extended Length value + }; + +private: + uint8_t mType; + uint8_t mLength; +} OT_TOOL_PACKED_END; + +OT_TOOL_PACKED_BEGIN +class ExtendedTlv: public Tlv +{ +public: + /** + * This method returns the Length value. + * + */ + uint16_t GetLength(void) const { return HostSwap16(mLength); } + + /** + * This method sets the Length value. + * + * @param[in] aLength The Length value. + * + */ + void SetLength(uint16_t aLength) { Tlv::SetLength(kExtendedLength); mLength = HostSwap16(aLength); } + +private: + uint16_t mLength; +} OT_TOOL_PACKED_END; + +} // namespace Thread + +#endif // TLVS_HPP_ diff --git a/src/core/thread/thread_tlvs.cpp b/src/core/meshcop/timestamp.cpp similarity index 63% rename from src/core/thread/thread_tlvs.cpp rename to src/core/meshcop/timestamp.cpp index 4780f6559..ce897824d 100644 --- a/src/core/thread/thread_tlvs.cpp +++ b/src/core/meshcop/timestamp.cpp @@ -28,46 +28,48 @@ /** * @file - * This file implements common Thread Network Layer TLV processing. + * This file implements common MeshCoP timestamp processing. */ -#include -#include -#include +#include + +#include +#include namespace Thread { +namespace MeshCoP { -ThreadError ThreadTlv::GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, ThreadTlv &aTlv) +int Timestamp::Compare(const Timestamp &aCompare) const { - ThreadError error = kThreadError_Parse; - uint16_t offset = aMessage.GetOffset(); - uint16_t end = aMessage.GetLength(); + uint64_t thisSeconds = GetSeconds(); + uint64_t compareSeconds = aCompare.GetSeconds(); + uint16_t thisTicks = GetTicks(); + uint16_t compareTicks = aCompare.GetTicks(); + int rval; - while (offset < end) + if (compareSeconds > thisSeconds) { - ThreadTlv tlv; - uint16_t totalLength; - - aMessage.Read(offset, sizeof(tlv), &tlv); - totalLength = sizeof(tlv) + tlv.GetLength(); - - if (tlv.GetType() == aType && (offset + totalLength) <= end) - { - if (aMaxLength > totalLength) - { - aMaxLength = totalLength; - } - - aMessage.Read(offset, aMaxLength, &aTlv); - - ExitNow(error = kThreadError_None); - } - - offset += sizeof(tlv) + tlv.GetLength(); + rval = 1; + } + else if (compareSeconds < thisSeconds) + { + rval = -1; + } + else if (compareTicks > thisTicks) + { + rval = 1; + } + else if (compareTicks < thisTicks) + { + rval = -1; + } + else + { + rval = 0; } -exit: - return error; + return rval; } -} +} // namespace MeshCoP +} // namespace Thread diff --git a/src/core/meshcop/timestamp.hpp b/src/core/meshcop/timestamp.hpp new file mode 100644 index 000000000..d96136b13 --- /dev/null +++ b/src/core/meshcop/timestamp.hpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for manipulating MeshCoP timestamps. + * + */ + +#ifndef MESHCOP_TIMESTAMP_HPP_ +#define MESHCOP_TIMESTAMP_HPP_ + +namespace Thread { +namespace MeshCoP { + +/** + * This class implements Timestamp generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class Timestamp +{ +public: + /** + * This method initializes the Timestamp + * + */ + void Init(void) { memset(mSeconds, 0, sizeof(mSeconds)); mTicks = 0; } + + /** + * This method compares this timestamp to another. + * + * @param[in] aCompare A reference to the timestamp to compare. + * + * @retval -1 if @p aCompare is less than this timestamp. + * @retval 0 if @p aCompare is equal to this timestamp. + * @retval 1 if @p aCompare is greater than this timestamp. + * + */ + int Compare(const Timestamp &aCompare) const; + + /** + * This method returns the Seconds value. + * + * @returns The Seconds value. + * + */ + uint64_t GetSeconds(void) const { + uint64_t seconds = 0; + + for (size_t i = 0; i < sizeof(mSeconds); i++) { + seconds = (seconds << 8) | mSeconds[i]; + } + + return seconds; + } + + /** + * This method sets the Seconds value. + * + * @param[in] aSeconds The Seconds value. + * + */ + void SetSeconds(uint64_t aSeconds) { + for (size_t i = 0; i < sizeof(mSeconds); i++, aSeconds >>= 8) { + mSeconds[sizeof(mSeconds) - 1 - i] = aSeconds & 0xff; + } + } + + /** + * This method returns the Ticks value. + * + * @returns The Ticks value. + * + */ + uint16_t GetTicks(void) const { return mTicks >> kTicksOffset; } + + /** + * This method sets the Ticks value. + * + * @param[in] aTicks The Ticks value. + * + */ + void SetTicks(uint16_t aTicks) { + mTicks = (mTicks & ~kTicksMask) | ((aTicks << kTicksOffset) & kTicksMask); + } + + /** + * This method returns the Authoritative value. + * + * @returns The Authoritative value. + * + */ + bool GetAuthoritative(void) const { return (mTicks & kAuthoritativeMask) != 0; } + + /** + * This method sets the Authoritative value. + * + * @param[in] aAuthoritative The Authoritative value. + * + */ + void SetAuthoritative(bool aAuthoritative) { + mTicks = (mTicks & kTicksMask) | ((aAuthoritative << kAuthoritativeOffset) & kAuthoritativeMask); + } + +private: + uint8_t mSeconds[6]; + + enum + { + kTicksOffset = 1, + kTicksMask = 0x7fff << kTicksOffset, + kAuthoritativeOffset = 0, + kAuthoritativeMask = 1 << kAuthoritativeOffset, + }; + uint16_t mTicks; +} OT_TOOL_PACKED_END; + +} // namespace MeshCoP +} // namespace Thread + +#endif // MESHCOP_TIMESTAMP_HPP_ diff --git a/src/core/meshcop/tlvs.cpp b/src/core/meshcop/tlvs.cpp deleted file mode 100644 index 526d24c78..000000000 --- a/src/core/meshcop/tlvs.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2016, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file implements common MeshCoP TLV processing. - */ - -#include -#include - -namespace Thread { -namespace MeshCoP { - -int Timestamp::Compare(const Timestamp &aCompare) const -{ - uint64_t thisSeconds = GetSeconds(); - uint64_t compareSeconds = aCompare.GetSeconds(); - uint16_t thisTicks = GetTicks(); - uint16_t compareTicks = aCompare.GetTicks(); - int rval; - - if (compareSeconds > thisSeconds) - { - rval = 1; - } - else if (compareSeconds < thisSeconds) - { - rval = -1; - } - else if (compareTicks > thisTicks) - { - rval = 1; - } - else if (compareTicks < thisTicks) - { - rval = -1; - } - else - { - rval = 0; - } - - return rval; -} - -ThreadError Tlv::GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv) -{ - ThreadError error = kThreadError_Parse; - uint16_t offset = aMessage.GetOffset(); - uint16_t end = aMessage.GetLength(); - - while (offset < end) - { - Tlv tlv; - uint16_t totalLength; - - aMessage.Read(offset, sizeof(tlv), &tlv); - totalLength = sizeof(tlv) + tlv.GetLength(); - - if (tlv.GetType() == aType && (offset + totalLength) <= end) - { - if (aMaxLength > totalLength) - { - aMaxLength = totalLength; - } - - aMessage.Read(offset, aMaxLength, &aTlv); - - ExitNow(error = kThreadError_None); - } - - offset += sizeof(tlv) + tlv.GetLength(); - } - -exit: - return error; -} - -ThreadError Tlv::GetValueOffset(const Message &aMessage, Type aType, uint16_t &aOffset, uint16_t &aLength) -{ - ThreadError error = kThreadError_Parse; - uint16_t offset = aMessage.GetOffset(); - uint16_t end = aMessage.GetLength(); - - while (offset < end) - { - Tlv tlv; - uint16_t length; - - aMessage.Read(offset, sizeof(tlv), &tlv); - offset += sizeof(tlv); - - length = tlv.GetLength(); - - if (length == kExtendedLength) - { - aMessage.Read(offset, sizeof(length), &length); - offset += sizeof(length); - length = HostSwap16(length); - } - - if (tlv.GetType() == aType) - { - aOffset = offset; - aLength = length; - ExitNow(error = kThreadError_None); - } - - offset += length; - } - -exit: - return error; -} - -} // namespace MeshCoP -} // namespace Thread diff --git a/src/core/meshcop/tlvs.hpp b/src/core/meshcop/tlvs.hpp index a45b54db4..4c9a6c6e6 100644 --- a/src/core/meshcop/tlvs.hpp +++ b/src/core/meshcop/tlvs.hpp @@ -40,6 +40,8 @@ #include #include #include +#include +#include using Thread::Encoding::BigEndian::HostSwap16; using Thread::Encoding::BigEndian::HostSwap32; @@ -52,7 +54,7 @@ namespace MeshCoP { * */ OT_TOOL_PACKED_BEGIN -class Tlv +class Tlv : public Thread::Tlv { public: /** @@ -93,22 +95,13 @@ public: kDiscoveryResponse = OT_MESHCOP_TLV_DISCOVERYRESPONSE, ///< Discovery Response TLV }; - /** - * Length values. - * - */ - enum - { - kExtendedLength = 255, ///< Extended Length value - }; - /** * This method returns the Type value. * * @returns The Type value. * */ - Type GetType(void) const { return static_cast(mType); } + Type GetType(void) const { return static_cast(Thread::Tlv::GetType()); } /** * This method sets the Type value. @@ -116,37 +109,7 @@ public: * @param[in] aType The Type value. * */ - void SetType(Type aType) { mType = static_cast(aType); } - - /** - * This method returns the Length value. - * - */ - uint8_t GetLength(void) const { return mLength; } - - /** - * This method sets the Length value. - * - * @param[in] aLength The Length value. - * - */ - void SetLength(uint8_t aLength) { mLength = aLength; } - - /** - * This method returns a pointer to the Value. - * - * @returns A pointer to the value. - * - */ - uint8_t *GetValue(void) { return reinterpret_cast(this) + sizeof(Tlv); } - - /** - * This method returns a pointer to the Value. - * - * @returns A pointer to the value. - * - */ - const uint8_t *GetValue(void) const { return reinterpret_cast(this) + sizeof(Tlv); } + void SetType(Type aType) { Thread::Tlv::SetType(static_cast(aType)); } /** * This method returns a pointer to the next TLV. @@ -155,11 +118,11 @@ public: * */ Tlv *GetNext(void) { - return reinterpret_cast(reinterpret_cast(this) + sizeof(*this) + mLength); + return static_cast(Thread::Tlv::GetNext()); } const Tlv *GetNext(void) const { - return reinterpret_cast(reinterpret_cast(this) + sizeof(*this) + mLength); + return static_cast(Thread::Tlv::GetNext()); } /** @@ -174,7 +137,9 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv); + static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv) { + return Thread::Tlv::Get(aMessage, static_cast(aType), aMaxLength, aTlv); + } /** * This static method finds the offset and length of a given TLV type. @@ -188,33 +153,10 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetValueOffset(const Message &aMesasge, Type aType, uint16_t &aOffset, uint16_t &aLength); + static ThreadError GetValueOffset(const Message &aMessage, Type aType, uint16_t &aOffset, uint16_t &aLength) { + return Thread::Tlv::GetValueOffset(aMessage, static_cast(aType), aOffset, aLength); + } -private: - uint8_t mType; - uint8_t mLength; -} OT_TOOL_PACKED_END; - -OT_TOOL_PACKED_BEGIN -class ExtendedTlv: public Tlv -{ -public: - /** - * This method returns the Length value. - * - */ - uint16_t GetLength(void) const { return HostSwap16(mLength); } - - /** - * This method sets the Length value. - * - * @param[in] aLength The Length value. - * - */ - void SetLength(uint16_t aLength) { Tlv::SetLength(kExtendedLength); mLength = HostSwap16(aLength); } - -private: - uint16_t mLength; } OT_TOOL_PACKED_END; /** @@ -827,109 +769,6 @@ private: uint8_t mFlags; } OT_TOOL_PACKED_END; -/** - * This class implements Timestamp generation and parsing. - * - */ -OT_TOOL_PACKED_BEGIN -class Timestamp -{ -public: - /** - * This method initializes the Timestamp - * - */ - void Init(void) { memset(mSeconds, 0, sizeof(mSeconds)); mTicks = 0; } - - /** - * This method compares this timestamp to another. - * - * @param[in] aCompare A reference to the timestamp to compare. - * - * @retval -1 if @p aCompare is less than this timestamp. - * @retval 0 if @p aCompare is equal to this timestamp. - * @retval 1 if @p aCompare is greater than this timestamp. - * - */ - int Compare(const Timestamp &aCompare) const; - - /** - * This method returns the Seconds value. - * - * @returns The Seconds value. - * - */ - uint64_t GetSeconds(void) const { - uint64_t seconds = 0; - - for (size_t i = 0; i < sizeof(mSeconds); i++) { - seconds = (seconds << 8) | mSeconds[i]; - } - - return seconds; - } - - /** - * This method sets the Seconds value. - * - * @param[in] aSeconds The Seconds value. - * - */ - void SetSeconds(uint64_t aSeconds) { - for (size_t i = 0; i < sizeof(mSeconds); i++, aSeconds >>= 8) { - mSeconds[sizeof(mSeconds) - 1 - i] = aSeconds & 0xff; - } - } - - /** - * This method returns the Ticks value. - * - * @returns The Ticks value. - * - */ - uint16_t GetTicks(void) const { return mTicks >> kTicksOffset; } - - /** - * This method sets the Ticks value. - * - * @param[in] aTicks The Ticks value. - * - */ - void SetTicks(uint16_t aTicks) { - mTicks = (mTicks & ~kTicksMask) | ((aTicks << kTicksOffset) & kTicksMask); - } - - /** - * This method returns the Authoritative value. - * - * @returns The Authoritative value. - * - */ - bool GetAuthoritative(void) const { return (mTicks & kAuthoritativeMask) != 0; } - - /** - * This method sets the Authoritative value. - * - * @param[in] aAuthoritative The Authoritative value. - * - */ - void SetAuthoritative(bool aAuthoritative) { - mTicks = (mTicks & kTicksMask) | ((aAuthoritative << kAuthoritativeOffset) & kAuthoritativeMask); - } - -private: - uint8_t mSeconds[6]; - - enum - { - kTicksOffset = 1, - kTicksMask = 0x7fff << kTicksOffset, - kAuthoritativeOffset = 0, - kAuthoritativeMask = 1 << kAuthoritativeOffset, - }; - uint16_t mTicks; -} OT_TOOL_PACKED_END; - /** * This class implements Active Timestamp TLV generation and parsing. * diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp index a667d544e..ca6220d6d 100644 --- a/src/core/thread/mle_tlvs.hpp +++ b/src/core/thread/mle_tlvs.hpp @@ -39,7 +39,8 @@ #include #include #include -#include +#include +#include #include #include @@ -65,7 +66,7 @@ namespace Mle { * */ OT_TOOL_PACKED_BEGIN -class Tlv +class Tlv : public Thread::Tlv { public: /** @@ -110,7 +111,7 @@ public: * @returns The Type value. * */ - Type GetType(void) const { return static_cast(mType); } + Type GetType(void) const { return static_cast(Thread::Tlv::GetType()); } /** * This method sets the Type value. @@ -118,21 +119,7 @@ public: * @param[in] aType The Type value. * */ - void SetType(Type aType) { mType = static_cast(aType); } - - /** - * This method returns the Length value. - * - */ - uint8_t GetLength(void) const { return mLength; } - - /** - * This method sets the Length value. - * - * @param[in] aLength The Length value. - * - */ - void SetLength(uint8_t aLength) { mLength = aLength; } + void SetType(Type aType) { Thread::Tlv::SetType(static_cast(aType)); } /** * This static method reads the requested TLV out of @p aMessage. @@ -146,7 +133,9 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv); + static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv) { + return Thread::Tlv::Get(aMessage, static_cast(aType), aMaxLength, aTlv); + } /** * This static method obtains the offset of a TLV within @p aMessage. @@ -159,11 +148,10 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset); + static ThreadError GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset) { + return Thread::Tlv::GetOffset(aMessage, static_cast(aType), aOffset); + } -private: - uint8_t mType; - uint8_t mLength; } OT_TOOL_PACKED_END; /** diff --git a/src/core/thread/network_diagnostic_tlvs.cpp b/src/core/thread/network_diagnostic_tlvs.cpp deleted file mode 100644 index 121a0d7c0..000000000 --- a/src/core/thread/network_diagnostic_tlvs.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016, The OpenThread Authors. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file - * This file implements common methods for manipulating Network Diagnostic TLVs. - */ - -#include -#include -#include - -namespace Thread { -namespace NetworkDiagnostic { - -ThreadError NetworkDiagnosticTlv::GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, - NetworkDiagnosticTlv &aTlv) -{ - ThreadError error = kThreadError_Parse; - uint16_t offset; - - SuccessOrExit(error = GetOffset(aMessage, aType, offset)); - aMessage.Read(offset, sizeof(NetworkDiagnosticTlv), &aTlv); - - if (aMaxLength > sizeof(aTlv) + aTlv.GetLength()) - { - aMaxLength = sizeof(aTlv) + aTlv.GetLength(); - } - - aMessage.Read(offset, aMaxLength, &aTlv); - -exit: - return error; -} - -ThreadError NetworkDiagnosticTlv::GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset) -{ - ThreadError error = kThreadError_Parse; - uint16_t offset = aMessage.GetOffset(); - uint16_t end = aMessage.GetLength(); - NetworkDiagnosticTlv tlv; - - while (offset < end) - { - aMessage.Read(offset, sizeof(NetworkDiagnosticTlv), &tlv); - - if (tlv.GetType() == aType && (offset + sizeof(tlv) + tlv.GetLength()) <= end) - { - aOffset = offset; - ExitNow(error = kThreadError_None); - } - - offset += sizeof(tlv) + tlv.GetLength(); - } - -exit: - return error; -} - -} // namespace NetworkDiagnostic -} // namespace Thread diff --git a/src/core/thread/network_diagnostic_tlvs.hpp b/src/core/thread/network_diagnostic_tlvs.hpp index 90704fd6c..36986d414 100644 --- a/src/core/thread/network_diagnostic_tlvs.hpp +++ b/src/core/thread/network_diagnostic_tlvs.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -71,7 +72,7 @@ enum * */ OT_TOOL_PACKED_BEGIN -class NetworkDiagnosticTlv +class NetworkDiagnosticTlv : public Thread::Tlv { public: /** @@ -104,7 +105,7 @@ public: * @returns The Type value. * */ - Type GetType(void) const { return static_cast(mType); } + Type GetType(void) const { return static_cast(Thread::Tlv::GetType()); } /** * This method sets the Type value. @@ -112,26 +113,7 @@ public: * @param[in] aType The Type value. * */ - void SetType(Type aType) { mType = static_cast(aType); } - - /** - * This method returns the Length value. - * - */ - uint8_t GetLength(void) const { return mLength; } - - /** - * This method returns the length to be sent - */ - uint8_t GetSize(void) const { return mLength + sizeof(NetworkDiagnosticTlv); } - - /** - * This method sets the Length value. - * - * @param[in] aLength The Length value. - * - */ - void SetLength(uint8_t aLength) { mLength = aLength; } + void SetType(Type aType) { Thread::Tlv::SetType(static_cast(aType)); } /** * This static method reads the requested TLV out of @p aMessage. @@ -145,7 +127,9 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, NetworkDiagnosticTlv &aTlv); + static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv) { + return Thread::Tlv::Get(aMessage, static_cast(aType), aMaxLength, aTlv); + } /** * This static method obtains the offset of a TLV within @p aMessage. @@ -158,11 +142,10 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset); + static ThreadError GetOffset(const Message &aMessage, Type aType, uint16_t &aOffset) { + return Thread::Tlv::GetOffset(aMessage, static_cast(aType), aOffset); + } -private: - uint8_t mType; - uint8_t mLength; } OT_TOOL_PACKED_END; /** diff --git a/src/core/thread/thread_tlvs.hpp b/src/core/thread/thread_tlvs.hpp index d2974a635..ba9656e11 100644 --- a/src/core/thread/thread_tlvs.hpp +++ b/src/core/thread/thread_tlvs.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -55,7 +56,7 @@ enum * */ OT_TOOL_PACKED_BEGIN -class ThreadTlv +class ThreadTlv : public Thread::Tlv { public: /** @@ -82,7 +83,7 @@ public: * @returns The Type value. * */ - Type GetType(void) const { return static_cast(mType); } + Type GetType(void) const { return static_cast(Thread::Tlv::GetType()); } /** * This method sets the Type value. @@ -90,21 +91,7 @@ public: * @param[in] aType The Type value. * */ - void SetType(Type aType) { mType = static_cast(aType); } - - /** - * This method returns the Length value. - * - */ - uint8_t GetLength(void) const { return mLength; } - - /** - * This method sets the Length value. - * - * @param[in] aLength The Length value. - * - */ - void SetLength(uint8_t aLength) { mLength = aLength; } + void SetType(Type aType) { Thread::Tlv::SetType(static_cast(aType)); } /** * This static method reads the requested TLV out of @p aMessage. @@ -118,11 +105,10 @@ public: * @retval kThreadError_NotFound Could not find the TLV with Type @p aType. * */ - static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, ThreadTlv &aTlv); + static ThreadError GetTlv(const Message &aMessage, Type aType, uint16_t aMaxLength, Tlv &aTlv) { + return Thread::Tlv::Get(aMessage, static_cast(aType), aMaxLength, aTlv); + } -private: - uint8_t mType; - uint8_t mLength; } OT_TOOL_PACKED_END; /**