blob: 436bb887f4616e1896d46dde85dc55033c4f7ed4 [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* This file implements a process to effect a functional test for
* the Message Header class within the transport layer
*
*/
#include <lib/core/ErrorStr.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <protocols/Protocols.h>
#include <transport/raw/MessageHeader.h>
#include <gtest/gtest.h>
namespace {
using namespace chip;
TEST(TestMessageHeader, TestPacketHeaderInitialState)
{
PacketHeader header;
EXPECT_FALSE(header.IsSecureSessionControlMsg());
EXPECT_EQ(header.GetMessageCounter(), 0u);
EXPECT_EQ(header.GetSessionId(), 0);
EXPECT_EQ(header.GetSessionType(), Header::SessionType::kUnicastSession);
EXPECT_TRUE(header.IsSessionTypeValid());
EXPECT_FALSE(header.IsEncrypted());
EXPECT_FALSE(header.GetDestinationNodeId().HasValue());
EXPECT_FALSE(header.GetDestinationGroupId().HasValue());
EXPECT_FALSE(header.GetSourceNodeId().HasValue());
}
TEST(TestMessageHeader, TestPayloadHeaderInitialState)
{
PayloadHeader header;
EXPECT_EQ(header.GetMessageType(), 0);
EXPECT_EQ(header.GetExchangeID(), 0);
EXPECT_TRUE(header.HasProtocol(Protocols::NotSpecified));
}
TEST(TestMessageHeader, TestPacketHeaderEncodeDecode)
{
PacketHeader header;
uint8_t buffer[64];
uint16_t encodeLen;
uint16_t decodeLen;
header.SetMessageCounter(123);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetMessageCounter(), 123u);
EXPECT_FALSE(header.GetDestinationNodeId().HasValue());
header.SetSourceNodeId(55);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetMessageCounter(), 123u);
EXPECT_FALSE(header.GetDestinationNodeId().HasValue());
EXPECT_EQ(header.GetSourceNodeId(), Optional<uint64_t>::Value(55ull));
header.ClearSourceNodeId().SetDestinationNodeId(11);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetMessageCounter(), 123u);
EXPECT_EQ(header.GetDestinationNodeId(), Optional<uint64_t>::Value(11ull));
EXPECT_FALSE(header.GetSourceNodeId().HasValue());
header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetMessageCounter(), 234u);
EXPECT_EQ(header.GetDestinationNodeId(), Optional<uint64_t>::Value(88ull));
EXPECT_EQ(header.GetSourceNodeId(), Optional<uint64_t>::Value(77ull));
header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetSecureSessionControlMsg(true);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(header.GetMessageCounter(), 234u);
EXPECT_EQ(header.GetDestinationNodeId(), Optional<uint64_t>::Value(88ull));
EXPECT_EQ(header.GetSourceNodeId(), Optional<uint64_t>::Value(77ull));
EXPECT_TRUE(header.IsSecureSessionControlMsg());
header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetSessionId(2);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(header.GetMessageCounter(), 234u);
EXPECT_EQ(header.GetDestinationNodeId(), Optional<uint64_t>::Value(88ull));
EXPECT_EQ(header.GetSourceNodeId(), Optional<uint64_t>::Value(77ull));
EXPECT_TRUE(header.IsEncrypted());
EXPECT_EQ(header.GetSessionId(), 2);
header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationNodeId(88);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationNodeId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(header.GetMessageCounter(), 234u);
EXPECT_EQ(header.GetDestinationNodeId(), Optional<uint64_t>::Value(88ull));
EXPECT_EQ(header.GetSourceNodeId(), Optional<uint64_t>::Value(77ull));
// Verify Group Id helpers
header.SetMessageCounter(234).SetSourceNodeId(77).SetDestinationGroupId(45);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_ERROR_INTERNAL);
header.ClearDestinationNodeId();
header.SetSessionType(Header::SessionType::kGroupSession);
header.SetFlags(Header::SecFlagValues::kPrivacyFlag);
header.SetSecureSessionControlMsg(false);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationGroupId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(header.GetMessageCounter(), 234u);
EXPECT_EQ(header.GetDestinationGroupId(), Optional<uint16_t>::Value((uint16_t) 45));
EXPECT_EQ(header.GetSourceNodeId(), Optional<uint64_t>::Value(77ull));
EXPECT_FALSE(header.IsSecureSessionControlMsg());
EXPECT_TRUE(header.IsValidGroupMsg());
// Verify MCSP state
header.ClearDestinationGroupId().SetDestinationNodeId(42).SetFlags(Header::SecFlagValues::kPrivacyFlag);
header.SetSecureSessionControlMsg(true);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
// change it to verify decoding
header.SetMessageCounter(222).SetSourceNodeId(1).SetDestinationGroupId(2);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(header.GetDestinationNodeId(), Optional<uint64_t>::Value(42ull));
EXPECT_FALSE(header.HasDestinationGroupId());
EXPECT_TRUE(header.HasPrivacyFlag());
EXPECT_TRUE(header.IsValidMCSPMsg());
}
TEST(TestMessageHeader, TestPayloadHeaderEncodeDecode)
{
PayloadHeader header;
uint8_t buffer[64];
uint16_t encodeLen;
uint16_t decodeLen;
header.SetMessageType(Protocols::Id(VendorId::Common, 0), 112).SetExchangeID(2233);
EXPECT_EQ(header.GetProtocolID(), Protocols::Id(VendorId::Common, 0));
header.SetMessageType(Protocols::Id(VendorId::Common, 1221), 112).SetExchangeID(2233).SetInitiator(true);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
header.SetMessageType(Protocols::Id(VendorId::Common, 4567), 221).SetExchangeID(3322);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetMessageType(), 112);
EXPECT_EQ(header.GetExchangeID(), 2233);
EXPECT_EQ(header.GetProtocolID(), Protocols::Id(VendorId::Common, 1221));
EXPECT_TRUE(header.IsInitiator());
header.SetMessageType(Protocols::Id(VendorId::Common, 1221), 112).SetExchangeID(2233);
EXPECT_EQ(header.Encode(buffer, &encodeLen), CHIP_NO_ERROR);
header.SetMessageType(Protocols::Id(VendorId::NotSpecified, 0), 111).SetExchangeID(222);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetExchangeID(), 2233);
EXPECT_EQ(header.GetProtocolID(), Protocols::Id(VendorId::Common, 1221));
header.SetMessageType(Protocols::Id(VendorId::NotSpecified, 4567), 221).SetExchangeID(3322);
EXPECT_EQ(header.Decode(buffer, &decodeLen), CHIP_NO_ERROR);
EXPECT_EQ(encodeLen, decodeLen);
EXPECT_EQ(header.GetExchangeID(), 2233);
EXPECT_EQ(header.GetProtocolID(), Protocols::Id(VendorId::Common, 1221));
}
TEST(TestMessageHeader, TestPacketHeaderEncodeDecodeBounds)
{
PacketHeader header;
uint8_t buffer[64] = {};
uint16_t unusedLen = 0;
for (uint16_t shortLen = 0; shortLen < 8; shortLen++)
{
EXPECT_NE(header.Encode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
EXPECT_NE(header.Decode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
// Now check that with 8 bytes we can successfully encode a
// default-constructed PacketHeader.
static const size_t minLen = 8;
uint16_t encoded_len;
EXPECT_EQ(header.Encode(buffer, minLen, &encoded_len), CHIP_NO_ERROR);
EXPECT_EQ(encoded_len, minLen);
// Verify that decoding at any smaller length fails.
for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
{
EXPECT_NE(header.Decode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
uint16_t decoded_len;
EXPECT_EQ(header.Decode(buffer, encoded_len, &decoded_len), CHIP_NO_ERROR);
EXPECT_EQ(decoded_len, encoded_len);
// Now test encoding/decoding with a source node id present.
header.SetSourceNodeId(1);
for (uint16_t shortLen = minLen; shortLen < minLen + 8; shortLen++)
{
EXPECT_NE(header.Encode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
EXPECT_EQ(header.Encode(buffer, minLen + 8, &encoded_len), CHIP_NO_ERROR);
EXPECT_EQ(encoded_len, minLen + 8);
for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
{
EXPECT_NE(header.Decode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
EXPECT_EQ(header.Decode(buffer, encoded_len, &decoded_len), CHIP_NO_ERROR);
EXPECT_EQ(decoded_len, encoded_len);
// Now test encoding/decoding with a source and destination node id present.
header.SetDestinationNodeId(1);
for (uint16_t shortLen = minLen; shortLen < minLen + 16; shortLen++)
{
EXPECT_NE(header.Encode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
EXPECT_EQ(header.Encode(buffer, minLen + 16, &encoded_len), CHIP_NO_ERROR);
EXPECT_EQ(encoded_len, minLen + 16);
for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
{
EXPECT_NE(header.Decode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
EXPECT_EQ(header.Decode(buffer, encoded_len, &decoded_len), CHIP_NO_ERROR);
EXPECT_EQ(decoded_len, encoded_len);
// Now test encoding/decoding with a source node id and destination group id present.
header.ClearDestinationNodeId();
header.SetDestinationGroupId(25);
header.SetSessionType(Header::SessionType::kGroupSession);
for (uint16_t shortLen = minLen; shortLen < minLen + 10; shortLen++)
{
EXPECT_NE(header.Encode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
EXPECT_EQ(header.Encode(buffer, minLen + 10, &encoded_len), CHIP_NO_ERROR);
EXPECT_EQ(encoded_len, minLen + 10);
for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
{
EXPECT_NE(header.Decode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
EXPECT_EQ(header.Decode(buffer, encoded_len, &decoded_len), CHIP_NO_ERROR);
EXPECT_EQ(decoded_len, encoded_len);
}
TEST(TestMessageHeader, TestPayloadHeaderEncodeDecodeBounds)
{
PayloadHeader header;
uint8_t buffer[64] = {};
uint16_t unusedLen = 0;
for (uint16_t shortLen = 0; shortLen < 6; shortLen++)
{
EXPECT_NE(header.Encode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
EXPECT_NE(header.Decode(buffer, shortLen, &unusedLen), CHIP_NO_ERROR);
}
}
constexpr size_t HDR_LEN = 8; ///< Message header length
constexpr size_t SRC_LEN = 8; ///< Source Node ID length
constexpr size_t DST_LEN = 8; ///< Destination Node ID length
constexpr size_t GID_LEN = 2; ///< Group ID length
constexpr size_t MX_LEN = 6; ///< Message Exchange block length
constexpr size_t SX_LEN = 6; ///< Security Exchange block length
constexpr size_t PRO_LEN = 6; ///< Protocol header length
constexpr size_t APP_LEN = 2; ///< App payload length
/// Size of fixed portion of message header + max source node id + max destination node id.
constexpr size_t MAX_FIXED_HEADER_SIZE = (HDR_LEN + SRC_LEN + DST_LEN);
struct SpecComplianceTestVector
{
uint8_t encoded[MAX_FIXED_HEADER_SIZE]; // Fixed header + max source id + max dest id
uint8_t messageFlags;
uint16_t sessionId;
uint8_t sessionType;
uint8_t securityFlags;
uint32_t messageCounter;
bool isSecure;
uint8_t size;
int groupId; // negative means no value
};
struct SpecComplianceTestVector theSpecComplianceTestVector[] = {
{
// Secure unicast message
.encoded = { 0x00, 0x88, 0x77, 0x00, 0x44, 0x33, 0x22, 0x11 },
.messageFlags = 0x00,
.sessionId = 0x7788,
.sessionType = 0x00,
.securityFlags = 0x00,
.messageCounter = 0x11223344,
.isSecure = true,
.size = 8,
.groupId = -1,
},
{
// Secure group message
.encoded = { 0x02, 0xEE, 0xDD, 0xC1, 0x40, 0x30, 0x20, 0x10, 0x56, 0x34 },
.messageFlags = 0x02,
.sessionId = 0xDDEE,
.sessionType = 0x01,
.securityFlags = 0xC1,
.messageCounter = 0x10203040,
.isSecure = true,
.size = 10,
.groupId = 0x3456,
},
{
// Unsecured message
.encoded = { 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x20, 0x10 },
.messageFlags = 0x00,
.sessionId = 0x0000,
.sessionType = 0x00,
.securityFlags = 0x00,
.messageCounter = 0x10203040,
.isSecure = false,
.size = 8,
.groupId = -1,
},
};
TEST(TestMessageHeader, TestSpecComplianceEncode)
{
uint8_t buffer[MAX_FIXED_HEADER_SIZE];
uint16_t encodeSize;
for (const auto & testEntry : theSpecComplianceTestVector)
{
PacketHeader packetHeader;
packetHeader.SetMessageFlags(testEntry.messageFlags);
packetHeader.SetSecurityFlags(testEntry.securityFlags);
packetHeader.SetSessionId(testEntry.sessionId);
packetHeader.SetMessageCounter(testEntry.messageCounter);
if (testEntry.groupId >= 0)
{
packetHeader.SetDestinationGroupId(static_cast<GroupId>(testEntry.groupId));
}
EXPECT_EQ(packetHeader.Encode(buffer, sizeof(buffer), &encodeSize), CHIP_NO_ERROR);
EXPECT_EQ(encodeSize, testEntry.size);
EXPECT_EQ(memcmp(buffer, testEntry.encoded, encodeSize), 0);
}
}
TEST(TestMessageHeader, TestSpecComplianceDecode)
{
PacketHeader packetHeader;
uint16_t decodeSize;
for (const auto & testEntry : theSpecComplianceTestVector)
{
EXPECT_EQ(packetHeader.Decode(testEntry.encoded, testEntry.size, &decodeSize), CHIP_NO_ERROR);
EXPECT_EQ(decodeSize, testEntry.size);
EXPECT_EQ(packetHeader.GetMessageFlags(), testEntry.messageFlags);
EXPECT_EQ(packetHeader.GetSecurityFlags(), testEntry.securityFlags);
EXPECT_EQ(packetHeader.GetSessionId(), testEntry.sessionId);
EXPECT_EQ(packetHeader.GetMessageCounter(), testEntry.messageCounter);
EXPECT_EQ(packetHeader.IsEncrypted(), testEntry.isSecure);
}
}
struct TestVectorMsgExtensions
{
uint8_t payloadOffset;
uint8_t appPayloadOffset;
uint16_t msgLength;
const char * msg;
};
struct TestVectorMsgExtensions theTestVectorMsgExtensions[] = {
{
// SRC=none, DST=none, MX=0, SX=0
.payloadOffset = HDR_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + PRO_LEN + APP_LEN,
.msg = "\x00\x00\x00\x00\xCC\xCC\xCC\xCC"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
// ================== Test MX ==================
{
// SRC=none, DST=none, MX=1, SX=0
.payloadOffset = HDR_LEN + MX_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + MX_LEN + PRO_LEN + APP_LEN,
.msg = "\x00\x00\x00\x20\xCC\xCC\xCC\xCC\x04\x00\xE4\xE3\xE2\xE1"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
{
// SRC=1, DST=none, MX=1, SX=0
.payloadOffset = HDR_LEN + MX_LEN + SRC_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + MX_LEN + SRC_LEN + PRO_LEN + APP_LEN,
.msg = "\x04\x00\x00\x20\xCC\xCC\xCC\xCC\x11\x11\x11\x11\x11\x11\x11\x11\x04\x00\xE4\xE3\xE2\xE1"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
{
// SRC=none, DST=1, MX=1, SX=0
.payloadOffset = HDR_LEN + MX_LEN + DST_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + MX_LEN + DST_LEN + PRO_LEN + APP_LEN,
.msg = "\x01\x00\x00\x20\xCC\xCC\xCC\xCC\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\x04\x00\xE4\xE3\xE2\xE1"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
{
// SRC=1, DST=1, MX=1, SX=0
.payloadOffset = HDR_LEN + MX_LEN + SRC_LEN + DST_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + MX_LEN + SRC_LEN + DST_LEN + PRO_LEN + APP_LEN,
.msg = "\x05\x00\x00\x20\xCC\xCC\xCC\xCC\x11\x11\x11\x11\x11\x11\x11\x11\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\x04\x00\xE4\xE3"
"\xE2\xE1"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
{
// SRC=none, DST=group, MX=1, SX=0
.payloadOffset = HDR_LEN + MX_LEN + GID_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + MX_LEN + GID_LEN + PRO_LEN + APP_LEN,
.msg = "\x02\x00\x00\x21\xCC\xCC\xCC\xCC\xDD\xDD\x04\x00\xE4\xE3\xE2\xE1"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
{
// SRC=1, DST=group, MX=1, SX=0
.payloadOffset = HDR_LEN + MX_LEN + SRC_LEN + GID_LEN,
.appPayloadOffset = PRO_LEN,
.msgLength = HDR_LEN + MX_LEN + SRC_LEN + GID_LEN + PRO_LEN + APP_LEN,
.msg = "\x06\x00\x00\x21\xCC\xCC\xCC\xCC\x11\x11\x11\x11\x11\x11\x11\x11\xDD\xDD\x04\x00\xE4\xE3\xE2\xE1"
"\x01\xCC\xEE\xEE\x66\x66\xBB\xBB",
},
// ================== Test SX ==================
{
// SRC=none, DST=none, MX=0, SX=1
.payloadOffset = HDR_LEN,
.appPayloadOffset = PRO_LEN + SX_LEN,
.msgLength = HDR_LEN + PRO_LEN + SX_LEN + APP_LEN,
.msg = "\x00\x00\x00\x00\xCC\xCC\xCC\xCC"
"\x08\xCC\xEE\xEE\x66\x66\x04\x00\xE4\xE3\xE2\xE1\xBB\xBB",
},
{
// SRC=none, DST=none, MX=1, SX=1
.payloadOffset = HDR_LEN + MX_LEN,
.appPayloadOffset = PRO_LEN + SX_LEN,
.msgLength = HDR_LEN + MX_LEN + PRO_LEN + SX_LEN + APP_LEN,
.msg = "\x00\x00\x00\x20\xCC\xCC\xCC\xCC\x04\x00\xE4\xE3\xE2\xE1"
"\x08\xCC\xEE\xEE\x66\x66\x04\x00\xE4\xE3\xE2\xE1\xBB\xBB",
},
{
// SRC=1, DST=1, MX=1, SX=1
.payloadOffset = HDR_LEN + MX_LEN + SRC_LEN + DST_LEN,
.appPayloadOffset = PRO_LEN + SX_LEN,
.msgLength = HDR_LEN + MX_LEN + SRC_LEN + DST_LEN + PRO_LEN + SX_LEN + APP_LEN,
.msg = "\x05\x00\x00\x20\xCC\xCC\xCC\xCC\x11\x11\x11\x11\x11\x11\x11\x11\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\x04\x00\xE4\xE3"
"\xE2\xE1"
"\x09\xCC\xEE\xEE\x66\x66\x04\x00\xE4\xE3\xE2\xE1\xBB\xBB",
},
};
TEST(TestMessageHeader, TestMsgExtensionsDecode)
{
PacketHeader packetHeader;
PayloadHeader payloadHeader;
uint16_t decodeSize;
ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR);
for (const auto & testEntry : theTestVectorMsgExtensions)
{
System::PacketBufferHandle msg = System::PacketBufferHandle::NewWithData(testEntry.msg, testEntry.msgLength);
EXPECT_EQ(packetHeader.Decode(msg->Start(), msg->DataLength(), &decodeSize), CHIP_NO_ERROR);
EXPECT_EQ(decodeSize, testEntry.payloadOffset);
EXPECT_EQ(payloadHeader.Decode(msg->Start() + decodeSize, msg->DataLength(), &decodeSize), CHIP_NO_ERROR);
EXPECT_EQ(decodeSize, testEntry.appPayloadOffset);
}
chip::Platform::MemoryShutdown();
}
} // namespace