PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
test_alarmNotification.cpp
Go to the documentation of this file.
1
19
20#include <gtest/gtest.h>
21
22#include <cstdint>
23
24#include "profinet/alarms.h"
25
26namespace profinet
27{
28namespace
29{
37Bytes BuildAlarmBlock(bool highPriority = false, std::uint16_t specifier = 0x0401, const Bytes& items = {})
38{
39 Bytes body;
40
41 wire::PutU16(body, 0x0001);
42 wire::PutU32(body, 0x00000000);
43 wire::PutU16(body, 1);
44 wire::PutU16(body, 1);
45 wire::PutU32(body, 0x00000001);
46 wire::PutU32(body, 0x00000001);
47 wire::PutU16(body, specifier);
48
49 EXPECT_EQ(body.size(), 20U);
50
51 const std::uint16_t blockType = highPriority ? 0x0001 : 0x0002;
52
53 Bytes rest{0x01, 0x00};
54
55 rest.insert(rest.end(), body.begin(), body.end());
56 rest.insert(rest.end(), items.begin(), items.end());
57
58 Bytes result;
59
60 wire::PutU16(result, blockType);
61 wire::PutU16(result, static_cast<std::uint16_t>(rest.size()));
62 result.insert(result.end(), rest.begin(), rest.end());
63
64 return result;
65}
66
73class AlarmNotificationTest : public ::testing::Test
74{
75 protected:
79 static Bytes MakeChannelDiagnosisItem()
80 {
81 Bytes item;
82
83 wire::PutU16(item, 0x8000);
84 wire::PutU16(item, 1);
85 wire::PutU16(item, 0x0800);
86 wire::PutU16(item, 9);
87
88 return item;
89 }
90};
91
92} // namespace
93
95TEST_F(AlarmNotificationTest, ItemLessAlarmIsAccepted)
96{
97 const Bytes block = BuildAlarmBlock();
98
99 EXPECT_EQ(block.size(), 26U);
100
101 const auto notification = ParseAlarmNotification(block);
102
103 EXPECT_EQ(notification.slotNumber, 1U);
104
105 EXPECT_TRUE(notification.items.empty());
106}
107
109TEST_F(AlarmNotificationTest, ChannelDiagnosisItemIsDecoded)
110{
111 const Bytes item = MakeChannelDiagnosisItem();
112
113 const auto notification = ParseAlarmNotification(BuildAlarmBlock(false, 0x0401, item));
114
115 ASSERT_EQ(notification.items.size(), 1U);
116 auto* diag = std::get_if<DiagnosisItem>(&notification.items[0]);
117 EXPECT_EQ(diag->userStructureId, static_cast<Usi>(0x8000U));
118 EXPECT_EQ(diag->channelNumber, 1U);
119 EXPECT_EQ(diag->channelErrorType, 9U);
120}
121
128TEST_F(AlarmNotificationTest, EthernetPaddingIsNotParsedAsItems)
129{
130 const Bytes block = BuildAlarmBlock(false, 0x0401, MakeChannelDiagnosisItem());
131
132 Bytes padded = block;
133
134 padded.insert(padded.end(), 6U, 0x00);
135
136 const auto notification = ParseAlarmNotification(padded);
137
138 EXPECT_EQ(notification.items.size(), 1U);
139}
140
142TEST_F(AlarmNotificationTest, ArDiagnosisIsBit14)
143{
144 const auto notification = ParseAlarmNotification(BuildAlarmBlock(false, 0x4000 | 1));
145
146 EXPECT_TRUE(notification.arDiagnosisState);
147}
148
150TEST_F(AlarmNotificationTest, ReservedBit15IsNotArDiagnosis)
151{
152 const auto notification = ParseAlarmNotification(BuildAlarmBlock(false, 0x8000 | 1));
153
154 EXPECT_FALSE(notification.arDiagnosisState);
155}
156} // namespace profinet
Declares PROFINET alarm, diagnosis, maintenance, and USI payload types and parsers.
void PutU16(std::vector< std::uint8_t > &out, std::uint16_t value)
Append a 16-bit value to a buffer in big-endian order.
Definition wire.h:97
void PutU32(std::vector< std::uint8_t > &out, std::uint32_t value)
Append a 32-bit value to a buffer in big-endian order.
Definition wire.h:105
TEST_F(AlarmListenerTests, InitializesWithEndpoint)
AlarmNotification ParseAlarmNotification(const Bytes &data)
Parse a complete AlarmNotification PDU (BlockHeader + body + items).
Definition alarms.cpp:245
Usi
PROFINET User Structure Identifiers (USI).
Definition indices.h:526
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
Definition protocol.h:55