PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
rpcTypes.h
Go to the documentation of this file.
1
11#pragma once
12
13#include <cstdint>
14#include <optional>
15#include <string>
16#include <vector>
17
18#include "profinet/blocks.h"
19#include "profinet/dcp.h"
20
21namespace profinet::rpc
22{
23// =============================================================================
24// Constants
25// =============================================================================
26// NOLINTBEGIN(readability-identifier-naming)
28inline constexpr std::uint16_t RPC_PORT = 0x8894;
30inline constexpr std::uint16_t RPC_BIND_PORT = 0x8895;
31
33inline const std::string UUID_NULL = "00000000-0000-0000-0000-000000000000";
35inline const std::string UUID_EPM_V4 = "e1af8308-5d1f-11c9-91a4-08002b14a0fa";
37inline const std::string UUID_PNIO_DEVICE = "dea00001-6c97-11d1-8271-00a02442df7d";
39inline const std::string UUID_PNIO_CONTROLLER = "dea00002-6c97-11d1-8271-00a02442df7d";
41inline const std::string UUID_PNIO_SUPERVISOR = "dea00003-6c97-11d1-8271-00a02442df7d";
43inline const std::string UUID_PNIO_PARAMETER_SERVER = "dea00004-6c97-11d1-8271-00a02442df7d";
44
46inline constexpr std::uint32_t PNIO_DEVICE_INTERFACE_VERSION = 1;
47
49inline constexpr std::uint32_t EPM_LOOKUP = 0x02;
51inline constexpr std::uint32_t EPM_INQUIRY_ALL = 0x00;
53inline constexpr std::uint32_t EPM_INQUIRY_INTERFACE = 0x01;
54
56inline constexpr double DEFAULT_TIMEOUT = 5.0;
58inline constexpr double CONNECTION_TIMEOUT = 10.0;
59
60// CONTROL block types / commands (subset of indices.h's catalog needed
61// directly by RPCCon).
63inline constexpr std::uint16_t BLOCK_IOD_CONTROL_PRM_END_REQ = 0x0110;
65inline constexpr std::uint16_t BLOCK_IOD_CONTROL_APP_READY_REQ = 0x0112;
67inline constexpr std::uint16_t BLOCK_IOD_CONTROL_APP_READY_RES = 0x8112;
69inline constexpr std::uint16_t BLOCK_IOD_CONTROL_RT_CLASS_3_REQ = 0x0117;
71inline constexpr std::uint16_t BLOCK_PRM_BEGIN_REQ = 0x0118;
73inline constexpr std::uint16_t BLOCK_RELEASE_REQ = 0x0114;
74
76inline constexpr std::uint16_t CONTROL_CMD_PRM_END = 0x0001;
78inline constexpr std::uint16_t CONTROL_CMD_APP_READY = 0x0002;
80inline constexpr std::uint16_t CONTROL_CMD_RELEASE = 0x0004;
82inline constexpr std::uint16_t CONTROL_CMD_DONE = 0x0008;
84inline constexpr std::uint16_t CONTROL_CMD_READY_FOR_COMPANION = 0x0010;
86inline constexpr std::uint16_t CONTROL_CMD_READY_FOR_RT_CLASS_3 = 0x0020;
88inline constexpr std::uint16_t CONTROL_CMD_PRM_BEGIN = 0x0040;
89// NOLINTEND(readability-identifier-naming)
90// =============================================================================
91// IOCR (cyclic IO) configuration
92// =============================================================================
93
95struct IOSlot
96{
98 std::uint16_t slot = 0;
99
101 std::uint16_t subslot = 0;
102
104 std::uint16_t inputLength = 0;
105
107 std::uint16_t outputLength = 0;
108
110 std::uint32_t moduleIdent = 0;
111
113 std::uint32_t submoduleIdent = 0;
114
120 bool operator==(const IOSlot&) const = default;
121};
122
123enum class StartupMode : std::uint16_t
124{
125 Legacy,
127};
128
130{
131 std::uint16_t numberOfAr = 0;
132
134
135 std::vector<std::uint16_t> sendClockTimingProperties;
136
137 std::vector<std::uint16_t> reductionRatioTimingProperties;
138
144 bool operator==(const ApplicationRelations&) const = default;
145};
146
149{
151 std::vector<IOSlot> slots;
152
154 std::uint16_t sendClockFactor = 32;
155
157 std::uint16_t reductionRatio = 32;
158
160 std::uint16_t watchdogFactor = 6;
161
163 std::uint16_t dataHoldFactor = 6;
164
166
169 [[nodiscard]] std::uint32_t CycleTimeUs() const
170 {
171 return static_cast<std::uint32_t>(reductionRatio) * sendClockFactor * 125 / 4;
172 }
173
176 [[nodiscard]] double CycleTimeMs() const
177 {
178 return CycleTimeUs() / 1000.0;
179 }
180
183 [[nodiscard]] std::vector<std::string> Validate() const;
184
190 bool operator==(const IOCRSetup&) const = default;
191};
192namespace raw
193{
195enum class Flags1 : std::uint8_t
196{
198 None = 0x00,
199
201 Reserved1 = 1 << 7,
202
204 Broadcast = 1 << 6,
205
207 Idempotent = 1 << 5,
208
210 Maybe = 1 << 4,
211
213 NoFack = 1 << 3,
214
216 Fragment = 1 << 2,
217
219 LastFragment = 1 << 1,
220
222 Reserved0 = 1 << 0
223};
224
229[[nodiscard]] constexpr Flags1 operator|(Flags1 lhs, Flags1 rhs) noexcept
230{
231 return static_cast<Flags1>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
232}
233
238[[nodiscard]] constexpr Flags1 operator&(Flags1 lhs, Flags1 rhs) noexcept
239{
240 return static_cast<Flags1>(static_cast<std::uint8_t>(lhs) & static_cast<std::uint8_t>(rhs));
241}
242
247[[nodiscard]] constexpr std::uint8_t operator&(std::uint8_t lhs, Flags1 rhs) noexcept
248{
249 return lhs & static_cast<std::uint8_t>(rhs);
250}
251
256[[nodiscard]] constexpr std::uint8_t operator&(Flags1 lhs, std::uint8_t rhs) noexcept
257{
258 return static_cast<std::uint8_t>(lhs) & rhs;
259}
260
265[[nodiscard]] constexpr std::uint8_t operator|(std::uint8_t lhs, Flags1 rhs) noexcept
266{
267 return lhs | static_cast<std::uint8_t>(rhs);
268}
269
274[[nodiscard]] constexpr std::uint8_t operator|(Flags1 lhs, std::uint8_t rhs) noexcept
275{
276 return static_cast<std::uint8_t>(lhs) | rhs;
277}
278
283[[nodiscard]] constexpr bool HasFlag(Flags1 flags, Flags1 test) noexcept
284{
285 return (flags & test) == test;
286}
287
292[[nodiscard]] constexpr bool HasFlag(std::uint8_t flags, Flags1 test) noexcept
293{
294 const auto testVal = static_cast<std::uint8_t>(test);
295 return (flags & testVal) == testVal;
296}
297
302[[nodiscard]] constexpr bool HasFlag(Flags1 flags, std::uint8_t test) noexcept
303{
304 return (static_cast<std::uint8_t>(flags) & test) == test;
305}
306
311{
313 static constexpr std::uint8_t kLittleEndianDrepFlag = 0x10U;
314
316 std::uint8_t version{};
317
319 std::uint8_t packetType{};
320
322 std::uint8_t flags1{};
323
325 std::uint8_t flags2{};
326
328 std::uint8_t serialHigh{};
329
333 std::array<std::uint8_t, 3> drep{};
334
336 std::array<std::uint8_t, uuidLenght> objectUuid{};
337
339 std::array<std::uint8_t, uuidLenght> interfaceUuid{};
340
342 std::array<std::uint8_t, uuidLenght> activityUuid{};
343
345 std::uint32_t interfaceVersion{};
346
348 std::uint32_t sequenceNumber{};
349
351 std::uint16_t operationNumber{};
352
354 std::uint8_t serialLow{};
355
358
364};
365
397std::optional<RawRpcHeader> ParseRawRpcHeader(const Bytes& data);
398} // namespace raw
399
402{
404 std::array<std::uint8_t, uuidLenght> arUuid{};
405
407 std::uint16_t sessionKey = 0;
408
410 std::uint16_t inputFrameId = 0;
411
413 std::uint16_t outputFrameId = 0;
414
416 std::optional<raw::RawRpcHeader> header;
417
420
423 [[nodiscard]] bool HasCyclic() const
424 {
425 return inputFrameId != 0 || outputFrameId != 0;
426 }
427};
428
429// =============================================================================
430// RPCCon - PROFINET DCE/RPC connection to an IO-Device
431// =============================================================================
434{
436 std::uint16_t slot = 0;
438 std::uint16_t subslot = 0;
440 std::uint16_t index = 0;
444 std::uint32_t api = 0;
445};
446
450struct AllIM
451{
453 std::optional<PNInM0> im0;
455 std::optional<PNInM1> im1;
457 std::optional<PNInM2> im2;
459 std::optional<PNInM3> im3;
461 std::optional<PNInM4> im4;
463 std::optional<PNInM5> im5;
465 std::optional<PNInM6> im6;
467 std::optional<PNInM7> im7;
469 std::optional<PNInM8> im8;
471 std::optional<PNInM9> im9;
473 std::optional<PNInM10> im10;
475 std::optional<PNInM11> im11;
477 std::optional<PNInM12> im12;
479 std::optional<PNInM13> im13;
481 std::optional<PNInM14> im14;
483 std::optional<PNInM15> im15;
484
490 bool operator==(const AllIM&) const = default;
491};
494{
496 std::string status;
498 std::string name;
500 std::size_t size = 0;
502 std::string error;
504 std::uint8_t errorCode1 = 0;
506 std::uint8_t errorCode2 = 0;
507};
508
516{
519
521 std::uint16_t rpcPort = RPC_PORT;
522};
523} // namespace profinet::rpc
Declares PROFINET IO connection-management block structures and wire serialization.
PROFINET DCP discovery and device configuration interface.
constexpr bool HasFlag(Flags1 flags, Flags1 test) noexcept
Checks if all flag bits in 'test' are set within 'flags'.
Definition rpcTypes.h:283
std::optional< RawRpcHeader > ParseRawRpcHeader(const Bytes &data)
Parses a raw network byte vector into a structured DCE/RPC v4 Connectionless Header.
Definition rpc.cpp:1858
constexpr Flags1 operator&(Flags1 lhs, Flags1 rhs) noexcept
Bitwise AND operator for intersecting two ApplicationReadyResponseFlags1 values.
Definition rpcTypes.h:238
constexpr Flags1 operator|(Flags1 lhs, Flags1 rhs) noexcept
Bitwise OR operator for combining two ApplicationReadyResponseFlags1 values.
Definition rpcTypes.h:229
Flags1
Represents bitwise flags for Application Ready Response header options (byte 1).
Definition rpcTypes.h:196
@ Fragment
Bit 2 (0x04): Packet is a fragment of a larger body.
@ Reserved0
Bit 0 (0x01): Reserved for implementation.
@ LastFragment
Bit 1 (0x02): Final fragment in the sequence.
@ Maybe
Bit 4 (0x10): No response or acknowledgment expected from server.
@ Reserved1
Bit 7 (0x80): Reserved for implementation.
@ Idempotent
Bit 5 (0x20): Activity call is idempotent (safe to retry).
@ Broadcast
Bit 6 (0x40): Packet was sent as a broadcast.
@ NoFack
Bit 3 (0x08): Do not send FACK (fragment acknowledgment) frames.
const std::string UUID_PNIO_PARAMETER_SERVER
PROFINET IO-ParameterServer interface UUID.
Definition rpcTypes.h:43
constexpr std::uint16_t BLOCK_IOD_CONTROL_APP_READY_REQ
Block type: IODControlReqAppReady.
Definition rpcTypes.h:65
constexpr std::uint16_t CONTROL_CMD_DONE
Control command bit: Done.
Definition rpcTypes.h:82
constexpr std::uint16_t BLOCK_PRM_BEGIN_REQ
Block type: PrmBeginReq.
Definition rpcTypes.h:71
const std::string UUID_PNIO_SUPERVISOR
PROFINET IO-Supervisor interface UUID.
Definition rpcTypes.h:41
constexpr std::uint16_t CONTROL_CMD_PRM_BEGIN
Control command bit: PrmBegin.
Definition rpcTypes.h:88
const std::string UUID_PNIO_CONTROLLER
PROFINET IO-Controller interface UUID.
Definition rpcTypes.h:39
const std::string UUID_EPM_V4
Endpoint Mapper interface UUID.
Definition rpcTypes.h:35
constexpr double DEFAULT_TIMEOUT
Default RPC response timeout in seconds.
Definition rpcTypes.h:56
constexpr std::uint16_t BLOCK_IOD_CONTROL_RT_CLASS_3_REQ
Block type: IODControlReqRTClass3.
Definition rpcTypes.h:69
constexpr std::uint32_t PNIO_DEVICE_INTERFACE_VERSION
Interface version used for the PNIO device interface.
Definition rpcTypes.h:46
constexpr std::uint16_t BLOCK_IOD_CONTROL_PRM_END_REQ
Block type: IODControlReqPrmEnd.
Definition rpcTypes.h:63
constexpr std::uint16_t RPC_PORT
PROFINET IO RPC port (34964).
Definition rpcTypes.h:28
constexpr std::uint16_t BLOCK_RELEASE_REQ
Block type: IODReleaseReq.
Definition rpcTypes.h:73
constexpr std::uint16_t CONTROL_CMD_RELEASE
Control command bit: Release.
Definition rpcTypes.h:80
constexpr std::uint16_t CONTROL_CMD_READY_FOR_COMPANION
Control command bit: ReadyForCompanion.
Definition rpcTypes.h:84
constexpr std::uint16_t CONTROL_CMD_PRM_END
Control command bit: PrmEnd.
Definition rpcTypes.h:76
const std::string UUID_NULL
Null (all-zero) DCE/RPC UUID string.
Definition rpcTypes.h:33
constexpr std::uint16_t RPC_BIND_PORT
PROFINET IO RPC bind port (34965).
Definition rpcTypes.h:30
constexpr std::uint32_t EPM_INQUIRY_ALL
EPM inquiry type: all interfaces.
Definition rpcTypes.h:51
const std::string UUID_PNIO_DEVICE
PROFINET IO-Device interface UUID.
Definition rpcTypes.h:37
constexpr double CONNECTION_TIMEOUT
Maximum idle time in seconds before an AR is considered to need re-connection.
Definition rpcTypes.h:58
constexpr std::uint16_t CONTROL_CMD_APP_READY
Control command bit: ApplicationReady.
Definition rpcTypes.h:78
constexpr std::uint32_t EPM_INQUIRY_INTERFACE
EPM inquiry type: specific interface.
Definition rpcTypes.h:53
constexpr std::uint16_t CONTROL_CMD_READY_FOR_RT_CLASS_3
Control command bit: ReadyForRTClass3.
Definition rpcTypes.h:86
constexpr std::uint16_t BLOCK_IOD_CONTROL_APP_READY_RES
Block type: IODControlResAppReady.
Definition rpcTypes.h:67
constexpr std::uint32_t EPM_LOOKUP
EPM operation: Lookup.
Definition rpcTypes.h:49
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
Definition protocol.h:55
All I&M records a device supports, read in one call.
Definition rpcTypes.h:451
std::optional< PNInM7 > im7
I&M7 (reserved), if supported.
Definition rpcTypes.h:467
std::optional< PNInM15 > im15
I&M15 (reserved), if supported.
Definition rpcTypes.h:483
std::optional< PNInM9 > im9
I&M9 (reserved), if supported.
Definition rpcTypes.h:471
std::optional< PNInM14 > im14
I&M14 (reserved), if supported.
Definition rpcTypes.h:481
std::optional< PNInM1 > im1
I&M1 (tag function/location), if supported.
Definition rpcTypes.h:455
std::optional< PNInM5 > im5
I&M5 (free-text annotation), if supported.
Definition rpcTypes.h:463
std::optional< PNInM10 > im10
I&M10 (reserved), if supported.
Definition rpcTypes.h:473
std::optional< PNInM3 > im3
I&M3 (free-text descriptor), if supported.
Definition rpcTypes.h:459
std::optional< PNInM6 > im6
I&M6 (reserved), if supported.
Definition rpcTypes.h:465
std::optional< PNInM13 > im13
I&M13 (reserved), if supported.
Definition rpcTypes.h:479
std::optional< PNInM11 > im11
I&M11 (reserved), if supported.
Definition rpcTypes.h:475
bool operator==(const AllIM &) const =default
Compares two AllIM for equality.
std::optional< PNInM2 > im2
I&M2 (installation date), if supported.
Definition rpcTypes.h:457
std::optional< PNInM12 > im12
I&M12 (reserved), if supported.
Definition rpcTypes.h:477
std::optional< PNInM4 > im4
I&M4 (PROFIsafe signature), if supported.
Definition rpcTypes.h:461
std::optional< PNInM0 > im0
I&M0 (mandatory identification data).
Definition rpcTypes.h:453
std::optional< PNInM8 > im8
I&M8 (reserved), if supported.
Definition rpcTypes.h:469
bool operator==(const ApplicationRelations &) const =default
Compares two application relations for equality.
std::vector< std::uint16_t > reductionRatioTimingProperties
Definition rpcTypes.h:137
std::vector< std::uint16_t > sendClockTimingProperties
Definition rpcTypes.h:135
Result of a successful RPCCon::Connect() that also established cyclic IO.
Definition rpcTypes.h:402
std::array< std::uint8_t, uuidLenght > arUuid
AR UUID assigned to this connection.
Definition rpcTypes.h:404
bool HasCyclic() const
Whether cyclic IO was actually established.
Definition rpcTypes.h:423
int deviceAlarmRef
Device's local alarm reference, if an AlarmCR was also established.
Definition rpcTypes.h:419
std::uint16_t outputFrameId
Frame ID assigned to the output (controller -> device) IOCR.
Definition rpcTypes.h:413
std::uint16_t sessionKey
Session key for this connection.
Definition rpcTypes.h:407
std::optional< raw::RawRpcHeader > header
The DCE/RPC header.
Definition rpcTypes.h:416
std::uint16_t inputFrameId
Frame ID assigned to the input (device -> controller) IOCR.
Definition rpcTypes.h:410
Configuration for establishing cyclic IO alongside an AR.
Definition rpcTypes.h:149
std::uint16_t watchdogFactor
Watchdog factor (missed-frame tolerance before a timeout fault).
Definition rpcTypes.h:160
std::uint16_t dataHoldFactor
Data hold factor (how long to keep the last good frame's data).
Definition rpcTypes.h:163
std::vector< IOSlot > slots
Slots to include in the cyclic data frames.
Definition rpcTypes.h:151
bool operator==(const IOCRSetup &) const =default
Compares two IOCR configurations for equality.
std::vector< std::string > Validate() const
Sanity-check this configuration.
Definition rpc.cpp:546
double CycleTimeMs() const
Compute the cycle time in milliseconds.
Definition rpcTypes.h:176
std::uint16_t reductionRatio
Reduction ratio relative to the send clock.
Definition rpcTypes.h:157
std::uint16_t sendClockFactor
Send clock base factor (31.25us units).
Definition rpcTypes.h:154
ApplicationRelations applicationRelations
Definition rpcTypes.h:165
std::uint32_t CycleTimeUs() const
Compute the cycle time in microseconds from SendClockFactor/ReductionRatio.
Definition rpcTypes.h:169
One slot/subslot's expected module configuration and IO data sizes.
Definition rpcTypes.h:96
bool operator==(const IOSlot &) const =default
Compares two IO slot configurations for equality.
std::uint16_t inputLength
Expected input data length in bytes (0 if no input data).
Definition rpcTypes.h:104
std::uint16_t slot
Slot number.
Definition rpcTypes.h:98
std::uint16_t outputLength
Expected output data length in bytes (0 if no output data).
Definition rpcTypes.h:107
std::uint32_t moduleIdent
Expected module ident number.
Definition rpcTypes.h:110
std::uint32_t submoduleIdent
Expected submodule ident number.
Definition rpcTypes.h:113
std::uint16_t subslot
Subslot number.
Definition rpcTypes.h:101
Result of probing one index in EnumerateIndices().
Definition rpcTypes.h:494
std::uint8_t errorCode1
PNIOError ErrorCode1, if the error was a PNIOError.
Definition rpcTypes.h:504
std::string name
Human-readable name of the index.
Definition rpcTypes.h:498
std::size_t size
Payload size in bytes; valid when Status == "readable".
Definition rpcTypes.h:500
std::uint8_t errorCode2
PNIOError ErrorCode2, if the error was a PNIOError.
Definition rpcTypes.h:506
std::string error
Error message; valid when Status == "error".
Definition rpcTypes.h:502
std::string status
Probe outcome: "readable", "empty", or "error".
Definition rpcTypes.h:496
Configuration options for an RPC connection.
Definition rpcTypes.h:516
double timeoutSec
Timeout in seconds for RPC operations.
Definition rpcTypes.h:518
std::uint16_t rpcPort
UDP port used for RPC communication.
Definition rpcTypes.h:521
A single write operation for WriteMultiple().
Definition rpcTypes.h:434
std::uint16_t slot
Slot number.
Definition rpcTypes.h:436
Bytes data
Record data to write.
Definition rpcTypes.h:442
std::uint32_t api
API number.
Definition rpcTypes.h:444
std::uint16_t subslot
Subslot number.
Definition rpcTypes.h:438
std::uint16_t index
Record data index to write.
Definition rpcTypes.h:440
DREP-aware fields we need out of a raw incoming RPC request; PROFINET block payloads inside the NRD b...
Definition rpcTypes.h:311
std::array< std::uint8_t, 3 > drep
Data Representation (DREP) bytes.
Definition rpcTypes.h:333
std::uint8_t packetType
RPC packet type, such as request or response.
Definition rpcTypes.h:319
std::uint8_t serialLow
Low byte of the RPC serial number.
Definition rpcTypes.h:354
static constexpr std::uint8_t kLittleEndianDrepFlag
DREP flag indicating little-endian byte order.
Definition rpcTypes.h:313
std::uint8_t serialHigh
High byte of the RPC serial number.
Definition rpcTypes.h:328
std::uint32_t interfaceVersion
RPC interface version.
Definition rpcTypes.h:345
std::uint16_t operationNumber
RPC operation number.
Definition rpcTypes.h:351
std::uint8_t flags2
Second RPC flags byte.
Definition rpcTypes.h:325
std::array< std::uint8_t, uuidLenght > interfaceUuid
Raw interface UUID bytes.
Definition rpcTypes.h:339
std::array< std::uint8_t, uuidLenght > objectUuid
Raw object UUID bytes.
Definition rpcTypes.h:336
std::uint8_t version
RPC protocol version.
Definition rpcTypes.h:316
std::uint32_t sequenceNumber
RPC sequence number.
Definition rpcTypes.h:348
bool isLittleEndian
True when RPC scalar fields use little-endian byte order.
Definition rpcTypes.h:357
std::array< std::uint8_t, uuidLenght > activityUuid
Raw activity UUID bytes.
Definition rpcTypes.h:342
std::uint8_t flags1
First RPC flags byte.
Definition rpcTypes.h:322
Bytes payload
Remaining bytes after the fixed RPC header.
Definition rpcTypes.h:363