Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / messaging / tests / TestMessageCounterSyncMgr.cpp
1 /*
2  *
3  *    Copyright (c) 2021 Project CHIP Authors
4  *    All rights reserved.
5  *
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
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 /**
20  *    @file
21  *      This file implements unit tests for the MessageCounterSyncMgr implementation.
22  */
23
24 #include "TestMessagingLayer.h"
25
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>
34
35 #include <nlbyteorder.h>
36 #include <nlunit-test.h>
37
38 #include <errno.h>
39
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>
45
46 namespace {
47
48 using namespace chip;
49 using namespace chip::Inet;
50 using namespace chip::Transport;
51 using namespace chip::Messaging;
52 using namespace chip::Protocols;
53
54 using TestContext = chip::Test::MessagingContext;
55
56 TestContext sContext;
57
58 constexpr NodeId kSourceNodeId        = 123654;
59 constexpr NodeId kDestinationNodeId   = 111222333;
60 constexpr NodeId kTestPeerGroupKeyId  = 0x4000;
61 constexpr NodeId kTestLocalGroupKeyId = 0x5000;
62
63 const char PAYLOAD[] = "Hello!";
64
65 class LoopbackTransport : public Transport::Base
66 {
67 public:
68     /// Transports are required to have a constructor that takes exactly one argument
69     CHIP_ERROR Init(const char * unused) { return CHIP_NO_ERROR; }
70
71     CHIP_ERROR SendMessage(const PacketHeader & header, const PeerAddress & address, System::PacketBufferHandle msgBuf) override
72     {
73         HandleMessageReceived(header, address, std::move(msgBuf));
74
75         return CHIP_NO_ERROR;
76     }
77
78     bool CanSendToPeer(const PeerAddress & address) override { return true; }
79 };
80
81 class TestExchangeMgr : public SecureSessionMgrDelegate
82 {
83 public:
84     void OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, SecureSessionHandle session,
85                            System::PacketBufferHandle msgBuf, SecureSessionMgr * mgr) override
86     {
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);
90
91         ReceiveHandlerCallCount++;
92     }
93
94     void OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr) override {}
95
96     void OnConnectionExpired(SecureSessionHandle session, SecureSessionMgr * mgr) override {}
97
98     nlTestSuite * mSuite        = nullptr;
99     int ReceiveHandlerCallCount = 0;
100 };
101
102 class MockAppDelegate : public ExchangeDelegate
103 {
104 public:
105     void OnMessageReceived(ExchangeContext * ec, const PacketHeader & packetHeader, const PayloadHeader & payloadHeader,
106                            System::PacketBufferHandle msgBuf) override
107     {
108         IsOnMessageReceivedCalled = true;
109
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);
114     }
115
116     void OnResponseTimeout(ExchangeContext * ec) override {}
117
118     nlTestSuite * mSuite           = nullptr;
119     bool IsOnMessageReceivedCalled = false;
120 };
121
122 TransportMgr<LoopbackTransport> gTransportMgr;
123
124 void CheckSendMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext)
125 {
126     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
127
128     ctx.GetInetLayer().SystemLayer()->Init(nullptr);
129
130     IPAddress addr;
131     IPAddress::FromString("127.0.0.1", addr);
132
133     CHIP_ERROR err = CHIP_NO_ERROR;
134     TestExchangeMgr testExchangeMgr;
135
136     testExchangeMgr.mSuite = inSuite;
137     ctx.GetSecureSessionManager().SetDelegate(&testExchangeMgr);
138
139     MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
140     NL_TEST_ASSERT(inSuite, sm != nullptr);
141
142     Optional<Transport::PeerAddress> peer(Transport::PeerAddress::UDP(addr, CHIP_PORT));
143
144     SecurePairingUsingTestSecret pairingLocalToPeer(kTestPeerGroupKeyId, kTestLocalGroupKeyId);
145
146     err = ctx.GetSecureSessionManager().NewPairing(peer, kDestinationNodeId, &pairingLocalToPeer,
147                                                    SecureSessionMgr::PairingDirection::kInitiator, 0);
148     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
149
150     SecurePairingUsingTestSecret pairingPeerToLocal(kTestLocalGroupKeyId, kTestPeerGroupKeyId);
151
152     err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal,
153                                                    SecureSessionMgr::PairingDirection::kResponder, 1);
154     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
155
156     SecureSessionHandle session(kDestinationNodeId, 0x4000, 0);
157
158     // Should be able to send a message to itself by just calling send.
159     testExchangeMgr.ReceiveHandlerCallCount = 0;
160
161     err = sm->SendMsgCounterSyncReq(session);
162     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
163     NL_TEST_ASSERT(inSuite, testExchangeMgr.ReceiveHandlerCallCount == 1);
164 }
165
166 void CheckReceiveMsgCounterSyncReq(nlTestSuite * inSuite, void * inContext)
167 {
168     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
169
170     ctx.GetInetLayer().SystemLayer()->Init(nullptr);
171
172     IPAddress addr;
173     IPAddress::FromString("127.0.0.1", addr);
174
175     CHIP_ERROR err = CHIP_NO_ERROR;
176     MockAppDelegate mockAppDelegate;
177
178     mockAppDelegate.mSuite = inSuite;
179
180     MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
181     NL_TEST_ASSERT(inSuite, sm != nullptr);
182
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);
186
187     Optional<Transport::PeerAddress> peer(Transport::PeerAddress::UDP(addr, CHIP_PORT));
188
189     SecurePairingUsingTestSecret pairingLocalToPeer(kTestPeerGroupKeyId, kTestLocalGroupKeyId);
190
191     err = ctx.GetSecureSessionManager().NewPairing(peer, kDestinationNodeId, &pairingLocalToPeer,
192                                                    SecureSessionMgr::PairingDirection::kInitiator, 0);
193     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
194
195     SecurePairingUsingTestSecret pairingPeerToLocal(kTestLocalGroupKeyId, kTestPeerGroupKeyId);
196
197     err = ctx.GetSecureSessionManager().NewPairing(peer, kSourceNodeId, &pairingPeerToLocal,
198                                                    SecureSessionMgr::PairingDirection::kResponder, 1);
199     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
200
201     SecureSessionHandle session(kDestinationNodeId, 0x4000, 0);
202
203     err = sm->SendMsgCounterSyncReq(session);
204     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
205     NL_TEST_ASSERT(inSuite, mockAppDelegate.IsOnMessageReceivedCalled == true);
206 }
207
208 void CheckAddRetransTable(nlTestSuite * inSuite, void * inContext)
209 {
210     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
211
212     ctx.GetInetLayer().SystemLayer()->Init(nullptr);
213
214     MockAppDelegate mockAppDelegate;
215     ExchangeContext * exchange = ctx.NewExchangeToPeer(&mockAppDelegate);
216     NL_TEST_ASSERT(inSuite, exchange != nullptr);
217
218     MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
219     NL_TEST_ASSERT(inSuite, sm != nullptr);
220
221     System::PacketBufferHandle buffer = MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
222     NL_TEST_ASSERT(inSuite, !buffer.IsNull());
223
224     CHIP_ERROR err =
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);
228 }
229
230 void CheckAddToReceiveTable(nlTestSuite * inSuite, void * inContext)
231 {
232     TestContext & ctx = *reinterpret_cast<TestContext *>(inContext);
233
234     ctx.GetInetLayer().SystemLayer()->Init(nullptr);
235
236     MessageCounterSyncMgr * sm = ctx.GetExchangeManager().GetMessageCounterSyncMgr();
237     NL_TEST_ASSERT(inSuite, sm != nullptr);
238
239     System::PacketBufferHandle buffer = MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD));
240     NL_TEST_ASSERT(inSuite, !buffer.IsNull());
241
242     PacketHeader packetHeader;
243     PayloadHeader payloadHeader;
244
245     CHIP_ERROR err = sm->AddToReceiveTable(packetHeader, payloadHeader, { chip::kTestDeviceNodeId, 0, 0 }, std::move(buffer));
246     NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR);
247 }
248
249 // Test Suite
250
251 /**
252  *  Test Suite that lists all the test functions.
253  */
254 // clang-format off
255 const nlTest sTests[] =
256 {
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),
261     NL_TEST_SENTINEL()
262 };
263 // clang-format on
264
265 int Initialize(void * aContext);
266 int Finalize(void * aContext);
267
268 // clang-format off
269 nlTestSuite sSuite =
270 {
271     "Test-MessageCounterSyncMgr",
272     &sTests[0],
273     Initialize,
274     Finalize
275 };
276 // clang-format on
277
278 /**
279  *  Initialize the test suite.
280  */
281 int Initialize(void * aContext)
282 {
283     CHIP_ERROR err = chip::Platform::MemoryInit();
284     if (err != CHIP_NO_ERROR)
285         return FAILURE;
286
287     err = gTransportMgr.Init("LOOPBACK");
288     if (err != CHIP_NO_ERROR)
289         return FAILURE;
290
291     err = reinterpret_cast<TestContext *>(aContext)->Init(&sSuite, &gTransportMgr);
292     return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE;
293 }
294
295 /**
296  *  Finalize the test suite.
297  */
298 int Finalize(void * aContext)
299 {
300     CHIP_ERROR err = reinterpret_cast<TestContext *>(aContext)->Shutdown();
301     return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE;
302 }
303
304 } // namespace
305
306 /**
307  *  Main
308  */
309 int TestMessageCounterSyncMgr()
310 {
311     // Run test suit against one context
312     nlTestRunner(&sSuite, &sContext);
313
314     return (nlTestRunnerStats(&sSuite));
315 }