3 * Copyright (c) 2021 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 unit tests for the MessageCounterSyncMgr implementation.
24 #include "TestMessagingLayer.h"
26 #include <core/CHIPCore.h>
27 #include <messaging/ReliableMessageContext.h>
28 #include <messaging/ReliableMessageMgr.h>
29 #include <protocols/Protocols.h>
30 #include <protocols/echo/Echo.h>
31 #include <support/CodeUtils.h>
32 #include <transport/SecureSessionMgr.h>
33 #include <transport/TransportMgr.h>
35 #include <nlbyteorder.h>
36 #include <nlunit-test.h>
40 #include <messaging/ExchangeContext.h>
41 #include <messaging/ExchangeMgr.h>
42 #include <messaging/Flags.h>
43 #include <messaging/tests/MessagingContext.h>
44 #include <support/logging/CHIPLogging.h>
49 using namespace chip::Inet;
50 using namespace chip::Transport;
51 using namespace chip::Messaging;
52 using namespace chip::Protocols;
54 using TestContext = chip::Test::MessagingContext;
58 constexpr NodeId kSourceNodeId = 123654;
59 constexpr NodeId kDestinationNodeId = 111222333;
60 constexpr NodeId kTestPeerGroupKeyId = 0x4000;
61 constexpr NodeId kTestLocalGroupKeyId = 0x5000;
63 const char PAYLOAD[] = "Hello!";
65 class LoopbackTransport : public Transport::Base
68 /// Transports are required to have a constructor that takes exactly one argument
69 CHIP_ERROR Init(const char * unused) { return CHIP_NO_ERROR; }
71 CHIP_ERROR SendMessage(const PacketHeader & header, const PeerAddress & address, System::PacketBufferHandle msgBuf) override
73 HandleMessageReceived(header, address, std::move(msgBuf));
78 bool CanSendToPeer(const PeerAddress & address) override { return true; }
81 class TestExchangeMgr : public SecureSessionMgrDelegate
84 void OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, SecureSessionHandle session,
85 System::PacketBufferHandle msgBuf, SecureSessionMgr * mgr) override
87 NL_TEST_ASSERT(mSuite, header.GetSourceNodeId() == Optional<NodeId>::Value(kSourceNodeId));
88 NL_TEST_ASSERT(mSuite, header.GetDestinationNodeId() == Optional<NodeId>::Value(kDestinationNodeId));
89 NL_TEST_ASSERT(mSuite, msgBuf->DataLength() == kMsgCounterChallengeSize);
91 ReceiveHandlerCallCount++;
94 void OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr) override {}
96 void OnConnectionExpired(SecureSessionHandle session, SecureSessionMgr * mgr) override {}
98 nlTestSuite * mSuite = nullptr;
99 int ReceiveHandlerCallCount = 0;
102 class MockAppDelegate : public ExchangeDelegate
105 void OnMessageReceived(ExchangeContext * ec, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
106 System::PacketBufferHandle msgBuf) override
108 IsOnMessageReceivedCalled = true;
110 NL_TEST_ASSERT(mSuite, payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncReq));
111 NL_TEST_ASSERT(mSuite, packetHeader.GetSourceNodeId() == Optional<NodeId>::Value(kSourceNodeId));
112 NL_TEST_ASSERT(mSuite, packetHeader.GetDestinationNodeId() == Optional<NodeId>::Value(kDestinationNodeId));
113 NL_TEST_ASSERT(mSuite, msgBuf->DataLength() == kMsgCounterChallengeSize);
116 void OnResponseTimeout(ExchangeContext * ec) override {}
118 nlTestSuite * mSuite = nullptr;
119 bool IsOnMessageReceivedCalled = false;
122 TransportMgr<LoopbackTransport> gTransportMgr;
124 void CheckSendMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext)
126 TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
128 ctx.GetInetLayer().SystemLayer()->Init(nullptr);
131 IPAddress::FromString("127.0.0.1", addr);
133 CHIP_ERROR err = CHIP_NO_ERROR;
134 TestExchangeMgr testExchangeMgr;
136 testExchangeMgr.mSuite = inSuite;
137 ctx.GetSecureSessionManager().SetDelegate(&testExchangeMgr);
139 MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
140 NL_TEST_ASSERT(inSuite, sm != nullptr);
142 Optional<Transport::PeerAddress> peer(Transport::PeerAddress::UDP(addr, CHIP_PORT));
144 SecurePairingUsingTestSecret pairingLocalToPeer(kTestPeerGroupKeyId, kTestLocalGroupKeyId);
146 err = ctx.GetSecureSessionManager().NewPairing(peer, kDestinationNodeId, &pairingLocalToPeer,
147 SecureSessionMgr::PairingDirection::kInitiator, 0);
148 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
150 SecurePairingUsingTestSecret pairingPeerToLocal(kTestLocalGroupKeyId, kTestPeerGroupKeyId);
152 err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal,
153 SecureSessionMgr::PairingDirection::kResponder, 1);
154 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
156 SecureSessionHandle session(kDestinationNodeId, 0x4000, 0);
158 // Should be able to send a message to itself by just calling send.
159 testExchangeMgr.ReceiveHandlerCallCount = 0;
161 err = sm->SendMsgCounterSyncReq(session);
162 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
163 NL_TEST_ASSERT(inSuite, testExchangeMgr.ReceiveHandlerCallCount == 1);
166 void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext)
168 TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
170 ctx.GetInetLayer().SystemLayer()->Init(nullptr);
173 IPAddress::FromString("127.0.0.1", addr);
175 CHIP_ERROR err = CHIP_NO_ERROR;
176 MockAppDelegate mockAppDelegate;
178 mockAppDelegate.mSuite = inSuite;
180 MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
181 NL_TEST_ASSERT(inSuite, sm != nullptr);
183 // Register to receive unsolicited Secure Channel Request messages from the exchange manager.
184 err = ctx.GetExchangeManager().RegisterUnsolicitedMessageHandlerForProtocol(Protocols::SecureChannel::Id, &mockAppDelegate);
185 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
187 Optional<Transport::PeerAddress> peer(Transport::PeerAddress::UDP(addr, CHIP_PORT));
189 SecurePairingUsingTestSecret pairingLocalToPeer(kTestPeerGroupKeyId, kTestLocalGroupKeyId);
191 err = ctx.GetSecureSessionManager().NewPairing(peer, kDestinationNodeId, &pairingLocalToPeer,
192 SecureSessionMgr::PairingDirection::kInitiator, 0);
193 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
195 SecurePairingUsingTestSecret pairingPeerToLocal(kTestLocalGroupKeyId, kTestPeerGroupKeyId);
197 err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal,
198 SecureSessionMgr::PairingDirection::kResponder, 1);
199 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
201 SecureSessionHandle session(kDestinationNodeId, 0x4000, 0);
203 err = sm->SendMsgCounterSyncReq(session);
204 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
205 NL_TEST_ASSERT(inSuite, mockAppDelegate.IsOnMessageReceivedCalled == true);
208 void CheckAddRetransTable(nlTestSuite * inSuite, void * inContext)
210 TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
212 ctx.GetInetLayer().SystemLayer()->Init(nullptr);
214 MockAppDelegate mockAppDelegate;
215 ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockAppDelegate);
216 NL_TEST_ASSERT(inSuite, exchange != nullptr);
218 MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
219 NL_TEST_ASSERT(inSuite, sm != nullptr);
221 System::PacketBufferHandle buffer = MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
222 NL_TEST_ASSERT(inSuite, !buffer.IsNull());
225 sm->AddToRetransmissionTable(Protocols::Echo::Id, static_cast<uint8_t>(Protocols::Echo::MsgType::EchoRequest),
226 Messaging::SendFlags(Messaging::SendMessageFlags::kNone), std::move(buffer), exchange);
227 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
230 void CheckAddToReceiveTable(nlTestSuite * inSuite, void * inContext)
232 TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
234 ctx.GetInetLayer().SystemLayer()->Init(nullptr);
236 MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
237 NL_TEST_ASSERT(inSuite, sm != nullptr);
239 System::PacketBufferHandle buffer = MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
240 NL_TEST_ASSERT(inSuite, !buffer.IsNull());
242 PacketHeader packetHeader;
243 PayloadHeader payloadHeader;
245 CHIP_ERROR err = sm->AddToReceiveTable(packetHeader, payloadHeader, { chip::kTestDeviceNodeId, 0, 0 }, std::move(buffer));
246 NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
252 * Test Suite that lists all the test functions.
255 const nlTest sTests[] =
257 NL_TEST_DEF("Test MessageCounterSyncMgr::ReceiveMsgCounterSyncReq", CheckReceiveMsgCounterSyncReq),
258 NL_TEST_DEF("Test MessageCounterSyncMgr::SendMsgCounterSyncReq", CheckSendMsgCounterSyncReq),
259 NL_TEST_DEF("Test MessageCounterSyncMgr::AddToRetransTable", CheckAddRetransTable),
260 NL_TEST_DEF("Test MessageCounterSyncMgr::AddToReceiveTable", CheckAddToReceiveTable),
265 int Initialize(void * aContext);
266 int Finalize(void * aContext);
271 "Test-MessageCounterSyncMgr",
279 * Initialize the test suite.
281 int Initialize(void * aContext)
283 CHIP_ERROR err = chip::Platform::MemoryInit();
284 if (err != CHIP_NO_ERROR)
287 err = gTransportMgr.Init("LOOPBACK");
288 if (err != CHIP_NO_ERROR)
291 err = reinterpret_cast<TestContext *>(aContext)->Init(&sSuite, &gTransportMgr);
292 return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE;
296 * Finalize the test suite.
298 int Finalize(void * aContext)
300 CHIP_ERROR err = reinterpret_cast<TestContext *>(aContext)->Shutdown();
301 return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE;
309 int TestMessageCounterSyncMgr()
311 // Run test suit against one context
312 nlTestRunner(&sSuite, &sContext);
314 return (nlTestRunnerStats(&sSuite));