PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
PROFINET IO Controller Stack

A C++20 PROFINET IO Controller stack for Linux.

The project provides the building blocks required to discover, configure, connect to, operate and release connections to PROFINET IO-Devices. It is intended as a reusable controller stack rather than as a device-specific application.

The primary focus is protocol correctness, interoperability with real PROFINET devices, deterministic resource management and testability.

The stack currently includes:

  • PROFINET DCP discovery and configuration
  • PROFINET DCE/RPC communication
  • Application Relation (AR) establishment and release
  • Expected submodule configuration
  • IOCR configuration
  • Alarm CR configuration
  • Parameterization lifecycle support
  • Application Ready handling
  • Cyclic RTC1 process-data communication
  • RTA alarm reception and acknowledgement
  • Acyclic implicit read/write operations
  • GSDML XML parsing and device configuration support
  • Diagnosis and topology parsing
  • I&M record access
  • Raw Linux Ethernet transport
  • RPC transport abstractions
  • Asio-based transport infrastructure
  • GoogleTest and GoogleMock based tests
  • Wire-format and conformance-oriented regression tests

Project status: Active development. The main current interoperability objective is reliable, generic AR establishment against real PROFINET IO-Devices, followed by robust cyclic RTC1 communication.


Why This Stack Exists

PROFINET IO communication requires considerably more than sending cyclic Ethernet frames.

A controller must first discover or identify a device, establish its communication endpoint, negotiate an Application Relation, provide the expected device configuration, configure cyclic communication, complete parameterization and transition the device into application operation.

The intended lifecycle is broadly:

Discover device
|
v
Obtain device information
|
v
Resolve PROFINET RPC endpoint
|
v
Establish Application Relation
|
v
IODConnectReq / IODConnectRes
|
v
Parameterization
|
+--> PrmBegin
|
+--> ExpectedSubmodule configuration
|
+--> IOCR configuration
|
+--> Alarm CR configuration
|
+--> PrmEnd
|
v
ApplicationReady
|
v
Start alarm handling
|
v
Start cyclic RTC1 communication
|
v
Read inputs / write outputs
|
v
Release AR

The goal of this repository is to make this lifecycle available through a C++20 implementation with explicit protocol serialization and clear separation between:

  • PROFINET protocol logic
  • device configuration
  • connection lifecycle
  • cyclic communication
  • alarms
  • acyclic communication
  • networking and transport

Architecture Overview

The high-level architecture is:

Application / CLI
|
v
ProfinetDevice
|
+-------------------+-------------------+-------------------+
| | | |
v v v v
DCP RPC / AR Cyclic RTC1 Alarm Handling
| | | |
+-------------------+-------------------+-------------------+
|
v
Transport Abstractions
| |
v v
Raw Ethernet RPC / UDP
| |
v v
Linux AF_PACKET Asio / UDP

GSDML configuration feeds the controller configuration used during AR establishment and cyclic I/O setup.

The architecture is evolving toward using Asio for asynchronous I/O and timeout management, while retaining native Linux packet-socket creation and configuration where AF_PACKET functionality is required.

See:

  • ARCHITECTURE.md

for editable architecture and lifecycle diagrams.


Repository Layout

profinet-io-controller-stack/
├── include/profinet/ Public C++ API
├── src/ Implementations
├── tests/ GoogleTest / GoogleMock tests
│ └── gsdml/ GSDML test data
├── examples/ Example applications
├── tools/ Hardware and development tools
├── scripts/ Repository maintenance and generation scripts
├── documentation/ Documentation configuration
├── .cmakecommon/ Shared CMake helpers
├── .devcontainer/ Development container configuration
├── CMakeLists.txt Main build definition
├── CMakePresets.json Standard build configurations
├── vcpkg.json Dependency manifest
├── .clang-format Formatting configuration
├── .clang-tidy Static analysis configuration
└── README.md Project documentation

The build defines the ProfinetIoController library and example/test executables. The current CMake configuration builds the core stack from DCP, RPC transport, RPC, RT, cyclic, alarms, blocks, diagnosis, device and GSDML implementations.


Main Components

include/profinet/device.h / src/device.cpp

The high-level controller front.

ProfinetDevice is intended to provide application-facing operations for:

  • device discovery
  • connection lifecycle
  • AR ownership
  • acyclic read/write operations
  • I&M access
  • diagnosis access
  • topology and slot discovery
  • alarm integration
  • cyclic communication startup
  • connection cleanup

Typical application code should normally use ProfinetDevice rather than manually coordinating every lower-level component.


include/profinet/dcp.h / src/dcp.cpp

Implements PROFINET DCP communication.

Responsibilities include:

  • device discovery
  • DCP Identify requests and responses
  • station name operations
  • IP configuration
  • DCP Set requests and responses
  • device description parsing
  • filtering unrelated Ethernet traffic
  • transaction handling
  • malformed frame handling

DCP operates over Layer 2 Ethernet.


include/profinet/IRawEthernetSocket.h

Defines the raw Ethernet transport boundary used by Layer-2 protocol components.

This interface is important because it allows:

  • DCP logic to be tested independently of real sockets
  • cyclic communication to use mock transports
  • alarm reception to be tested using deterministic frames
  • production transport implementations to evolve without rewriting protocol logic

The repository also contains mock socket implementations used by protocol and conformance tests.


include/profinet/IRpcTransport.h / src/rpcTransport.cpp

Defines and implements the transport boundary for PROFINET RPC communication.

The direction of the architecture is to isolate:

RPC protocol state
|
v
IRpcTransport
|
v
Asio-based UDP transport

This keeps socket and timeout handling separate from RPC packet construction, response parsing and AR state.


include/profinet/rpc.h / src/rpc.cpp

Contains PROFINET DCE/RPC and AR connection logic.

Responsibilities include:

  • endpoint discovery
  • station information retrieval
  • UUID handling
  • RPC packet construction
  • RPC response parsing
  • session and activity handling
  • IODConnect communication
  • AR establishment
  • parameterization requests
  • ApplicationReady handling
  • AR release and disconnect
  • acyclic record operations

This is one of the most important parts of the stack because correct AR establishment is required before cyclic IO communication can operate against real devices.


include/profinet/IRPCCon.h

Defines the connection operations required by higher-level components.

The interface allows device orchestration and lifecycle tests to use mocked RPC behavior rather than requiring real UDP sockets or devices.


include/profinet/protocol.h

Contains PROFINET protocol structures and constants used across the stack.

This includes wire-level structures for major protocol operations.

Network protocol serialization should remain explicit. Correct C++ object layout must never be assumed to imply correct wire layout.


include/profinet/wire.h

Provides byte-level serialization and parsing helpers.

PROFINET protocol fields are primarily represented in network byte order. This layer centralizes:

  • big-endian integer reads
  • big-endian integer writes
  • buffer handling
  • offset-based parsing support

Explicit byte serialization is preferred over sending C++ structures with memcpy. This will be updated to C++ 20 std::copy and std::bit_cast.


include/profinet/blocks.h / src/blocks.cpp

Implements PROFINET block parsing and serialization.

Responsibilities include parsing and representing block-oriented protocol structures such as:

  • block headers
  • multiple block headers
  • real identification data
  • interface and port data
  • module differences
  • expected submodule configuration
  • write-multiple support

