22 #ifndef LELY_COAPP_SDO_HPP_
23 #define LELY_COAPP_SDO_HPP_
74 return ev::make_empty_future<::std::exception_ptr>();
83 template <class T, class V = typename ::std::decay<T>::type>
86 return ev::make_ready_future<::std::exception_ptr, V>(
87 ::std::forward<T>(value));
100 ::std::error_code ec) {
114 ::std::error_code ec, const ::std::string& what_arg) {
115 return ev::make_error_future<T>(
129 ::std::error_code ec,
const char* what_arg) {
130 return ev::make_error_future<T>(
139 inline ::std::chrono::milliseconds
141 using ::std::chrono::milliseconds;
142 return timeout <= 0 ? milliseconds::max() : milliseconds(timeout);
146 template <
class Rep,
class Period>
149 using ::std::chrono::duration;
150 using ::std::chrono::duration_cast;
151 using ::std::chrono::milliseconds;
153 if (d == duration<Rep, Period>::max())
return 0;
154 auto timeout = duration_cast<milliseconds>(d).count();
156 if (timeout < 1)
return 1;
157 if (timeout > ::std::numeric_limits<int>::max())
158 return ::std::numeric_limits<int>::max();
167 const ::std::chrono::milliseconds& timeout_ = {})
201 ::std::error_code
ec;
204 virtual void operator()() noexcept = 0;
206 virtual
void OnRequest(
void* data) noexcept = 0;
212 using SdoRequestBase::SdoRequestBase;
217 const ::std::chrono::milliseconds&
timeout = {})
219 value(::std::forward<U>(value_)) {}
228 using SdoRequestBase::SdoRequestBase;
251 using Signature = void(uint8_t
id, uint16_t idx, uint8_t subidx,
252 ::std::error_code ec);
261 : detail::SdoDownloadRequestBase<T>(exec), con_(::std::forward<F>(con)) {}
264 void operator()() noexcept final;
266 void OnRequest(
void* data) noexcept final;
268 ::std::function<Signature> con_;
287 using Signature = void(uint8_t
id, uint16_t idx, uint8_t subidx,
288 ::std::error_code ec, T value);
297 : detail::SdoUploadRequestBase<T>(exec), con_(::std::forward<F>(con)) {}
300 void operator()() noexcept final;
302 void OnRequest(
void* data) noexcept final;
304 ::std::function<Signature> con_;
312 using Signature = void(uint8_t
id, uint16_t idx, uint8_t subidx,
313 ::std::error_code ec);
315 template <
class U,
class F>
318 const ::std::chrono::milliseconds& timeout)
321 con_(::std::forward<F>(con)) {}
324 void operator()() noexcept
final;
326 void OnRequest(
void* data) noexcept
final;
328 ::std::function<Signature> con_;
334 using Signature = void(uint8_t
id, uint16_t idx, uint8_t subidx,
335 ::std::error_code ec, T value);
339 F&& con, const ::std::chrono::milliseconds& timeout)
341 con_(::std::forward<F>(con)) {}
344 void operator()() noexcept
final;
346 void OnRequest(
void* data) noexcept
final;
348 ::std::function<Signature> con_;
371 template <
class T,
class U,
class F>
375 const ::std::chrono::milliseconds& timeout = {}) {
376 return new detail::SdoDownloadRequestWrapper<T>(
377 exec, idx, subidx, ::std::forward<U>(value), ::std::forward<F>(con),
398 template <
class T,
class F>
399 inline detail::SdoUploadRequestWrapper<T>*
401 const ::std::chrono::milliseconds& timeout = {}) {
402 return new detail::SdoUploadRequestWrapper<T>(
403 exec, idx, subidx, ::std::forward<F>(con), timeout);
458 Sdo& operator=(
const Sdo&) =
delete;
468 explicit operator bool() const noexcept {
return !!impl_; }
472 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
492 template <class T, class F, class U = typename ::std::decay<T>::type>
493 typename ::std::enable_if<detail::is_canopen_type<U>::value>::type
495 F&& con, const ::std::chrono::milliseconds& timeout = {}) {
496 Submit(*make_sdo_download_request<U>(exec, idx, subidx,
497 ::std::forward<T>(value),
498 ::std::forward<F>(con), timeout));
503 typename ::std::enable_if<detail::is_canopen_type<T>::value,
bool>::type
505 return Cancel(req, ac);
510 typename ::std::enable_if<detail::is_canopen_type<T>::value,
bool>::type
517 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
536 template <
class T,
class F>
537 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
539 const ::std::chrono::milliseconds& timeout = {}) {
540 Submit(*make_sdo_upload_request<T>(exec, idx, subidx,
541 ::std::forward<F>(con), timeout));
546 typename ::std::enable_if<detail::is_canopen_type<T>::value,
bool>::type
548 return Cancel(req, ac);
553 typename ::std::enable_if<detail::is_canopen_type<T>::value,
bool>::type
573 template <class T, class U = typename ::std::decay<T>::type>
574 typename ::std::enable_if<detail::is_canopen_type<U>::value,
577 const ::std::chrono::milliseconds& timeout = {}) {
580 exec, idx, subidx, ::std::forward<T>(value),
581 [p](uint8_t
id, uint16_t idx, uint8_t subidx,
582 ::std::error_code ec)
mutable {
587 p.
set(util::success());
609 typename ::std::enable_if<detail::is_canopen_type<T>::value,
612 const ::std::chrono::milliseconds& timeout = {}) {
616 [p](uint8_t
id, uint16_t idx, uint8_t subidx, ::std::error_code ec,
622 p.
set(util::success(::std::move(value)));
629 void Submit(detail::SdoRequestBase& req);
640 bool Cancel(detail::SdoRequestBase& req,
SdoErrc ac);
649 ::std::size_t CancelAll(
SdoErrc ac);
658 bool Abort(detail::SdoRequestBase& req);
666 ::std::size_t AbortAll();
670 ::std::unique_ptr<Impl_> impl_;
An opaque CAN network interface type.
An opaque CANopen Client-SDO service type.
An opaque CANopen device type.
An SDO download (i.e., write) request.
void(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec) Signature
The signature of the callback function invoked on completion of an SDO download request.
SdoDownloadRequest(ev_exec_t *exec, F &&con)
Constructs an empty SDO download request.
An SDO upload (i.e., read) request.
SdoUploadRequest(ev_exec_t *exec, F &&con)
Constructs an empty SDO upload request.
void(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec, T value) Signature
The signature of the callback function invoked on completion of an SDO upload request.
typename ::std::enable_if< detail::is_canopen_type< T >::value, bool >::type AbortUpload(SdoUploadRequest< T > &req)
Aborts an SDO upload request.
typename ::std::enable_if< detail::is_canopen_type< T >::value >::type SubmitDownload(SdoDownloadRequest< T > &req)
Queues an SDO download request.
typename ::std::enable_if< detail::is_canopen_type< U >::value, SdoFuture< void > >::type AsyncDownload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout={})
Queues an asynchronous SDO download request and creates a future which becomes ready once the request...
typename ::std::enable_if< detail::is_canopen_type< T >::value, bool >::type CancelDownload(SdoDownloadRequest< T > &req, SdoErrc ac)
Cancels an SDO download request.
typename ::std::enable_if< detail::is_canopen_type< T >::value, SdoFuture< T > >::type AsyncUpload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout={})
Queues an asynchronous SDO upload request and creates a future which becomes ready once the request c...
typename ::std::enable_if< detail::is_canopen_type< T >::value >::type SubmitUpload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout={})
Queues an SDO upload request.
Sdo()
Default-constructs an invalid Client-SDO queue.
typename ::std::enable_if< detail::is_canopen_type< T >::value >::type SubmitUpload(SdoUploadRequest< T > &req)
Queues an SDO upload request.
typename ::std::enable_if< detail::is_canopen_type< T >::value, bool >::type CancelUpload(SdoUploadRequest< T > &req, SdoErrc ac)
Cancels an SDO upload request.
typename ::std::enable_if< detail::is_canopen_type< T >::value, bool >::type AbortDownload(SdoDownloadRequest< T > &req)
Aborts an SDO download request.
typename ::std::enable_if< detail::is_canopen_type< U >::value >::type SubmitDownload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, T &&value, F &&con, const ::std::chrono::milliseconds &timeout={})
Queues an SDO download request.
~Sdo()
Destructs the Client-SDO queue.
uint16_t idx
The object index.
::std::chrono::milliseconds timeout
The SDO timeout.
ev::Executor GetExecutor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
uint8_t subidx
The object sub-index.
::std::error_code ec
The SDO abort code (0 on success).
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Future< T, E > get_future() const noexcept
Returns a lely::ev::Future with (a reference to) the same shared state as *this.
bool set(U &&u)
Satisfies a promise, if it was not aready satisfied, and stores the specified value as the result in ...
This header file is part of the C++ CANopen application library; it contains the CANopen type traits.
This header file is part of the event library; it contains the C++ interface for the futures and prom...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
inline ::std::chrono::milliseconds from_sdo_timeout(int timeout)
Converts an SDO timeout to a duration.
int to_sdo_timeout(const ::std::chrono::duration< Rep, Period > &d)
Converts a duration to an SDO timeout.
SdoFuture< V > make_ready_sdo_future(T &&value)
Returns an SDO future with a shared state that is immediately ready, containing a successful result c...
detail::SdoUploadRequestWrapper< T > * make_sdo_upload_request(ev_exec_t *exec, uint16_t idx, uint8_t subidx, F &&con, const ::std::chrono::milliseconds &timeout={})
Creates an SDO upload request with a completion task.
SdoFuture< T > make_error_sdo_future(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec)
Returns an SDO future with a shared state that is immediately ready, containing a failure result cons...
SdoErrc
The SDO abort codes.
detail::SdoDownloadRequestWrapper< T > * make_sdo_download_request(ev_exec_t *exec, uint16_t idx, uint8_t subidx, U &&value, F &&con, const ::std::chrono::milliseconds &timeout={})
Creates an SDO download request with a completion task.
SdoFuture< void > make_empty_sdo_future()
Returns an SDO future with a shared state that is immediately ready, containing a successful result o...
::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 ...
This header file is part of the C++ CANopen application library; it contains the SDO error declaratio...
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
#define EV_TASK_INIT(exec, func)
The static initializer for ev_task.