PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
profinet::device::ProfinetDevice Class Reference

High-level PROFINET device interface. More...

#include <device.h>

+ Collaboration diagram for profinet::device::ProfinetDevice:

Public Member Functions

 ProfinetDevice (dcp::DCPDeviceDescription info, std::string interface, MacAddress srcMac, double timeoutSec=5.0, std::unique_ptr< rpc::IRPCCon > rpc=nullptr, std::unique_ptr< IAlarmListener > alarmListener=nullptr)
 Construct a device wrapper directly.
 
 ~ProfinetDevice ()
 Close() the connection and release resources.
 
 ProfinetDevice (const ProfinetDevice &)=delete
 Not copyable (owns an RPC connection and alarm listener).
 
ProfinetDeviceoperator= (const ProfinetDevice &)=delete
 Not copyable (owns an RPC connection and alarm listener).
 
 ProfinetDevice (ProfinetDevice &&)=default
 Move-construct, transferring ownership of the connection.
 
ProfinetDeviceoperator= (ProfinetDevice &&)=default
 Move-assign, transferring ownership of the connection.
 
void Connect ()
 Establish the AR.
 
void Disconnect ()
 Gracefully disconnect (sends Release).
 
void Close ()
 Stop the alarm listener (if running) and fully close the RPC connection.
 
bool IsConnected () const
 Whether the AR is currently established.
 
const std::string & Name () const
 The device's station name.
 
const std::string & Ip () const
 The device's IPv4 address.
 
std::string Mac () const
 The device's MAC address.
 
DeviceInfo GetInfo (bool includeTopology=false)
 Gather a complete device information summary.
 
Bytes Read (std::uint16_t slot, std::uint16_t subslot, std::uint16_t index, std::uint32_t api=0)
 Read a raw record.
 
Bytes ReadImplicit (std::uint16_t slot, std::uint16_t subslot, std::uint16_t index, std::uint32_t api=0)
 Read a record using the AR-less Read Implicit service.
 
void Write (std::uint16_t slot, std::uint16_t subslot, std::uint16_t index, const Bytes &data, std::uint32_t api=0)
 Write a raw record.
 
std::vector< blocks::WriteMultipleResultWriteMultiple (const std::vector< WriteItem > &writes)
 Write multiple records atomically.
 
