21#include <gtest/gtest.h>
40constexpr MacAddress kDeviceMac{0x02, 0x00, 0x00, 0x00, 0x00, 0x01};
42constexpr std::size_t kEthernetHeaderLength = 14U;
43constexpr std::size_t kDcpHeaderLength = 12U;
44constexpr std::size_t kDcpPayloadOffset = kEthernetHeaderLength + kDcpHeaderLength;
46constexpr std::uint16_t kExpectedDcpFrameId =
static_cast<std::uint16_t
>(
DcpFrameId::GetSet);
47constexpr std::uint8_t kExpectedSetServiceId =
static_cast<std::uint8_t
>(
DcpServiceId::Set);
56[[nodiscard]] std::uint16_t ReadU16(std::span<const std::uint8_t>
frame, std::size_t offset)
58 EXPECT_GE(
frame.size(), offset + 2U);
60 return static_cast<std::uint16_t
>((
static_cast<std::uint16_t
>(
frame[offset]) << 8U) |
61 static_cast<std::uint16_t
>(
frame[offset + 1U]));
70[[nodiscard]] std::uint32_t ReadU32(std::span<const std::uint8_t>
frame, std::size_t offset)
72 EXPECT_GE(
frame.size(), offset + 4U);
74 return (
static_cast<std::uint32_t
>(
frame[offset]) << 24U) |
75 (
static_cast<std::uint32_t
>(
frame[offset + 1U]) << 16U) |
76 (
static_cast<std::uint32_t
>(
frame[offset + 2U]) << 8U) |
77 static_cast<std::uint32_t
>(
frame[offset + 3U]);
90[[nodiscard]] std::size_t VerifySetFrameHeader(std::span<const std::uint8_t>
frame)
92 EXPECT_GE(
frame.size(), kDcpPayloadOffset);
94 if (
frame.size() < kDcpPayloadOffset)
102 EXPECT_EQ(ReadU16(
frame, 14), kExpectedDcpFrameId);
104 EXPECT_EQ(
frame[16], kExpectedSetServiceId);
105 EXPECT_EQ(
frame[17], kExpectedRequestServiceType);
110 EXPECT_EQ(ReadU16(
frame, 22), 0U);
113 const std::uint16_t dcpLength = ReadU16(
frame, 24);
115 EXPECT_EQ(
frame.size() - kDcpPayloadOffset, dcpLength);
117 return kDcpPayloadOffset;
160 const Bytes frame = BuildSetNameRequest(
"abc");
161 const std::size_t payloadOffset = VerifySetFrameHeader(
frame);
162 const auto payload = std::span<const std::uint8_t>(
frame).subspan(payloadOffset);
164 ASSERT_EQ(
payload.size(), 10U);
168 EXPECT_EQ(ReadU16(
payload, 2), 5U);
171 EXPECT_EQ(
payload[6],
static_cast<std::uint8_t
>(
'a'));
172 EXPECT_EQ(
payload[7],
static_cast<std::uint8_t
>(
'b'));
173 EXPECT_EQ(
payload[8],
static_cast<std::uint8_t
>(
'c'));
186 const Bytes frame = BuildSetNameRequest(
"abcd");
187 const std::size_t payloadOffset = VerifySetFrameHeader(
frame);
188 const auto payload = std::span<const std::uint8_t>(
frame).subspan(payloadOffset);
190 ASSERT_EQ(
payload.size(), 10U);
196 EXPECT_EQ(ReadU16(
payload, 2), 6U);
199 EXPECT_EQ(
payload[6],
static_cast<std::uint8_t
>(
'a'));
200 EXPECT_EQ(
payload[7],
static_cast<std::uint8_t
>(
'b'));
201 EXPECT_EQ(
payload[8],
static_cast<std::uint8_t
>(
'c'));
202 EXPECT_EQ(
payload[9],
static_cast<std::uint8_t
>(
'd'));
208 const Bytes frame = BuildSetNameRequest(
"abcd");
209 const std::size_t payloadOffset = VerifySetFrameHeader(
frame);
210 const auto payload = std::span<const std::uint8_t>(
frame).subspan(payloadOffset);
218 const Bytes frame = BuildSetNameRequest(
"abcd",
true);
219 const std::size_t payloadOffset = VerifySetFrameHeader(
frame);
220 const auto payload = std::span<const std::uint8_t>(
frame).subspan(payloadOffset);
288 ASSERT_GE(
frame.size(), kDcpPayloadOffset + 8U);
290 const auto payload = std::span<const std::uint8_t>(
frame).subspan(kDcpPayloadOffset);
294 EXPECT_EQ(ReadU16(
payload, 2), 4U);
296 EXPECT_EQ(ReadU16(
payload, 4), 0x0000U);
PROFINET DCP discovery and device configuration interface.
Declares exceptions and error types used by the PROFINET IO controller stack.
Bytes BuildSetParamRequest(const MacAddress &dst, const MacAddress &src, const std::string ¶m, const std::string &value, bool permanent)
Build a serialized DCP SET request for a named parameter.
Bytes BuildDcpSignalRequest(const MacAddress &dst, const MacAddress &src)
Build a serialized DCP Signal request.
TEST_F(DcpWireFormatTest, OddLengthNameIsPaddedAndBlockLengthExcludesPadding)
constexpr MacAddress kControllerMac
@ Temporary
Change applies until the next power cycle only.
@ Permanent
Change is persisted permanently.
@ Signal
Signal / flash LEDs.
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
@ GetSet
DCP GET/SET request or response.
constexpr std::uint16_t PROFINET_ETHERTYPE
EtherType value identifying PROFINET frames (0x8892).
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
PROFINET protocol wire-format structures and serialization helpers.
static constexpr std::pair< std::uint8_t, std::uint8_t > NAME_OF_STATION
Block option/suboption: station name.
Generic helpers for reading and writing integer and byte data in big- and little-endian wire formats.