Parser robustness is particularly important here because block length fields and nested structures must always be validated against the remaining input buffer.


include/profinet/rt.h / src/rt.cpp

Contains RT_CLASS_1 cyclic communication structures.

Responsibilities include:

  • RT frame representation
  • IOCR configuration
  • IO data object mapping
  • cyclic frame serialization
  • cyclic frame parsing
  • process-data layout construction
  • IOPS/IOCS handling
  • Ethernet frame construction

IOCR correctness is a primary interoperability concern because incorrect field ordering, offsets or data lengths can cause AR establishment failures.


include/profinet/cyclic.h / src/cyclic.cpp

Implements cyclic RTC1 process-data operation.

Responsibilities include:

  • cyclic lifecycle management
  • transmit scheduling
  • cyclic receive handling
  • input process-data updates
  • output process-data updates
  • IOPS/IOCS processing
  • cycle counters
  • cyclic statistics
  • frame loss, duplicate and ordering detection
  • controlled shutdown

The next major development objective after generic AR establishment is reliable operation of this path against real PROFINET hardware.


include/profinet/alarms.h / src/alarms.cpp

Implements alarm data structures and parsing.

Supported responsibilities include:

  • alarm notification parsing
  • alarm item parsing
  • diagnosis-related alarm information
  • maintenance information
  • USI-based alarm data interpretation

Alarm parsing must remain bounds-checked because notifications may contain nested or variable-length data.


include/profinet/IAlarmListener.h

Defines the alarm listener boundary used by higher-level components.

This allows alarm lifecycle behavior to be tested independently from real Layer-2 traffic.


include/profinet/alarmListener.h / src/alarmListener.cpp

Handles PROFINET alarm reception and acknowledgement.

Responsibilities include:

  • RTA frame reception
  • VLAN-aware frame handling where required
  • alarm notification parsing
  • callback registration
  • AlarmAck generation and transmission
  • listener lifecycle and shutdown

include/profinet/gsdml.h / src/gsdml.cpp

Implements GSDML parsing.

GSDML is now part of the stack and is used to transform PROFINET device descriptions into C++ configuration data.

The intended configuration flow is:

GSDML XML
|
v
Parsed device model
|
v
Selected modules / submodules
|
v
IO configuration
|
+--> ExpectedSubmoduleBlock
|
+--> IOCR configuration
|
+--> cyclic data mapping

A key architectural objective is to avoid maintaining separate, manually duplicated descriptions of module identifiers, submodule identifiers and I/O lengths.


include/profinet/diagnosis.h / src/diagnosis.cpp

Implements diagnosis parsing and interpretation.

Responsibilities include:

  • channel diagnosis parsing
  • extended diagnosis handling
  • qualified diagnosis handling
  • diagnosis block parsing
  • protocol-specific error decoding

include/profinet/indices.h / src/indices.cpp

Contains standardized PROFINET record indices and lookup helpers.

It provides symbolic access to protocol indices and related metadata rather than spreading raw numeric constants throughout application code.


include/profinet/exceptions.h / src/exceptions.cpp

Defines the project's protocol and transport error hierarchy.

Errors should preserve enough context to identify:

  • operation
  • protocol phase
  • block or request type
  • device
  • timeout or socket failure
  • expected versus actual data where relevant

include/profinet/vendors.h / src/vendors.cpp

Provides PROFINET vendor ID lookup.

The vendor table is generated rather than manually maintained.

Vendor map generation

The only remaining Python-related workflow documented by this project is the generation of the PROFINET vendor map.

The generation script reads the authoritative vendor mapping source and produces C++ data for lookup.

For example:

python3 scripts/gen_vendors.py \
/path/to/vendors.py \
include/profinet/vendors_data.h

The generated output should be committed when the vendor table is intentionally updated.

Python is not required to build or use the PROFINET IO Controller stack itself.


Examples

The repository builds several example applications when PROFINET_BUILD_EXAMPLES is enabled:

  • pn_discover
  • pn_set_name
  • pn_read_im0
  • pn_cyclic_demo
  • pn_alarm_demo
  • pn_diagnosis_demo
  • pn_device_demo
  • pn_hw_control

These targets are defined by the current CMake build configuration.


Building

Requirements

The project uses:

  • CMake 3.27 or newer
  • a C++20 compiler
  • vcpkg
  • the dependencies declared in vcpkg.json

The current dependency manifest includes:

  • GoogleTest
  • OpenSSL
  • Asio
  • LibXml2

with Asio pinned through the manifest configuration.

vcpkg

Set VCPKG_ROOT to your vcpkg installation.

For example:

export VCPKG_ROOT=/path/to/vcpkg

The project uses the vcpkg CMake toolchain through CMakePresets.json.

Do not manually duplicate dependency include paths or library paths when using the supplied presets.


CMake Presets

CMakePresets.json is the preferred way to configure the project.

The base preset configures:

  • the vcpkg toolchain
  • C++20
  • output directories
  • install directories
  • vcpkg overlay configuration
  • optional Linux raw-socket capability setup

The current presets include:

MSVC64-v143-Release
MSVC64-v143-Debug
linux-clang-19-release
linux-clang-19-debug
linux-clang-19-debug-coverage

The Linux presets use Ninja and Clang 19, while the coverage preset enables the repository's coverage configuration.

Linux Debug build

cmake --preset linux-clang-19-debug
cmake --build --preset linux-clang-19-debug
ctest --preset linux-clang-19-debug --output-on-failure

Linux Release build

cmake --preset linux-clang-19-release
cmake --build --preset linux-clang-19-release
ctest --preset linux-clang-19-release --output-on-failure

Coverage build

cmake --preset linux-clang-19-debug-coverage
cmake --build --preset linux-clang-19-debug-coverage
ctest --preset linux-clang-19-debug-coverage --output-on-failure

Raw Ethernet Permissions

Layer-2 PROFINET operations use Linux raw Ethernet capabilities.

Depending on the configured environment, raw socket operations may require:

CAP_NET_RAW

The CMake build contains optional setcap support for test executables when ENABLE_SETCAP is enabled and passwordless access to setcap is available.

Avoid running the entire development environment as root when Linux capabilities provide the required access.


Usage Examples

Discover devices

#include "profinet/dcp.h"
const auto localMac = profinet::GetMac("eth0");
// Create the configured raw Ethernet socket implementation.
profinet::EthernetSocket socket("eth0");
profinet::dcp::SendDiscover(socket, localMac);
const auto responses = profinet::dcp::ReadResponse(socket, localMac, 5);
for (const auto& response : responses)
{
// Process discovered devices.
}
A minimal RAII wrapper around a Linux AF_PACKET raw socket bound to an interface.
Definition util.h:196
PROFINET DCP discovery and device configuration interface.
void SendDiscover(const EthernetSocket &sock, const MacAddress &src, std::uint16_t responseDelay=DEFAULT_RESPONSE_DELAY_FACTOR)
Send a DCP Identify multicast request to discover all devices on the segment.
Definition dcp.cpp:1094
ResponseMap ReadResponse(const EthernetSocket &sock, const MacAddress &myMac, int timeoutSec=DEFAULT_RESPONSE_TIMEOUT, bool once=false, std::optional< std::uint32_t > expectedXid=std::nullopt)
Read and parse DCP Identify responses.
Definition dcp.cpp:1139
MacAddress GetMac(const std::string &ifname)
Get the MAC address of a network interface.
Definition util.cpp:267

