3 * Copyright (c) 2020 Project CHIP Authors
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 * This file implements a process to effect a functional test for
22 * the Message Header class within the transport layer
25 #include <protocols/Protocols.h>
26 #include <support/CodeUtils.h>
27 #include <support/ErrorStr.h>
28 #include <support/UnitTestRegistration.h>
29 #include <transport/raw/MessageHeader.h>
31 #include <nlunit-test.h>
37 void TestPacketHeaderInitialState(nlTestSuite * inSuite, void * inContext)
41 NL_TEST_ASSERT(inSuite, !header.IsSecureSessionControlMsg());
42 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 0);
43 NL_TEST_ASSERT(inSuite, header.GetEncryptionKeyID() == 0);
44 NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue());
45 NL_TEST_ASSERT(inSuite, !header.GetSourceNodeId().HasValue());
48 void TestPayloadHeaderInitialState(nlTestSuite * inSuite, void * inContext)
52 NL_TEST_ASSERT(inSuite, header.GetMessageType() == 0);
53 NL_TEST_ASSERT(inSuite, header.GetExchangeID() == 0);
54 NL_TEST_ASSERT(inSuite, header.HasProtocol(Protocols::NotSpecified));
57 void TestPacketHeaderEncodeDecode(nlTestSuite * inSuite, void * inContext)
64 header.SetMessageId(123);
65 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
67 // change it to verify decoding
68 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
70 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
71 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
72 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 123);
73 NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue());
75 header.SetSourceNodeId(55);
76 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
78 // change it to verify decoding
79 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
81 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
82 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
83 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 123);
84 NL_TEST_ASSERT(inSuite, !header.GetDestinationNodeId().HasValue());
85 NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional<uint64_t>::Value(55));
87 header.ClearSourceNodeId().SetDestinationNodeId(11);
88 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
90 // change it to verify decoding
91 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
92 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
93 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
94 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 123);
95 NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional<uint64_t>::Value(11));
96 NL_TEST_ASSERT(inSuite, !header.GetSourceNodeId().HasValue());
98 header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88);
99 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
101 // change it to verify decoding
102 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
103 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
104 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
105 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234);
106 NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional<uint64_t>::Value(88));
107 NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional<uint64_t>::Value(77));
109 header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetSecureSessionControlMsg(true);
110 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
112 // change it to verify decoding
113 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
114 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
115 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234);
116 NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional<uint64_t>::Value(88));
117 NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional<uint64_t>::Value(77));
118 NL_TEST_ASSERT(inSuite, header.IsSecureSessionControlMsg());
120 header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88).SetEncryptionKeyID(2);
121 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
123 // change it to verify decoding
124 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
125 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
126 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234);
127 NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional<uint64_t>::Value(88));
128 NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional<uint64_t>::Value(77));
129 NL_TEST_ASSERT(inSuite, header.GetEncryptionKeyID() == 2);
131 header.SetMessageId(234).SetSourceNodeId(77).SetDestinationNodeId(88);
132 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
134 // change it to verify decoding
135 header.SetMessageId(222).SetSourceNodeId(1).SetDestinationNodeId(2);
136 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
137 NL_TEST_ASSERT(inSuite, header.GetMessageId() == 234);
138 NL_TEST_ASSERT(inSuite, header.GetDestinationNodeId() == Optional<uint64_t>::Value(88));
139 NL_TEST_ASSERT(inSuite, header.GetSourceNodeId() == Optional<uint64_t>::Value(77));
142 void TestPayloadHeaderEncodeDecode(nlTestSuite * inSuite, void * inContext)
144 PayloadHeader header;
149 header.SetMessageType(Protocols::Id(VendorId::Common, 0), 112).SetExchangeID(2233);
150 NL_TEST_ASSERT(inSuite, header.GetProtocolID() == Protocols::Id(VendorId::Common, 0));
152 header.SetMessageType(Protocols::Id(VendorId::Common, 1221), 112).SetExchangeID(2233).SetInitiator(true);
153 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
155 header.SetMessageType(Protocols::Id(VendorId::Common, 4567), 221).SetExchangeID(3322);
156 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
157 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
158 NL_TEST_ASSERT(inSuite, header.GetMessageType() == 112);
159 NL_TEST_ASSERT(inSuite, header.GetExchangeID() == 2233);
160 NL_TEST_ASSERT(inSuite, header.GetProtocolID() == Protocols::Id(VendorId::Common, 1221));
161 NL_TEST_ASSERT(inSuite, header.IsInitiator());
163 header.SetMessageType(Protocols::Id(VendorId::Common, 1221), 112).SetExchangeID(2233);
165 NL_TEST_ASSERT(inSuite, header.Encode(buffer, &encodeLen) == CHIP_NO_ERROR);
167 header.SetMessageType(Protocols::Id(VendorId::NotSpecified, 0), 111).SetExchangeID(222);
169 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
170 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
171 NL_TEST_ASSERT(inSuite, header.GetExchangeID() == 2233);
172 NL_TEST_ASSERT(inSuite, header.GetProtocolID() == Protocols::Id(VendorId::Common, 1221));
174 header.SetMessageType(Protocols::Id(VendorId::NotSpecified, 4567), 221).SetExchangeID(3322);
176 NL_TEST_ASSERT(inSuite, header.Decode(buffer, &decodeLen) == CHIP_NO_ERROR);
177 NL_TEST_ASSERT(inSuite, encodeLen == decodeLen);
178 NL_TEST_ASSERT(inSuite, header.GetExchangeID() == 2233);
179 NL_TEST_ASSERT(inSuite, header.GetProtocolID() == Protocols::Id(VendorId::Common, 1221));
182 void TestPacketHeaderEncodeDecodeBounds(nlTestSuite * inSuite, void * inContext)
188 for (uint16_t shortLen = 0; shortLen < 8; shortLen++)
190 NL_TEST_ASSERT(inSuite, header.Encode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
191 NL_TEST_ASSERT(inSuite, header.Decode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
194 // Now check that with 8 bytes we can successfully encode a
195 // default-constructed PacketHeader.
196 static const size_t minLen = 8;
197 uint16_t encoded_len;
198 NL_TEST_ASSERT(inSuite, header.Encode(buffer, minLen, &encoded_len) == CHIP_NO_ERROR);
199 NL_TEST_ASSERT(inSuite, encoded_len == minLen);
200 // Verify that decoding at any smaller length fails.
201 for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
203 NL_TEST_ASSERT(inSuite, header.Decode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
205 uint16_t decoded_len;
206 NL_TEST_ASSERT(inSuite, header.Decode(buffer, encoded_len, &decoded_len) == CHIP_NO_ERROR);
207 NL_TEST_ASSERT(inSuite, decoded_len == encoded_len);
209 // Now test encoding/decoding with a source node id present.
210 header.SetSourceNodeId(1);
211 for (uint16_t shortLen = minLen; shortLen < minLen + 8; shortLen++)
213 NL_TEST_ASSERT(inSuite, header.Encode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
215 NL_TEST_ASSERT(inSuite, header.Encode(buffer, minLen + 8, &encoded_len) == CHIP_NO_ERROR);
216 NL_TEST_ASSERT(inSuite, encoded_len == minLen + 8);
217 for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
219 NL_TEST_ASSERT(inSuite, header.Decode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
221 NL_TEST_ASSERT(inSuite, header.Decode(buffer, encoded_len, &decoded_len) == CHIP_NO_ERROR);
222 NL_TEST_ASSERT(inSuite, decoded_len == encoded_len);
224 // Now test encoding/decoding with a source and destination node id present.
225 header.SetDestinationNodeId(1);
226 for (uint16_t shortLen = minLen; shortLen < minLen + 16; shortLen++)
228 NL_TEST_ASSERT(inSuite, header.Encode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
230 NL_TEST_ASSERT(inSuite, header.Encode(buffer, minLen + 16, &encoded_len) == CHIP_NO_ERROR);
231 NL_TEST_ASSERT(inSuite, encoded_len == minLen + 16);
232 for (uint16_t shortLen = 0; shortLen < encoded_len; shortLen++)
234 NL_TEST_ASSERT(inSuite, header.Decode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
236 NL_TEST_ASSERT(inSuite, header.Decode(buffer, encoded_len, &decoded_len) == CHIP_NO_ERROR);
237 NL_TEST_ASSERT(inSuite, decoded_len == encoded_len);
240 void TestPayloadHeaderEncodeDecodeBounds(nlTestSuite * inSuite, void * inContext)
242 PayloadHeader header;
246 for (uint16_t shortLen = 0; shortLen < 6; shortLen++)
248 NL_TEST_ASSERT(inSuite, header.Encode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
249 NL_TEST_ASSERT(inSuite, header.Decode(buffer, shortLen, &unusedLen) != CHIP_NO_ERROR);
256 static const nlTest sTests[] =
258 NL_TEST_DEF("PacketInitialState", TestPacketHeaderInitialState),
259 NL_TEST_DEF("PayloadInitialState", TestPayloadHeaderInitialState),
260 NL_TEST_DEF("PacketEncodeDecode", TestPacketHeaderEncodeDecode),
261 NL_TEST_DEF("PayloadEncodeDecode", TestPayloadHeaderEncodeDecode),
262 NL_TEST_DEF("PacketEncodeDecodeBounds", TestPacketHeaderEncodeDecodeBounds),
263 NL_TEST_DEF("PayloadEncodeDecodeBounds", TestPayloadHeaderEncodeDecodeBounds),
268 int TestMessageHeader(void)
270 nlTestSuite theSuite = { "Transport-MessageHeader", &sTests[0], nullptr, nullptr };
271 nlTestRunner(&theSuite, nullptr);
272 return nlTestRunnerStats(&theSuite);
275 CHIP_REGISTER_TEST_SUITE(TestMessageHeader)