diff --git a/examples/posix/platform/radio.c b/examples/posix/platform/radio.c index f94d68ea3..81e97676f 100644 --- a/examples/posix/platform/radio.c +++ b/examples/posix/platform/radio.c @@ -80,11 +80,11 @@ typedef enum PhyState kStateAckWait = 6, } PhyState; -struct RadioMessage +struct OT_TOOL_PACKED_BEGIN RadioMessage { uint8_t mChannel; uint8_t mPsdu[kMaxPHYPacketSize]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; static void radioSendAck(void); static void radioProcessFrame(void); diff --git a/include/openthread-types.h b/include/openthread-types.h index ba1bc2027..233f0567b 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -37,6 +37,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -197,7 +198,7 @@ enum /** * This structure represents an IPv6 address. */ -typedef struct otIp6Address +typedef OT_TOOL_PACKED_BEGIN struct otIp6Address { union { @@ -205,7 +206,7 @@ typedef struct otIp6Address uint16_t m16[kIp6AddressSize / sizeof(uint16_t)]; uint32_t m32[kIp6AddressSize / sizeof(uint32_t)]; }; -} __attribute__((packed)) otIp6Address; +} OT_TOOL_PACKED_END otIp6Address; /** * This structure represents an IPv6 prefix. diff --git a/include/platform/Makefile.am b/include/platform/Makefile.am index e3f79cfc1..513da0928 100644 --- a/include/platform/Makefile.am +++ b/include/platform/Makefile.am @@ -34,6 +34,7 @@ ot_platform_headers =\ radio.h \ random.h \ serial.h \ + toolchain.h \ $(NULL) ot_platformdir = $(includedir)/platform diff --git a/include/platform/toolchain.h b/include/platform/toolchain.h new file mode 100644 index 000000000..762557f30 --- /dev/null +++ b/include/platform/toolchain.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2016, Nest Labs, Inc. + * 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. + */ + +/** + * @defgroup toolchain Toolchain + * @ingroup platform + * + * @brief + * This module defines a toolchain abstraction layer through macros. + * + * Usage: + * + * @code + * + * typedef + * OT_TOOL_PACKED_BEGIN + * struct + * { + * char mField1; + * union + * { + * char mField2; + * long mField3; + * } OT_TOOL_PACKED_FIELD; + * } OT_TOOL_PACKED_END packed_struct_t; + * + * @endcode + * + * @{ + * + */ + +#ifndef TOOLCHAIN_H_ +#define TOOLCHAIN_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @def OT_TOOL_PACKED_BEGIN + * + * Compiler-specific indication that a class or struct must be byte packed. + * + */ + +/** + * @def OT_TOOL_PACKED_FIELD + * + * Indicate to the compiler a nested struct or union to be packed + * within byte packed class or struct. + * + */ + +/** + * @def OT_TOOL_PACKED_END + * + * Compiler-specific indication at the end of a byte packed class or struct. + * + */ + +/** + * @def OT_TOOL_DEPRECATED + * + * Indicate to the compiler to warn upon use that a field or function + * has been deprecated. + * + * @param[in] symbol The name of the field or function to deprecate. + * + */ + +// =========== TOOLCHAIN SELECTION : START =========== + +#if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) + +// https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html +// http://www.keil.com/support/man/docs/armcc/armcc_chr1359124973480.htm + +#define OT_TOOL_PACKED_BEGIN +#define OT_TOOL_PACKED_FIELD __attribute__((packed)) +#define OT_TOOL_PACKED_END __attribute__((packed)) +#define OT_TOOL_DEPRECATED(symbol) __attribute__((deprecated)) + +#elif defined(__ICCARM__) || defined(__ICC8051__) + +// http://supp.iar.com/FilesPublic/UPDINFO/004916/arm/doc/EWARM_DevelopmentGuide.ENU.pdf + +#include "intrinsics.h" + +#define OT_TOOL_PACKED_BEGIN __packed +#define OT_TOOL_PACKED_FIELD +#define OT_TOOL_PACKED_END +#define OT_TOOL_DEPRECATED(symbol) + +#elif defined(_MSC_VER) + +#define OT_TOOL_PACKED_BEGIN __pragma(pack(push,1)) +#define OT_TOOL_PACKED_FIELD +#define OT_TOOL_PACKED_END __pragma(pack(pop)) +#define OT_TOOL_DEPRECATED(symbol) __pragma(deprecated(symbol)) + +#elif defined(__SDCC) + +// Structures are packed by default in sdcc, as it primarily targets 8-bit MCUs. + +#define OT_TOOL_PACKED_BEGIN +#define OT_TOOL_PACKED_FIELD +#define OT_TOOL_PACKED_END +#define OT_TOOL_DEPRECATED(symbol) + +#else + +#error "Error: No valid Toolchain specified" + +// Symbols for Doxygen + +#define OT_TOOL_PACKED_BEGIN +#define OT_TOOL_PACKED_FIELD +#define OT_TOOL_PACKED_END +#define OT_TOOL_DEPRECATED(symbol) + +#endif + +// =========== TOOLCHAIN SELECTION : END =========== + +/** + * @} + * + */ + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // TOOLCHAIN_H_ diff --git a/src/core/mac/mac_frame.hpp b/src/core/mac/mac_frame.hpp index 8f67e2925..f4238ff24 100644 --- a/src/core/mac/mac_frame.hpp +++ b/src/core/mac/mac_frame.hpp @@ -108,6 +108,7 @@ struct Address * This class implements IEEE 802.15.4 MAC frame generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class Frame: public RadioPacket { public: @@ -762,7 +763,7 @@ private: uint8_t mFlags; char mNetworkName[kNetworkNameSize]; uint8_t mExtendedPanId[kExtPanIdSize]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * @} diff --git a/src/core/net/icmp6.hpp b/src/core/net/icmp6.hpp index 80eb3a9f1..54235bc0c 100644 --- a/src/core/net/icmp6.hpp +++ b/src/core/net/icmp6.hpp @@ -61,6 +61,7 @@ enum * This structure represents an ICMPv6 header. * */ +OT_TOOL_PACKED_BEGIN struct IcmpHeaderPoD { uint8_t mType; ///< Type @@ -72,12 +73,13 @@ struct IcmpHeaderPoD uint16_t m16[kIcmp6DataSize / sizeof(uint16_t)]; uint32_t m32[kIcmp6DataSize / sizeof(uint32_t)]; } mData; ///< Message-specific data -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements ICMPv6 header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class IcmpHeader: private IcmpHeaderPoD { public: @@ -202,7 +204,7 @@ public: */ static uint8_t GetDataOffset() { return offsetof(IcmpHeaderPoD, mData); } -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements an ICMPv6 echo client. diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index c309a1f06..6e74cb7a5 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -107,6 +107,7 @@ enum * This structure represents an IPv6 header. * */ +OT_TOOL_PACKED_BEGIN struct HeaderPoD { union @@ -120,12 +121,13 @@ struct HeaderPoD uint8_t mHopLimit; ///< Hop Limit otIp6Address mSource; ///< Source otIp6Address mDestination; ///< Destination -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements IPv6 header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class Header: private HeaderPoD { public: @@ -262,12 +264,13 @@ private: kVersion6 = 0x60, kVersionMask = 0xf0, }; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements IPv6 Extension Header generation and processing. * */ +OT_TOOL_PACKED_BEGIN class ExtensionHeader { public: @@ -306,20 +309,22 @@ public: private: uint8_t mNextHeader; uint8_t mLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements IPv6 Hop-by-Hop Options Header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class HopByHopHeader: public ExtensionHeader { -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements IPv6 Options generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class OptionHeader { public: @@ -379,12 +384,13 @@ public: private: uint8_t mType; uint8_t mLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements IPv6 Fragment Header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class FragmentHeader { public: @@ -459,7 +465,7 @@ private: }; uint16_t mOffsetMore; uint32_t mIdentification; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements the core IPv6 message processing. diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index 2d7dd66a3..f029e1833 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -52,6 +52,7 @@ namespace Ip6 { * This class implements an IPv6 address object. * */ +OT_TOOL_PACKED_BEGIN class Address: public otIp6Address { public: @@ -286,7 +287,7 @@ private: { kInterfaceIdentifierOffset = 8, ///< Interface Identifier offset in bytes. }; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * @} diff --git a/src/core/net/ip6_mpl.hpp b/src/core/net/ip6_mpl.hpp index b844ab235..d623f4e63 100644 --- a/src/core/net/ip6_mpl.hpp +++ b/src/core/net/ip6_mpl.hpp @@ -56,6 +56,7 @@ namespace Ip6 { * This class implements MPL header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class OptionMpl: public OptionHeader { public: @@ -160,7 +161,7 @@ private: uint8_t mControl; uint8_t mSequence; uint16_t mSeed; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements MPL message processing. diff --git a/src/core/net/udp6.hpp b/src/core/net/udp6.hpp index 08bd49973..595d1f2d1 100644 --- a/src/core/net/udp6.hpp +++ b/src/core/net/udp6.hpp @@ -167,18 +167,20 @@ private: static UdpSocket *sSockets; }; +OT_TOOL_PACKED_BEGIN struct UdpHeaderPoD { uint16_t mSource; uint16_t mDestination; uint16_t mLength; uint16_t mChecksum; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements UDP header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class UdpHeader: private UdpHeaderPoD { public: @@ -262,7 +264,7 @@ public: */ static uint8_t GetChecksumOffset(void) { return offsetof(UdpHeaderPoD, mChecksum); } -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * @} diff --git a/src/core/thread/lowpan.hpp b/src/core/thread/lowpan.hpp index 441a8e110..010728f8a 100644 --- a/src/core/thread/lowpan.hpp +++ b/src/core/thread/lowpan.hpp @@ -220,6 +220,7 @@ private: * This class implements Mesh Header generation and processing. * */ +OT_TOOL_PACKED_BEGIN class MeshHeader { public: @@ -316,12 +317,13 @@ private: uint8_t mDispatchHopsLeft; uint16_t mSource; uint16_t mDestination; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Fragment Header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class FragmentHeader { public: @@ -421,10 +423,10 @@ private: { uint8_t mDispatchOffsetSize; uint16_t mSize; - } __attribute__((packed)); + } OT_TOOL_PACKED_FIELD; uint16_t mTag; uint8_t mOffset; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * @} diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index e39003038..9222bfed8 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -106,6 +106,7 @@ enum DeviceState * This class implements MLE Header generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class Header { public: @@ -307,7 +308,7 @@ private: uint32_t mFrameCounter; uint8_t mKeyIdentifier[5]; uint8_t mCommand; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements MLE functionality required by the Thread EndDevices, Router, and Leader roles. diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp index 176aea228..d38dac57d 100644 --- a/src/core/thread/mle_tlvs.hpp +++ b/src/core/thread/mle_tlvs.hpp @@ -63,6 +63,7 @@ namespace Mle { * This class implements MLE TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class Tlv { public: @@ -142,12 +143,13 @@ public: private: uint8_t mType; uint8_t mLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class SourceAddressTlv: public Tlv { public: @@ -184,12 +186,13 @@ public: private: uint16_t mRloc16; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ModeTlv: public Tlv { public: @@ -234,12 +237,13 @@ public: private: uint8_t mMode; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class TimeoutTlv: public Tlv { public: @@ -276,12 +280,13 @@ public: private: uint32_t mTimeout; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ChallengeTlv: public Tlv { public: @@ -323,12 +328,13 @@ public: private: uint8_t mChallenge[kMaxSize]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ResponseTlv: public Tlv { public: @@ -370,12 +376,13 @@ public: private: uint8_t mResponse[kMaxSize]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class LinkFrameCounterTlv: public Tlv { public: @@ -412,12 +419,13 @@ public: private: uint32_t mFrameCounter; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class RouteTlv: public Tlv { public: @@ -580,12 +588,13 @@ private: uint8_t mRouterIdSequence; uint8_t mRouterIdMask[BitVectorBytes(kMaxRouterId)]; uint8_t mRouteData[kMaxRouters]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class MleFrameCounterTlv: public Tlv { public: @@ -622,12 +631,13 @@ public: private: uint32_t mFrameCounter; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class Address16Tlv: public Tlv { public: @@ -664,12 +674,13 @@ public: private: uint16_t mRloc16; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class LeaderDataTlv: public Tlv { public: @@ -774,12 +785,13 @@ private: uint8_t mDataVersion; uint8_t mStableDataVersion; uint8_t mLeaderRouterId; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class NetworkDataTlv: public Tlv { public: @@ -816,12 +828,13 @@ public: private: uint8_t mNetworkData[255]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class TlvRequestTlv: public Tlv { public: @@ -862,12 +875,13 @@ private: kMaxTlvs = 8, }; uint8_t mTlvs[kMaxTlvs]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ScanMaskTlv: public Tlv { public: @@ -942,12 +956,13 @@ public: private: uint8_t mMask; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ConnectivityTlv: public Tlv { public: @@ -1086,12 +1101,13 @@ private: uint8_t mLinkQuality1; uint8_t mLeaderCost; uint8_t mIdSequence; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class LinkMarginTlv: public Tlv { public: @@ -1128,12 +1144,13 @@ public: private: uint8_t mLinkMargin; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class StatusTlv: public Tlv { public: @@ -1178,12 +1195,13 @@ public: private: uint8_t mStatus; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class VersionTlv: public Tlv { public: @@ -1220,12 +1238,13 @@ public: private: uint16_t mVersion; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class AddressRegistrationEntry { public: @@ -1313,13 +1332,14 @@ private: { uint8_t mIid[Ip6::Address::kInterfaceIdentifierSize]; Ip6::Address mIp6Address; - } __attribute__((packed)); -} __attribute__((packed)); + } OT_TOOL_PACKED_FIELD; +} OT_TOOL_PACKED_END; /** * This class implements Source Address TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class AddressRegistrationTlv: public Tlv { public: @@ -1367,7 +1387,7 @@ public: private: AddressRegistrationEntry mAddresses[4]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * @} diff --git a/src/core/thread/network_data_tlvs.hpp b/src/core/thread/network_data_tlvs.hpp index d8155c086..27a8c5769 100644 --- a/src/core/thread/network_data_tlvs.hpp +++ b/src/core/thread/network_data_tlvs.hpp @@ -58,6 +58,7 @@ namespace NetworkData { * This class implements Thread Network Data TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class NetworkDataTlv { public: @@ -160,12 +161,13 @@ private: }; uint8_t mType; uint8_t mLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Has Route TLV entry generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class HasRouteEntry { public: @@ -215,12 +217,13 @@ private: uint16_t mRloc; uint8_t mFlags; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Has Route TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class HasRouteTlv: public NetworkDataTlv { public: @@ -249,12 +252,13 @@ public: HasRouteEntry *GetEntry(int i) { return reinterpret_cast(GetValue() + (i * sizeof(HasRouteEntry))); } -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Prefix TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class PrefixTlv: public NetworkDataTlv { public: @@ -330,12 +334,13 @@ public: private: uint8_t mDomainId; uint8_t mPrefixLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Border Router Entry generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class BorderRouterEntry { public: @@ -512,12 +517,13 @@ private: uint16_t mRloc; uint8_t mFlags; uint8_t mReserved; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Border Router TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class BorderRouterTlv: public NetworkDataTlv { public: @@ -546,12 +552,13 @@ public: BorderRouterEntry *GetEntry(int i) { return reinterpret_cast(GetValue() + (i * sizeof(BorderRouterEntry))); } -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Context TLV generation and processing. * */ +OT_TOOL_PACKED_BEGIN class ContextTlv: public NetworkDataTlv { public: @@ -623,7 +630,7 @@ private: }; uint8_t mFlags; uint8_t mContextLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * @} diff --git a/src/core/thread/thread_tlvs.hpp b/src/core/thread/thread_tlvs.hpp index cc38560ac..593e0ef19 100644 --- a/src/core/thread/thread_tlvs.hpp +++ b/src/core/thread/thread_tlvs.hpp @@ -54,6 +54,7 @@ enum * This class implements Network Layer TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ThreadTlv { public: @@ -119,12 +120,13 @@ public: private: uint8_t mType; uint8_t mLength; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Target EID TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ThreadTargetTlv: public ThreadTlv { public: @@ -161,7 +163,7 @@ public: private: Ip6::Address mTarget; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Extended MAC Address TLV generation and parsing. @@ -209,6 +211,7 @@ private: * This class implements RLOC16 TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ThreadRloc16Tlv: public ThreadTlv { public: @@ -245,12 +248,13 @@ public: private: uint16_t mRloc16; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements ML-EID TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ThreadMeshLocalEidTlv: public ThreadTlv { public: @@ -287,12 +291,13 @@ public: private: uint8_t mIid[8]; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Status TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ThreadStatusTlv: public ThreadTlv { public: @@ -339,12 +344,13 @@ public: private: uint8_t mStatus; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** * This class implements Time Since Last Transaction TLV generation and parsing. * */ +OT_TOOL_PACKED_BEGIN class ThreadLastTransactionTimeTlv: public ThreadTlv { public: @@ -381,7 +387,7 @@ public: private: uint32_t mTime; -} __attribute__((packed)); +} OT_TOOL_PACKED_END; /** diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index 163433f7d..f73ced12b 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -68,6 +68,7 @@ check_PROGRAMS = \ test-mac-frame \ test-message \ test-timer \ + test-toolchain \ $(NULL) # Test applications and scripts that should be built and run when the @@ -100,6 +101,9 @@ test_message_SOURCES = test_message.cpp test_timer_LDADD = $(COMMON_LDADD) test_timer_SOURCES = test_timer.cpp +test_toolchain_LDADD = $(COMMON_LDADD) +test_toolchain_SOURCES = test_toolchain.cpp + endif # OPENTHREAD_BUILD_TESTS include $(abs_top_nlbuild_autotools_dir)/automake/post.am diff --git a/tests/unit/test_toolchain.cpp b/tests/unit/test_toolchain.cpp new file mode 100644 index 000000000..f5d3f4be4 --- /dev/null +++ b/tests/unit/test_toolchain.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016, Nest Labs, Inc. + * 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. + */ + +#include +#include +#include +#include "test_util.h" + +void test_packed1() +{ + typedef OT_TOOL_PACKED_BEGIN struct + { + uint8_t mByte; + uint32_t mWord; + uint16_t mShort; + } OT_TOOL_PACKED_END packed_t; + + VerifyOrQuit(sizeof(packed_t) == 7, "Toolchain::OT_TOOL_PACKED failed 1\n"); +} + +void test_packed2() +{ + typedef OT_TOOL_PACKED_BEGIN struct + { + uint8_t mBytes[3]; + uint8_t mByte; + } OT_TOOL_PACKED_END packed_t; + + VerifyOrQuit(sizeof(packed_t) == 4, "Toolchain::OT_TOOL_PACKED failed 2\n"); +} + +void test_packed_union() +{ + typedef struct + { + uint16_t mField; + } nested_t; + + typedef OT_TOOL_PACKED_BEGIN struct + { + uint8_t mBytes[3]; + union + { + nested_t mNestedStruct; + uint8_t mByte; + } OT_TOOL_PACKED_FIELD; + } OT_TOOL_PACKED_END packed_t; + + VerifyOrQuit(sizeof(packed_t) == 5, "Toolchain::OT_TOOL_PACKED failed 3\n"); +} + +int test_deprecated() OT_TOOL_DEPRECATED(test_deprecated); + +int test_deprecated() +{ + return 0; +} + +void TestToolchain(void) +{ + test_packed1(); + test_packed2(); + test_packed_union(); + + SuccessOrQuit(test_deprecated(), "Toolchain::OT_TOOL_DEPRECATED failed\n"); +} + +int main(void) +{ + TestToolchain(); + printf("All tests passed\n"); + return 0; +}