The exact returned types and available fields should be taken from the current public header.


High-level device usage

ProfinetDevice is intended to provide the high-level application-facing API.

Conceptually:

auto device = profinet::device::ProfinetDevice::Discover("my-device", "eth0");
device.Connect();
// Perform supported acyclic operations.
// Read device information.
// Configure cyclic I/O.
device.Close();
static ProfinetDevice Discover(const std::string &identifier, const std::string &interface, double timeoutSec=10.0)
Discover a device by station name or MAC address.
Definition device.cpp:231
High-level PROFINET device interface and device lifecycle management.

The public API uses CamelCase naming. New examples and documentation should use the names currently defined in the C++ headers rather than historical snake_case names.


Acyclic record access

Acyclic communication is performed after the device connection and AR state allow the requested operation.

Conceptually:

device.Connect();
const auto value = device.Read(/* API */, /* slot */, /* subslot */, /* index */);
// Or write a record:
device.Write(/* API */, /* slot */, /* subslot */, /* index */, data);
device.Close();

For production code, the API, slot, subslot and record index should originate from device configuration or explicit application configuration rather than unexplained literals.


GSDML-driven configuration

The intended usage model is:

Load GSDML
|
v
Parse device/module/submodule definitions
|
v
Select the configuration required by the application
|
v
Build controller I/O configuration
|
v
Use configuration for AR / ExpectedSubmodule / IOCR

This is preferable to manually duplicating module and submodule identifiers and I/O lengths throughout application code.


Cyclic IO

The intended cyclic flow is:

Application updates output process data
|
v
CyclicController
|
v
RTC1 Ethernet frame
|
v
PROFINET IO-Device
PROFINET IO-Device
|
v
RTC1 Ethernet frame
|
v
CyclicController
|
v
Application reads input process data

or more linear:

Cyclic communication should only start after the AR and required parameterization/application-ready lifecycle have completed successfully.


Testing

The repository uses GoogleTest and GoogleMock.

The test target includes coverage across:

  • utilities
  • protocol serialization
  • vendor lookup
  • RPC transport
  • RPC behavior
  • RT frames
  • cyclic communication
  • cyclic conformance behavior
  • received IOPS handling
  • alarms
  • alarm listener behavior
  • DCP wire format
  • DCP behavior
  • RPC conformance
  • protocol blocks
  • diagnosis
  • device wrappers
  • device cyclic startup lifecycle
  • GSDML parsing
  • real-device-oriented GSDML data
  • exception handling

The current CMake target lists these tests explicitly.

Testing principles

For PROFINET protocol code:

  1. Exact bytes matter.
  2. A test should verify complete serialized output for critical protocol blocks.
  3. Parsers should be tested with malformed and truncated input.
  4. Every protocol fix should add a regression test.
  5. Lifecycle tests should verify rollback after partial startup failure.
  6. Mock transports should verify complete transmitted frames where practical.
  7. Real-device captures should be used as references when available (we currently only have Auma, sort of).

Important regression validation candidates include:

  • DCP Identify
  • DCP Set
  • ExpectedSubmoduleBlockReq
  • IOCRBlockReq
  • AlarmCRBlockReq
  • IODConnectReq
  • PrmBegin
  • PrmEnd
  • ApplicationReady
  • AlarmAck
  • RTC1 cyclic frames
  • implicit read/write requests and responses

File Header Script

The repository contains:

scripts/add_file_headers.py

This script adds Doxygen-compatible headers to C++ source and header files.

It scans recursively for:

.cpp
.h

files and adds:

when a compatible file header is not already present.

Usage:

python3 scripts/add_file_headers.py .

Or target a specific directory:

python3 scripts/add_file_headers.py include/profinet

Use --force to replace an existing compatible @file / @brief header:

python3 scripts/add_file_headers.py include/profinet --force

The script deliberately avoids silently adding a second header when a file already starts with a different @file declaration.


Architecture Diagrams

The diagrams provide:

  • component architecture
  • transport boundaries
  • GSDML configuration flow
  • planned Asio transport direction
  • complete happy-path lifecycle from discovery through AR release

See:

ARCHITECTURE

The lifecycle sequence covers:

Discover
|
v
DCP Identify
|
v
Device information
|
v
Endpoint resolution
|
v
IODConnectReq
|
v
IODConnectRes
|
v
PrmBegin
|
v
ExpectedSubmodule / IOCR / Alarm CR
|
v
PrmEnd
|
v
ApplicationReady
|
v
Start alarms
|
v
Start cyclic RTC1
|
v
Cyclic operation
|
v
Stop cyclic operation
|
v
Stop alarms
|
v
Release AR

Glossary

The following table explains the abbreviations and protocol terminology used throughout the project and its implementation.