PNInM0 ReadIm0 (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read I&M0 (mandatory identification data).
 
PNInM1 ReadIm1 (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read I&M1 (tag function/location).
 
PNInM2 ReadIm2 (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read I&M2 (installation date).
 
PNInM3 ReadIm3 (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read I&M3 (free-text descriptor).
 
PNInM4 ReadIm4 (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read I&M4 (PROFIsafe signature).
 
PNInM5 ReadIm5 (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read I&M5 (free-text annotation).
 
rpc::AllIM ReadAllIm (std::uint16_t slot=0, std::uint16_t subslot=1)
 Read all I&M records the device supports.
 
void WriteIm1 (const std::string &tagFunction, const std::string &tagLocation, std::uint16_t slot=0, std::uint16_t subslot=1)
 Write I&M1 (tag function + location).
 
void WriteIm2 (const std::string &date, std::uint16_t slot=0, std::uint16_t subslot=1)
 Write I&M2 (installation date).
 
void WriteIm3 (const std::string &descriptor, std::uint16_t slot=0, std::uint16_t subslot=1)
 Write I&M3 (free-text descriptor).
 
blocks::ModuleDiffBlock ReadModuleDiff ()
 Read and parse the device's ModuleDiffBlock.
 
diagnosis::DiagnosisData ReadDiagnosis (std::uint16_t slot=0, std::uint16_t subslot=0, std::uint16_t index=0xF000)
 Read and parse diagnosis data at the given location/index.
 
std::map< std::uint16_t, diagnosis::DiagnosisDataReadAllDiagnosis ()
 Read diagnosis from all standard diagnosis indices.
 
std::vector< blocks::SlotInfoDiscoverSlots ()
 List the device's populated slots.
 
blocks::PDRealData ReadTopology ()
 Read the device's physical topology.
 
std::optional< AlarmNotificationReadAlarm (std::uint16_t slot=0, std::uint16_t subslot=0, std::uint16_t index=0x800C)
 Attempt to read an alarm notification at the given location.
 
void OnAlarm (std::function< void(const AlarmNotification &)> callback)
 Register a callback for alarm notifications.
 
void StartAlarmListener ()
 Start the background alarm listener.
 
void StopAlarmListener ()
 Stop the alarm listener.
 
bool AlarmListenerRunning () const
 Whether the alarm listener is currently running.
 
std::unique_ptr< cyclic::ICyclicControllerStartCyclic (const rpc::IOCRSetup &iocrSetup, int maxConsecutiveTimeouts=3, std::unique_ptr< cyclic::ICyclicController > controller=nullptr)
 Establish cyclic IO end-to-end.
 
std::map< std::uint16_t, rpc::IndexProbeResultEnumerateIndices (std::uint16_t slot=0, std::uint16_t subslot=1)
 Probe standard indices and report which are readable/empty/erroring.
 
std::string ToString () const
 Human-readable summary of this device, for logging/debugging.
 

Static Public Member Functions

static ProfinetDevice Discover (const std::string &identifier, const std::string &interface, double timeoutSec=10.0)
 Discover a device by station name or MAC address.
 
static ProfinetDevice FromIp (const std::string &ip, const std::string &interface, double timeoutSec=10.0)
 Discover a device by IP address.
 
static ProfinetDevice FromDcpInfo (dcp::DCPDeviceDescription info, const std::string &interface, double timeoutSec=5.0)
 Wrap an already-discovered DCPDeviceDescription.
 

Private Member Functions

rpc::IRPCConEnsureConnected ()
 Return the underlying RPCCon, connecting first if necessary.
 
void ReleaseAr (rpc::IRPCCon &releaseRpc)
 Release a PROFINET Application Relationship.
 

Private Attributes

dcp::DCPDeviceDescription info
 DCP-discovered description of this device.
 
std::string interface
 Network interface name in use.
 
MacAddress srcMac {}
 This host's MAC address.
 
double timeout
 Default RPC response timeout in seconds.
 
std::unique_ptr< rpc::IRPCConrpc
 Underlying RPC connection, created lazily on first use.
 
bool connected = false
 Whether the AR is currently established.
 
std::unique_ptr< IAlarmListeneralarmListener
 Background alarm listener, created lazily by StartAlarmListener().
 
std::vector< std::function< void(const AlarmNotification &)> > alarmCallbacks
 Callbacks registered via OnAlarm(), applied to alarmListener once started.
 

Detailed Description

High-level PROFINET device interface.

Manages its own connection lifecycle (RAII: the destructor calls Close()). Example:

auto device = ProfinetDevice::Discover("my-device", "eth0");
device.Connect();
auto im0 = device.ReadIm0();
device.WriteIm1("Pump Control", "Building A");
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

Definition at line 167 of file device.h.

Constructor & Destructor Documentation

◆ ProfinetDevice() [1/3]

profinet::device::ProfinetDevice::ProfinetDevice ( dcp::DCPDeviceDescription  info,
std::string  interface,
MacAddress  srcMac,
double  timeoutSec = 5.0,
std::unique_ptr< rpc::IRPCCon rpc = nullptr,
std::unique_ptr< IAlarmListener alarmListener = nullptr 
)

Construct a device wrapper directly.

Parameters
infoDCP-discovered description of the target device.
interfaceNetwork interface name to use, e.g. "eth0".
srcMacThis host's MAC address.
timeoutSecDefault RPC response timeout.
rpcConstructor injection of rpc con, used for validation testing
alarmListenerConstructor injection of alarm listener, used for validation testing

Prefer Discover()/FromIp()/FromDcpInfo() instead of calling this constructor directly.

Definition at line 220 of file device.cpp.

◆ ~ProfinetDevice()

profinet::device::ProfinetDevice::~ProfinetDevice ( )

Close() the connection and release resources.

Definition at line 226 of file device.cpp.

References Close().

+ Here is the call graph for this function:

◆ ProfinetDevice() [2/3]

profinet::device::ProfinetDevice::ProfinetDevice ( const ProfinetDevice )
delete

Not copyable (owns an RPC connection and alarm listener).

◆ ProfinetDevice() [3/3]

profinet::device::ProfinetDevice::ProfinetDevice ( ProfinetDevice &&  )
default

Move-construct, transferring ownership of the connection.

Member Function Documentation

◆ AlarmListenerRunning()

bool profinet::device::ProfinetDevice::AlarmListenerRunning ( ) const

Whether the alarm listener is currently running.

Returns
True if StartAlarmListener() was called and StopAlarmListener() was not.

Definition at line 664 of file device.cpp.

References alarmListener.

◆ Close()

void profinet::device::ProfinetDevice::Close ( )

Stop the alarm listener (if running) and fully close the RPC connection.

Called automatically by the destructor.

Definition at line 323 of file device.cpp.

References alarmListener, connected, and rpc.

Referenced by ~ProfinetDevice().

+ Here is the caller graph for this function:

◆ Connect()

void profinet::device::ProfinetDevice::Connect ( )

Establish the AR.

Called automatically by any operation that needs it, but can be called explicitly for early connection. Throws RPCConnectionError on failure.

Definition at line 289 of file device.cpp.

References connected, info, profinet::dcp::DCPDeviceDescription::name, rpc, srcMac, timeout, and profinet::rpc::RPCConOptions::timeoutSec.

Referenced by EnsureConnected().

+ Here is the caller graph for this function:

◆ Disconnect()

void profinet::device::ProfinetDevice::Disconnect ( )

Gracefully disconnect (sends Release).

Keeps the device object reusable for a later Connect().

Definition at line 314 of file device.cpp.

References connected, and rpc.

◆ Discover()

ProfinetDevice profinet::device::ProfinetDevice::Discover ( const std::string &  identifier,
const std::string &  interface,
double  timeoutSec = 10.0 
)
static

Discover a device by station name or MAC address.

Parameters
identifierStation name, or MAC address as "aa:bb:cc:dd:ee:ff".
interfaceNetwork interface name to use, e.g. "eth0".
timeoutSecHow long to wait for a response.
Returns
The discovered device.

Throws DCPDeviceNotFoundError if not found, PermissionDeniedError if raw-socket privileges are insufficient.

Definition at line 231 of file device.cpp.

References profinet::GetMac(), profinet::rpc::GetStationInfo(), info, interface, Mac(), profinet::device::ParseMac(), profinet::dcp::ReadResponse(), profinet::dcp::SendDiscover(), srcMac, and profinet::dcp::DCPDeviceDescription::ToString().

+ Here is the call graph for this function:

◆ DiscoverSlots()

std::vector< blocks::SlotInfo > profinet::device::ProfinetDevice::DiscoverSlots ( )

List the device's populated slots.

Returns
The device's slots.

Definition at line 587 of file device.cpp.

References profinet::rpc::IRPCCon::DiscoverSlots(), and EnsureConnected().

+ Here is the call graph for this function:

◆ EnsureConnected()

rpc::IRPCCon & profinet::device::ProfinetDevice::EnsureConnected ( )
private

Return the underlying RPCCon, connecting first if necessary.

Returns
Reference to the (now-connected) RPCCon.

Definition at line 362 of file device.cpp.

References Connect(), connected, and rpc.

Referenced by DiscoverSlots(), EnumerateIndices(), GetInfo(), Read(), ReadAllDiagnosis(), ReadAllIm(), ReadDiagnosis(), ReadIm0(), ReadIm1(), ReadIm2(), ReadIm3(), ReadIm4(), ReadIm5(), ReadModuleDiff(), ReadTopology(), StartCyclic(), Write(), and WriteMultiple().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ EnumerateIndices()

std::map< std::uint16_t, rpc::IndexProbeResult > profinet::device::ProfinetDevice::EnumerateIndices ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Probe standard indices and report which are readable/empty/erroring.

Parameters
slotSlot number to probe.
subslotSubslot number to probe.
Returns
Probe results keyed by index.

Definition at line 697 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::EnumerateIndices().

+ Here is the call graph for this function:

◆ FromDcpInfo()

ProfinetDevice profinet::device::ProfinetDevice::FromDcpInfo ( dcp::DCPDeviceDescription  info,
const std::string &  interface,
double  timeoutSec = 5.0 
)
static

Wrap an already-discovered DCPDeviceDescription.

Parameters
infoDCP-discovered description (e.g. from a prior Scan()).
interfaceNetwork interface name to use, e.g. "eth0".
timeoutSecDefault RPC response timeout.
Returns
The wrapped device, without performing discovery again.

Definition at line 281 of file device.cpp.

References profinet::GetMac(), info, interface, and srcMac.

+ Here is the call graph for this function:

◆ FromIp()

ProfinetDevice profinet::device::ProfinetDevice::FromIp ( const std::string &  ip,
const std::string &  interface,
double  timeoutSec = 10.0 
)
static

Discover a device by IP address.

Parameters
ipIPv4 address to look for.
interfaceNetwork interface name to use, e.g. "eth0".
timeoutSecHow long to wait for a response.
Returns
The discovered device.

Performs a full DCP Identify broadcast, filtered by IP in the response. Throws DCPDeviceNotFoundError if not found at that IP.

Definition at line 262 of file device.cpp.

References profinet::GetMac(), info, interface, profinet::dcp::DCPDeviceDescription::ip, Mac(), profinet::dcp::ReadResponse(), profinet::dcp::SendDiscover(), and srcMac.

+ Here is the call graph for this function:

◆ GetInfo()

DeviceInfo profinet::device::ProfinetDevice::GetInfo ( bool  includeTopology = false)

Gather a complete device information summary.

Parameters
includeTopologyWhether to also read physical topology (PDRealData).
Returns
The combined device information.

Combines DCP discovery data with I&M0 and (optionally) topology. I&M0/EPM/topology failures are swallowed (matching device.py's "log and continue" behavior) – check the optional fields.

Definition at line 371 of file device.cpp.

References profinet::device::DeviceInfo::annotation, profinet::dcp::DCPDeviceDescription::DeviceId(), profinet::device::DeviceInfo::deviceId, profinet::dcp::DCPDeviceDescription::deviceRoles, profinet::device::DeviceInfo::deviceRoles, profinet::dcp::DCPDeviceDescription::deviceType, profinet::device::DeviceInfo::deviceType, EnsureConnected(), profinet::rpc::EpmLookup(), profinet::dcp::DCPDeviceDescription::gateway, profinet::device::DeviceInfo::gateway, profinet::device::DeviceInfo::im0, info, profinet::dcp::DCPDeviceDescription::ip, profinet::device::DeviceInfo::ip, profinet::dcp::DCPDeviceDescription::mac, profinet::device::DeviceInfo::mac, profinet::dcp::DCPDeviceDescription::name, profinet::device::DeviceInfo::name, profinet::dcp::DCPDeviceDescription::netmask, profinet::device::DeviceInfo::netmask, rpc, profinet::device::DeviceInfo::topology, profinet::dcp::DCPDeviceDescription::VendorId(), profinet::device::DeviceInfo::vendorId, profinet::dcp::DCPDeviceDescription::VendorName(), and profinet::device::DeviceInfo::vendorName.

+ Here is the call graph for this function:

◆ Ip()

const std::string & profinet::device::ProfinetDevice::Ip ( ) const
inline

The device's IPv4 address.

Returns
The IP address from the DCP discovery info.

Definition at line 268 of file device.h.

References info, and profinet::dcp::DCPDeviceDescription::ip.

◆ IsConnected()

bool profinet::device::ProfinetDevice::IsConnected ( ) const
inline

Whether the AR is currently established.

Returns
True if connected.

Definition at line 250 of file device.h.

References connected.

◆ Mac()

std::string profinet::device::ProfinetDevice::Mac ( ) const
inline

The device's MAC address.

Returns
The MAC address, formatted as a string.

Definition at line 275 of file device.h.

References info, and profinet::dcp::DCPDeviceDescription::mac.

Referenced by Discover(), and FromIp().

+ Here is the caller graph for this function:

◆ Name()

const std::string & profinet::device::ProfinetDevice::Name ( ) const
inline

The device's station name.

Returns
The station name from the DCP discovery info.

Definition at line 261 of file device.h.

References info, and profinet::dcp::DCPDeviceDescription::name.

◆ OnAlarm()

void profinet::device::ProfinetDevice::OnAlarm ( std::function< void(const AlarmNotification &)>  callback)

Register a callback for alarm notifications.

Parameters
callbackInvoked for each received alarm.

Can be called before or after StartAlarmListener(); if the listener is already running, the callback is added to it immediately too.

Definition at line 616 of file device.cpp.

References alarmCallbacks, and alarmListener.

◆ operator=() [1/2]

ProfinetDevice & profinet::device::ProfinetDevice::operator= ( const ProfinetDevice )
delete

Not copyable (owns an RPC connection and alarm listener).

◆ operator=() [2/2]

ProfinetDevice & profinet::device::ProfinetDevice::operator= ( ProfinetDevice &&  )
default

Move-assign, transferring ownership of the connection.

Returns
Reference to this device.

◆ Read()

Bytes profinet::device::ProfinetDevice::Read ( std::uint16_t  slot,
std::uint16_t  subslot,
std::uint16_t  index,
std::uint32_t  api = 0 
)

Read a raw record.

Parameters
slotSlot number.
subslotSubslot number.
indexRecord data index to read.
apiAPI number.
Returns
The raw record payload.

Connects automatically if not already connected.

Definition at line 427 of file device.cpp.

References EnsureConnected(), and ReadImplicit().

Referenced by ReadAlarm().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadAlarm()

std::optional< AlarmNotification > profinet::device::ProfinetDevice::ReadAlarm ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 0,
std::uint16_t  index = 0x800C 
)

Attempt to read an alarm notification at the given location.

Parameters
slotSlot number to read the alarm from.
subslotSubslot number to read the alarm from.
indexAlarm record index to read.
Returns
The parsed alarm, or std::nullopt if no alarm is present or the read/parse fails (matching device.py's "return None on any error" behavior).

Definition at line 597 of file device.cpp.

References profinet::ParseAlarmNotification(), and Read().

+ Here is the call graph for this function:

◆ ReadAllDiagnosis()

std::map< std::uint16_t, diagnosis::DiagnosisData > profinet::device::ProfinetDevice::ReadAllDiagnosis ( )

Read diagnosis from all standard diagnosis indices.

Returns
Diagnosis data keyed by index, for indices with at least one entry.

Definition at line 582 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadAllDiagnosis().

+ Here is the call graph for this function:

◆ ReadAllIm()

rpc::AllIM profinet::device::ProfinetDevice::ReadAllIm ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read all I&M records the device supports.

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The records that were successfully read.

Definition at line 512 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadAllIm().

+ Here is the call graph for this function:

◆ ReadDiagnosis()

diagnosis::DiagnosisData profinet::device::ProfinetDevice::ReadDiagnosis ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 0,
std::uint16_t  index = 0xF000 
)

Read and parse diagnosis data at the given location/index.

Parameters
slotSlot number to read diagnosis for.
subslotSubslot number to read diagnosis for.
indexDiagnosis record index to read.
Returns
The parsed diagnosis data (empty if none is present).

Definition at line 576 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadDiagnosis().

+ Here is the call graph for this function:

◆ ReadIm0()

PNInM0 profinet::device::ProfinetDevice::ReadIm0 ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read I&M0 (mandatory identification data).

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The parsed I&M0 record.

Definition at line 488 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadIm0().

+ Here is the call graph for this function:

◆ ReadIm1()

PNInM1 profinet::device::ProfinetDevice::ReadIm1 ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read I&M1 (tag function/location).

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The parsed I&M1 record.

Definition at line 492 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadIm1().

+ Here is the call graph for this function:

◆ ReadIm2()

PNInM2 profinet::device::ProfinetDevice::ReadIm2 ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read I&M2 (installation date).

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The parsed I&M2 record.

Definition at line 496 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadIm2().

+ Here is the call graph for this function:

◆ ReadIm3()

PNInM3 profinet::device::ProfinetDevice::ReadIm3 ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read I&M3 (free-text descriptor).

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The parsed I&M3 record.

Definition at line 500 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadIm3().

+ Here is the call graph for this function:

◆ ReadIm4()

PNInM4 profinet::device::ProfinetDevice::ReadIm4 ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read I&M4 (PROFIsafe signature).

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The parsed I&M4 record.

Definition at line 504 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadIm4().

+ Here is the call graph for this function:

◆ ReadIm5()

PNInM5 profinet::device::ProfinetDevice::ReadIm5 ( std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Read I&M5 (free-text annotation).

Parameters
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).
Returns
The parsed I&M5 record.

Definition at line 508 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadIm5().

+ Here is the call graph for this function:

◆ ReadImplicit()

Bytes profinet::device::ProfinetDevice::ReadImplicit ( std::uint16_t  slot,
std::uint16_t  subslot,
std::uint16_t  index,
std::uint32_t  api = 0 
)

Read a record using the AR-less Read Implicit service.

Reads a PROFINET record from the device without requiring an established Application Relationship (AR).

The device is addressed by IP address only and the ARUUID is set to zero. This allows records to be read from devices that reject or do not support the Device Access AR.

Read Implicit is a read-only service. Writing records requires an established AR and is therefore not supported by this function.

If the device already has an established RPC connection, that connection is reused. Otherwise, a temporary RPC connection is created for the duration of the operation and closed automatically afterwards.

The returned data contains only the record payload and does not include the PROFINET block header.

Parameters
slotSlot number containing the target submodule.
subslotSubslot number containing the target record.
indexPROFINET record index.
apiAPI number. Defaults to 0.
Returns
Raw record payload without the PROFINET block header.
Exceptions
RPCErrorIf the RPC Read Implicit request fails.
PNIOErrorIf the device returns a PROFINET IO error.

Definition at line 444 of file device.cpp.

References profinet::rpc::RPCCon::Close(), connected, info, profinet::PNIODHeader::payload, profinet::rpc::RPCCon::ReadImplicit(), rpc, timeout, and profinet::rpc::RPCConOptions::timeoutSec.

Referenced by Read().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ReadModuleDiff()

blocks::ModuleDiffBlock profinet::device::ProfinetDevice::ReadModuleDiff ( )

Read and parse the device's ModuleDiffBlock.

Returns
The parsed module/submodule configuration differences.

Definition at line 571 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadModuleDiff().

+ Here is the call graph for this function:

◆ ReadTopology()

blocks::PDRealData profinet::device::ProfinetDevice::ReadTopology ( )

Read the device's physical topology.

Returns
The parsed interface and port information.

Definition at line 592 of file device.cpp.

References EnsureConnected(), and profinet::rpc::IRPCCon::ReadPdRealData().

+ Here is the call graph for this function:

◆ ReleaseAr()

void profinet::device::ProfinetDevice::ReleaseAr ( rpc::IRPCCon releaseRpc)
private

Release a PROFINET Application Relationship.

Performs best-effort teardown of the specified RPC connection.

Alarm processing is stopped first, followed by the PROFINET RPC disconnect procedure. A disconnect failure is intentionally ignored because this function is used for cleanup and the RPC connection must still be closed afterwards.

After closing the connection, the controller's RPC and connection state are cleared only if the supplied RPC connection is still the connection currently owned by the controller.

This prevents an older/stale RPC connection from clearing the state of a newer connection.

Parameters
releaseRpcRPC connection representing the Application Relationship to release.

LOG_DEBUG("AR release failed: {}", e.what());

Definition at line 338 of file device.cpp.

References profinet::rpc::IRPCCon::Close(), connected, profinet::rpc::IRPCCon::Disconnect(), rpc, and StopAlarmListener().

+ Here is the call graph for this function:

◆ StartAlarmListener()

void profinet::device::ProfinetDevice::StartAlarmListener ( )

Start the background alarm listener.

Requires an established connection with AlarmCR enabled (i.e. Connect() must have been called, and the device must have accepted an AlarmCR – reconnect via the RPCCon directly with WithAlarmCr=true if needed since ProfinetDevice::Connect() always requests one). Throws std::runtime_error if not connected or AlarmCR unavailable.

Definition at line 625 of file device.cpp.

References alarmCallbacks, alarmListener, connected, profinet::AlarmEndpoint::controllerRef, profinet::AlarmEndpoint::deviceMac, profinet::AlarmEndpoint::deviceRef, info, profinet::AlarmEndpoint::interface, interface, profinet::dcp::DCPDeviceDescription::mac, rpc, srcMac, profinet::String2Mac(), and profinet::AlarmEndpoint::transport.

+ Here is the call graph for this function:

◆ StartCyclic()

std::unique_ptr< cyclic::ICyclicController > profinet::device::ProfinetDevice::StartCyclic ( const rpc::IOCRSetup iocrSetup,
int  maxConsecutiveTimeouts = 3,
std::unique_ptr< cyclic::ICyclicController controller = nullptr 
)

Establish cyclic IO end-to-end.

Parameters
iocrSetupCyclic IO configuration (slots, timing parameters).
maxConsecutiveTimeoutsConsecutive watchdog timeouts before transitioning to Fault.
controllerInjectable CyclicController, used to validate working.
Returns
The running controller (caller owns its lifecycle from here – call Stop() on it when done).

Reconnects with an IOCR+AlarmCR setup, sends PrmEnd, waits for ApplicationReady, then starts a CyclicController. EXPERIMENTAL, per cyclic.h's own caveat: not validated against real hardware. Throws RPCConnectionError/RPCError/std::runtime_error on failure.

Definition at line 670 of file device.cpp.

References profinet::rt::BuildIocrConfigs(), EnsureConnected(), info, interface, profinet::dcp::DCPDeviceDescription::mac, profinet::rpc::IOCRSetup::reductionRatio, profinet::rpc::IOCRSetup::sendClockFactor, profinet::rpc::IOCRSetup::slots, srcMac, profinet::String2Mac(), and profinet::rpc::IOCRSetup::watchdogFactor.

+ Here is the call graph for this function:

◆ StopAlarmListener()

void profinet::device::ProfinetDevice::StopAlarmListener ( )

Stop the alarm listener.

Safe to call even if not running.

Definition at line 655 of file device.cpp.

References alarmListener.

Referenced by ReleaseAr().

+ Here is the caller graph for this function:

◆ ToString()

std::string profinet::device::ProfinetDevice::ToString ( ) const

Human-readable summary of this device, for logging/debugging.

Returns
A string like "ProfinetDevice('my-device', 192.168.1.10, connected)".

Definition at line 703 of file device.cpp.

References connected, info, profinet::dcp::DCPDeviceDescription::ip, and profinet::dcp::DCPDeviceDescription::name.

◆ Write()

void profinet::device::ProfinetDevice::Write ( std::uint16_t  slot,
std::uint16_t  subslot,
std::uint16_t  index,
const Bytes data,
std::uint32_t  api = 0 
)

Write a raw record.

Parameters
slotSlot number.
subslotSubslot number.
indexRecord data index to write.
dataRecord data to write.
apiAPI number.

Connects automatically if not already connected.

Definition at line 469 of file device.cpp.

References EnsureConnected().

Referenced by WriteIm1(), WriteIm2(), and WriteIm3().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ WriteIm1()

void profinet::device::ProfinetDevice::WriteIm1 ( const std::string &  tagFunction,
const std::string &  tagLocation,
std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Write I&M1 (tag function + location).

Parameters
tagFunctionFunction description (max 32 chars).
tagLocationInstallation location (max 22 chars).
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).

Throws std::invalid_argument if TagFunction exceeds 32 chars or TagLocation exceeds 22 chars.

Definition at line 517 of file device.cpp.

References profinet::IM1, and Write().

+ Here is the call graph for this function:

◆ WriteIm2()

void profinet::device::ProfinetDevice::WriteIm2 ( const std::string &  date,
std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Write I&M2 (installation date).

Parameters
dateDate string, "YYYY-MM-DD HH:MM" format expected (max 16 chars).
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).

Throws std::invalid_argument if Date exceeds 16 chars.

Definition at line 539 of file device.cpp.

References profinet::IM2, and Write().

+ Here is the call graph for this function:

◆ WriteIm3()

void profinet::device::ProfinetDevice::WriteIm3 ( const std::string &  descriptor,
std::uint16_t  slot = 0,
std::uint16_t  subslot = 1 
)

Write I&M3 (free-text descriptor).

Parameters
descriptorDescriptor text (max 54 chars).
slotSlot number (defaults to 0, the device's DAP).
subslotSubslot number (defaults to 1).

Throws std::invalid_argument if Descriptor exceeds 54 chars.

Definition at line 555 of file device.cpp.

References profinet::IM3, and Write().

+ Here is the call graph for this function:

◆ WriteMultiple()

std::vector< blocks::WriteMultipleResult > profinet::device::ProfinetDevice::WriteMultiple ( const std::vector< WriteItem > &  writes)

Write multiple records atomically.

Parameters
writesThe individual write operations to perform.
Returns
Per-write results.

Definition at line 476 of file device.cpp.

References EnsureConnected().

+ Here is the call graph for this function:

Member Data Documentation

◆ alarmCallbacks

std::vector<std::function<void(const AlarmNotification&)> > profinet::device::ProfinetDevice::alarmCallbacks
private

Callbacks registered via OnAlarm(), applied to alarmListener once started.

Definition at line 562 of file device.h.

Referenced by OnAlarm(), and StartAlarmListener().

◆ alarmListener

std::unique_ptr<IAlarmListener> profinet::device::ProfinetDevice::alarmListener
private

Background alarm listener, created lazily by StartAlarmListener().

Definition at line 559 of file device.h.

Referenced by AlarmListenerRunning(), Close(), OnAlarm(), StartAlarmListener(), and StopAlarmListener().

◆ connected

bool profinet::device::ProfinetDevice::connected = false
private

Whether the AR is currently established.

Definition at line 556 of file device.h.

Referenced by Close(), Connect(), Disconnect(), EnsureConnected(), IsConnected(), ReadImplicit(), ReleaseAr(), StartAlarmListener(), and ToString().

◆ info

dcp::DCPDeviceDescription profinet::device::ProfinetDevice::info
private

DCP-discovered description of this device.

Definition at line 541 of file device.h.

Referenced by Connect(), Discover(), FromDcpInfo(), FromIp(), GetInfo(), Ip(), Mac(), Name(), ReadImplicit(), StartAlarmListener(), StartCyclic(), and ToString().

◆ interface

std::string profinet::device::ProfinetDevice::interface
private

Network interface name in use.

Definition at line 544 of file device.h.

Referenced by Discover(), FromDcpInfo(), FromIp(), StartAlarmListener(), and StartCyclic().

◆ rpc

std::unique_ptr<rpc::IRPCCon> profinet::device::ProfinetDevice::rpc
private

Underlying RPC connection, created lazily on first use.

Definition at line 553 of file device.h.

Referenced by Close(), Connect(), Disconnect(), EnsureConnected(), GetInfo(), ReadImplicit(), ReleaseAr(), and StartAlarmListener().

◆ srcMac

MacAddress profinet::device::ProfinetDevice::srcMac {}
private

This host's MAC address.

Definition at line 547 of file device.h.

Referenced by Connect(), Discover(), FromDcpInfo(), FromIp(), StartAlarmListener(), and StartCyclic().

◆ timeout

double profinet::device::ProfinetDevice::timeout
private

Default RPC response timeout in seconds.

Definition at line 550 of file device.h.

Referenced by Connect(), and ReadImplicit().


The documentation for this class was generated from the following files: