12#include <gmock/gmock.h>
13#include <gtest/gtest.h>
17#include <condition_variable>
35using ::testing::StrictMock;
37constexpr std::uint16_t kControllerReference = 1;
38constexpr std::uint16_t kDeviceReference = 42;
40constexpr std::uint16_t kUdpSourcePort = 45000;
43UdpEndpoint MakeSourceAddress()
46 .address =
"127.0.0.1",
47 .port = kUdpSourcePort};
58Bytes BuildUdpAlarmNotification()
70 EXPECT_EQ(body.size(), 20U);
71 if (body.size() < 20U)
90 constexpr std::uint16_t blockType = 0x0002;
117 ioContext = std::make_unique<asio::io_context>();
125 return MakeSourceAddress();
137 auto socket = std::make_unique<StrictMock<MockUdpSocket>>();
144 datagram.
data = BuildUdpAlarmNotification();
147 std::mutex callbackMutex;
148 std::condition_variable callbackCondition;
149 bool callbackReceived =
false;
151 listener->AddAlarmNotificationCallback(
158 std::scoped_lock lock(callbackMutex);
159 callbackReceived =
true;
162 callbackCondition.notify_one();
166 .WillOnce(::testing::Return(datagram))
170 EXPECT_CALL(*mockSocket, SendTo(_, _))
172 [&](
const Bytes& ack,
176 EXPECT_EQ(destination, source);
178 EXPECT_FALSE(ack.empty());
182 listener->Start(
nullptr, std::move(socket));
185 std::unique_lock lock(callbackMutex);
187 const bool received =
188 callbackCondition.wait_for(
190 std::chrono::seconds(1),
193 return callbackReceived;
196 EXPECT_TRUE(received);
199 EXPECT_TRUE(listener->IsRunning());
203 EXPECT_FALSE(listener->IsRunning());
212 auto socket = std::make_unique<StrictMock<MockUdpSocket>>();
216 std::mutex callbackMutex;
217 std::condition_variable callbackCondition;
218 bool callbackReceived =
false;
220 listener->AddAlarmNotificationCallback(
224 std::scoped_lock lock(callbackMutex);
225 callbackReceived =
true;
228 callbackCondition.notify_one();
232 invalidDatagram.
data = {0x01, 0x02, 0x03};
233 invalidDatagram.
source = SourceAddress();
236 .WillOnce(::testing::Return(invalidDatagram))
239 EXPECT_CALL(*mockSocket, SendTo(_, _))
242 listener->Start(
nullptr, std::move(socket));
244 std::unique_lock lock(callbackMutex);
246 EXPECT_FALSE(callbackCondition.wait_for(lock,
247 std::chrono::milliseconds(50),
250 return callbackReceived;
262 auto socket = std::make_unique<StrictMock<MockUdpSocket>>();
269 listener->Start(
nullptr, std::move(socket));
271 ASSERT_TRUE(listener->IsRunning());
275 EXPECT_TRUE(listener->IsRunning());
279 EXPECT_FALSE(listener->IsRunning());
285 EXPECT_FALSE(listener->IsRunning());
287 EXPECT_NO_THROW(listener->Stop());
289 EXPECT_FALSE(listener->IsRunning());
Declares the PROFINET RTA alarm listener and AlarmAck transmission support.
GoogleMock implementation of IUdpSocket.
Test fixture for UDP AlarmListener behavior.
std::unique_ptr< AlarmListener > listener
void SetUp() override
Construct an AlarmListener configured for UDP transport.
std::unique_ptr< asio::io_context > ioContext
UdpEndpoint SourceAddress() const
Build the source endpoint used for the injected UDP datagram.
GoogleMock implementation of IUdpSocket.
void PutU16(std::vector< std::uint8_t > &out, std::uint16_t value)
Append a 16-bit value to a buffer in big-endian order.
void PutU32(std::vector< std::uint8_t > &out, std::uint32_t value)
Append a 32-bit value to a buffer in big-endian order.
TEST_F(AlarmListenerTests, InitializesWithEndpoint)
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
constexpr std::size_t RECEIVE_BUFFER_LENGTH
Receive buffer length.
PROFINET protocol wire-format structures and serialization helpers.
Alarm endpoint configuration.
int transport
Transport: 0 = Layer2 (RTA), 1 = UDP.
std::string interface
Network interface name to bind to, e.g. "eth0".
std::uint16_t controllerRef
Controller's local alarm reference (from AlarmCRBlockReq).
std::uint16_t deviceRef
Device's local alarm reference (from AlarmCRBlockRes).
MacAddress deviceMac
The device's MAC address.
Complete parsed AlarmNotification PDU: header fields + parsed items.
std::uint16_t slotNumber
Slot number where the alarm originated.
std::uint16_t subslotNumber
Subslot number where the alarm originated.
static constexpr std::size_t kSize
Size in bytes of this PDU.
A UDP datagram together with the IPv4 address of its sender.
std::vector< std::uint8_t > data
Datagram payload.
UdpEndpoint source
IPv4 address and UDP port of the datagram sender.
Portable IPv4 UDP endpoint.
Generic helpers for reading and writing integer and byte data in big- and little-endian wire formats.