Abbreviation / Term Meaning Explanation in this project
AF_PACKET Linux Address Family, Packet Linux socket family used for direct Layer-2 Ethernet frame access. Used by the raw Ethernet transport for DCP, RTC1 and RTA traffic.
ALARM CR / AlarmCR Alarm Communication Relation PROFINET communication relation used for alarm transport between an IO Controller and IO Device. The project establishes an AlarmCRBlockReq during AR setup and uses it for alarm notifications and acknowledgements.
API Application Process Identifier PROFINET identifier used to associate protocol objects and IO configuration data with an application process. The project currently uses API 0 for the standard application process and carries API values in ExpectedSubmodule and IOCR structures.
AR Application Relation Logical PROFINET connection between an IO Controller and IO Device. The AR is established using DCE/RPC and contains the configured communication relations such as IOCRs and AlarmCR.
ARBlock Application Relation Block Block used during AR establishment/release to describe or control an Application Relation. The project handles AR-related request/response blocks through the RPC layer.
ARUUID Application Relation UUID UUID uniquely identifying an Application Relation. Generated by the controller when establishing a connection to an IO Device.
Asio Asynchronous I/O library Standalone C++ Asio library used/planned for asynchronous networking and event-driven socket handling. The project is moving toward using Asio for transport integration while retaining Linux-specific raw-socket functionality where required.
Acyclic IO Non-cyclic IO communication Communication that does not occur at the cyclic RTC interval. Used for configuration, diagnostics, identification and record read/write operations.
Acyclic record Acyclic record data PROFINET record identified by API, slot, subslot and index. The project exposes operations such as Read, ReadImplicit and Write for record data.
AR Application Relation The complete logical connection between controller and device, including parameterization and communication relations.
C_SDU Common Service Data Unit Service-data portion carried by a communication service. In PROFINET RPC terminology this represents application/service data passed through the RPC protocol structures.
Cyclic IO Cyclic Input/Output Periodic exchange of process data between an IO Controller and IO Device. In this project it is implemented using PROFINET RTC1 Ethernet frames and CyclicController.
CR Communication Relation Logical communication channel within a PROFINET Application Relation. An AR may contain multiple CRs, for example IOCRs and an AlarmCR.
DCP Discovery and Configuration Protocol PROFINET Layer-2 protocol used for device discovery and basic configuration. The project uses DCP Identify to discover devices and DCP Set to configure station names and related information.
DCE Distributed Computing Environment RPC framework/protocol family on which PROFINET's connection-management RPC communication is based.
DCE/RPC Distributed Computing Environment / Remote Procedure Call RPC protocol used by PROFINET for connection establishment, parameterization, record access and Application Relation management. The project implements the required DCE/RPC structures and transport.
DAP Device Access Point Special GSDML-defined module representing the device access point. Typically occupies slot 0 and provides the device-level entry point into the IO configuration.
DI Data Interface Generic term for an interface carrying data. In this project the term is primarily relevant when discussing protocol/data-layout interfaces rather than as a dedicated PROFINET protocol object.
EPM Endpoint Mapper DCE/RPC Endpoint Mapper. Used to resolve the RPC endpoint/interface information required to communicate with the PROFINET IO Device. The project defines the EPM interface UUID and lookup operations.
EtherType Ethernet Type field Ethernet header field identifying the payload protocol. PROFINET RT/RTA uses EtherType 0x8892; the project preserves and validates this field in raw Ethernet frames.
GSD General Station Description Generic term for the device description mechanism used by PROFINET. Modern PROFINET device descriptions are represented using GSDML.
GSDML General Station Description Markup Language XML-based format used to describe a PROFINET device, including modules, submodules, IO sizes, identities and configuration capabilities. The project contains a native C++ GSDML parser.
I&M Identification & Maintenance PROFINET identification and maintenance data. The project supports reading I&M records, including I&M0 and additional I&M records where supported by the device.
I&M0 Identification & Maintenance record 0 Mandatory basic identification record containing device identification information.
I&M1 Identification & Maintenance record 1 Identification/maintenance record containing tag-function and location information.
I&M2 Identification & Maintenance record 2 Identification/maintenance record containing installation-date information.
I&M3 Identification & Maintenance record 3 Identification/maintenance record containing descriptive/free-text information.
I&M4 Identification & Maintenance record 4 Identification/maintenance record associated with PROFIsafe-related information.
I&M5–I&M15 Identification & Maintenance records 5–15 Additional/reserved identification and maintenance records. The project models and can probe/read these records where supported.
IOD IO Device PROFINET IO Device. The term appears in protocol block names such as IODControl, IODConnect and IODRelease.
IODConnect IO Device Connect DCE/RPC operation used to establish the PROFINET Application Relation and its associated communication relations.
IODControl IO Device Control PROFINET control operations used during AR lifecycle transitions such as PrmBegin, PrmEnd, ApplicationReady and release.
IODRelease IO Device Release Operation used to release an established Application Relation.
IO Input/Output Process input/output data exchanged between the IO Controller and IO Device.
IOCR Input/Output Communication Relation Communication Relation responsible for cyclic IO data exchange. A typical AR contains an input IOCR and an output IOCR.
IOCRBlockReq IOCR Block Request PROFINET request block used to configure an IOCR during AR establishment. It contains the IOCR properties, frame ID, timing parameters and IO data object layout.
IOCRBlockRes IOCR Block Response Response to an IOCRBlockReq.
IOCS Input/Output Consumer Status Status byte associated with IO data consumed by the receiving side. It indicates whether the consumer considers the associated IO data valid.
IOPS Input/Output Provider Status Status byte associated with IO data provided by the sending side. The project uses IOPS to determine whether received process data is valid before exposing it to the application.
IODataObject IO Data Object Description of an individual process-data element inside an IOCR. It identifies its slot/subslot, data length and offsets for process data and IOxS bytes.
IOxS IO Provider/Consumer Status Generic notation for either IOPS or IOCS. x represents the provider/consumer role.
IP Internet Protocol Network-layer protocol used by the UDP transport for DCE/RPC and other IP-based communication.
IPv4 Internet Protocol version 4 IP version used by the project's UDP/RPC communication.
MAC Media Access Control Ethernet hardware address. The project uses source and destination MAC addresses for DCP, RTC1 and RTA Layer-2 communication.
PDU Protocol Data Unit A protocol-specific unit of transmitted data. The project uses the term for DCE/RPC, RTA and other protocol payloads.
PNIO PROFINET IO PROFINET IO protocol/application layer. The project uses PNIO in protocol status/error handling, interface identifiers and RPC structures.
PNIO-CM PROFINET IO Connection Manager PROFINET connection-management error/diagnostic domain used in PNIO error decoding.
PNIORW PROFINET IO Read/Write PROFINET IO read/write service domain used when decoding record-access errors.
PrmBegin Parameterization Begin AR lifecycle operation indicating the beginning of the parameterization phase.
PrmEnd Parameterization End AR lifecycle operation indicating that parameterization is complete and the controller is moving toward runtime operation.
PROFINET Process Field Network Industrial Ethernet communication technology standardized and maintained by PROFIBUS & PROFINET International (PI).
PROFINET IO PROFINET Input/Output PROFINET system architecture for cyclic process data, acyclic records, alarms and device configuration.
RTA Real-Time Acyclic PROFINET real-time alarm/acyclic communication carried directly over Ethernet Layer 2. The project implements RTA alarm notification and AlarmAck handling.
RTA-PDU Real-Time Acyclic Protocol Data Unit Protocol data unit carrying PROFINET RTA traffic, particularly alarms, over Ethernet.
RTC Real-Time Cyclic PROFINET terminology for cyclic real-time communication.
RTC1 Real-Time Cyclic Class 1 Standard software-based cyclic PROFINET real-time communication. The project uses RTC1 Ethernet frames for cyclic IO.
RTC2 Real-Time Cyclic Class 2 Higher-performance real-time cyclic communication class with more deterministic timing requirements than RTC1. It is not currently the project's primary cyclic transport.
RTC3 Real-Time Cyclic Class 3 Isochronous/highly deterministic real-time communication class associated with advanced PROFINET real-time operation. It is outside the current RTC1 implementation scope.
RT Real-Time Generic abbreviation used throughout the cyclic implementation for PROFINET real-time communication.
RT frame Real-Time frame Ethernet frame carrying PROFINET cyclic real-time process data. In this project, this normally refers to an RTC1 frame containing IO data and IOxS status bytes.
RT_CLASS_1 Real-Time Class 1 Software-based PROFINET real-time communication class used by the project's CyclicController.
RT_CLASS_2 Real-Time Class 2 PROFINET real-time communication class with stronger timing characteristics than RT_CLASS_1.
RT_CLASS_3 Real-Time Class 3 PROFINET real-time communication class used for highly deterministic/isochronous communication.
RPC Remote Procedure Call Communication mechanism allowing the controller to invoke PROFINET device services remotely. The project uses DCE/RPC for AR establishment, parameterization and acyclic services.
RPCCon RPC Connection Project-specific class representing the DCE/RPC connection to a PROFINET IO Device. It manages RPC operations and the AR lifecycle.
RPC_PORT PROFINET RPC UDP port UDP port 34964 (0x8894) used for PROFINET DCE/RPC communication by the project.
RPC_BIND_PORT RPC local bind port UDP port 34965 (0x8895) defined for the local RPC bind side.
RT_CLASS_1 Real-Time Class 1 PROFINET cyclic communication using standard Ethernet networking without the special hardware scheduling requirements of higher real-time classes.
SDU Service Data Unit Data supplied by a higher protocol/service layer to a lower protocol layer for transmission. C_SDU is used in the DCE/RPC/protocol context.
Subslot PROFINET subslot Addressable logical IO component inside a slot. A subslot can contain input data, output data, both, or no process data.
Slot PROFINET slot Logical position in an IO Device's modular configuration. The project models slot/subslot/module/submodule relationships and derives IO configuration from them.
ModuleIdentNumber Module Identification Number Numeric identifier describing the expected module at a slot. Supplied by GSDML/device configuration and encoded into the ExpectedSubmodule configuration.
SubmoduleIdentNumber Submodule Identification Number Numeric identifier describing the expected submodule within a slot.
ExpectedSubmodule Expected Submodule configuration PROFINET configuration structure describing which module/submodule the controller expects at a slot/subslot. Used during AR establishment.
ExpectedSubmoduleBlock Expected Submodule Block Block sent during parameterization to tell the IO Device which modules and submodules the controller expects to be present.
VLAN Virtual Local Area Network Ethernet frame tagging mechanism defined by IEEE 802.1Q. The raw Ethernet implementation can receive and process VLAN-tagged PROFINET frames.
VID VLAN Identifier Identifier contained in an IEEE 802.1Q VLAN tag.
PCP Priority Code Point IEEE 802.1Q VLAN priority field. Relevant when analysing VLAN-tagged PROFINET Ethernet frames.
TPID Tag Protocol Identifier Ethernet VLAN tag identifier. Commonly 0x8100 for IEEE 802.1Q VLAN tagging.
UUID Universally Unique Identifier 128-bit identifier used by DCE/RPC and PROFINET to identify interfaces and Application Relations.
EPM UUID Endpoint Mapper UUID UUID identifying the DCE/RPC Endpoint Mapper interface.
PNIO Device UUID PROFINET IO Device interface UUID DCE/RPC interface UUID identifying the PROFINET IO Device service.
PNIO Controller UUID PROFINET IO Controller interface UUID DCE/RPC interface UUID identifying the PROFINET IO Controller service.
USI User Structure Identifier Identifier describing the structure/format of diagnostic or alarm data following a diagnosis header. The project uses USI values such as channel diagnosis, extended channel diagnosis and qualified channel diagnosis.
Channel Diagnosis Channel-level diagnostic data PROFINET diagnosis describing a problem associated with a particular channel. The project identifies this using USI 0x8000.
ExtChannelDiagnosis Extended Channel Diagnosis Extended channel diagnostic information. The project identifies this using USI 0x8002.
QualifiedChannelDiagnosis Qualified Channel Diagnosis Qualified form of channel diagnosis. The project identifies this using USI 0x8003.
MultipleDiagnosis Multiple Diagnosis Diagnostic structure used when multiple diagnosis items are represented. The project identifies this using USI 0x8001.
PNIO Error PROFINET IO error Four-byte PROFINET status/error representation used by the RPC and record-access implementation. The project decodes PNIO-CM, PNIORW and related error domains.
ErrorCode Error Code First component of a PNIO error/status representation identifying the broad error source.
ErrorDecode Error Decode PNIO error field identifying how the remaining error fields should be interpreted.
ErrorCode1 Error Code 1 First detailed PNIO error-code component.
ErrorCode2 Error Code 2 Second detailed PNIO error-code component.
AlarmAck Alarm Acknowledgement PROFINET response acknowledging receipt/handling of an alarm notification. The project's AlarmListener generates and transmits AlarmAck messages.
AlarmNotification Alarm Notification PROFINET alarm message sent by an IO Device to the IO Controller. The project receives and parses these in AlarmListener.
AlarmCR Alarm Communication Relation Communication relation used to transport alarms between controller and device.
AR release Application Relation release Shutdown sequence in which cyclic IO and alarms are stopped and the Application Relation is released.
DataStatus IO Data Status Status information associated with cyclic IO data, indicating validity and related state information.
IOPS status IO Provider Status Provider-side validity indication for an IO data object. The project uses it to decide whether received input data may be consumed by the application.
IOCS status IO Consumer Status Consumer-side status indication associated with an IO data object.
Frame ID Ethernet Frame Identifier Identifier assigned to a PROFINET IOCR and used to associate cyclic Ethernet frames with the configured communication relation.
SendClockFactor Send Clock Factor PROFINET cyclic timing parameter defining the base timing relationship for cyclic communication.
ReductionRatio Reduction Ratio PROFINET cyclic timing parameter controlling how often an IOCR is transmitted relative to the configured send clock.
WatchdogFactor Watchdog Factor Parameter defining the tolerance for missed cyclic frames before the communication is considered timed out.
DataHoldFactor Data Hold Factor Parameter controlling how long previously valid process data may be retained following a communication interruption.
RTC data Real-Time Cyclic data Process data carried by RTC frames.
Ethernet Ethernet LAN technology Layer-2 networking technology used directly by DCP, RTC1 and RTA in this project.
UDP User Datagram Protocol Transport-layer protocol used for DCE/RPC and IP-based PROFINET services.
TCP Transmission Control Protocol General IP transport protocol. It is not the primary transport used by the PROFINET RPC implementation.
IP Internet Protocol Network-layer protocol used by UDP-based communication.
Layer 2 / L2 OSI Data Link Layer Ethernet frame layer. DCP, RTC1 and RTA can operate directly at this layer.
Layer 3 / L3 OSI Network Layer IP networking layer. Used by the UDP/IP transport for RPC-related communication.
AF_PACKET Linux packet socket family Linux-specific mechanism allowing applications to send and receive Ethernet frames without going through normal TCP/IP sockets.
CI Continuous Integration Automated build, test, static-analysis and coverage workflows used by the repository.
ASan AddressSanitizer Runtime instrumentation used to detect memory errors such as buffer overflows and use-after-free.
UBSan UndefinedBehaviorSanitizer Runtime instrumentation used to detect undefined C++ behaviour.
TSan ThreadSanitizer Runtime instrumentation used to detect data races and other threading errors.
CMakePresets CMake Presets Standardized CMake configuration mechanism used by the project to provide reproducible build configurations.
vcpkg Microsoft C++ package manager Dependency manager used by the project for third-party C++ dependencies.
XML Extensible Markup Language Markup language used by GSDML device description files.
Doxygen Documentation generator Tool used to generate API documentation from the project's C++/Doxygen comments.
CLI Command-Line Interface Command-line application interface. A project-specific CLI suitable for device discovery/configuration/control is currently under development.
RAII Resource Acquisition Is Initialization C++ resource-management idiom used throughout the project for sockets, threads and other owned resources.
PDU Protocol Data Unit Encapsulated unit of data belonging to a particular protocol layer. Used throughout the RPC, alarm and real-time protocol implementations.
SDU Service Data Unit Data passed between adjacent protocol layers before protocol-specific encapsulation.
L2 Layer 2 OSI Data Link Layer, corresponding to Ethernet framing in this project.
L3 Layer 3 OSI Network Layer, corresponding to IP communication.
I/O Input/Output Generic term for process data flowing between controller and device.
HW Hardware Used in names such as hardware-check/cyclic test tools for tests requiring a physical PROFINET device.
SW Software Generic abbreviation used when distinguishing software behaviour from hardware behaviour.
TX Transmit Direction in which the controller sends a frame or packet. The cyclic controller contains a TX path for output frames.
RX Receive Direction in which the controller receives a frame or packet. The cyclic controller contains an RX path for input frames.
Src MAC Source MAC Address Ethernet address of the frame sender.
Dst MAC Destination MAC Address Ethernet address of the intended Ethernet frame recipient.
MTU Maximum Transmission Unit Maximum payload size supported by a network interface without fragmentation at the relevant layer. Relevant when constructing Ethernet/IP frames.
NIC Network Interface Controller Network interface used by the controller to transmit/receive PROFINET Ethernet frames.
FD File Descriptor Linux integer handle representing an open socket or other kernel resource. The networking implementation uses socket FDs and is planned to integrate them with Asio descriptors.
I&M Identification & Maintenance PROFINET device identification and maintenance records.
RPC activity UUID RPC Activity Universally Unique Identifier UUID identifying an RPC activity/request context. Used in DCE/RPC request/response processing.
Session Key RPC session key PROFINET RPC connection/session value associated with the established Application Relation.
XID Transaction Identifier Identifier used to correlate DCP requests and responses. The DCP implementation uses transaction/request identifiers when filtering received frames.
API Application Process Identifier PROFINET application-process identifier used when addressing configuration and record data.
Slot/Subslot PROFINET address Combined logical address identifying a module/submodule within an IO Device.
IOCR reference IOCR identifier/reference Controller-selected reference identifying an IOCR within the Application Relation.
IOCR type IOCR direction/type Identifies whether an IOCR carries input or output process data.
Input CR Input Communication Relation IOCR carrying data from the IO Device to the IO Controller.
Output CR Output Communication Relation IOCR carrying data from the IO Controller to the IO Device.
DAP Device Access Point Device-level module normally associated with slot 0.
NO_IO No Input/Output Project terminology for a submodule that does not carry process input or output data. Such submodules still participate in expected configuration but do not contribute cyclic process data.
I/O Data Description IO data description Structure describing the length and status information associated with a submodule's process data.
Record Index Record data index 16-bit identifier selecting a particular acyclic record associated with a slot/subslot.
ReadImplicit Implicit record read Project API for reading a record using the implicit addressing/context defined by the PROFINET service.
PNRD PROFINET Record Data Project terminology/type used for PROFINET record-data responses exchanged through RPC.
CM Connection Manager Connection-management part of PROFINET IO, particularly visible in PNIO-CM error/status handling.
RMPM RPC/PROFINET parameter-management error domain Error-code grouping used by the project for connection/parameter-management failures such as missing IOCR blocks or incorrect AlarmCR configuration.
EPM Lookup Endpoint Mapper Lookup DCE/RPC operation used to resolve the endpoint associated with a requested interface.
RT timeout Real-Time timeout Condition in which expected cyclic real-time frames are not received within the configured watchdog tolerance.
IO watchdog IO communication watchdog Cyclic communication supervision mechanism detecting missing or stale RTC frames.
Wire format On-the-wire representation Exact byte-level representation transmitted over Ethernet/IP. The project contains wire-format regression tests for protocol structures and captured device traffic.
Wire-format regression test Exact protocol serialization regression test Test verifying that serialization/parsing remains compatible with previously validated packet representations or device captures.
DCP Identify DCP Identify request/response Layer-2 discovery mechanism used by the controller to find PROFINET devices.
DCP Set DCP Set request/response Layer-2 configuration operation used to set device properties such as station name.
RTC1 frame Real-Time Cyclic Class 1 Ethernet frame Ethernet frame containing cyclic process data exchanged at the configured cycle time.
RTA frame Real-Time Acyclic Ethernet frame Ethernet frame carrying PROFINET alarm/acyclic real-time information.
Alarm Data Alarm payload Application-specific data contained inside a PROFINET alarm notification.
Alarm Type Alarm classification PROFINET value identifying the type/category of an alarm.
Alarm Priority Alarm priority Priority associated with a PROFINET alarm and its communication relation.
Local Alarm Reference Controller-side alarm reference Reference used by the controller to identify its local AlarmCR endpoint.
MaxAlarmDataLength Maximum Alarm Data Length Maximum alarm payload size negotiated/configured for the AlarmCR.
RT Timeout Factor Real-Time Timeout Factor AlarmCR/real-time supervision parameter controlling timeout behaviour.
GSDML Module GSDML-described module Configurable device module defined in a GSDML file.
GSDML Submodule GSDML-described submodule Configurable device submodule defined in a GSDML file, including its IO data properties.
IO layout Cyclic IO memory/frame layout Calculated arrangement of process data, IOPS and IOCS bytes inside an IOCR frame. The project is working toward making one resolved IO layout authoritative for RPC configuration and runtime cyclic IO.
IOPS offset IO Provider Status offset Byte offset where an IODataObject's IOPS status is placed in the cyclic frame.
IOCS offset IO Consumer Status offset Byte offset where an IODataObject's IOCS status is placed in the cyclic frame.
Frame offset IO data frame offset Byte position of an IODataObject's process data within the cyclic Ethernet frame.
AR lifecycle Application Relation lifecycle Sequence of establishing, parameterizing, activating, operating and releasing an AR.
ApplicationReady Application Ready AR lifecycle transition indicating that the controller has completed parameterization and is ready for cyclic IO operation.
Prm Parameterization Abbreviation used in protocol block names such as PrmBegin and PrmEnd.
Req Request Suffix used for request protocol blocks, e.g. IOCRBlockReq.
Res Response Suffix used for response protocol blocks, e.g. IOCRBlockRes.
CR block Communication Relation block Protocol block configuring a particular Communication Relation during AR establishment.
BlockReq Block Request Protocol structure sent by the controller to request/configure a particular PROFINET service or relation.
BlockRes Block Response Protocol structure returned by the device in response to a block request.
UDP/IP User Datagram Protocol over Internet Protocol Network stack used for IP-based PROFINET RPC communication.
L2 Ethernet Layer-2 Ethernet Direct Ethernet communication without IP. Used by DCP and RTC/RTA traffic.
Endpoint RPC communication endpoint Network endpoint resolved/used by DCE/RPC to reach a specific PROFINET service.
Controller IO Controller PROFINET station responsible for configuring an IO Device and exchanging cyclic process data. This project implements the controller side.
IO Device / IO-Device Input/Output Device PROFINET station that provides/consumes process data and exposes configuration, diagnostic and acyclic services.
Provider IO data provider Station providing a particular IO data object. Its validity is represented by IOPS.
Consumer IO data consumer Station consuming a particular IO data object. Its status is represented by IOCS.
RTC cycle Real-Time Cyclic cycle Repeating time interval at which cyclic IO frames are transmitted and received.
Cycle counter Cyclic sequence counter Counter used by cyclic IO processing to detect duplicate, stale or out-of-order frames.
RT class Real-Time class PROFINET classification describing the real-time communication mechanism and timing requirements.
IRawEthernetSocket Raw Ethernet socket interface Project abstraction around Layer-2 Ethernet transmission/reception, allowing protocol components to be tested independently of the Linux socket implementation.
RpcTransport RPC transport abstraction Project abstraction separating DCE/RPC protocol handling from the underlying UDP transport.
RAII Resource Acquisition Is Initialization C++ ownership pattern used for deterministic resource lifetime, including sockets and threads.
CI Continuous Integration Automated build/test pipeline used to validate changes.
CLI Command-Line Interface Planned user-facing command-line interface for discovery and device operations.
XML Extensible Markup Language Underlying markup format of GSDML files.
POSIX Portable Operating System Interface Operating-system API family used by the Linux networking implementation, including socket/file-descriptor functionality.
Linux Linux operating system Current target operating system for the native raw-Ethernet and networking implementation.
ISO International Organization for Standardization Standards organization referenced by the broader industrial communication standards context.
IEC International Electrotechnical Commission Standards organization responsible for relevant international electrotechnical standards, including the IEC 61158 family covering fieldbus/industrial communication technologies.
PI PROFIBUS & PROFINET International Organization responsible for the PROFINET technology ecosystem, specifications, profiles and certification framework.
IEC 61158 IEC Industrial Communication Networks standard family International standards family containing specifications relevant to PROFINET and related industrial communication technologies.
IEEE Institute of Electrical and Electronics Engineers Standards organization responsible for Ethernet and VLAN standards used by the underlying network.
IEEE 802.1Q IEEE VLAN standard Ethernet VLAN tagging standard relevant to VLAN-tagged PROFINET frames.
IRQ Interrupt Request Hardware/software interrupt mechanism. Not part of the project's normal PROFINET protocol model, but relevant when discussing network-driver and real-time behaviour.
RTT Round-Trip Time Time between transmitting a request and receiving its response. Useful for analysing RPC communication and timeout behaviour.
Jitter Timing variation Variation in actual cyclic frame timing relative to the configured cycle. Important when evaluating RTC1 scheduling.
Watchdog Communication watchdog Mechanism that detects missing cyclic communication and moves the controller/device state toward a fault condition.
TX Transmit Sending a network frame.
RX Receive Receiving a network frame.
IOCR DataLength IOCR cyclic data length Total data length represented by an IOCR, including the configured process-data/status layout required by the protocol.
Data Description Process-data description Description of a submodule's input/output data and associated status lengths within an ExpectedSubmodule structure.
Module Properties Module configuration properties Encoded PROFINET properties describing module/submodule behaviour.
Submodule Properties Submodule configuration properties Encoded PROFINET properties describing IO direction and related submodule behaviour.
NO-IO No process IO Submodule configuration with no cyclic input/output process data.
Input Device → Controller process data Cyclic process data generated by the IO Device and consumed by the IO Controller.
Output Controller → Device process data Cyclic process data generated by the IO Controller and consumed by the IO Device.
Provider Status IOPS Status associated with the station providing an IO data object.
Consumer Status IOCS Status associated with the station consuming an IO data object.

