Motion Master
Loading...
Searching...
No Matches
spoe.h
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <boost/asio.hpp>
5#include <chrono>
6#include <nlohmann/json.hpp>
7#include <string>
8
9#include "base.h"
10#include "core/util.h"
11
12namespace mm::comm::spoe {
13
22enum class SpoeMessageType : uint8_t {
23 SDO_READ = 0x01,
24 SDO_WRITE = 0x02,
26 0x03,
27 PDO_CONTROL = 0x04,
28 SDO_BATCH_READ = 0x06,
29 FIRMWARE_UPDATE = 0x0B,
30 FILE_READ = 0x0C,
31 FILE_WRITE = 0x0D,
33 0x0E,
34 STATE_READ = 0x0F,
35 // PARAM_INDEXES_LIST = 0x10, ///< Request a list of parameter indexes.
36 PARAM_LIST = 0x13,
37 SERVER_INFO = 0x20
38};
39
46enum class SpoeMessageRequestStatus : uint8_t {
47 OK = 0x00,
48 FIRST = 0x80,
49 MIDDLE = 0xC0,
50 LAST = 0x40,
51};
52
57enum class SpoeMessageParamListErrorStatus : uint8_t {
58 SUCCESS_ACK = 0x58,
59
60 ERR = 0x63,
61 BUSY_INDICATION = 0x28,
62};
63
70enum class SpoeMessageSdoStatus : uint16_t {
71 NO_ERR = 0x0000,
72 GENERIC = 0x0001,
73 NOT_FOUND = 0x0002,
74 READ_ONLY = 0x0003,
75 WRITE_ONLY = 0x0004,
76 WRONG_TYPE = 0x0005,
77 INVALID_LIST = 0x0006,
78 INSUFFICIENT_BUFFER = 0x0007,
79 VALUEINFO_UNAVAILABLE = 0x0008,
81 LOCAL_TRANSFER = 0x000A,
82 UNSUPPORTED_ACCESS = 0x000B,
83 SI0_NOT_ZERO = 0x000C,
84 SUB_NOT_FOUND = 0x000D,
85};
86
87// enum class SpoeMessageSdoStatus : uint16_t {
88// NO_ERROR = 0x0000,
89// };
90
95enum class SpoeMessageFileErrorStatus : uint8_t {
96 SUCCESS_ACK = 0x58,
97
98 UNDEFINED = 0x00,
99 NOT_FOUND = 0x01,
100 ACCESS_DENIED = 0x02,
101 STORAGE_FULL = 0x03,
102 ILLEGAL_REQ = 0x04,
103 PACKET_NUMBER = 0x05,
104 ALREADY_EXISTS = 0x06,
105 NO_USER = 0x07,
106 BOOTSTRAP_ONLY = 0x08,
107 NOT_BOOTSTRAP = 0x09,
108 NO_RIGHTS = 0x0A,
109 PROGRAM_ERROR = 0x0B,
110 BUSY = 0x0C,
111 FILENAME_LEN = 0x0D,
112 TIMEOUT = 0x0E,
113 FLASH_BUSY = 0x28,
115};
116
123enum class SpoeMessagePacketStatus : uint8_t {
124 OK = 0x00,
125 FIRST = 0x80,
126 MIDDLE = 0xC0,
127 LAST = 0x40,
128};
129
141enum class PdoMode : uint8_t {
142 NONE = 0,
143 MONITOR =
144 1,
145 CONTROL = 2
146};
147
155struct Message {
157 static constexpr size_t kHeaderSize = 7;
158
160 static constexpr size_t kBufferSize = 1500 - kHeaderSize;
161
167
173 uint16_t id;
174
180 uint16_t status;
181
187 uint16_t size;
188
194 std::vector<uint8_t> data;
195};
196
198
215Message parseMessage(const std::vector<uint8_t>& buffer);
216
230std::vector<uint8_t> serializeSpoeMessage(const Message& message);
231
242
247};
248
262 public:
263 // Forward constructor to base class constructor
265 std::chrono::milliseconds interval);
266
267 protected:
285 void refresh(const std::vector<mm::comm::base::Parameter::Address>& addresses)
286 override;
287};
288
299 public:
313 Device(const std::string& ip, uint16_t port, uint16_t position = 0,
314 std::chrono::milliseconds refresherInterval =
315 std::chrono::milliseconds(3000));
316
322 ~Device();
323
332 std::string getSocketAddress() const;
333
346 uint16_t incrementSeqId();
347
358 bool connect(std::chrono::seconds expiryTime = std::chrono::seconds(3));
359
368 bool isConnected();
369
383 bool disconnect();
384
403 const Message& request,
404 const std::chrono::steady_clock::duration expiryTime);
405
406 uint16_t getPosition() const override;
407
435 uint8_t getState(bool refresh = false,
436 const std::chrono::steady_clock::duration expiryTime =
437 std::chrono::milliseconds(5000)) override;
438
456 bool setState(uint8_t state,
457 const std::chrono::steady_clock::duration expiryTime =
458 std::chrono::milliseconds(5000)) override;
459
510 std::vector<uint8_t> readFile(
511 const std::string& filename,
512 const std::chrono::steady_clock::duration expiryTime =
513 std::chrono::milliseconds(5000)) override;
514
515 std::vector<std::string> readFileList(
516 const bool stripSizeSuffix = true,
517 const std::chrono::steady_clock::duration expiryTime =
518 std::chrono::milliseconds(5000)) override;
519
537 void removeFile(const std::string& filename,
538 const std::chrono::steady_clock::duration expiryTime =
539 std::chrono::milliseconds(5000)) override;
540
563 const std::vector<std::uint8_t>& data,
564 const std::vector<std::string>& skipFiles = {"SOMANET_CiA_402.xml.zip",
565 "stack_image.svg.zip"},
566 std::function<void(uint8_t, std::string)> progressCallback = nullptr,
567 const std::chrono::steady_clock::duration expiryTime =
568 std::chrono::milliseconds(60000)) override;
569
591 void writeFile(const std::string& filename, const std::vector<uint8_t>& data,
592 const std::chrono::steady_clock::duration expiryTime =
593 std::chrono::milliseconds(5000)) override;
594
611 bool triggerFirmwareUpdate(const std::chrono::steady_clock::duration
612 expiryTime = std::chrono::milliseconds(2000));
613
640 std::vector<mm::comm::base::Parameter> getParametersFromDevice(
641 bool readValues = false,
642 const std::chrono::steady_clock::duration expiryTime =
643 std::chrono::milliseconds(1000));
644
664 std::vector<uint8_t> readSdo(
665 uint16_t index, uint8_t subindex,
666 const std::chrono::steady_clock::duration expiryTime =
667 std::chrono::milliseconds(1000));
668
697 std::vector<std::vector<uint8_t>> readSdoBatch(
698 const std::vector<mm::comm::base::Parameter::Address>& addresses,
699 const std::chrono::steady_clock::duration expiryTime =
700 std::chrono::milliseconds(1000));
701
714 std::vector<std::vector<uint8_t>> readSdoBatch(
715 const std::vector<mm::comm::base::Parameter>& parameters,
716 const std::chrono::steady_clock::duration expiryTime =
717 std::chrono::milliseconds(1000));
718
731 std::vector<mm::comm::base::Parameter>& parameters,
732 std::size_t batchSize = 50,
733 std::chrono::steady_clock::duration expiryTime =
734 std::chrono::milliseconds(1000));
735
755 bool writeSdo(uint16_t index, uint8_t subindex,
756 const std::vector<uint8_t>& data,
757 const std::chrono::steady_clock::duration expiryTime =
758 std::chrono::milliseconds(1000));
759
773 size_t loadParameters(bool readValues = false,
774 const std::chrono::steady_clock::duration expiryTime =
775 std::chrono::milliseconds(9000)) override;
776
777 void clearParameters() override;
778
790 std::vector<std::reference_wrapper<mm::comm::base::Parameter>> parameters()
791 override;
792
794 uint8_t subindex) override;
795
797 const uint16_t index, const uint8_t subindex,
798 const std::chrono::steady_clock::duration expiryTime =
799 std::chrono::milliseconds(3000)) override;
800
821 template <typename T>
822 T upload(uint16_t index, uint8_t subindex,
823 const std::chrono::steady_clock::duration expiryTime =
824 std::chrono::milliseconds(5000)) {
825 mm::comm::base::Parameter& parameter = upload(index, subindex, expiryTime);
826 return parameter.getValue<T>();
827 }
828
829 void download(uint16_t index, uint8_t subindex,
830 const std::chrono::steady_clock::duration expiryTime =
831 std::chrono::milliseconds(5000)) override;
832
833 void download(uint16_t index, uint8_t subindex,
835 const std::chrono::steady_clock::duration expiryTime =
836 std::chrono::milliseconds(5000)) override;
837
856 template <typename T>
857 void download(uint16_t index, uint8_t subindex, const T& value,
858 const std::chrono::steady_clock::duration expiryTime =
859 std::chrono::milliseconds(5000)) {
861 }
862
878 ServerInfo getServerInfo(const std::chrono::steady_clock::duration
879 expiryTime = std::chrono::milliseconds(3000));
880
881 bool setPdoMode(PdoMode mode,
882 const std::chrono::steady_clock::duration expiryTime =
883 std::chrono::milliseconds(3000));
884
902 std::vector<uint8_t> exchangeProcessData(
903 const std::vector<uint8_t>& data,
904 const std::chrono::steady_clock::duration expiryTime =
905 std::chrono::milliseconds(1000));
906
927
944 uint64_t missedCycles = 0) override;
945
947 uint16_t index, uint8_t subindex) const override;
948
963
974 bool isOnline() override;
975
980 DeviceParameterRefresher& refresher() { return refresher_; }
981
982 private:
983 boost::asio::io_context ioContext_;
985 boost::asio::ip::tcp::endpoint
986 endpoint_;
988 boost::asio::ip::tcp::socket
989 socket_;
990
997 std::recursive_mutex
998 mutex_;
999
1000 std::mutex disconnectMutex_;
1001
1009 std::atomic<uint16_t> seqId_{0};
1010
1011 uint16_t position_;
1013
1014 uint8_t state_;
1016
1017 std::unordered_map<mm::comm::base::Parameter::Address,
1019 parametersMap_;
1022 pdoMappings_;
1023
1024 std::atomic_flag isSendingAndReceivingProcessData_ =
1025 ATOMIC_FLAG_INIT;
1027
1029 txPdoQueue_;
1030
1031 std::mutex
1032 sendAndReceiveProcessDataExceptionPtrMutex_;
1035
1036 std::exception_ptr sendAndReceiveProcessDataExceptionPtr_ =
1037 nullptr;
1039
1040 DeviceParameterRefresher refresher_;
1042};
1043
1044} // namespace mm::comm::spoe
Base class for periodically refreshing a set of device parameters in a background thread.
Definition: base.h:1605
Abstract interface representing a generic device.
Definition: base.h:1032
Represents a device parameter identified by index and subindex.
Definition: base.h:463
ParameterValue getValue() const
Retrieves the value of the parameter based on its data type.
Definition: base.cc:36
std::pair< uint16_t, uint8_t > Address
Alias for a pair of uint16_t and uint8_t representing a parameter address.
Definition: base.h:473
Concrete refresher that uploads parameters from a device.
Definition: spoe.h:261
void refresh(const std::vector< mm::comm::base::Parameter::Address > &addresses) override
Rereads the specified device parameters in a single message exchange.
Definition: spoe.cc:65
Handles TCP communication with SOMANET devices over SPoE.
Definition: spoe.h:298
mm::comm::base::Parameter & findParameter(uint16_t index, uint8_t subindex) override
Finds and returns a reference to a parameter by its index and subindex.
Definition: spoe.cc:1012
size_t loadParameters(bool readValues=false, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(9000)) override
Loads parameters from the device and stores them locally.
Definition: spoe.cc:988
void clearParameters() override
Clears all loaded object dictionary parameters.
Definition: spoe.cc:998
void removeFile(const std::string &filename, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Remove a file from the SPoE device.
Definition: spoe.cc:477
Message exchangeWithTimeout(const Message &request, const std::chrono::steady_clock::duration expiryTime)
Exchanges a message with a remote server and waits for a response with a timeout.
Definition: spoe.cc:236
DeviceParameterRefresher & refresher()
Get a reference to the device parameter refresher.
Definition: spoe.h:980
bool setState(uint8_t state, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Sends a state control command to the SPoE device and checks the response.
Definition: spoe.cc:332
void readSdoBatchAndUpdateParameters(std::vector< mm::comm::base::Parameter > &parameters, std::size_t batchSize=50, std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(1000))
Reads the specified parameters in batches and updates their values.
Definition: spoe.cc:916
uint16_t getPosition() const override
Gets the device's position in the network chain.
Definition: spoe.cc:305
bool isConnected()
Checks if the SPoE socket is currently open.
Definition: spoe.cc:198
std::vector< std::reference_wrapper< mm::comm::base::Parameter > > parameters() override
Get a vector of references to parameters.
Definition: spoe.cc:1001
bool writeSdo(uint16_t index, uint8_t subindex, const std::vector< uint8_t > &data, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(1000))
Writes a Service Data Object (SDO) to the device.
Definition: spoe.cc:941
std::vector< uint8_t > readFile(const std::string &filename, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Reads a file from the device using segmented SPoE messages.
Definition: spoe.cc:358
void writeFile(const std::string &filename, const std::vector< uint8_t > &data, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Write a file to the SPoE device in segments.
Definition: spoe.cc:544
void performProcessDataExchangeAsync()
Perform asynchronous process data exchange with the SPoE device.
Definition: spoe.cc:1157
std::vector< uint8_t > exchangeProcessData(const std::vector< uint8_t > &data, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(1000))
Exchanges process data (PDO) with the device.
Definition: spoe.cc:1127
std::string getSocketAddress() const
Returns the socket address as a string in the format "IP:port".
Definition: spoe.cc:150
bool connect(std::chrono::seconds expiryTime=std::chrono::seconds(3))
Attempts to connect the SPoE device to the specified endpoint.
Definition: spoe.cc:160
void download(uint16_t index, uint8_t subindex, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Downloads a parameter to the device using SDO communication.
Definition: spoe.cc:1045
std::vector< uint8_t > readSdo(uint16_t index, uint8_t subindex, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(1000))
Reads an SDO (Service Data Object) from the device.
Definition: spoe.cc:787
void download(uint16_t index, uint8_t subindex, const T &value, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000))
Sets and downloads a parameter value to the device using the specified type.
Definition: spoe.h:857
T upload(uint16_t index, uint8_t subindex, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000))
Uploads a parameter from the device and returns its value as the specified type.
Definition: spoe.h:822
~Device()
Destructor for the Device class.
Definition: spoe.cc:145
bool triggerFirmwareUpdate(const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(2000))
Sends a firmware update request to the connected Integro device.
Definition: spoe.cc:606
uint8_t getState(bool refresh=false, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Sends a request to read the state of the device and returns the state value.
Definition: spoe.cc:307
mm::comm::base::MappedParameterValues getMappedParameterValues()
Retrieves the mapped parameter values for the SPoE device.
Definition: spoe.cc:1306
std::vector< std::vector< uint8_t > > readSdoBatch(const std::vector< mm::comm::base::Parameter::Address > &addresses, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(1000))
Reads a batch of SDOs from the device in a single request.
Definition: spoe.cc:823
bool isOnline() override
Checks if the SPoE device is online.
Definition: spoe.cc:1324
mm::comm::base::PdoMappingStatus getPdoMappingStatus(uint16_t index, uint8_t subindex) const override
Determines the PDO mapping status of a parameter by its index and subindex.
Definition: spoe.cc:1278
uint16_t incrementSeqId()
Increments the sequence ID atomically and wraps it around at the maximum value.
Definition: spoe.cc:155
mm::comm::base::Parameter & upload(const uint16_t index, const uint8_t subindex, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(3000)) override
Uploads a parameter from the device via SDO and updates the local parameter store.
Definition: spoe.cc:1025
bool disconnect()
Gracefully disconnects the SPoE device.
Definition: spoe.cc:200
void updateFirmware(const std::vector< std::uint8_t > &data, const std::vector< std::string > &skipFiles={"SOMANET_CiA_402.xml.zip", "stack_image.svg.zip"}, std::function< void(uint8_t, std::string)> progressCallback=nullptr, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(60000)) override
Updates the firmware on this SPoE device.
bool setPdoMode(PdoMode mode, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(3000))
Definition: spoe.cc:1107
void exchangeProcessDataAndUpdateParameters(uint64_t missedCycles=0) override
Exchanges process data and updates device parameters.
Definition: spoe.cc:1217
std::vector< std::string > readFileList(const bool stripSizeSuffix=true, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(5000)) override
Reads a list of file names from the device.
Definition: spoe.cc:439
ServerInfo getServerInfo(const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(3000))
Retrieves the server information from the connected SPoE device.
Definition: spoe.cc:1071
std::vector< mm::comm::base::Parameter > getParametersFromDevice(bool readValues=false, const std::chrono::steady_clock::duration expiryTime=std::chrono::milliseconds(1000))
Retrieves the parameter list from the device.
Definition: spoe.cc:625
A simple thread-safe FIFO queue.
Definition: util.h:484
uint8_t type
Definition: co_dictionary.h:1
uint8_t * value
Definition: co_dictionary.h:9
uint16_t index
Definition: co_dictionary.h:0
std::variant< bool, std::int8_t, std::int16_t, std::int32_t, std::int64_t, std::uint8_t, std::uint16_t, std::uint32_t, std::uint64_t, float, double, std::string, std::vector< std::uint8_t > > ParameterValue
Definition: base.h:405
PdoMappingStatus
Represents the PDO mapping status of a parameter.
Definition: base.h:436
Definition: spoe.cc:10
SpoeMessagePacketStatus
Packet status codes for SPoE messages.
Definition: spoe.h:123
SpoeMessageFileErrorStatus
Error status codes returned when reading or writing a file via SPoE message.
Definition: spoe.h:95
SpoeMessageParamListErrorStatus
Error status codes returned when reading the parameter list via SPoE.
Definition: spoe.h:57
PdoMode
Defines the modes for Process Data Object (PDO) communication over SPoE.
Definition: spoe.h:141
@ NONE
No process or cyclic data exchange available.
@ CONTROL
Both RxPDO and TxPDO data exchange enabled.
@ MONITOR
Device sends RxPDO values only; incoming requests are ignored.
std::vector< uint8_t > serializeSpoeMessage(const Message &message)
Serializes an SpoeMessage object into a byte buffer.
Definition: spoe.cc:39
SpoeMessageType
Enumeration of SPoE message types used in the protocol.
Definition: spoe.h:22
@ SDO_BATCH_READ
Read multiple SDOs in a single request.
@ SERVER_INFO
Request information about the server or device.
@ STATE_CONTROL
Control the state of the device (e.g., INIT, PREOP).
@ FILE_READ
Read a file from the device.
@ STATE_READ
Read the current state of the device.
@ SDO_WRITE
Write a value to a Service Data Object (SDO).
@ SDO_READ
Read a Service Data Object (SDO) value.
@ FIRMWARE_UPDATE
Perform firmware update operation.
@ FILE_WRITE
Write a file to the device.
@ PDO_CONTROL
Control or configure PDO behavior.
@ PARAM_LIST
Request a full list of parameters.
@ PDO_RXTX_FRAME
Transmit or receive a Process Data Object (PDO) frame.
SpoeMessageRequestStatus
Status codes representing the state of an SPoE request message.
Definition: spoe.h:46
@ FIRST
First segment of a multi-part message.
@ MIDDLE
Middle segment of a multi-part message.
@ OK
Message is complete and valid.
@ LAST
Last segment of a multi-part message.
SpoeMessageSdoStatus
Status codes returned during SDO (Service Data Object) read and write operations.
Definition: spoe.h:70
@ NO_ERR
Success Acknowledgement.
Message parseMessage(const std::vector< uint8_t > &buffer)
Parses a raw SPoE message buffer into a structured SpoeMessage.
Definition: spoe.cc:12
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Message, type, id, status, size, data)
Holds collections of mapped parameter values for RX and TX directions.
Definition: base.h:425
Represents the mapped PDO entries for a slave device.
Definition: base.h:145
Definition: spoe.h:155
uint16_t status
The status of the response message.
Definition: spoe.h:180
uint16_t size
The size of the buffer in the response message.
Definition: spoe.h:187
static constexpr size_t kBufferSize
Definition: spoe.h:160
SpoeMessageType type
The type of the response message.
Definition: spoe.h:166
std::vector< uint8_t > data
The payload data of the response message.
Definition: spoe.h:194
static constexpr size_t kHeaderSize
Definition: spoe.h:157
uint16_t id
The sequence ID of the response message.
Definition: spoe.h:173
Contains information about the server's protocol version and monitoring mode.
Definition: spoe.h:237
uint16_t protocolVersion
Version of the communication protocol used by the server.
Definition: spoe.h:241
uint8_t monitoringMode
Indicates the monitoring mode configuration.
Definition: spoe.h:246