From ede95a12202ea52ad7ea4424d3a352f3f563adad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Duda?= Date: Wed, 9 Nov 2016 10:00:08 +0100 Subject: [PATCH] 6LoWPAN: Introduce test vectors and improvements (#947) * 6LoWPAN: Add compression flag to the Context structure. * IP: Add option to initialize IPv6 header. * 6LoWPAN: Bugfixes for compression and decompression procedure. * 6LoWPAN: Add test vectors for 6LoWPAN compression and decompression. --- etc/visual-studio/UnitTests.vcxproj | 7 +- etc/visual-studio/UnitTests.vcxproj.filters | 9 +- src/core/net/ip6_headers.hpp | 7 + src/core/thread/lowpan.cpp | 96 +- src/core/thread/lowpan.hpp | 1 + src/core/thread/network_data_leader.cpp | 4 + tests/unit/Makefile.am | 4 +- tests/unit/test_lowpan.cpp | 1955 ++++++++++++++++++- tests/unit/test_lowpan.hpp | 282 +++ tests/unit/test_util.cpp | 4 +- tests/unit/test_vector.c | 157 -- tests/unit/test_vector.h | 74 - 12 files changed, 2252 insertions(+), 348 deletions(-) create mode 100644 tests/unit/test_lowpan.hpp delete mode 100644 tests/unit/test_vector.c delete mode 100644 tests/unit/test_vector.h diff --git a/etc/visual-studio/UnitTests.vcxproj b/etc/visual-studio/UnitTests.vcxproj index 03403e498..d41ec3bf1 100644 --- a/etc/visual-studio/UnitTests.vcxproj +++ b/etc/visual-studio/UnitTests.vcxproj @@ -1,6 +1,6 @@  - + {FD64BF17-8D36-4578-8D13-77B123BE30D3} Win32Proj @@ -80,14 +80,13 @@ - + - @@ -103,4 +102,4 @@ - \ No newline at end of file + diff --git a/etc/visual-studio/UnitTests.vcxproj.filters b/etc/visual-studio/UnitTests.vcxproj.filters index 375ac3b9f..d7d5eb2ea 100644 --- a/etc/visual-studio/UnitTests.vcxproj.filters +++ b/etc/visual-studio/UnitTests.vcxproj.filters @@ -15,9 +15,6 @@ - - Source Files - Source Files @@ -62,14 +59,14 @@ Header Files + + Header Files + Header Files Header Files - - Header Files - diff --git a/src/core/net/ip6_headers.hpp b/src/core/net/ip6_headers.hpp index 6cfae04cd..78c523586 100644 --- a/src/core/net/ip6_headers.hpp +++ b/src/core/net/ip6_headers.hpp @@ -44,6 +44,7 @@ #include using Thread::Encoding::BigEndian::HostSwap16; +using Thread::Encoding::BigEndian::HostSwap32; namespace Thread { @@ -138,6 +139,12 @@ public: */ void Init() { mVersionClassFlow.m32[0] = 0; mVersionClassFlow.m8[0] = kVersion6; } + /** + * This method initializes the IPv6 header and sets Version, Traffic Control and Flow Label fields. + * + */ + void Init(uint32_t aVersionClassFlow) { mVersionClassFlow.m32[0] = HostSwap32(aVersionClassFlow); } + /** * This method indicates whether or not the IPv6 Version is set to 6. * diff --git a/src/core/thread/lowpan.cpp b/src/core/thread/lowpan.cpp index 9e0f3d8ae..6e88c4ce5 100644 --- a/src/core/thread/lowpan.cpp +++ b/src/core/thread/lowpan.cpp @@ -174,6 +174,7 @@ int Lowpan::CompressDestinationIid(const Mac::Address &aMacAddr, const Ip6::Addr int Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, uint8_t *aBuf) { uint8_t *cur = aBuf; + Context multicastContext; aHcCtl |= kHcMulticast; @@ -181,12 +182,14 @@ int Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, uin { if (aIpAddr.mFields.m8[i]) { + // Check if multicast address can be compressed to 8-bits (ff02::00xx) if (aIpAddr.mFields.m8[1] == 0x02 && i >= 15) { aHcCtl |= kHcDstAddrMode3; cur[0] = aIpAddr.mFields.m8[15]; cur++; } + // Check if multicast address can be compressed to 32-bits (ffxx::00xx:xxxx) else if (i >= 13) { aHcCtl |= kHcDstAddrMode2; @@ -194,7 +197,8 @@ int Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, uin memcpy(cur + 1, aIpAddr.mFields.m8 + 13, 3); cur += 4; } - else if (i >= 9) + // Check if multicast address can be compressed to 48-bits (ffxx::00xx:xxxx:xxxx) + else if (i >= 11) { aHcCtl |= kHcDstAddrMode1; cur[0] = aIpAddr.mFields.m8[1]; @@ -203,8 +207,21 @@ int Lowpan::CompressMulticast(const Ip6::Address &aIpAddr, uint16_t &aHcCtl, uin } else { - memcpy(cur, aIpAddr.mFields.m8, sizeof(Ip6::Address)); - cur += sizeof(Ip6::Address); + // Check if multicast address can be compressed using Context ID 0. + if (mNetworkData.GetContext(0, multicastContext) == kThreadError_None && + multicastContext.mPrefixLength == aIpAddr.mFields.m8[3] && + memcmp(multicastContext.mPrefix, aIpAddr.mFields.m8 + 4, 8) == 0) + { + aHcCtl |= kHcDstAddrContext | kHcDstAddrMode0; + memcpy(cur, aIpAddr.mFields.m8 + 1, 2); + memcpy(cur + 2, aIpAddr.mFields.m8 + 12, 4); + cur += 6; + } + else + { + memcpy(cur, aIpAddr.mFields.m8, sizeof(Ip6::Address)); + cur += sizeof(Ip6::Address); + } } break; @@ -223,16 +240,20 @@ int Lowpan::Compress(Message &aMessage, const Mac::Address &aMacSource, const Ma Context srcContext, dstContext; bool srcContextValid = true, dstContextValid = true; uint8_t nextHeader; + uint8_t ecn = 0; + uint8_t dscp = 0; aMessage.Read(aMessage.GetOffset(), sizeof(ip6Header), &ip6Header); - if (mNetworkData.GetContext(ip6Header.GetSource(), srcContext) != kThreadError_None) + if (mNetworkData.GetContext(ip6Header.GetSource(), srcContext) != kThreadError_None || + srcContext.mCompressFlag == false) { mNetworkData.GetContext(0, srcContext); srcContextValid = false; } - if (mNetworkData.GetContext(ip6Header.GetDestination(), dstContext) != kThreadError_None) + if (mNetworkData.GetContext(ip6Header.GetDestination(), dstContext) != kThreadError_None || + dstContext.mCompressFlag == false) { mNetworkData.GetContext(0, dstContext); dstContextValid = false; @@ -251,35 +272,42 @@ int Lowpan::Compress(Message &aMessage, const Mac::Address &aMacSource, const Ma cur++; } - // Traffic Class - if (((ip6HeaderBytes[0] & 0x0f) == 0) && ((ip6HeaderBytes[1] & 0xf0) == 0)) - { - hcCtl |= kHcTrafficClass; - } + dscp = ((ip6HeaderBytes[0] << 2) & 0x3c) | (ip6HeaderBytes[1] >> 6); + ecn = (ip6HeaderBytes[1] << 2) & 0xc0; // Flow Label if (((ip6HeaderBytes[1] & 0x0f) == 0) && ((ip6HeaderBytes[2]) == 0) && ((ip6HeaderBytes[3]) == 0)) { - hcCtl |= kHcFlowLabel; - } - - if ((hcCtl & kHcTrafficFlowMask) != kHcTrafficFlow) - { - cur[0] = ((ip6HeaderBytes[1] >> 4) << 6) & 0xff; - - if ((hcCtl & kHcTrafficClass) == 0) + if (dscp == 0 && ecn == 0) { - cur[0] |= ((ip6HeaderBytes[0] & 0x0f) << 2) | (ip6HeaderBytes[1] >> 6); + // Elide Flow Label and Traffic Class. + hcCtl |= kHcTrafficClass | kHcFlowLabel; + } + else + { + // Elide Flow Label and carry Traffic Class in-line. + hcCtl |= kHcFlowLabel; + + cur[0] = ecn | dscp; cur++; } + } + else if (dscp == 0) + { + // Carry Flow Label and ECN only with 2-bit padding. + hcCtl |= kHcTrafficClass; - if ((hcCtl & kHcFlowLabel) == 0) - { - cur[0] |= ip6HeaderBytes[1] & 0x0f; - cur[1] = ip6HeaderBytes[2]; - cur[2] = ip6HeaderBytes[3]; - cur += 3; - } + cur[0] = ecn | (ip6HeaderBytes[1] & 0x0f); + memcpy(cur + 1, ip6HeaderBytes + 2, 2); + cur += 3; + } + else + { + // Carry Flow Label and Traffic Class in-line. + cur[0] = ecn | dscp; + cur[1] = ip6HeaderBytes[1] & 0x0f; + memcpy(cur + 2, ip6HeaderBytes + 2, 2); + cur += 4; } // Next Header @@ -703,17 +731,17 @@ int Lowpan::DecompressBaseHeader(Ip6::Header &ip6Header, const Mac::Address &aMa break; } - if ((hcCtl & kHcSrcAddrContext) == 0) + if ((hcCtl & kHcSrcAddrModeMask) != kHcSrcAddrMode0) { - if ((hcCtl & kHcSrcAddrModeMask) != 0) + if ((hcCtl & kHcSrcAddrContext) == 0) { ip6Header.GetSource().mFields.m16[0] = HostSwap16(0xfe80); } - } - else - { - VerifyOrExit(srcContextValid,); - CopyContext(srcContext, ip6Header.GetSource()); + else + { + VerifyOrExit(srcContextValid,); + CopyContext(srcContext, ip6Header.GetSource()); + } } if ((hcCtl & kHcMulticast) == 0) @@ -723,6 +751,7 @@ int Lowpan::DecompressBaseHeader(Ip6::Header &ip6Header, const Mac::Address &aMa switch (hcCtl & kHcDstAddrModeMask) { case kHcDstAddrMode0: + VerifyOrExit((hcCtl & kHcDstAddrContext) == 0,); VerifyOrExit(remaining >= sizeof(Ip6::Address),); memcpy(&ip6Header.GetDestination(), cur, sizeof(ip6Header.GetDestination())); cur += sizeof(Ip6::Address); @@ -1019,6 +1048,7 @@ int Lowpan::Decompress(Message &aMessage, const Mac::Address &aMacSource, const compressed = (((static_cast(cur[0]) << 8) | cur[1]) & kHcNextHeader) != 0; VerifyOrExit((rval = DecompressBaseHeader(ip6Header, aMacSource, aMacDest, cur, remaining)) >= 0,); + cur += rval; remaining -= rval; diff --git a/src/core/thread/lowpan.hpp b/src/core/thread/lowpan.hpp index bc140214d..4dff5e0b5 100644 --- a/src/core/thread/lowpan.hpp +++ b/src/core/thread/lowpan.hpp @@ -72,6 +72,7 @@ struct Context const uint8_t *mPrefix; ///< A pointer to the prefix. uint8_t mPrefixLength; ///< The prefix length. uint8_t mContextId; ///< The Context ID. + bool mCompressFlag; ///< The Context compression flag. }; /** diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index b6eb1735a..a88fca1b6 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -141,6 +141,7 @@ ThreadError Leader::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aC aContext.mPrefix = mMle.GetMeshLocalPrefix(); aContext.mPrefixLength = 64; aContext.mContextId = 0; + aContext.mCompressFlag = true; } for (NetworkDataTlv *cur = reinterpret_cast(mTlvs); @@ -171,6 +172,7 @@ ThreadError Leader::GetContext(const Ip6::Address &aAddress, Lowpan::Context &aC aContext.mPrefix = prefix->GetPrefix(); aContext.mPrefixLength = prefix->GetPrefixLength(); aContext.mContextId = contextTlv->GetContextId(); + aContext.mCompressFlag = contextTlv->IsCompress(); } } @@ -188,6 +190,7 @@ ThreadError Leader::GetContext(uint8_t aContextId, Lowpan::Context &aContext) aContext.mPrefix = mMle.GetMeshLocalPrefix(); aContext.mPrefixLength = 64; aContext.mContextId = 0; + aContext.mCompressFlag = true; ExitNow(error = kThreadError_None); } @@ -216,6 +219,7 @@ ThreadError Leader::GetContext(uint8_t aContextId, Lowpan::Context &aContext) aContext.mPrefix = prefix->GetPrefix(); aContext.mPrefixLength = prefix->GetPrefixLength(); aContext.mContextId = contextTlv->GetContextId(); + aContext.mCompressFlag = contextTlv->IsCompress(); ExitNow(error = kThreadError_None); } diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am index f4586ec50..3fd625681 100644 --- a/tests/unit/Makefile.am +++ b/tests/unit/Makefile.am @@ -34,9 +34,9 @@ include $(abs_top_nlbuild_autotools_dir)/automake/pre.am # noinst_HEADERS = \ test_platform.h \ + test_lowpan.hpp \ test_util.h \ test_util.hpp \ - test_vector.h \ $(NULL) # @@ -130,7 +130,7 @@ test_link_quality_LDADD = $(COMMON_LDADD) test_link_quality_SOURCES = test_platform.cpp test_link_quality.cpp test_lowpan_LDADD = $(COMMON_LDADD) -test_lowpan_SOURCES = test_platform.cpp test_lowpan.cpp test_util.cpp test_vector.c +test_lowpan_SOURCES = test_platform.cpp test_lowpan.cpp test_util.cpp test_mac_frame_LDADD = $(COMMON_LDADD) test_mac_frame_SOURCES = test_platform.cpp test_mac_frame.cpp diff --git a/tests/unit/test_lowpan.cpp b/tests/unit/test_lowpan.cpp index c8178719c..2872e1a2b 100644 --- a/tests/unit/test_lowpan.cpp +++ b/tests/unit/test_lowpan.cpp @@ -27,16 +27,10 @@ */ #include "test_util.hpp" -#include "test_vector.h" -#include -#include - -#include -#include -#include -#include +#include "test_lowpan.hpp" using namespace Thread; +using Thread::Encoding::BigEndian::HostSwap16; namespace Thread { @@ -44,83 +38,1906 @@ Ip6::Ip6 sIp6; ThreadNetif sMockThreadNetif(sIp6); Lowpan::Lowpan sMockLowpan(sMockThreadNetif); -void TestLowpanIphc(void) +void TestIphcVector::GetCompressedStream(uint8_t *aIphc, uint16_t &aIphcLength) +{ + memcpy(aIphc, mIphcHeader.mData, mIphcHeader.mLength); + memcpy(aIphc + mIphcHeader.mLength, mPayload.mData, mPayload.mLength); + + aIphcLength = mIphcHeader.mLength + mPayload.mLength; +} + +void TestIphcVector::GetUncompressedStream(uint8_t *aIp6, uint16_t &aIp6Length) +{ + aIp6Length = 0; + + memcpy(aIp6, reinterpret_cast(&mIpHeader), sizeof(mIpHeader)); + aIp6Length += sizeof(mIpHeader); + + if (mExtHeader.mLength) + { + memcpy(aIp6 + aIp6Length, mExtHeader.mData, mExtHeader.mLength); + aIp6Length += mExtHeader.mLength; + } + + if (mIpTunneledHeader.GetPayloadLength()) + { + memcpy(aIp6 + aIp6Length, reinterpret_cast(&mIpTunneledHeader), sizeof(mIpTunneledHeader)); + aIp6Length += sizeof(mIpTunneledHeader); + } + + if (mUdpHeader.GetLength()) + { + memcpy(aIp6 + aIp6Length, reinterpret_cast(&mUdpHeader), sizeof(mUdpHeader)); + aIp6Length += sizeof(mUdpHeader); + } + + memcpy(aIp6 + aIp6Length, mPayload.mData, mPayload.mLength); + aIp6Length += mPayload.mLength; +} + +void TestIphcVector::GetUncompressedStream(Message &aMessage) +{ + SuccessOrQuit(aMessage.Append(reinterpret_cast(&mIpHeader), sizeof(mIpHeader)), + "6lo: Message::Append failed"); + + if (mExtHeader.mLength) + { + SuccessOrQuit(aMessage.Append(mExtHeader.mData, mExtHeader.mLength), + "6lo: Message::Append failed"); + } + + if (mIpTunneledHeader.GetPayloadLength()) + { + SuccessOrQuit(aMessage.Append(reinterpret_cast(&mIpTunneledHeader), sizeof(mIpTunneledHeader)), + "6lo: Message::Append failed"); + } + + if (mUdpHeader.GetLength()) + { + SuccessOrQuit(aMessage.Append(reinterpret_cast(&mUdpHeader), sizeof(mUdpHeader)), + "6lo: Message::Append failed"); + } + + SuccessOrQuit(aMessage.Append(mPayload.mData, mPayload.mLength), "6lo: Message::Append failed5"); +} + +/** + * This function initializes Thread Interface. + * + */ +static void Init() +{ + uint8_t meshLocalPrefix[] = {0xfd, 0x00, 0xca, 0xfe, 0xfa, 0xce, 0x12, 0x34}; + sMockThreadNetif.GetMle().SetMeshLocalPrefix(meshLocalPrefix); + + // Emulate global prefixes with contextes. + uint8_t mockNetworkData[] = + { + // Prefix 2001:2:0:1::/64 + 0x03, 0x0e, // Prefix TLV + 0x00, 0x40, + 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, + 0x07, 0x02, // 6LoWPAN Context ID TLV + 0x11, 0x40, // Context ID = 1, C = TRUE + + // Prefix 2001:2:0:2::/64 + 0x03, 0x0e, // Prefix TLV + 0x00, 0x40, + 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, + 0x07, 0x02, // 6LoWPAN Context ID TLV + 0x02, 0x40 // Context ID = 2, C = FALSE + }; + + sMockThreadNetif.GetNetworkDataLeader().SetNetworkData(0, 0, true, mockNetworkData, sizeof(mockNetworkData)); +} + +/** + * This function performs compression or/and decompression based on the given test vector. + * + * @note Performing decompression and compression on the same LOWPAN_IPHC frame may give different result. + * This situation may occur when sender does not use the best possible compression, + * e.g. doesn't use LOWPAN_NHC for UDP - which is still valid. + * + * @param aVector Test vector that has to be tested. + * @param aCompress Set to TRUE, if compression should be tested. + * @param aDecompress Set to TRUE, if decomrpession should be tested. + */ +static void Test(TestIphcVector &aVector, bool aCompress, bool aDecompress) { Message *message = NULL; + uint8_t result[512]; + uint8_t iphc[512]; + uint8_t ip6[512]; + uint16_t iphcLength; + uint16_t ip6Length; - uint8_t result[1500]; - uint16_t resultLength = 0; + aVector.GetCompressedStream(iphc, iphcLength); + aVector.GetUncompressedStream(ip6, ip6Length); - Mac::Address macSource; - Mac::Address macDest; + printf("\n=== Test name: %s ===\n\n", aVector.mTestName); - test_lowpan_vector_t *tests = sTestVectorLowpan; + printf("Expected error -------------- %s\n", aVector.mError ? "yes" : "no"); + printf("UDP present ----------------- %s\n", aVector.mUdpHeader.GetLength() ? "yes" : "no"); + printf("Extension Headers present --- %s\n", aVector.mExtHeader.mLength ? "yes" : "no"); + printf("IP-in-IP present ------------ %s\n", aVector.mIpTunneledHeader.GetPayloadLength() ? "yes" : "no"); + printf("LOWPAN_IPHC length ---------- %d\n", aVector.mIphcHeader.mLength); + printf("IPv6 uncompressed offset ---- %d\n\n", aVector.mPayloadOffset); - for (unsigned i = 0; i < sTestVectorLowpanLen; i++) + printf("Expected IPv6 uncompressed packet: \n"); + otTestPrintHex(ip6, ip6Length); + printf("\n"); + + printf("Expected LOWPAN_IPHC compressed frame: \n"); + otTestPrintHex(iphc, iphcLength); + printf("\n"); + + if (aCompress) { - // Prepare next test vector - std::string ipString(tests[i].mRaw); - std::vector ipVector; - otTestHexToVector(ipString, ipVector); - - std::string iphcString(tests[i].mCompressed); - std::vector iphcVector; - otTestHexToVector(iphcString, iphcVector); - - printf("=== Packet #%d: %s ===\n", i, tests[i].mTest); - printf("6lo Packet:\n"); - otTestPrintHex(iphcVector); - - printf("Decompressed Reference:\n"); - otTestPrintHex(ipVector); - - // Test decompression - - Mac::Frame frame; - frame.mPsdu = iphcVector.data(); - frame.mLength = static_cast(iphcVector.size()); - frame.GetSrcAddr(macSource); - frame.GetDstAddr(macDest); - VerifyOrQuit((message = sIp6.mMessagePool.New(Message::kTypeIp6, 0)) != NULL, "6lo: Ip6::NewMessage failed"); - // ===> Test Lowpan::Decompress - int decompressedBytes = - sMockLowpan.Decompress(*message, macSource, macDest, - frame.GetPayload(), - frame.GetPayloadLength(), 0); + aVector.GetUncompressedStream(*message); - uint16_t ip6PayloadLength = frame.GetPayloadLength() - - static_cast(decompressedBytes); - SuccessOrQuit(message->Append(frame.GetPayload() + decompressedBytes, - ip6PayloadLength), - "6lo: Message::Append failed"); - - resultLength = message->GetLength(); - message->Read(0, resultLength, result); - - printf("Decompressed OpenThread:\n"); - otTestPrintHex(result, resultLength); - - VerifyOrQuit(memcmp(ipVector.data(), result, resultLength) == 0, - "6lo: Lowpan::Decompress failed"); - - message->SetOffset(0); - - // ===> Test Lowpan::Compress - int compressBytes = sMockLowpan.Compress(*message, macSource, macDest, + int compressBytes = sMockLowpan.Compress(*message, aVector.mMacSource, aVector.mMacDestination, result); - printf("Compressed OpenThread:\n"); - otTestPrintHex(result, compressBytes); - VerifyOrQuit(memcmp(frame.GetPayload(), result, static_cast(compressBytes)) == 0, - "6lo: Lowpan::Compress failed"); + if (aVector.mError == kThreadError_None) + { + // Append payload to the LOWPAN_IPHC. + message->Read(message->GetOffset(), + message->GetLength() - message->GetOffset(), + result + compressBytes); - SuccessOrQuit(message->Free(), "6lo: Message:Free failed"); - printf("PASS\n\n"); + printf("Resulted LOWPAN_IPHC compressed frame: \n"); + otTestPrintHex(result, compressBytes + message->GetLength() - message->GetOffset()); + printf("\n"); + VerifyOrQuit(compressBytes == aVector.mIphcHeader.mLength, "6lo: Lowpan::Compress failed"); + VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "6lo: Lowpan::Compress failed"); + VerifyOrQuit(memcmp(iphc, result, iphcLength) == 0, + "6lo: Lowpan::Compress failed"); + } + else + { + VerifyOrQuit(compressBytes < 0 , "6lo: Lowpan::Compress failed"); + } + + message->Free(); + message = NULL; } + + if (aDecompress) + { + VerifyOrQuit((message = sIp6.mMessagePool.New(Message::kTypeIp6, 0)) != NULL, + "6lo: Ip6::NewMessage failed"); + + int decompressedBytes = sMockLowpan.Decompress(*message, aVector.mMacSource, aVector.mMacDestination, + iphc, iphcLength, 0); + + message->Read(0, message->GetLength(), result); + + if (aVector.mError == kThreadError_None) + { + // Append payload to the IPv6 Packet. + memcpy(result + message->GetLength(), iphc + decompressedBytes, + iphcLength - decompressedBytes); + + printf("Resulted IPv6 uncompressed packet: \n"); + otTestPrintHex(result, message->GetLength() + iphcLength - decompressedBytes); + printf("\n"); + + VerifyOrQuit(decompressedBytes == aVector.mIphcHeader.mLength , "6lo: Lowpan::Decompress failed"); + VerifyOrQuit(message->GetOffset() == aVector.mPayloadOffset, "6lo: Lowpan::Decompress failed"); + VerifyOrQuit(message->GetOffset() == message->GetLength(), "6lo: Lowpan::Decompress failed"); + VerifyOrQuit(memcmp(ip6, result, ip6Length) == 0, "6lo: Lowpan::Decompress failed"); + } + else + { + VerifyOrQuit(decompressedBytes < 0 , "6lo: Lowpan::Decompress failed"); + } + + message->Free(); + message = NULL; + } + + printf("PASS\n\n"); +} + +/*************************************************************************************************** + * @section Test constants. + **************************************************************************************************/ +static const uint8_t sTestMacSourceDefaultLong[] = {0x00, 0x00, 0x5e, 0xef, 0x10, 0x22, 0x11, 0x00}; +static const uint8_t sTestMacDestinationDefaultLong[] = {0x00, 0x00, 0x5e, 0xef, 0x10, 0xaa, 0xbb, 0xcc}; + +static uint16_t sTestMacSourceDefaultShort = 0x0000; +static uint16_t sTestMacDestinationDefaultShort = 0xc003; +static uint16_t sTestMacDestinationBroadcast = 0xffff; + +static const uint8_t sTestPayloadDefault[] = {0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + +/*************************************************************************************************** +* @section Test cases. +**************************************************************************************************/ + +static void TestFullyCompressableLongAddresses(void) +{ + TestIphcVector testVector("Fully compressable IPv6 addresses using long MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x33, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestFullyCompressableShortAddresses(void) +{ + TestIphcVector testVector("Fully compressable IPv6 addresses using short MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::ff:fe00:0000", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x33, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestFullyCompressableShortLongAddresses(void) +{ + TestIphcVector testVector("Fully compressable IPv6 addresses using short and long MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::ff:fe00:0000", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x33, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestFullyCompressableLongShortAddresses(void) +{ + TestIphcVector testVector("Fully compressable IPv6 addresses using long and short MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x33, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSourceUnspecifiedAddress(void) +{ + TestIphcVector testVector("Unspecified source IPv6 address"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "::", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x43, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSource128bitDestination128bitAddresses(void) +{ + TestIphcVector testVector("IPv6 addresses inline"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "2001:2:0:3:aaaa:bbbb:cccc:dddd", + "2001:2:0:4::"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x00, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x03, 0xaa, 0xaa, 0xbb, 0xbb, 0xcc, + 0xcc, 0xdd, 0xdd, 0x20, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSource64bitDestination64bitLongAddresses(void) +{ + TestIphcVector testVector("IPv6 addresses 64-bit using long MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1101", + "fe80::200:5eef:10aa:bbcd"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x11, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, + 0x22, 0x11, 0x01, 0x02, 0x00, 0x5e, 0xef, 0x10, + 0xaa, 0xbb, 0xcd + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSource64bitDestination64bitShortAddresses(void) +{ + TestIphcVector testVector("IPv6 addresses 64-bit using short MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1101", + "fe80::200:5eef:10aa:bbcd"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x11, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, + 0x22, 0x11, 0x01, 0x02, 0x00, 0x5e, 0xef, 0x10, + 0xaa, 0xbb, 0xcd + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSource16bitDestination16bitAddresses(void) +{ + TestIphcVector testVector("IPv6 addresses 16-bit using short MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::ff:fe00:0001", + "fe80::ff:fe00:c004"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x22, 0x3a, 0x00, 0x01, 0xc0, 0x04}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSourceCompressedDestination16bitAddresses(void) +{ + TestIphcVector testVector("Fully compressable IPv6 source and destination 16-bit using long MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::ff:fe00:beaf"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x32, 0x3a, 0xbe, 0xaf}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestSourceCompressedDestination128bitAddresses(void) +{ + TestIphcVector testVector("Fully compressable IPv6 source and destination inline using long MAC addresses"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "2001:2:0:4::"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x30, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + + +static void TestMulticast128bitAddress(void) +{ + TestIphcVector testVector("Multicast address inline"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "ff05::100:0030:0001"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x38, 0x3a, 0xff, 0x05, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x30, 0x00, 0x01 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestMulticast48bitAddress(void) +{ + TestIphcVector testVector("Multicast address 48-bit"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "ff05::1:0030:0001"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x39, 0x3a, 0x05, 0x01, 0x00, 0x30, 0x00, + 0x01 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestMulticast32bitAddress(void) +{ + TestIphcVector testVector("Multicast address 32-bit"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "ff03::fc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x1a, 0x3a, 0x02, 0x00, 0x5e, 0xef, 0x10, + 0x22, 0x11, 0x00, 0x03, 0x00, 0x00, 0xfc + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestMulticast8bitAddress(void) +{ + TestIphcVector testVector("Multicast address 8-bit"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "ff02::2"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x3b, 0x3a, 0x02}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulSource64bitDestination64bitContext0(void) +{ + TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 0"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234:abcd:ef01:2345:6789", + "fd00:cafe:face:1234:c31d:a702:0d41:beef"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x55, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, + 0x41, 0xbe, 0xef + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulSource64bitDestination64bitContext0IfContextInLine(void) +{ + TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 0 inline"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234:abcd:ef01:2345:6789", + "fd00:cafe:face:1234:c31d:a702:0d41:beef"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0xd5, 0x00, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, + 0x41, 0xbe, 0xef + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform decompression test only. + Test(testVector, false, true); +} + +static void TestStatefulSource16bitDestination16bitContext0(void) +{ + TestIphcVector testVector("Stateful compression source and destination addresses 16-bit, context 0"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234::ff:fe00:fffc", + "fd00:cafe:face:1234::ff:fe00:fffe"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x66, 0x3a, 0xff, 0xfc, 0xff, 0xfe}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulCompressableLongAddressesContext0(void) +{ + TestIphcVector testVector("Stateful compression compressable long addresses, context 0"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234:0200:5eef:1022:1100", + "fd00:cafe:face:1234:0200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x77, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulCompressableShortAddressesContext0(void) +{ + TestIphcVector testVector("Stateful compression compressable short addresses, context 0"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "fd00:cafe:face:1234::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x77, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulCompressableLongShortAddressesContext0(void) +{ + TestIphcVector testVector("Stateful compression compressable long and short addresses, context 0"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234:0200:5eef:1022:1100", + "fd00:cafe:face:1234::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x77, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulSource64bitDestination128bitContext1(void) +{ + TestIphcVector testVector("Stateful compression source addresses 64-bit and destination inline, context 1"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "2001:2:0:1:abcd:ef01:2345:6789", + "2001:2:0:3:c31d:a702:0d41:beef"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0xd0, 0x10, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0x20, 0x01, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x03, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, 0xbe, + 0xef + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulSource64bitDestination64bitContext1(void) +{ + TestIphcVector testVector("Stateful compression source and destination addresses 64-bit, context 1"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "2001:2:0:1:abcd:ef01:2345:6789", + "2001:2:0:1:c31d:a702:0d41:beef"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0xd5, 0x11, 0x3a, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, 0x41, + 0xbe, 0xef + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestStatefulSourceDestinationInlineContext2CIDFalse(void) +{ + TestIphcVector testVector("Stateful compression source and destination addresses inline, context 2 (C=FALSE)"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "2001:2:0:2:abcd:ef01:2345:6789", + "2001:2:0:2:c31d:a702:0d41:beef"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x00, 0x3a, 0x20, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0xab, 0xcd, 0xef, 0x01, 0x23, + 0x45, 0x67, 0x89, 0x20, 0x01, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x02, 0xc3, 0x1d, 0xa7, 0x02, 0x0d, + 0x41, 0xbe, 0xef + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression test only. + Test(testVector, true, false); +} + +static void TestStatefulMulticastDestination48bitContext0(void) +{ + TestIphcVector testVector("Stateful compression multicast address, context 0"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fd00:cafe:face:1234:0200:5eef:1022:1100", + "ff33:0040:fd00:cafe:face:1234:0000:0001"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x7c, 0x3a, 0x33, 0x00, 0x00, 0x00, 0x00, + 0x01 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform decompression tests. + Test(testVector, true, true); +} + +static void TestTrafficClassFlowLabel3Bytes(void) +{ + TestIphcVector testVector("Traffic Class and Flow Label 3 bytes"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x6011ac59, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x6a, 0x33, 0x41, 0xac, 0x59, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestTrafficClassFlowLabel1Byte(void) +{ + TestIphcVector testVector("Traffic Class and Flow Label 1 byte"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60d00000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x72, 0x33, 0x43, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestTrafficClassFlowLabel1ByteEcnOnly(void) +{ + TestIphcVector testVector("Traffic Class and Flow Label 1 byte with ecn only"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60100000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x72, 0x33, 0x40, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestTrafficClassFlowLabelInline(void) +{ + TestIphcVector testVector("Traffic Class and Flow Label inline"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x6ea12345, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x62, 0x33, 0xBA, 0x01, 0x23, 0x45, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestHopLimit1(void) +{ + TestIphcVector testVector("Hop Limit 1"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 1, + "fe80::ff:fe00:0000", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x79, 0x33, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestHopLimit255(void) +{ + TestIphcVector testVector("Hop Limit 255"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 255, + "fe80::ff:fe00:0000", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7B, 0x33, 0x3a}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestHopLimitInline(void) +{ + TestIphcVector testVector("Hop Limit Inline"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 63, + "fe80::ff:fe00:0000", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x78, 0x33, 0x3a, 0x3f}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestUdpSourceDestinationInline(void) +{ + TestIphcVector testVector("UDP source and destination inline"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Setup UDP header. + testVector.SetUDPHeader(5683, 5684, sizeof(sTestPayloadDefault) + 8, 0xbeef); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0xf0, 0x16, 0x33, 0x16, 0x34, 0xbe, 0xef}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestUdpSourceInlineDestination8bit(void) +{ + TestIphcVector testVector("UDP source inline destination 8-bit"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Setup UDP header. + testVector.SetUDPHeader(5683, 61441, sizeof(sTestPayloadDefault) + 8, 0xbeef); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0xf1, 0x16, 0x33, 0x01, 0xbe, 0xef}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestUdpSource8bitDestinationInline(void) +{ + TestIphcVector testVector("UDP source 8-bit destination 8-bit"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Setup UDP header. + testVector.SetUDPHeader(61695, 5683, sizeof(sTestPayloadDefault) + 8, 0xbeef); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0xf2, 0xff, 0x16, 0x33, 0xbe, 0xef}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestUdpFullyCompressed(void) +{ + TestIphcVector testVector("UDP fully compressed"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Setup UDP header. + testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0xf3, 0x0f, 0xfa, 0xce}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestUdpFullyCompressedMulticast(void) +{ + TestIphcVector testVector("UDP fully compressed with IP multicast"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, + "fe80::200:5eef:1022:1100", + "ff02::1"); + + // Setup UDP header. + testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x3b, 0x01, 0xf3, 0x0f, 0xfa, 0xce}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestUdpWithoutNhc(void) +{ + TestIphcVector testVector("UDP without LOWPAN_NHC compression"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationDefaultShort); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoUdp, 64, + "fe80::ff:fe00:0000", + "fe80::ff:fe00:c003"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x33, 0x11}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(40); + testVector.SetError(kThreadError_None); + + // Perform only decompression test. + Test(testVector, false, true); +} + +static void TestExtensionHeaderHopByHopNoPadding(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with no padding"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x04, 0x60, 0x11, 0x00, 0x0c}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x06, 0x6d, 0x04, 0x60, 0x11, 0x00, 0x0c + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPad1(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with Pad1"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x03, 0x60, 0x11, 0x00, 0x00}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x05, 0x6d, 0x03, 0x60, 0x11, 0x00 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN2(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN2"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x02, 0x60, 0x11, 0x01, 0x00}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x04, 0x6d, 0x02, 0x60, 0x11 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN3(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN3"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x01, 0x60, 0x01, 0x01, 0x00}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x03, 0x6d, 0x01, 0x60 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN4(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN4"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x00, 0x6d, 0x00, 0x01, 0x02, 0x00, 0x00}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x02, 0x6d, 0x00 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(48); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN5(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN5"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 16, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x01, 0x6d, 0x07, 0x01, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00 + }; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x09, 0x6d, 0x07, 0x01, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x33 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(56); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN6(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN6"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 24, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x02, 0x6d, 0x0e, 0x01, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00 + }; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x10, 0x6d, 0x0e, 0x01, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11, + 0x00 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(64); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN7(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN7"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 24, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x3a, 0x02, 0x6d, 0x0d, 0x01, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, + 0x11, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe0, 0x3a, + 0x0f, 0x6d, 0x0d, 0x01, 0x02, 0x01, 0x00, 0x00, + 0x00, 0x33, 0x01, 0x03, 0x00, 0x00, 0x00, 0x11 + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(64); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestExtensionHeaderHopByHopPadN2UdpFullyCompressed(void) +{ + TestIphcVector testVector("Extension Header - Hop-by-Hop with PadN2 and UDP"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 16, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::1"); + + // Setup extension header. + uint8_t extHeader[] = {0x11, 0x00, 0x6d, 0x02, 0x60, 0x11, 0x01, 0x00}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Setup UDP header. + testVector.SetUDPHeader(61616, 61631, sizeof(sTestPayloadDefault) + 8, 0xface); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0x01, 0xe1, 0x04, + 0x6d, 0x02, 0x60, 0x11, 0xf3, 0x0f, 0xfa, 0xce + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(56); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestIpInIpHopByHopPadN2UdpSourceDestinationInline(void) +{ + TestIphcVector testVector("IP-in-IP with Hop-by-Hop with PadN2 and UDP"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultShort); + testVector.SetMacDestination(sTestMacDestinationBroadcast); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 56, Ip6::kProtoHopOpts, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff03::fc"); + + // Setup extension header. + uint8_t extHeader[] = {0x29, 0x00, 0x6d, 0x02, 0x00, 0x11, 0x01, 0x00}; + testVector.SetExtHeader(extHeader, sizeof(extHeader)); + + // Setup IPv6 tunneled header. + testVector.SetIpTunneledHeader(0x60000000, sizeof(sTestPayloadDefault) + 8, Ip6::kProtoUdp, 64, + "fd00:cafe:face:1234::ff:fe00:0000", + "ff05::1"); + + // Setup UDP header. + testVector.SetUDPHeader(5683, 5684, sizeof(sTestPayloadDefault) + 8, 0xbeef); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x7a, 0x03, 0x00, 0x00, 0xfc, 0xe1, 0x04, + 0x6d, 0x02, 0x00, 0x11, 0xee, 0x7e, 0x7a, 0x05, + 0x00, 0x00, 0x01, 0xf0, 0x16, 0x33, 0x16, 0x34, + 0xbe, 0xef + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(96); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestIpInIpWithoutExtensionHeader(void) +{ + TestIphcVector testVector("IP-in-IP without extension header"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Setup IPv6 header. + testVector.SetIpHeader(0x60000000, sizeof(sTestPayloadDefault) + 40, Ip6::kProtoIp6, 64, + "fe80::200:5eef:1022:1100", + "ff03::1"); + + // Setup IPv6 tunneled header. + testVector.SetIpTunneledHeader(0x60000000, sizeof(sTestPayloadDefault), Ip6::kProtoIcmp6, 1, + "fe80::200:5eef:1022:1100", + "fe80::200:5eef:10aa:bbcc"); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x3a, 0x03, 0x00, 0x00, 0x01, 0xee, 0x79, + 0x33, 0x3a + }; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetPayload(sTestPayloadDefault, sizeof(sTestPayloadDefault)); + testVector.SetPayloadOffset(80); + testVector.SetError(kThreadError_None); + + // Perform compression and decompression tests. + Test(testVector, true, true); +} + +static void TestErrorNoIphcDispatch(void) +{ + TestIphcVector testVector("Invalid dispatch"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorTruncatedIphc(void) +{ + TestIphcVector testVector("Truncated LOWPAN_IPHC"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x00}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorReservedValueDestination0100(void) +{ + TestIphcVector testVector("Reserved value of M-DAC-DAM - 0100"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x34, 0x3A}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorReservedValueDestination1101(void) +{ + TestIphcVector testVector("Reserved value of M-DAC-DAM - 1101"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x3D, 0x3A}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorReservedValueDestination1110(void) +{ + TestIphcVector testVector("Reserved value of M-DAC-DAM - 1110"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x3E, 0x3A}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorReservedValueDestination1111(void) +{ + TestIphcVector testVector("Reserved value of M-DAC-DAM - 1111"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7a, 0x3F, 0x3A}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorUnknownNhc(void) +{ + TestIphcVector testVector("Unknown value of LOWPAN_NHC ID"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0x00}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorReservedNhc5(void) +{ + TestIphcVector testVector("Reserved value of LOWPAN_NHC EID - 0x05"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0xea}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +static void TestErrorReservedNhc6(void) +{ + TestIphcVector testVector("Reserved value of LOWPAN_NHC EID - 0x06"); + + // Setup MAC addresses. + testVector.SetMacSource(sTestMacSourceDefaultLong); + testVector.SetMacDestination(sTestMacDestinationDefaultLong); + + // Set LOWPAN_IPHC header. + uint8_t iphc[] = {0x7e, 0x33, 0xec}; + testVector.SetIphcHeader(iphc, sizeof(iphc)); + + // Set payload and error. + testVector.SetError(kThreadError_Parse); + + // Perform decompression test. + Test(testVector, false, true); +} + +/*************************************************************************************************** + * @section Main test. + **************************************************************************************************/ + +void TestLowpanIphc(void) +{ + Init(); + + // Stateless unicast addresses compression / decompression tests. + TestFullyCompressableLongAddresses(); + TestFullyCompressableShortAddresses(); + TestFullyCompressableShortLongAddresses(); + TestFullyCompressableLongShortAddresses(); + TestSourceUnspecifiedAddress(); + TestSource128bitDestination128bitAddresses(); + TestSource64bitDestination64bitLongAddresses(); + TestSource64bitDestination64bitShortAddresses(); + TestSource16bitDestination16bitAddresses(); + TestSourceCompressedDestination16bitAddresses(); + TestSourceCompressedDestination128bitAddresses(); + + // Stateless multicast addresses compression / decompression tests. + TestMulticast128bitAddress(); + TestMulticast48bitAddress(); + TestMulticast32bitAddress(); + TestMulticast8bitAddress(); + + // Stateful unicast addresses compression / decompression tests. + TestStatefulSource64bitDestination64bitContext0(); + TestStatefulSource64bitDestination64bitContext0IfContextInLine(); + TestStatefulSource16bitDestination16bitContext0(); + TestStatefulCompressableLongAddressesContext0(); + TestStatefulCompressableShortAddressesContext0(); + TestStatefulCompressableLongShortAddressesContext0(); + TestStatefulSource64bitDestination128bitContext1(); + TestStatefulSource64bitDestination64bitContext1(); + TestStatefulSourceDestinationInlineContext2CIDFalse(); + + // Stateful multicast addresses compression / decompression tests. + TestStatefulMulticastDestination48bitContext0(); + + // Traffic Class and Flow Label compression / decompression tests. + TestTrafficClassFlowLabel3Bytes(); + TestTrafficClassFlowLabel1Byte(); + TestTrafficClassFlowLabel1ByteEcnOnly(); + TestTrafficClassFlowLabelInline(); + + // Hop Limit compression / decompression tests. + TestHopLimit1(); + TestHopLimit255(); + TestHopLimitInline(); + + // UDP compression / decompression tests. + TestUdpSourceDestinationInline(); + TestUdpSourceInlineDestination8bit(); + TestUdpSource8bitDestinationInline(); + TestUdpFullyCompressed(); + TestUdpFullyCompressedMulticast(); + TestUdpWithoutNhc(); + + // Extension Headers compression / decompression tests. + TestExtensionHeaderHopByHopNoPadding(); + TestExtensionHeaderHopByHopPad1(); + TestExtensionHeaderHopByHopPadN2(); + TestExtensionHeaderHopByHopPadN3(); + TestExtensionHeaderHopByHopPadN4(); + TestExtensionHeaderHopByHopPadN5(); + TestExtensionHeaderHopByHopPadN6(); + TestExtensionHeaderHopByHopPadN7(); + TestExtensionHeaderHopByHopPadN2UdpFullyCompressed(); + + // IP-in-IP compression / decompression tests. + TestIpInIpHopByHopPadN2UdpSourceDestinationInline(); + TestIpInIpWithoutExtensionHeader(); + + // Invalid frame to be decompressed. + TestErrorNoIphcDispatch(); + TestErrorTruncatedIphc(); + TestErrorReservedValueDestination0100(); + TestErrorReservedValueDestination1101(); + TestErrorReservedValueDestination1110(); + TestErrorReservedValueDestination1111(); + TestErrorUnknownNhc(); + TestErrorReservedNhc5(); + TestErrorReservedNhc6(); } } // namespace Thread diff --git a/tests/unit/test_lowpan.hpp b/tests/unit/test_lowpan.hpp new file mode 100644 index 000000000..c68a3444c --- /dev/null +++ b/tests/unit/test_lowpan.hpp @@ -0,0 +1,282 @@ +/* + * 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. + */ + +#ifndef TEST_LOWPAN_HPP +#define TEST_LOWPAN_HPP + +#include + +#include +#include +#include +#include +#include + +namespace Thread { + +class TestIphcVector +{ +public: + enum + { + kContextUnused = 255, + kPayloadMaxLength = 512 + }; + + struct Payload + { + uint8_t mData[kPayloadMaxLength]; + uint16_t mLength; + }; + + /** + * Default constructor for the object. + * + */ + TestIphcVector(const char *aTestName) { + memset(this, 0, sizeof(*this)); + mTestName = aTestName; + mSrcContext.mContextId = kContextUnused; + mDstContext.mContextId = kContextUnused; + } + + /** + * This method sets long MAC source address. + * + * @param aAddress Pointer to the long MAC address. + * + */ + void SetMacSource(const uint8_t *aAddress) { + mMacSource.mLength = OT_EXT_ADDRESS_SIZE; + memcpy(&mMacSource.mExtAddress, aAddress, mMacSource.mLength); + } + + /** + * This method sets short MAC source address. + * + * @param aAddress Short MAC address. + * + */ + void SetMacSource(uint16_t aAddress) { + mMacSource.mLength = 2; + mMacSource.mShortAddress = aAddress; + } + + /** + * This method sets long MAC destination address. + * + * @param aAddress Pointer to the long MAC address. + * + */ + void SetMacDestination(const uint8_t *aAddress) { + mMacDestination.mLength = OT_EXT_ADDRESS_SIZE; + memcpy(&mMacDestination.mExtAddress, aAddress, mMacDestination.mLength); + } + + /** + * This method sets short MAC destination address. + * + * @param aAddress Short MAC address. + * + */ + void SetMacDestination(uint16_t aAddress) { + mMacDestination.mLength = 2; + mMacDestination.mShortAddress = aAddress; + } + + /** + * This method initializes IPv6 Header. + * + * @param aVersionClassFlow Value of the Version, Traffic class and Flow control fields. + * @param aPayloadLength Value of the payload length field. + * @param aNextHeader Value of the next header field. + * @param aHopLimit Value of the hop limit field. + * @param aSource String represents IPv6 source address. + * @param aDestination String represents IPv6 destination address. + * + */ + void SetIpHeader(uint32_t aVersionClassFlow, uint16_t aPayloadLength, + Ip6::IpProto aNextHeader, uint8_t aHopLimit, + const char *aSource, const char *aDestination) { + mIpHeader.Init(aVersionClassFlow); + mIpHeader.SetPayloadLength(aPayloadLength); + mIpHeader.SetNextHeader(aNextHeader); + mIpHeader.SetHopLimit(aHopLimit); + mIpHeader.GetSource().FromString(aSource); + mIpHeader.GetDestination().FromString(aDestination); + } + + /** + * This method initializes IPv6 Encapsulated Header. + * + * @param aVersionClassFlow Value of the Version, Traffic class and Flow control fields. + * @param aPayloadLength Value of the payload length field. + * @param aNextHeader Value of the next header field. + * @param aHopLimit Value of the hop limit field. + * @param aSource String represents IPv6 source address. + * @param aDestination String represents IPv6 destination address. + * + */ + void SetIpTunneledHeader(uint32_t aVersionClassFlow, uint16_t aPayloadLength, + Ip6::IpProto aNextHeader, uint8_t aHopLimit, + const char *aSource, const char *aDestination) { + mIpTunneledHeader.Init(aVersionClassFlow); + mIpTunneledHeader.SetPayloadLength(aPayloadLength); + mIpTunneledHeader.SetNextHeader(aNextHeader); + mIpTunneledHeader.SetHopLimit(aHopLimit); + mIpTunneledHeader.GetSource().FromString(aSource); + mIpTunneledHeader.GetDestination().FromString(aDestination); + } + + /** + * This method initializes IPv6 Extension Header. + * + * @param aExtHeader Pointer to the extension header data. + * @param aExtHeaderLength Length of the extension header data. + * + */ + void SetExtHeader(const uint8_t *aExtHeader, uint16_t aExtHeaderLength) { + memcpy(mExtHeader.mData, aExtHeader, aExtHeaderLength); + mExtHeader.mLength = aExtHeaderLength; + } + + /** + * This method initializes UDP Header. + * + * @param aSource Value of the source port. + * @param aDestination Value of the destination port. + * @param aLength Value of the length field. + * @param aChecksum Value of the checksum field. + * + */ + void SetUDPHeader(uint16_t aSource, uint16_t aDestination, uint16_t aLength, + uint16_t aChecksum) { + mUdpHeader.SetSourcePort(aSource); + mUdpHeader.SetDestinationPort(aDestination); + mUdpHeader.SetLength(aLength); + mUdpHeader.SetChecksum(aChecksum); + } + + /** + * This method initializes LOWPAN_IPHC Header. + * + * @param aIphc Pointer to the LOWPAN_IPHC header. + * @param aIphcLength Length of the LOWPAN_IPHC header. + * + */ + void SetIphcHeader(const uint8_t *aIphc, uint16_t aIphcLength) { + memcpy(mIphcHeader.mData, aIphc, aIphcLength); + mIphcHeader.mLength = aIphcLength; + } + + /** + * This method sets the expect result of the compression / decompression procedure. + * + * @param aError Expected result. + * + */ + void SetError(ThreadError aError) { mError = aError; } + + /** + * This method initializes IPv6 Payload (uncompressed data). + * + * @param aPayload Pointer to the payload data. + * @param aLength Length of the payload data. + * + */ + void SetPayload(const uint8_t *aPayload, uint16_t aLength) { + memcpy(mPayload.mData, aPayload, aLength); + mPayload.mLength = aLength; + } + + /** + * This method sets the offset from the beginning of the IPv6 header to the uncompressed + * payload. + * + * @param aPayloadOffset The offset from the beginning of the IPv6 header to the uncompressed + * payload. + * + */ + void SetPayloadOffset(uint16_t aPayloadOffset) { mPayloadOffset = aPayloadOffset; } + + /** + * This method returns compressed LOWPAN_IPHC frame. + * + * @returns The compressed stream. + * + */ + void GetCompressedStream(uint8_t *aIphc, uint16_t &aIphcLength); + + /** + * This method returns message object with the uncompressed IPv6 packet. + * + * @returns The message object with the uncompressed IPv6 packet. + * + */ + void GetUncompressedStream(Message &aMessage); + + /** + * This method returns data with the uncompressed IPv6 packet. + * + * @returns The data with the uncompressed IPv6 packet. + * + */ + void GetUncompressedStream(uint8_t *aIp6, uint16_t &aIp6Length); + + /** + * This fields represent uncompressed IPv6 packet. + * + */ + Mac::Address mMacSource; + Mac::Address mMacDestination; + Ip6::Header mIpHeader; + Payload mExtHeader; + Ip6::Header mIpTunneledHeader; + Ip6::UdpHeader mUdpHeader; + + /** + * This fields represent compressed IPv6 packet. + * + */ + Payload mIphcHeader; + uint16_t mPayloadOffset; + Lowpan::Context mSrcContext; + Lowpan::Context mDstContext; + + /** + * General purpose fields. + * + */ + Payload mPayload; + ThreadError mError; + const char *mTestName; +}; + +} // namespace Thread + +#endif // TEST_LOWPAN_HPP diff --git a/tests/unit/test_util.cpp b/tests/unit/test_util.cpp index 86ed7a1a6..3956b0738 100644 --- a/tests/unit/test_util.cpp +++ b/tests/unit/test_util.cpp @@ -55,7 +55,7 @@ void otTestPrintHex(uint8_t *aBuffer, int aLength) if (i % 16 == 7) { printf(" "); } - if (i % 16 == 15) { printf("\n"); } + if (i % 16 == 15 && aLength != i + 1) { printf("\n"); } } printf("\n"); @@ -70,5 +70,3 @@ void otTestPrintHex(std::vector &aBytes) { otTestPrintHex((uint8_t *)&aBytes[0], static_cast(aBytes.size())); } - - diff --git a/tests/unit/test_vector.c b/tests/unit/test_vector.c deleted file mode 100644 index 83f7b8042..000000000 --- a/tests/unit/test_vector.c +++ /dev/null @@ -1,157 +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. - */ - -#include "test_vector.h" - -test_lowpan_vector_t sTestVectorLowpan[] = -{ - { - // I1_t1_AF_pass.pcap - .mTest = "LL64 unicast ICMP ping request", - .mCompressed = - "61 cc 1d ce fa 03 00 00 00 00 0a 6e 14 01 00 00 " - "00 00 0a 6e 14 7a 33 3a 80 00 30 be 00 00 00 00 " - "41 42 43 44 45 46 47 48 48 ff", - .mRaw = - "60 00 00 00 00 10 3a 40 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 01 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 03 80 00 30 be 00 00 00 00 " - "41 42 43 44 45 46 47 48", - .mMac = - { - .mSrc = "14 6e 0a 00 00 00 00 01", - .mDst = "14 6e 0a 00 00 00 00 03", - .mPanid = 0xFACE, - }, - .mSrc = "fe80::166e:a00:0:1", - .mDst = "fe80::166e:a00:0:3", - .mHops = 64 - }, - { - // I1_t1_AF_pass.pcap - .mTest = "LL64 unicast ICMP ping reply", - .mCompressed = - "61 cc 07 ce fa 01 00 00 00 00 0a 6e 14 03 00 00 " - "00 00 0a 6e 14 7a 33 3a 81 00 2f be 00 00 00 00 " - "41 42 43 44 45 46 47 48 37 59", - .mRaw = - "60 00 00 00 00 10 3a 40 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 03 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 01 81 00 2f be 00 00 00 00 " - "41 42 43 44 45 46 47 48", - .mMac = - { - .mSrc = "14 6e 0a 00 00 00 00 03", - .mDst = "14 6e 0a 00 00 00 00 01", - .mPanid = 0xFACE, - }, - }, - { - // I1_t2_AF_AS_pass.pcap - .mTest = "LL16 unicast ICMP ping request", - .mCompressed = - "61 88 13 ce fa 00 10 00 00 7a 33 3a 80 00 63 9e " - "00 00 00 00 41 42 43 44 45 46 47 48 84 5f", - .mRaw = - "60 00 00 00 00 10 3a 40 fe 80 00 00 00 00 00 00 " - "00 00 00 ff fe 00 00 00 fe 80 00 00 00 00 00 00 " - "00 00 00 ff fe 00 10 00 80 00 63 9e 00 00 00 00 " - "41 42 43 44 45 46 47 48" - }, - { - // I1_t2_AF_AS_pass.pcap - .mTest = "LL16 unicast ICMP ping reply", - .mCompressed = - "61 88 0f ce fa 00 00 00 10 7a 33 3a 81 00 62 9e " - "00 00 00 00 41 42 43 44 45 46 47 48 e0 35", - .mRaw = - "60 00 00 00 00 10 3a 40 fe 80 00 00 00 00 00 00 " - "00 00 00 ff fe 00 10 00 fe 80 00 00 00 00 00 00 " - "00 00 00 ff fe 00 00 00 81 00 62 9e 00 00 00 00 " - "41 42 43 44 45 46 47 48" - }, - { - // I1_t3_SF_pass.pcap - .mTest = "LL64 multicast FF02::1 ICMP ping request", - .mCompressed = - "41 c8 99 ce fa ff ff 01 00 00 00 00 0a 6e 14 7a " - "3b 3a 01 80 00 54 b4 40 41 42 43 44 45 46 47 68 " - "44", - .mRaw = - "60 00 00 00 00 0c 3a 40 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 01 ff 02 00 00 00 00 00 00 " - "00 00 00 00 00 00 00 01 80 00 54 b4 40 41 42 43 " - "44 45 46 47 " - }, - { - // I1_t3_SF_pass.pcap - .mTest = "LL64 multicast FF02::1 ICMP ping reply", - .mCompressed = - "61 cc fc ce fa 01 00 00 00 00 0a 6e 14 02 00 00 " - "00 00 0a 6e 14 7a 33 3a 81 00 33 c7 40 41 42 43 " - "44 45 46 47 1a 80", - .mRaw = - "60 00 00 00 00 0c 3a 40 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 02 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 01 81 00 33 c7 40 41 42 43 " - "44 45 46 47" - }, - { - // I1_t4_FS_pass.pcap - .mTest = "LL16 multicast FF02::1 ICMP ping request", - .mCompressed = - "41 88 df ce fa ff ff 00 08 7a 3b 3a 01 80 00 76 " - "0e 00 01 00 04 50 50 50 50 50 50 50 50 50 50 50 " - "50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 " - "50 50 50 50 50 a7 d2", - .mRaw = - "60 00 00 00 00 28 3a 40 fe 80 00 00 00 00 00 00 " - "00 00 00 ff fe 00 08 00 ff 02 00 00 00 00 00 00 " - "00 00 00 00 00 00 00 01 80 00 76 0e 00 01 00 04 " - "50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 " - "50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 " - }, - { - // I1_t4_FS_pass.pcap - .mTest = "LL16 multicast FF02::1 ICMP ping reply", - .mCompressed = - "61 c8 41 ce fa 00 08 03 00 00 00 00 0a 6e 14 7a " - "33 3a 81 00 55 20 00 01 00 04 50 50 50 50 50 50 " - "50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 " - "50 50 50 50 50 50 50 50 50 50 ab 56", - .mRaw = - "60 00 00 00 00 28 3a 40 fe 80 00 00 00 00 00 00 " - "16 6e 0a 00 00 00 00 03 fe 80 00 00 00 00 00 00 " - "00 00 00 ff fe 00 08 00 81 00 55 20 00 01 00 04 " - "50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 " - "50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 " - }, -}; - -const unsigned sTestVectorLowpanLen = - sizeof(sTestVectorLowpan) / sizeof(sTestVectorLowpan[0]); diff --git a/tests/unit/test_vector.h b/tests/unit/test_vector.h deleted file mode 100644 index 544a2f137..000000000 --- a/tests/unit/test_vector.h +++ /dev/null @@ -1,74 +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. - */ - -#ifndef TEST_VECTOR_H -#define TEST_VECTOR_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef const struct -{ - const char *mResult; - - uint16_t mFcf; - uint16_t mSeq; - uint16_t mPanid; ///< default panid is destination panid - const char *mSrc; - const char *mDst; -} test_mac_vector_t; - -typedef const struct -{ - const char *mTest; - const char *mCompressed; - const char *mRaw; - - const char *mPrefix; - - test_mac_vector_t mMac; - - uint16_t mTraffic; - uint16_t mFlow; - uint16_t mHops; - const char *mSrc; - const char *mDst; -} test_lowpan_vector_t; - - -extern test_lowpan_vector_t sTestVectorLowpan[]; -extern const unsigned sTestVectorLowpanLen; - -#ifdef __cplusplus -} -#endif - -#endif