Abbreviations used in protocol block names

The project uses a number of compact suffixes and protocol naming conventions:

Abbreviation Meaning Example
Req Request IOCRBlockReq
Res Response IOCRBlockRes
AR Application Relation ARBlockReq
CR Communication Relation AlarmCRBlockReq
IOCR Input/Output Communication Relation IOCRBlockReq
IOD IO Device IODControlReqPrmEnd
Prm Parameterization PrmBegin, PrmEnd
App Application IODControlReqAppReady
RT Real-Time RTClass3
RTA Real-Time Acyclic RTA alarm PDU
IOPS IO Provider Status Cyclic input/output status
IOCS IO Consumer Status Cyclic input/output status
PNIO PROFINET IO PNIO status/error
EPM Endpoint Mapper DCE/RPC endpoint lookup
RPC Remote Procedure Call RPCCon, RpcTransport
DCP Discovery and Configuration Protocol DCP Identify
UUID Universally Unique Identifier AR UUID / interface UUID
USI User Structure Identifier Diagnostic/alarm structure identifier
I&M Identification & Maintenance I&M0, I&M1, etc.
MAC Media Access Control address Source/destination Ethernet address
UDP User Datagram Protocol RPC transport
IP Internet Protocol UDP/IP transport
VLAN Virtual Local Area Network Tagged Ethernet frames
PDU Protocol Data Unit RPC/RTA protocol unit
SDU Service Data Unit Service-layer data
TX Transmit Cyclic TX path
RX Receive Cyclic RX path
HW Hardware Hardware test utilities
CLI Command-Line Interface Planned controller CLI
CI Continuous Integration GitHub Actions
GTest GoogleTest Unit-test framework
GMock GoogleMock Mocking framework
Asio Asynchronous I/O library Planned/common asynchronous transport infrastructure

