Lely core libraries  2.2.5
sdo_error.cpp
Go to the documentation of this file.
1 
24 #include "coapp.hpp"
25 #include <lely/co/sdo.h>
26 #include <lely/coapp/sdo_error.hpp>
27 #include <lely/util/error.hpp>
28 
29 #include <iomanip>
30 #include <sstream>
31 #include <string>
32 
33 namespace lely {
34 
35 namespace canopen {
36 
37 namespace {
38 
39 class 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(int ev) const
47  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
56 SdoErrcCategory::default_error_condition(int ev) const noexcept {
57  switch (static_cast<SdoErrc>(ev)) {
58  case SdoErrc::TOGGLE:
59  return ::std::errc::protocol_error;
60  case SdoErrc::TIMEOUT:
61  return ::std::errc::timed_out;
62  case SdoErrc::NO_CS:
63  case SdoErrc::BLK_SIZE:
64  case SdoErrc::BLK_SEQ:
65  return ::std::errc::protocol_error;
66  case SdoErrc::BLK_CRC:
67  return ::std::errc::illegal_byte_sequence;
68  case SdoErrc::NO_MEM:
69  return ::std::errc::not_enough_memory;
70  case SdoErrc::NO_ACCESS:
71  case SdoErrc::NO_READ:
72  case SdoErrc::NO_WRITE:
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;
82  case SdoErrc::HARDWARE:
83  return ::std::errc::io_error;
84  case SdoErrc::TYPE_LEN:
87  return ::std::errc::invalid_argument;
88  case SdoErrc::NO_SUB:
89  return ::std::errc::no_such_file_or_directory;
90  case SdoErrc::PARAM_VAL:
91  return ::std::errc::invalid_argument;
92  case SdoErrc::PARAM_HI:
93  case SdoErrc::PARAM_LO:
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;
101  case SdoErrc::DATA_CTL:
102  case SdoErrc::DATA_DEV:
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
115 SdoWhat(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 
129 SdoError::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 
136 SdoError::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 
143 SdoError::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 
150 SdoError::SdoError(uint8_t id, uint16_t idx, uint8_t subidx, int ev)
151  : SdoError(id, idx, subidx, ::std::error_code(ev, SdoCategory())) {}
152 
153 SdoError::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 
158 SdoError::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 
163 const ::std::error_category&
164 SdoCategory() noexcept {
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 
179 SdoErrc
180 sdo_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
209 make_sdo_exception_ptr(uint8_t id, uint16_t idx, uint8_t subidx,
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
222 make_sdo_exception_ptr(uint8_t id, uint16_t idx, uint8_t subidx,
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
236 make_sdo_exception_ptr(uint8_t id, uint16_t idx, uint8_t subidx,
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
General parameter incompatibility reason.
Data cannot be transferred or stored to the application because of the present device state...
Maximum value is less than minimum value (download only).
Invalid value for parameter (download only).
This is the internal header file of the C++ CANopen application library.
This header file is part of the C++ CANopen application library; it contains the SDO error declaratio...
SdoErrc sdo_errc(::std::error_code ec)
Returns the SDO abort code corresponding to an error code.
Definition: sdo_error.cpp:180
Invalid block size (block mode only).
Attempt to write a read only object.
STL namespace.
Access failed due to a hardware error.
Resource not available: SDO connection.
This header file is part of the CANopen library; it contains the Service Data Object (SDO) declaratio...
Unsupported access to an object.
Data cannot be transferred or stored to the application because of local control. ...
The mask to get/set the toggle bit from an NMT state.
Sub-index does not exist.
No data available. (NO_DATA is a macro defined in <netdb.h>)
Data cannot be transferred or stored to the application.
SdoErrc
The SDO abort codes.
Definition: sdo_error.hpp:42
Data type does not match, length of service parameter too high.
Data type does not match, length of service parameter does not match.
CRC error (block mode only).
Invalid sequence number (block mode only).
const char * co_sdo_ac2str(co_unsigned32_t ac)
Returns a string describing an SDO abort code.
Definition: sdo.c:57
errnum_t errc2num(int errc)
Transforms a native error code to a platform-independent error number.
Definition: errnum.c:310
This header file is part of the utilities library; it contains C++ convenience functions for creating...
::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 ...
Definition: sdo_error.cpp:209
SDO protocol timed out.
Object does not exist in the object dictionary.
Client/server command specifier not valid or unknown.
Value of parameter written too low (download only).
Not enough space.
Definition: errnum.h:169
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
Data type does not match, length of service parameter too low.
Definition: buf.hpp:32
General internal incompatibility in the device.
const ::std::error_category & SdoCategory() noexcept
Returns a reference to the error category object for SDO abort codes.
Definition: sdo_error.cpp:164
::std::error_condition make_error_condition(SdoErrc e) noexcept
Creates an error condition corresponding to an SDO abort code.
Definition: sdo_error.cpp:175
Attempt to read a write only object.
The type of exception thrown when an SDO abort code is received.
Definition: sdo_error.hpp:121
Connection timed out.
Definition: errnum.h:226
Value of parameter written too high (download only).