60 .blockLength = r.
U16()};
86 std::uint8_t b10, std::uint8_t b11, std::uint8_t b12,
87 std::uint8_t b13, std::uint8_t b14, std::uint8_t b15);
98std::array<std::uint8_t, uuidLenght>
StringToUuidBytes(
const std::string& uuidStr);
122 const std::string& name,
163 asio::io_context* context =
nullptr);
180 std::optional<ConnectResult>
Connect(std::optional<MacAddress>
srcMac = std::nullopt,
181 bool withAlarmCr =
false,
182 std::optional<IOCRSetup>
iocrSetup = std::nullopt)
override;
191 PNIODHeader Read(std::uint32_t api, std::uint16_t slot, std::uint16_t subslot, std::uint16_t idx)
override;
199 PNIODHeader ReadImplicit(std::uint32_t api, std::uint16_t slot, std::uint16_t subslot, std::uint16_t idx)
override;
207 void Write(std::uint32_t api, std::uint16_t slot, std::uint16_t subslot, std::uint16_t idx,
208 const Bytes& data)
override;
215 std::vector<blocks::WriteMultipleResult>
WriteMultiple(
const std::vector<WriteItem>& writes)
override;
222 Bytes ReadRaw(std::uint16_t idx, std::uint16_t slot = 0, std::uint16_t subslot = 1);
228 PNInM0 ReadIm0(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
234 PNInM1 ReadIm1(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
240 PNInM2 ReadIm2(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
246 PNInM3 ReadIm3(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
252 PNInM4 ReadIm4(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
258 PNInM5 ReadIm5(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
264 PNInM6 ReadIm6(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
270 PNInM7 ReadIm7(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
276 PNInM8 ReadIm8(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
282 PNInM9 ReadIm9(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
288 PNInM10 ReadIm10(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
294 PNInM11 ReadIm11(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
300 PNInM12 ReadIm12(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
306 PNInM13 ReadIm13(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
312 PNInM14 ReadIm14(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
318 PNInM15 ReadIm15(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
324 AllIM ReadAllIm(std::uint16_t slot = 0, std::uint16_t subslot = 1)
override;
343 std::uint16_t index = 0xF000)
override;
348 std::map<std::uint16_t, diagnosis::DiagnosisData>
ReadAllDiagnosis()
override;
364 std::pair<blocks::PDRealData, blocks::RealIdentificationData>
DiscoverTopology()
override;
374 std::uint16_t slot = 0, std::uint16_t subslot = 1,
375 std::optional<std::vector<std::uint16_t>> customIndices = std::nullopt)
override;
403 void Close() noexcept override;
421 [[nodiscard]]
const std::array<std::uint8_t, uuidLenght>&
ArUuid()
const
466 std::vector<EPMEndpoint>
EpmLookup(
const std::string& ip, std::uint16_t port =
RPC_PORT,
468 std::optional<std::string> interfaceFilter = std::nullopt)
override;
531 const
Bytes& subBlocks = {});
543 std::array<std::uint8_t, uuidLenght>
arUuid{};
Runs an Asio I/O context on a dedicated worker thread.
Interface for PROFINET IO-Device RPC connections.
Declares PROFINET IO connection-management block structures and wire serialization.
Abstract interface for raw Ethernet frame transport.
Parsed PROFINET device information from a DCP response.
Abstract interface for a PROFINET RPC connection.
Connection to a PROFINET IO-Device: establishes an AR (Application Relationship) and performs acyclic...
PNInM13 ReadIm13(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M13 (reserved).
PNInM0 ReadIm0(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M0 (mandatory identification data).
std::unique_ptr< IRpcTransport > ccontrolResponseTransport
static std::uint16_t ParseIocrResponse(const Bytes &responseData, int iocrType)
Parse an IOCRBlockRes from a CONNECT response.
int DeviceAlarmRef() const override
Device's local alarm reference, from AlarmCRBlockRes.
std::uint32_t sequenceNumber
Monotonically increasing RPC sequence number.
blocks::PDRealData ReadPdRealData() override
Read and parse the device's PDRealData (physical topology).
std::array< std::uint8_t, uuidLenght > arUuid
AR UUID for this connection.
blocks::ModuleDiffBlock ReadModuleDiff() override
Read and parse the device's ModuleDiffBlock.
PNInM2 ReadIm2(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M2 (installation date).
RPCCon(RPCCon &&)=delete
Deleted move constructor to prevent moving instances of this class.
Bytes BuildAlarmCrBlock(int transport=0, int priority=0) const
Build an AlarmCRBlockReq for inclusion in the CONNECT request.
double timeout
Default RPC response timeout in seconds.
PNInM8 ReadIm8(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M8 (reserved).
std::array< std::uint8_t, uuidLenght > localObjectUuid
This controller's own object UUID.
~RPCCon()
Disconnect (best-effort) and close the underlying sockets.
static PNNRDData CreateNrd(const Bytes &payload)
Wrap a payload in an NRD (Network Representation Data) header.
PNInM4 ReadIm4(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M4 (PROFIsafe signature).
PNInM15 ReadIm15(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M15 (reserved).
std::uint16_t SessionKey() const
The session key for this connection.
bool HasAlarmCr() const override
Whether an AlarmCR was successfully established.
AllIM ReadAllIm(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read all I&M records a device supports.
std::vector< blocks::SlotInfo > DiscoverSlots() override
Convenience accessor for ReadRealIdentificationData().Slots.
static int ParseAlarmCrResponse(const Bytes &responseData)
Parse the AlarmCRBlockRes from a CONNECT response.
Bytes PrmEnd() override
Send PrmEnd (end of the parameterization phase).
const dcp::DCPDeviceDescription & Info() const override
The device this connection targets.
PNInM6 ReadIm6(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M6 (reserved).
static Bytes BuildExpectedSubmoduleBlock(const IOCRSetup &setup)
Build an ExpectedSubmoduleBlockReq for the CONNECT request.
Bytes SendControl(BlockType blockType, ControlCommand controlCommand, bool waitResponse=true, const Bytes &subBlocks={})
Send a CONTROL operation and optionally wait for its response.
void Disconnect() override
Send Release to terminate the AR.
RPCCon(const RPCCon &)=delete
Not copyable because the connection owns non-copyable Asio sockets.
int deviceAlarmRef
Device's local alarm reference, if an AlarmCR was established.
std::vector< EPMEndpoint > EpmLookup(const std::string &ip, std::uint16_t port=RPC_PORT, double timeoutSec=DEFAULT_TIMEOUT, std::optional< std::string > interfaceFilter=std::nullopt) override
Query a device's Endpoint Mapper for available RPC endpoints.
std::unique_ptr< asio::io_context > rpcContext
PNInM11 ReadIm11(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M11 (reserved).
std::pair< blocks::PDRealData, blocks::RealIdentificationData > DiscoverTopology() override
Read both PDRealData and RealIdentificationData in one call.
std::unique_ptr< IAsioIoContextRunner > rpcContextRunner
std::array< std::uint8_t, 3 > dataRepresentation
AR DREP for this connection.
RPCCon & operator=(RPCCon &&)=delete
Deleted move assignment operator to prevent moving instances of this class.
std::array< std::uint8_t, uuidLenght > remoteObjectUuid
The target device's object UUID.
dcp::DCPDeviceDescription info
DCP-discovered description of the target device.
bool reconnecting
Whether timeout has occured and reconnection is needed.
RPCCon & operator=(const RPCCon &)=delete
Not copyable because the connection owns non-copyable Asio sockets.
std::uint16_t LocalAlarmRef() const override
Controller's own local alarm reference.
diagnosis::DiagnosisData ReadDiagnosis(std::uint16_t slot=0, std::uint16_t subslot=0, std::uint16_t index=0xF000) override
Read and parse diagnosis data at the given location/index.
PNInM14 ReadIm14(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M14 (reserved).
void Close() noexcept override
Disconnect() and close the underlying sockets.
PNInM12 ReadIm12(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M12 (reserved).
int inputIocrRef
IOCR reference for the input (device -> controller) IOCR.
bool IsConnected() const override
Whether the AR is currently established.
std::optional< MacAddress > srcMac
Source MAC address used to establish the AR.
std::map< std::uint16_t, diagnosis::DiagnosisData > ReadAllDiagnosis() override
Read diagnosis from all standard diagnosis indices.
std::map< std::uint16_t, IndexProbeResult > EnumerateIndices(std::uint16_t slot=0, std::uint16_t subslot=1, std::optional< std::vector< std::uint16_t > > customIndices=std::nullopt) override
Probe a set of indices and report which are readable/empty/erroring.
static Bytes BuildIocrBlock(IocrType iocrType, const IOCRSetup &setup)
Build an IOCRBlockReq (header + API object list) for the CONNECT request.
bool alarmCrEnabled
Whether an AlarmCR was successfully established.
std::chrono::steady_clock::time_point liveMonotonic
Timestamp of the last successful RPC exchange, for CONNECTION_TIMEOUT tracking.
void CheckTimeout()
Reconnect if the AR has been idle longer than CONNECTION_TIMEOUT.
Bytes PrmBegin() override
Send PrmBegin (start of the parameterization phase).
int outputIocrRef
IOCR reference for the output (controller -> device) IOCR.
std::uint16_t outputFrameId
Frame ID assigned to the output IOCR.
PNInM5 ReadIm5(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M5 (free-text annotation).
PNInM9 ReadIm9(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M9 (reserved).
std::unique_ptr< IRpcTransport > rpcTransport
std::uint16_t alarmRef
Controller's own local alarm reference.
std::array< std::uint8_t, uuidLenght > interfaceUuid
Interface UUID for the current RPC exchange.
PNInM10 ReadIm10(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M10 (reserved).
PNInM3 ReadIm3(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M3 (free-text descriptor).
asio::io_context & ioContext
Asio execution context used by the RPC transport.
std::uint16_t inputFrameId
Frame ID assigned to the input IOCR.
blocks::RealIdentificationData ReadRealIdentificationData() override
Read and parse the device's RealIdentificationData (logical structure).
void CloseSockets() noexcept
Close the RPC and CControl UDP sockets.
std::optional< ConnectResult > Connect(std::optional< MacAddress > srcMac=std::nullopt, bool withAlarmCr=false, std::optional< IOCRSetup > iocrSetup=std::nullopt) override
Establish (or re-establish) the AR with the device.
PNInM1 ReadIm1(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M1 (tag function/location).
PNIODHeader Read(std::uint32_t api, std::uint16_t slot, std::uint16_t subslot, std::uint16_t idx) override
Read a data record via slot/subslot/index (AR must be connected).
void Write(std::uint32_t api, std::uint16_t slot, std::uint16_t subslot, std::uint16_t idx, const Bytes &data) override
Write a data record via slot/subslot/index (AR must be connected).
std::uint16_t sessionKey
Session key for this connection.
PNRPCHeader CreateRpc(std::uint16_t operation, const Bytes &nrd)
Build an RPC header for the given operation and NRD body.
std::unique_ptr< IRpcTransport > ccontrolTransport
Bytes ReadRaw(std::uint16_t idx, std::uint16_t slot=0, std::uint16_t subslot=1)
Read a raw record payload by index (convenience wrapper over Read()).
PNRPCHeader SendReceive(const PNRPCHeader &request)
Send an RPC request and synchronously wait for its response.
PNInM7 ReadIm7(std::uint16_t slot=0, std::uint16_t subslot=1) override
Read I&M7 (reserved).
Bytes ReadyForRtClass3() override
Send ReadyForRTClass3 (isochronous real-time readiness).
std::vector< blocks::WriteMultipleResult > WriteMultiple(const std::vector< WriteItem > &writes) override
Write multiple records atomically via IODWriteMultipleReq (0xE040).
bool live
Whether the AR is currently established.
const std::array< std::uint8_t, uuidLenght > & ArUuid() const
The AR UUID for this connection.
PNIODHeader ReadImplicit(std::uint32_t api, std::uint16_t slot, std::uint16_t subslot, std::uint16_t idx) override
Read a data record without an established AR.
std::optional< IOCRSetup > iocrSetup
Cyclic IO configuration used for the current AR, if any.
std::array< std::uint8_t, uuidLenght > activityUuid
Activity UUID for the current RPC exchange.
Lightweight cursor for parsing a big-endian byte buffer without copies.
void SkipTo(std::size_t offset)
Move the read position to an absolute byte offset.
std::uint16_t U16()
Read and consume a big-endian 16-bit value.
PROFINET DCP discovery and device configuration interface.
PROFINET diagnosis data structures, error decoding, and parsers.
Declares exceptions and error types used by the PROFINET IO controller stack.
PROFINET record-data indices, block types, and protocol enumerations.
std::array< std::uint8_t, uuidLenght > BuildObjectUuid(std::uint8_t b10, std::uint8_t b11, std::uint8_t b12, std::uint8_t b13, std::uint8_t b14, std::uint8_t b15)
Builds a PROFINET object UUID.
constexpr std::uint8_t VERSION_HIGH
Version high.
std::string UuidBytesToString(const std::array< std::uint8_t, uuidLenght > &data)
Format a 16-byte DCE/RPC UUID as a canonical string.
dcp::DCPDeviceDescription GetStationInfo(IRawEthernetSocket &sock, const MacAddress &src, const std::string &name, double timeoutSec=DEFAULT_TIMEOUT *2)
Resolve a device by PROFINET station name via DCP.
constexpr double DEFAULT_TIMEOUT
Default RPC response timeout in seconds.
constexpr std::uint16_t RPC_PORT
PROFINET IO RPC port (34964).
std::optional< EPMEndpoint > ParseEpmTower(const Bytes &towerData)
Parses a DCE/RPC EPM tower into a PROFINET endpoint.
BlockHeaderView PeekBlockHeader(const Bytes &data, std::size_t offset)
constexpr std::uint8_t VERSION_LOW
Version low.
std::array< std::uint8_t, uuidLenght > StringToUuidBytes(const std::string &uuidStr)
Parse a canonical UUID string into 16 raw DCE/RPC UUID bytes.
BlockType
PROFINET block types.
std::array< std::uint8_t, macAddressLength > MacAddress
A 6-byte Ethernet MAC address.
IocrType
PROFINET IOCR types.
ControlCommand
PROFINET IOD control command values.
@ ApplicationReady
Application Ready command.
std::vector< std::uint8_t > Bytes
Generic byte buffer alias used throughout the library for raw wire data.
PROFINET protocol wire-format structures and serialization helpers.
UDP transport abstraction for PROFINET DCE/RPC.
Shared data types used by the PROFINET DCE/RPC layer.
I&M0: mandatory identification data (vendor, order ID, serial number, revisions).
I&M1: user-assigned tag function and location strings.
I&M3: free-text descriptor.
I&M4: PROFIsafe signature (binary, not text).
I&M5: free-text annotation.
I&M6-I&M15: reserved for future use per IEC 61158-6-10.
NRD (Network Representation Data) wrapper carrying the actual IOD payload.
Parsed ModuleDiffBlock (0x8104).
Parsed PDRealData (0xF841) structure.
Parsed RealIdentificationData (0xF000/0x0013) structure.
Complete diagnosis data for one slot/subslot.
All I&M records a device supports, read in one call.
Configuration for establishing cyclic IO alongside an AR.
Configuration options for an RPC connection.
Declares Linux Ethernet, addressing, timing, and utility helpers used by the PROFINET stack.