PROFINET communication classes

Term Meaning Project relevance
RT_CLASS_1 / RTC1 Real-Time Class 1 Primary cyclic IO mechanism currently implemented by CyclicController.
RT_CLASS_2 / RTC2 Real-Time Class 2 Higher real-time class; not the current primary implementation target.
RT_CLASS_3 / RTC3 Real-Time Class 3 Highly deterministic/isochronous real-time class. The protocol layer contains support for related control operations, but the current cyclic runtime is focused on RTC1.
RT frame Real-Time Ethernet frame Frame carrying cyclic process data.
RTA frame Real-Time Acyclic frame Frame carrying alarms and related real-time acyclic data.
Acyclic record Non-cyclic record service Used for configuration, diagnostics, I&M and device-specific data.
Cyclic IO Periodic process-data exchange Implemented using RTC1 frames.

Project-specific naming

A few names in the code are project types or identifiers rather than standards abbreviations:

Name Meaning
RPCCon Project class representing a PROFINET DCE/RPC connection and AR lifecycle.
RpcTransport Transport abstraction used by the RPC implementation.
CyclicController Runtime component responsible for cyclic RTC1 TX/RX processing.
CyclicDataBuilder Component constructing and updating cyclic IO frame data.
IODataObject Runtime description of a cyclic IO data object and its frame offsets/status bytes.
IOCRSetup Project configuration describing the IOCR/cyclic configuration before connection.
IOSlot Project representation of a configured PROFINET slot/subslot and its IO properties.
GsdmlDevice Project representation/parser for a GSDML-described device.
AlarmListener Background component receiving, parsing and acknowledging PROFINET alarms.
IRawEthernetSocket Testable abstraction for raw Layer-2 Ethernet sockets.
IRPCCon Interface abstraction for the RPC connection.
Bytes Project alias for a byte buffer (std::vector<std::uint8_t>).
PNIOError Project exception/type representing a decoded PROFINET IO error.
PNRTAHeader Project representation of the PROFINET RTA header.
PNInM0PNInM15 Project structures representing the corresponding I&M records.

