PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
test_protocol.cpp
Go to the documentation of this file.
1
17
18#include <gtest/gtest.h>
19
20#include "profinet/protocol.h"
21
22using namespace profinet;
23
24class ProtocolTest : public ::testing::Test
25{
26};
27
29TEST_F(ProtocolTest, PNDCPHeaderRoundTrips)
30{
32 h.frameId = DcpFrameId::GetSet;
33 h.serviceId = DcpServiceId::Identify;
34 h.serviceType = DcpServiceType::Request;
35 h.xId = 0x12345678;
36 h.respDelay = 0x0080;
37 h.length = 4;
38 h.payload = {0xFF, 0xFF, 0x00, 0x00};
39
40 const Bytes encoded = h.ToBytes();
41
42 EXPECT_EQ(encoded.size(), PNDCPHeader::kFixedSize + h.payload.size());
43
44 const PNDCPHeader decoded = PNDCPHeader::Parse(encoded);
45
46 EXPECT_EQ(decoded.frameId, h.frameId);
47 EXPECT_EQ(decoded.serviceId, h.serviceId);
48 EXPECT_EQ(decoded.xId, h.xId);
49 EXPECT_EQ(decoded.respDelay, h.respDelay);
50 EXPECT_EQ(decoded.length, h.length);
51 EXPECT_EQ(decoded.payload, h.payload);
52}
53
55TEST_F(ProtocolTest, PNDCPBlockParsesStatusAndPayload)
56{
57 // option=1 suboption=2, length=14
58 // 2 status bytes + 12 IP payload bytes
59 Bytes data = {
60 0x01,
61 0x02,
62 0x00,
63 0x0E,
64 0x00,
65 0x00};
66
67 std::vector<std::uint8_t> ipPayload = {
68 192, 168, 1, 1,
69 255, 255, 255, 0,
70 192, 168, 1, 254};
71
72 data.insert(
73 data.end(),
74 ipPayload.begin(),
75 ipPayload.end());
76
77 const PNDCPBlock block = PNDCPBlock::Parse(data);
78
79 EXPECT_EQ(
80 block.option,
81 static_cast<std::uint8_t>(1));
82
83 EXPECT_EQ(
84 block.suboption,
85 static_cast<std::uint8_t>(2));
86
87 EXPECT_EQ(
88 block.payload.size(),
89 static_cast<std::size_t>(12));
90
91 const IPConfiguration ip = block.ParseIp();
92
93 EXPECT_EQ(ip.address, "192.168.1.1");
94 EXPECT_EQ(ip.netmask, "255.255.255.0");
95 EXPECT_EQ(ip.gateway, "192.168.1.254");
96}
97
99TEST_F(ProtocolTest, EthernetHeaderRoundTrips)
100{
101 EthernetHeader eth;
102
103 eth.dst = String2Mac("01:0e:cf:00:00:00");
104 eth.src = String2Mac("aa:bb:cc:dd:ee:ff");
106 eth.payload = {
107 0x01,
108 0x02,
109 0x03};
110
111 const Bytes encoded = eth.ToBytes();
112
113 const EthernetHeader decoded =
114 EthernetHeader::Parse(encoded);
115
116 EXPECT_EQ(decoded.dst, eth.dst);
117 EXPECT_EQ(decoded.src, eth.src);
118 EXPECT_EQ(decoded.type, eth.type);
119 EXPECT_EQ(decoded.payload, eth.payload);
120}
121
122// This test pins them so a future edit can't silently
123// reintroduce a sizing bug that would break wire compatibility.
124
126TEST_F(ProtocolTest, PacketStructFixedSizesMatchExpectedSizes)
127{
128 EXPECT_EQ(
130 static_cast<std::size_t>(12));
131
132 EXPECT_EQ(
134 static_cast<std::size_t>(4));
135
136 EXPECT_EQ(
138 static_cast<std::size_t>(6));
139
140 EXPECT_EQ(
142 static_cast<std::size_t>(80));
143
144 EXPECT_EQ(
146 static_cast<std::size_t>(20));
147
148 EXPECT_EQ(
150 static_cast<std::size_t>(64));
151
152 EXPECT_EQ(
154 static_cast<std::size_t>(6));
155
156 EXPECT_EQ(
158 static_cast<std::size_t>(58));
159
160 EXPECT_EQ(
162 static_cast<std::size_t>(32));
163
164 EXPECT_EQ(
166 static_cast<std::size_t>(60));
167
168 EXPECT_EQ(
170 static_cast<std::size_t>(60));
171
172 EXPECT_EQ(
174 static_cast<std::size_t>(22));
175
176 EXPECT_EQ(
178 static_cast<std::size_t>(60));
179
180 EXPECT_EQ(
182 static_cast<std::size_t>(60));
183
184 EXPECT_EQ(
186 static_cast<std::size_t>(70));
187
188 EXPECT_EQ(
190 static_cast<std::size_t>(6));
191
192 EXPECT_EQ(
194 static_cast<std::size_t>(12));
195
196 EXPECT_EQ(
198 static_cast<std::size_t>(46));
199
200 EXPECT_EQ(
202 static_cast<std::size_t>(26));
203
204 EXPECT_EQ(
206 static_cast<std::size_t>(12));
207
208 EXPECT_EQ(
210 static_cast<std::size_t>(26));
211
212 EXPECT_EQ(
214 static_cast<std::size_t>(22));
215
216 EXPECT_EQ(
218 static_cast<std::size_t>(12));
219
220 EXPECT_EQ(
222 static_cast<std::size_t>(6));
223
224 EXPECT_EQ(
226 static_cast<std::size_t>(64));
227
228 EXPECT_EQ(
230 static_cast<std::size_t>(64));
231
232 // Cross-check against ToBytes() actually producing the expected size.
233 EXPECT_EQ(
234 PNARBlockRequest{}.ToBytes().size(),
236
237 EXPECT_EQ(
238 PNAlarmCRBlockReq{}.ToBytes().size(),
240
241 EXPECT_EQ(
242 PNIOCRBlockReqHeader{}.ToBytes().size(),
244
245 EXPECT_EQ(
246 PNAlarmAckPDU{}.ToBytes().size(),
248
249 EXPECT_EQ(
250 PNRTAHeader{}.ToBytes().size(),
252
253 EXPECT_EQ(
254 PNIODWriteReq{}.ToBytes().size(),
256}
257
259TEST_F(ProtocolTest, PNRPCHeaderInterfaceUUIDMatchesExpectedPrefix)
260{
261 auto uuid = PNRPCHeader::IfaceUuidDevice();
262
263 EXPECT_EQ(
264 uuid[0],
265 static_cast<std::uint8_t>(0xDE));
266
267 EXPECT_EQ(
268 uuid[1],
269 static_cast<std::uint8_t>(0xA0));
270
271 EXPECT_EQ(
272 uuid[2],
273 static_cast<std::uint8_t>(0x00));
274
275 EXPECT_EQ(
276 uuid[3],
277 static_cast<std::uint8_t>(0x01));
278}
280TEST(EthernetVLANHeaderTests, RejectsTruncatedHeader)
281{
282 constexpr std::size_t kHeaderSize = 18U;
283
284 for (std::size_t size = 0U; size < kHeaderSize; ++size)
285 {
286 const Bytes data(size);
287
288 EXPECT_THROW((void)EthernetVLANHeader::Parse(data), std::runtime_error);
289 }
290}
292TEST(EthernetVLANHeaderTests, AcceptsCompleteHeader)
293{
294 constexpr std::size_t kHeaderSize = 18U;
295
296 Bytes data(kHeaderSize, 0U);
297
298 EXPECT_NO_THROW((void)EthernetVLANHeader::Parse(data));
299}
TEST_F(AlarmListenerTests, InitializesWithEndpoint)
TEST(AlarmEndpointTests, DefaultTransportIsLayer2)
MacAddress String2Mac(const std::string &macStr)
Parse a colon-separated MAC address string.
Definition util.cpp:122
constexpr std::uint16_t PROFINET_ETHERTYPE
EtherType value identifying PROFINET frames (0x8892).
Definition util.h:30
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
Definition protocol.h:55
PROFINET protocol wire-format structures and serialization helpers.
Plain (untagged) Ethernet II frame header.
Definition protocol.h:479
MacAddress src
Source MAC address.
Definition protocol.h:484
std::uint16_t type
EtherType field.
Definition protocol.h:487
static EthernetHeader Parse(const Bytes &data)
Parse an Ethernet header and payload from raw frame bytes.
Definition protocol.h:495
Bytes ToBytes() const
Serialize this header and its payload back to raw frame bytes.
Definition protocol.h:513
MacAddress dst
Destination MAC address.
Definition protocol.h:481
Bytes payload
Frame payload following the header.
Definition protocol.h:490
static EthernetVLANHeader Parse(const Bytes &data)
Parse a VLAN-tagged Ethernet header and payload from raw frame bytes.
Definition protocol.h:548
static constexpr std::size_t kSize
Size in bytes of this object.
Definition protocol.h:1907
Decoded IPv4 address/netmask/gateway triple.
Definition protocol.h:653
std::string gateway
IPv4 default gateway.
Definition protocol.h:661
std::string netmask
IPv4 subnet mask, e.g. "255.255.255.0".
Definition protocol.h:658
std::string address
IPv4 address, e.g. "192.168.1.1".
Definition protocol.h:655
ARBlockReq: establishes an Application Relationship (sent in the CONNECT request).
Definition protocol.h:1360
Bytes ToBytes() const
Serialize this block back to raw bytes.
Definition protocol.h:1428
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this block.
Definition protocol.h:1398
AlarmAck-PDU: acknowledges receipt of an AlarmNotification-PDU.
Definition protocol.h:2347
static constexpr std::size_t kSize
Size in bytes of this PDU.
Definition protocol.h:2370
Bytes ToBytes() const
Serialize this PDU back to raw bytes.
Definition protocol.h:2374
AlarmCRBlockReq: requests establishment of the alarm connection (part of the CONNECT request).
Definition protocol.h:2115
Bytes ToBytes() const
Serialize this block back to raw bytes.
Definition protocol.h:2197
static constexpr std::size_t kSize
Size in bytes of this block.
Definition protocol.h:2167
static constexpr std::size_t kSize
Size in bytes of this block.
Definition protocol.h:2235
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this PDU.
Definition protocol.h:2319
static constexpr std::size_t kSize
Size in bytes of this header.
Definition protocol.h:1323
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this block.
Definition protocol.h:681
DCP response block: Option(1) + SubOption(1) + Length(2) + Status(2) + payload.
Definition protocol.h:737
std::uint8_t suboption
DCP suboption code.
Definition protocol.h:742
static PNDCPBlock Parse(const Bytes &data)
Parse a DCP response block from raw bytes.
Definition protocol.h:797
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this block.
Definition protocol.h:792
std::uint8_t option
DCP option code.
Definition protocol.h:739
IPConfiguration ParseIp() const
Interpret this block's payload as an IP configuration triple.
Definition protocol.h:833
Bytes payload
Block payload (excludes Status).
Definition protocol.h:751
DCP (Discovery and Configuration Protocol) frame header.
Definition protocol.h:584
std::uint32_t xId
Transaction ID correlating requests and responses.
Definition protocol.h:600
Bytes ToBytes() const
Serialize this header and its block-list payload back to raw bytes.
Definition protocol.h:637
std::uint16_t respDelay
Response delay factor (requests) or reserved (responses).
Definition protocol.h:603
static PNDCPHeader Parse(const Bytes &data)
Parse a DCP header and block-list payload from raw bytes.
Definition protocol.h:617
DcpFrameId frameId
DCP frame ID identifying the service/multicast group.
Definition protocol.h:591
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this header.
Definition protocol.h:612
std::uint16_t length
Length in bytes of the block list that follows.
Definition protocol.h:606
DcpServiceId serviceId
DCP service ID (GET/SET/IDENTIFY/HELLO).
Definition protocol.h:594
DcpServiceType serviceType
DCP service type (REQUEST/RESPONSE/...).
Definition protocol.h:597
Bytes payload
DCP block list payload.
Definition protocol.h:609
static constexpr std::size_t kSize
Size in bytes of this description.
Definition protocol.h:2747
IOCRBlockReq header: requests establishment of one IOCR (part of the CONNECT request).
Definition protocol.h:1984
static constexpr std::size_t kSize
Size in bytes of this header.
Definition protocol.h:2042
Bytes ToBytes() const
Serialize this header back to raw bytes.
Definition protocol.h:2085
static constexpr std::size_t kSize
Size in bytes of this block.
Definition protocol.h:1959
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this header.
Definition protocol.h:1232
static constexpr std::size_t kSize
Size in bytes of this block.
Definition protocol.h:1472
IODWriteReqHeader: request header for writing a data record.
Definition protocol.h:2768
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this block.
Definition protocol.h:2808
Bytes ToBytes() const
Serialize this block back to raw bytes.
Definition protocol.h:2812
static constexpr std::size_t kSize
Size in bytes of this block.
Definition protocol.h:2878
static constexpr std::size_t kSize
Size in bytes of this record.
Definition protocol.h:1572
static constexpr std::size_t kSize
Size in bytes of this record.
Definition protocol.h:1640
static constexpr std::size_t kSize
Size in bytes of this record.
Definition protocol.h:1681
static constexpr std::size_t kSize
Size in bytes of this record.
Definition protocol.h:1722
static constexpr std::size_t kSize
Size in bytes of this record.
Definition protocol.h:1762
static constexpr std::size_t kSize
Size in bytes of this record.
Definition protocol.h:1802
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this wrapper.
Definition protocol.h:1148
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this header.
Definition protocol.h:979
static std::array< std::uint8_t, uuidLenght > IfaceUuidDevice()
Interface UUID identifying the IO-Device role.
Definition protocol.h:983
RTA-PDU Header - Real-Time Acyclic PDU for Layer 2 alarm transport.
Definition protocol.h:2390
static constexpr std::size_t kFixedSize
Size in bytes of the fixed portion of this header.
Definition protocol.h:2443
Bytes ToBytes() const
Serialize this header and variable part back to raw bytes.
Definition protocol.h:2469