PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
alarmListener.h
Go to the documentation of this file.
1
16
17#pragma once
18
19#include <asio/io_context.hpp>
20#include <atomic>
21#include <functional>
22#include <mutex>
23#include <optional>
24#include <string>
25#include <thread>
26#include <vector>
27
29#include "profinet/alarms.h"
30#include "profinet/util.h"
31
32namespace profinet
33{
34// NOLINTBEGIN(readability-identifier-naming)
36inline constexpr std::uint16_t FRAME_ID_ALARM_HIGH = 0xFC01;
38inline constexpr std::uint16_t FRAME_ID_ALARM_LOW = 0xFE01;
40inline constexpr std::uint16_t ETHERTYPE_PROFINET = 0x8892;
42inline constexpr std::uint16_t ALARM_UDP_PORT = 34964;
43// NOLINTEND(readability-identifier-naming)
44//
49{
51 std::string interface;
52
54 std::uint16_t controllerRef = 0;
55
57 std::uint16_t deviceRef = 0;
58
61
63 int transport = 0;
64};
65
79{
80 public:
83
95 explicit AlarmListener(asio::io_context& ioContext,
97 std::optional<MacAddress> controllerMac = std::nullopt);
98
100 ~AlarmListener() override;
101
103 AlarmListener(const AlarmListener&) = delete;
104
107
118 void AddAlarmNotificationCallback(std::function<void(const AlarmNotification&)> callback) override;
119
123 void RemoveAlarmNotificationCallback(std::function<void(const AlarmNotification&)> callback) override;
134 void AddRtaAlarmCallback(std::function<void(const RtaError&)> callback) override;
135
139 void RemoveRtaAlarmCallback(std::function<void(const RtaError&)> callback) override;
140
151 void Start(std::unique_ptr<IRawEthernetSocket> eSocket = nullptr,
152 std::unique_ptr<IUdpSocket> uSocket = nullptr) override;
153
156 void Stop() override;
157
160 bool IsRunning() const override
161 {
162 return running;
163 }
164
165 private:
167 void ListenLoop();
168
170 void HandleLayer2Frame();
171
173 void HandleUdpFrame();
174
180 void ProcessAlarm(const Bytes& payload, std::optional<bool> highPriority,
181 std::optional<MacAddress> srcMac, std::optional<UdpEndpoint> udpSource);
182
189 void SendRtaFrame(std::uint8_t pduType,
190 std::uint8_t addFlags,
191 const Bytes& ackData, const MacAddress& dstMac, bool highPriority);
192
197 void SendAck(const AlarmNotification& alarm, std::optional<MacAddress> srcMac, std::optional<UdpEndpoint> udpSource);
198
202 void SendTransportAck(std::optional<MacAddress> srcMac, bool highPriority);
203
207 void SendNack(std::optional<MacAddress> srcMac, bool highPriority);
208
213 void SendLayer2Ack(const Bytes& ackData, const MacAddress& dstMac, bool highPriority);
214
218 void SendUdpAck(const Bytes& ackData, const UdpEndpoint& dstAddr);
219
221 asio::io_context& ioContext;
222
225
228
230 std::atomic<bool> running{false};
231
233 std::jthread thread;
234
236 mutable std::mutex callbacksMutex;
237
244 std::vector<std::function<void(const AlarmNotification&)>> alarmNotificationCallbacks;
245
252 std::vector<std::function<void(const RtaError&)>> rtaAlarmCallbacks;
253
255 std::uint16_t sendSeqNum = 0;
256
258 std::uint16_t recvSeqNum = 0;
259
270 std::unique_ptr<IRawEthernetSocket> l2Sock;
271
277 std::unique_ptr<IUdpSocket> udpSock;
278
280 mutable std::mutex lifecycleMutex;
281};
282
283} // namespace profinet
Interface for PROFINET alarm listeners.
Declares PROFINET alarm, diagnosis, maintenance, and USI payload types and parsers.
Narrow private-access adapter used only by AlarmListener tests.
Background listener for PROFINET alarm notifications.
std::atomic< bool > running
Whether the listener thread should keep running.
asio::io_context & ioContext
Asio execution context used by the Layer-2 socket.
AlarmEndpoint endpoint
Alarm endpoint configuration.
void RemoveAlarmNotificationCallback(std::function< void(const AlarmNotification &)> callback) override
Remove a registered (alarm notification) callback.
void SendNack(std::optional< MacAddress > srcMac, bool highPriority)
Send an RTA-NACK for an out-of-sequence DATA PDU.
void RemoveRtaAlarmCallback(std::function< void(const RtaError &)> callback) override
Remove a registered (rta alarm) callback.
void HandleUdpFrame()
Receive and process one UDP frame.
AlarmListener(const AlarmListener &)=delete
Not copyable (owns a socket and background thread).
~AlarmListener() override
Stop (if running) and release resources.
void Stop() override
Stop the listener.
std::uint16_t recvSeqNum
Last received sequence number, for duplicate detection.
std::unique_ptr< IRawEthernetSocket > l2Sock
Raw Ethernet transport used for Layer 2 alarm reception.
MacAddress controllerMac
This host's MAC address.
std::uint16_t sendSeqNum
Sequence number for outgoing AlarmAck-PDUs.
void HandleLayer2Frame()
Receive and process one Layer 2 (RTA-PDU) frame.
bool IsRunning() const override
Whether the listener thread is currently running.
void AddAlarmNotificationCallback(std::function< void(const AlarmNotification &)> callback) override
Register a callback for received alarms.
void SendAck(const AlarmNotification &alarm, std::optional< MacAddress > srcMac, std::optional< UdpEndpoint > udpSource)
Build and send an AlarmAck-PDU for a received notification.
void ListenLoop()
Listener thread body: dispatches to the Layer 2 or UDP handler.
std::mutex lifecycleMutex
Guards lifecycle steps of listener against concurrent access.
std::jthread thread
Background thread receiving and processing alarms.
std::vector< std::function< void(const RtaError &)> > rtaAlarmCallbacks
Registered callbacks invoked for successfully parsed rta alarms.
void AddRtaAlarmCallback(std::function< void(const RtaError &)> callback) override
Register a callback for received alarms.
void SendTransportAck(std::optional< MacAddress > srcMac, bool highPriority)
Send a pure RTA-ACK (TACK) with empty var part.
void SendLayer2Ack(const Bytes &ackData, const MacAddress &dstMac, bool highPriority)
Send an AlarmAck-PDU over the Layer 2 transport.
void SendRtaFrame(std::uint8_t pduType, std::uint8_t addFlags, const Bytes &ackData, const MacAddress &dstMac, bool highPriority)
Build and send an RTA PDU (Layer 2); returns the frame bytes.
void ProcessAlarm(const Bytes &payload, std::optional< bool > highPriority, std::optional< MacAddress > srcMac, std::optional< UdpEndpoint > udpSource)
Parse an alarm payload and dispatch it to registered callbacks.
std::unique_ptr< IUdpSocket > udpSock
UDP transport used for UDP alarm reception and acknowledgement.
std::vector< std::function< void(const AlarmNotification &)> > alarmNotificationCallbacks
Registered callbacks invoked for successfully parsed alarmsnotifications.
AlarmListener & operator=(const AlarmListener &)=delete
Not copyable (owns a socket and background thread).
void SendUdpAck(const Bytes &ackData, const UdpEndpoint &dstAddr)
Send an AlarmAck-PDU over the UDP transport.
std::mutex callbacksMutex
Protects concurrent access to callbacks.
Abstract interface for receiving PROFINET alarm notifications.
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
Definition util.h:48
constexpr std::uint16_t ALARM_UDP_PORT
UDP port used for alarm transport when Transport == 1.
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
Definition protocol.h:55
constexpr std::uint16_t FRAME_ID_ALARM_HIGH
Frame ID used for high-priority alarms.
constexpr std::uint16_t ETHERTYPE_PROFINET
EtherType used by PROFINET RTA frames (0x8892).
constexpr std::uint16_t FRAME_ID_ALARM_LOW
Frame ID used for low-priority alarms.
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.
Definition alarms.h:356
Decoded PROFINET RTA ERR-PDU.
Definition protocol.h:2571
Portable IPv4 UDP endpoint.
Definition IUdpSocket.h:42
std::uint8_t pduType
RTA PDU type including version nibble.
std::uint8_t addFlags
RTA AdditionalFlags field.
Bytes payload
Definition test_dcp.cpp:392
Declares Linux Ethernet, addressing, timing, and utility helpers used by the PROFINET stack.