Roadmap

Phase 1 — Generic AR correctness

Highest priority

The primary objective is reliable AR establishment with different real PROFINET IO-Devices.

Focus on:

  • IODConnectReq correctness
  • IODConnectRes handling
  • ExpectedSubmoduleBlockReq correctness
  • IOCR block layout and DataLength calculations
  • AlarmCR configuration
  • block ordering
  • API/slot/subslot/module/submodule mapping
  • DCE/RPC endpoint handling
  • timeout behavior
  • session/activity/UUID handling
  • deterministic rollback after failed connection stages
  • AR release correctness

Success criterion:

A supported device can establish an AR using configuration derived from the device/application configuration without device-specific protocol hacks.


Phase 2 — Cyclic RTC1 interoperability

After generic AR establishment is reliable:

  • validate frame IDs
  • validate IOCR mapping
  • validate process-data offsets
  • validate input/output direction
  • validate IOPS/IOCS placement
  • validate cycle counters
  • validate VLAN and priority handling
  • validate transmit timing
  • validate receive filtering
  • validate startup and shutdown
  • test against real hardware and packet captures

Success criterion:

Application output data reaches the device and device input data is received consistently during long-running cyclic operation.


Phase 3 — Asio migration

Move blocking and ad-hoc socket handling toward a coherent asynchronous architecture.

