Lely core libraries 2.3.4
sdo_error.cpp
Go to the documentation of this file.
1
24#include "coapp.hpp"
25#include <lely/co/sdo.h>
27#include <lely/util/error.hpp>
28
29#include <iomanip>
30#include <sstream>
31#include <string>
32
33namespace lely {
34
35namespace canopen {
36
37namespace {
38
39class SdoErrcCategory : public ::std::error_category {
40 public:
41 const char*
42 name() const noexcept override {
43 return "SDO";
44 }
45
46 ::std::error_condition default_error_condition(
47 int ev) const noexcept override;
48
49 ::std::string
50 message(int ev) const override {
51 return co_sdo_ac2str(ev);
52 }
53};
54
55::std::error_condition
56SdoErrcCategory::default_error_condition(int ev) const noexcept {
57 switch (static_cast<SdoErrc>(ev)) {
58 case SdoErrc::TOGGLE:
59 return ::std::errc::protocol_error;
61 return ::std::errc::timed_out;
62 case SdoErrc::NO_CS:
65 return ::std::errc::protocol_error;
67 return ::std::errc::illegal_byte_sequence;
68 case SdoErrc::NO_MEM:
69 return ::std::errc::not_enough_memory;
73 return ::std::errc::permission_denied;
74 case SdoErrc::NO_OBJ:
75 return ::std::errc::no_such_file_or_directory;
76 // case SdoErrc::NO_PDO:
77 // case SdoErrc::PDO_LEN:
78 case SdoErrc::PARAM:
79 return ::std::errc::invalid_argument;
80 case SdoErrc::COMPAT:
81 return ::std::errc::no_such_device_or_address;
83 return ::std::errc::io_error;
87 return ::std::errc::invalid_argument;
88 case SdoErrc::NO_SUB:
89 return ::std::errc::no_such_file_or_directory;
91 return ::std::errc::invalid_argument;
95 return ::std::errc::result_out_of_range;
96 case SdoErrc::NO_SDO:
97 return ::std::errc::protocol_not_supported;
98 // case SdoErrc::ERROR:
99 case SdoErrc::DATA:
100 return ::std::errc::io_error;
103 return ::std::errc::device_or_resource_busy;
104 // case SdoErrc::NO_OD:
105#if !defined(__MINGW32__) || defined(ENODATA)
106 case SdoErrc::NO_VAL:
107 return ::std::errc::no_message_available;
108#endif
109 default:
110 return ::std::error_condition(ev, *this);
111 }
112}
113
114::std::string
115SdoWhat(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec,
116 const ::std::string& what_arg = "") {
117 ::std::stringstream ss;
118 ss << ::std::uppercase << ::std::setfill('0') << ::std::hex;
119 if (!what_arg.empty()) ss << what_arg << ':';
120 ss << ::std::setw(2) << int(id) << ':';
121 ss << ::std::setw(4) << idx << ':' << ::std::setw(2) << int(subidx) << ": ";
122 ss << ec.message();
123 ss << " (" << ::std::setw(8) << uint32_t(ec.value()) << ')';
124 return ss.str();
125}
126
127} // namespace
128
129SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx,
130 ::std::error_code ec)
131 : ::std::system_error(ec, SdoWhat(id, idx, subidx, ec)),
132 id_(id),
133 idx_(idx),
134 subidx_(subidx) {}
135
136SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx,
137 ::std::error_code ec, const ::std::string& what_arg)
138 : ::std::system_error(ec, SdoWhat(id, idx, subidx, ec, what_arg)),
139 id_(id),
140 idx_(idx),
141 subidx_(subidx) {}
142
143SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx,
144 ::std::error_code ec, const char* what_arg)
145 : ::std::system_error(ec, SdoWhat(id, idx, subidx, ec, what_arg)),
146 id_(id),
147 idx_(idx),
148 subidx_(subidx) {}
149
150SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx, int ev)
151 : SdoError(id, idx, subidx, ::std::error_code(ev, SdoCategory())) {}
152
153SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx, int ev,
154 const ::std::string& what_arg)
155 : SdoError(id, idx, subidx, ::std::error_code(ev, SdoCategory()),
156 what_arg) {}
157
158SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx, int ev,
159 const char* what_arg)
160 : SdoError(id, idx, subidx, ::std::error_code(ev, SdoCategory()),
161 what_arg) {}
162
163const ::std::error_category&
165 static const SdoErrcCategory category;
166 return category;
167}
168
169::std::error_code
171 return {static_cast<int>(e), SdoCategory()};
172}
173
174::std::error_condition
176 return {static_cast<int>(e), SdoCategory()};
177}
178
179SdoErrc
180sdo_errc(::std::error_code ec) {
181 if (ec) {
182 if (ec.category() == SdoCategory()) {
183 return static_cast<SdoErrc>(ec.value());
184 } else if (ec.category() == ::std::generic_category()) {
185 switch (static_cast<::std::errc>(ec.value())) {
186 case ::std::errc::timed_out:
187 return SdoErrc::TIMEOUT;
188 case ::std::errc::not_enough_memory:
189 return SdoErrc::NO_MEM;
190 default:
191 return SdoErrc::ERROR;
192 }
193 } else if (ec.category() == ::std::system_category()) {
194 switch (errc2num(ec.value())) {
195 case ERRNUM_TIMEDOUT:
196 return SdoErrc::TIMEOUT;
197 case ERRNUM_NOMEM:
198 return SdoErrc::NO_MEM;
199 default:
200 return SdoErrc::ERROR;
201 }
202 }
203 return SdoErrc::ERROR;
204 }
205 return static_cast<SdoErrc>(0);
206}
207
208::std::exception_ptr
210 ::std::error_code ec) noexcept {
211 try {
212 if (ec.category() == SdoCategory())
213 return ::std::make_exception_ptr(SdoError(id, idx, subidx, ec));
214 else
215 return ::std::make_exception_ptr(::std::system_error(ec));
216 } catch (...) {
217 return ::std::current_exception();
218 }
219}
220
221::std::exception_ptr
223 ::std::error_code ec,
224 const ::std::string& what_arg) noexcept {
225 try {
226 if (ec.category() == SdoCategory())
227 return ::std::make_exception_ptr(SdoError(id, idx, subidx, ec, what_arg));
228 else
229 return ::std::make_exception_ptr(::std::system_error(ec, what_arg));
230 } catch (...) {
231 return ::std::current_exception();
232 }
233}
234
235::std::exception_ptr
237 ::std::error_code ec, const char* what_arg) noexcept {
238 try {
239 if (ec.category() == SdoCategory())
240 return ::std::make_exception_ptr(SdoError(id, idx, subidx, ec, what_arg));
241 else
242 return ::std::make_exception_ptr(::std::system_error(ec, what_arg));
243 } catch (...) {
244 return ::std::current_exception();
245 }
246}
247
248} // namespace canopen
249
250} // namespace lely
A CANopen value.
Definition val.hpp:42
The type of exception thrown when an SDO abort code is received.
This is the internal header file of the C++ CANopen application library.
errnum_t errc2num(int errc)
Transforms a native error code to a platform-independent error number.
Definition errnum.c:309
@ ERRNUM_TIMEDOUT
Connection timed out.
Definition errnum.h:229
@ ERRNUM_NOMEM
Not enough space.
Definition errnum.h:172
This header file is part of the utilities library; it contains C++ convenience functions for creating...
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
const char * co_sdo_ac2str(co_unsigned32_t ac)
Returns a string describing an SDO abort code.
Definition sdo.c:57
const ::std::error_category & SdoCategory() noexcept
Returns a reference to the error category object for SDO abort codes.
SdoErrc
The SDO abort codes.
Definition sdo_error.hpp:42
@ TIMEOUT
SDO protocol timed out.
@ BLK_SIZE
Invalid block size (block mode only).
@ NO_CS
Client/server command specifier not valid or unknown.
@ TYPE_LEN_LO
Data type does not match, length of service parameter too low.
@ TOGGLE
Toggle bit not altered.
@ PARAM_VAL
Invalid value for parameter (download only).
@ PARAM
General parameter incompatibility reason.
@ NO_VAL
No data available. (NO_DATA is a macro defined in <netdb.h>)
@ NO_SUB
Sub-index does not exist.
@ PARAM_LO
Value of parameter written too low (download only).
@ BLK_SEQ
Invalid sequence number (block mode only).
@ DATA_DEV
Data cannot be transferred or stored to the application because of the present device state.
@ HARDWARE
Access failed due to a hardware error.
@ BLK_CRC
CRC error (block mode only).
@ PARAM_HI
Value of parameter written too high (download only).
@ TYPE_LEN
Data type does not match, length of service parameter does not match.
@ PARAM_RANGE
Maximum value is less than minimum value (download only).
@ COMPAT
General internal incompatibility in the device.
@ NO_MEM
Out of memory.
@ NO_OBJ
Object does not exist in the object dictionary.
@ NO_WRITE
Attempt to write a read only object.
@ NO_SDO
Resource not available: SDO connection.
@ DATA_CTL
Data cannot be transferred or stored to the application because of local control.
@ TYPE_LEN_HI
Data type does not match, length of service parameter too high.
@ NO_ACCESS
Unsupported access to an object.
@ DATA
Data cannot be transferred or stored to the application.
@ NO_READ
Attempt to read a write only object.
SdoErrc sdo_errc(::std::error_code ec)
Returns the SDO abort code corresponding to an error code.
::std::error_condition make_error_condition(SdoErrc e) noexcept
Creates an error condition corresponding to an SDO abort code.
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
::std::exception_ptr make_sdo_exception_ptr(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec) noexcept
Creates an std::exception_ptr that holds a reference to a lely::canopen::SdoError with the specified ...
STL namespace.
This header file is part of the C++ CANopen application library; it contains the SDO error declaratio...