Recommended order:

3.1 RPC transport

Use:

IRpcTransport
|
v
Asio-based UDP transport

Move timeout handling toward:

  • asynchronous receive
  • asio::steady_timer
  • cancellation
  • explicit operation lifetime

Avoid mixing RPC state machines with low-level blocking recv() loops.

3.2 Raw Ethernet transport

Retain Linux AF_PACKET where required, but integrate the descriptor with Asio.

Target model:

Native AF_PACKET socket creation/configuration
|
v
asio::posix::stream_descriptor
|
v
Asynchronous readiness notification
|
v
Frame-oriented recv()

The protocol abstraction should remain frame-oriented.

3.3 DCP

Migrate DCP receive handling to the Asio-backed raw Ethernet transport.

3.4 Alarm reception

Move alarm receive loops toward Asio-managed descriptor readiness and cancellation.

3.5 Cyclic receive

Migrate cyclic receive handling after DCP and alarm transports are stable.

3.6 Cyclic transmit

Do not prematurely replace deterministic cyclic scheduling with an Asio timer.

First measure the existing timing behavior and establish real-device correctness.

Asio timers can be evaluated later if they meet the required timing characteristics.


Phase 4 — Configuration model

Strengthen the path:

GSDML
|
v
Device model
|
v
Selected configuration
|
v
Expected configuration
|
+--> ExpectedSubmoduleBlock
|
+--> IOCR configuration
|
+--> cyclic mapping

Goals:

  • eliminate duplicated module definitions
  • eliminate duplicated I/O lengths
  • validate configuration before network communication
  • provide clear diagnostics for invalid configurations
  • support the developing CLI workflow

Phase 5 — CLI

Develop a CLI suitable for operating and diagnosing the stack.

Potential capabilities:

  • discover devices
  • inspect DCP information
  • load and inspect GSDML
  • inspect available modules/submodules
  • select/configure I/O
  • establish AR
  • display AR state
  • start/stop cyclic communication
  • inspect cyclic statistics
  • inspect input/output data
  • receive alarms
  • perform acyclic read/write operations
  • release connections cleanly

The CLI should exercise the public controller API rather than duplicating protocol logic.


Phase 6 — Protocol hardening

Expand regression coverage for:

  • malformed Ethernet frames
  • truncated DCP packets
  • truncated RPC packets
  • malformed block lengths
  • unexpected block types
  • invalid nested lengths
  • invalid IOCR configurations
  • wrong transaction IDs
  • wrong source MAC addresses
  • wrong source UDP endpoints
  • rejected AR responses
  • socket failures
  • receive timeouts
  • cancellation during shutdown

Phase 7 — Tooling and CI

Strengthen automated quality gates with:

  • Clang builds
  • GoogleTest
  • GoogleMock
  • coverage
  • AddressSanitizer
  • UndefinedBehaviorSanitizer
  • ThreadSanitizer where practical
  • clang-tidy
  • clang-format verification
  • protocol regression validation tests
  • artifact collection for failures

The repository already contains CMake warning options and Clang-oriented preset configurations; the next step is ensuring these checks consistently protect protocol behavior.


Phase 8 — Performance

Only after correctness and interoperability are established.

Potential areas:

  • cyclic buffer reuse
  • allocation reduction
  • unnecessary copies
  • receive buffer ownership
  • frame construction
  • socket batching where appropriate
  • callback overhead
  • cyclic scheduling measurements

Correctness takes priority over micro-optimisation.


Caveats

Area Current caveat Impact Recommended direction
AR establishment Generic AR interoperability remains the highest-priority development area Without a reliable AR, cyclic communication cannot be generally relied upon Prioritize exact IODConnect, ExpectedSubmodule, IOCR and AlarmCR validation
IOCR IOCR serialization and DataLength semantics are protocol-sensitive Incorrect values can cause devices to reject AR establishment Maintain exact byte-level regression validation tests and compare against captures
Cyclic RTC1 Real-device validation remains essential Loopback/unit success does not prove interoperability Validate against multiple physical devices and packet captures
Raw Ethernet Layer-2 communication requires Linux capabilities Deployment requires correct permissions Use CAP_NET_RAW; avoid unnecessarily running applications as root
Linux packet sockets AF_PACKET remains Linux-specific Limits portability Keep Linux-specific code behind meaningful transport boundaries
Asio migration Migration is ongoing/architectural work Mixing blocking and async models can complicate lifecycle management Migrate incrementally: RPC, DCP, alarms, cyclic RX
Timing Cyclic timing is sensitive Generic event-loop timing may not satisfy all cyclic requirements Measure before replacing dedicated scheduling
GSDML Parsing is implemented, but configuration integration should continue to mature Incorrect mapping can propagate into AR and IOCR configuration Establish one configuration source of truth
Protocol serialization Logical field correctness is insufficient One incorrect byte or length can break interoperability Prefer explicit serialization and exact regression validation tests
Parser robustness All network input is potentially malformed Unsafe parsing can cause crashes or invalid state Validate every offset and length before reading
CLI CLI functionality is under active development Operational workflows are not yet fully consolidated Build CLI on top of the public API
Device diversity PROFINET devices may differ in accepted optional behavior A flow working with one device may not be sufficiently generic Test against multiple vendors and use captures as evidence

Design Principles

The stack should continue to follow these principles:

Explicit wire serialization

Do not rely on compiler structure layout for network protocols.

RAII

Sockets, descriptors, threads, timers and connection resources should have deterministic lifetime.

Meaningful ownership

Prefer std::unique_ptr when ownership is exclusive.

Avoid std::shared_ptr unless shared lifetime is genuinely required.

Meaningful interfaces

Interfaces should exist because they provide:

  • a real architectural boundary
  • testability
  • multiple transport implementations
  • lifecycle isolation

Do not add abstractions merely to increase abstraction.

C++20

Prefer:

  • std::span
  • std::string_view
  • constexpr
  • enum class
  • RAII
  • move semantics
  • explicit integer types
  • strong protocol types where they prevent accidental interchange

Protocol correctness first

For PROFINET:

Correct bytes
>
Convenient abstraction
>
Performance optimisation

Tests are first-class

Every protocol defect should result in a regression test.


Development Priorities

Current priority order:

  1. Generic AR establishment
  2. IOCR correctness
  3. ExpectedSubmodule configuration correctness
  4. Alarm CR correctness
  5. Cyclic RTC1 interoperability
  6. Robust AR rollback and release
  7. GSDML-to-runtime configuration integration
  8. Asio migration
  9. CLI development
  10. Protocol hardening and expanded golden tests
  11. Performance optimisation

The most important success criterion is not simply that the stack builds or passes isolated unit tests.

The primary measure of success is:

A C++20 application can discover a real PROFINET IO-Device, derive or supply a valid configuration, establish a correct AR, complete parameterization, enter cyclic operation, exchange process data reliably, handle alarms and acyclic operations where configured, and release all resources deterministically.