22#ifndef LELY_COAPP_SDO_HPP_
23#define LELY_COAPP_SDO_HPP_
74 return ev::make_empty_future<::std::exception_ptr>();
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>(
139inline ::std::chrono::milliseconds
141 using ::std::chrono::milliseconds;
142 return timeout <= 0 ? milliseconds::max() :
milliseconds(timeout);
146template <
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;
156 if (timeout < 1)
return 1;
157 if (timeout > ::std::numeric_limits<int>::max())
158 return ::std::numeric_limits<int>::max();
168 const ::std::chrono::milliseconds&
timeout_ = {})
208 ::std::error_code
ec;
211 virtual void operator()()
noexcept = 0;
219 using SdoRequestBase::SdoRequestBase;
223 U&& value_,
bool block =
false,
224 const ::std::chrono::milliseconds&
timeout = {})
226 value(::std::forward<U>(value_)) {}
234 using SdoRequestBase::SdoRequestBase;
238 const ::std::chrono::milliseconds& timeout = {})
242 const ::std::chrono::milliseconds& timeout = {})
250 void Read(
const char*
path);
271 using SdoRequestBase::SdoRequestBase;
295 ::std::error_code ec);
304 : detail::SdoDownloadRequestBase<T>(exec), con_(::
std::
forward<
F>(con)) {}
311 ::
std::function<Signature> con_;
338 ::std::error_code ec);
349 : detail::SdoDownloadDcfRequestBase(exec), con_(::
std::
forward<
F>(con)) {}
356 ::
std::function<Signature> con_;
376 ::std::error_code ec, T value);
385 : detail::SdoUploadRequestBase<T>(exec), con_(::
std::
forward<
F>(con)) {}
392 ::
std::function<Signature> con_;
398class SdoDownloadRequestWrapper :
public SdoDownloadRequestBase<T> {
401 ::std::error_code ec);
403 template <
class U,
class F>
405 U&& value,
F&& con,
bool block,
406 const ::std::chrono::milliseconds& timeout)
407 : SdoDownloadRequestBase<T>(exec, idx, subidx, ::
std::
forward<
U>(value),
416 ::
std::function<Signature> con_;
419class SdoDownloadDcfRequestWrapper :
public SdoDownloadDcfRequestBase {
422 ::std::error_code ec);
427 const ::std::chrono::milliseconds& timeout)
428 : SdoDownloadDcfRequestBase(exec, begin, end, timeout),
432 SdoDownloadDcfRequestWrapper(
ev_exec_t* exec,
const char* path, F&& con,
433 const ::std::chrono::milliseconds& timeout)
434 : SdoDownloadDcfRequestBase(exec, path, timeout),
435 con_(::
std::forward<F>(con)) {}
438 SdoDownloadDcfRequestWrapper(
ev_exec_t* exec, const ::std::string& path,
440 const ::std::chrono::milliseconds& timeout)
441 : SdoDownloadDcfRequestBase(exec, path.c_str(), timeout),
442 con_(::
std::forward<F>(con)) {}
445 void operator()() noexcept final;
447 void OnRequest(
void* data) noexcept final;
449 ::
std::function<Signature> con_;
453class SdoUploadRequestWrapper : public SdoUploadRequestBase<T> {
455 using Signature = void(uint8_t
id, uint16_t idx, uint8_t subidx,
456 ::std::error_code ec, T value);
459 SdoUploadRequestWrapper(
ev_exec_t* exec, uint16_t idx, uint8_t subidx,
461 const ::std::chrono::milliseconds& timeout)
462 : SdoUploadRequestBase<T>(exec, idx, subidx, block, timeout),
463 con_(::
std::forward<F>(con)) {}
466 void operator()() noexcept final;
468 void OnRequest(
void* data) noexcept final;
470 ::
std::function<Signature> con_;
495template <class T, class U, class F>
496inline detail::SdoDownloadRequestWrapper<T>*
498 U&& value,
F&& con,
bool block =
false,
500 return new detail::SdoDownloadRequestWrapper<T>(
501 exec, idx, subidx, ::std::forward<U>(value), ::std::forward<F>(con),
526inline detail::SdoDownloadDcfRequestWrapper*
529 const ::std::chrono::milliseconds& timeout = {}) {
530 return new detail::SdoDownloadDcfRequestWrapper(
531 exec, begin, end, ::std::forward<F>(con), timeout);
552inline detail::SdoDownloadDcfRequestWrapper*
554 const ::std::chrono::milliseconds& timeout = {}) {
555 return new detail::SdoDownloadDcfRequestWrapper(
556 exec,
path, ::std::forward<F>(con), timeout);
578template <
class T,
class F>
579inline detail::SdoUploadRequestWrapper<T>*
582 const ::std::chrono::milliseconds& timeout = {}) {
583 return new detail::SdoUploadRequestWrapper<T>(
584 exec, idx, subidx, ::std::forward<F>(con), block, timeout);
598 friend class detail::SdoDownloadRequestWrapper;
600 friend class detail::SdoDownloadDcfRequestWrapper;
603 friend class detail::SdoUploadRequestWrapper;
643 Sdo& operator=(
const Sdo&) =
delete;
657 typename ::std::enable_if<is_canopen<T>::value>::type
680 typename ::std::enable_if<is_canopen<U>::value>::type
682 F&& con,
bool block =
false,
683 const ::std::chrono::milliseconds& timeout = {}) {
685 exec, idx, subidx, ::std::forward<T>(value), ::std::forward<F>(con),
691 typename ::std::enable_if<is_canopen<T>::value,
bool>::type
693 return Cancel(req, ac);
698 typename ::std::enable_if<is_canopen<T>::value,
bool>::type
729 F&& con, const ::std::chrono::milliseconds& timeout = {}) {
731 ::std::forward<F>(con), timeout));
751 const ::std::chrono::milliseconds& timeout = {}) {
759 return Cancel(req, ac);
770 typename ::std::enable_if<is_canopen<T>::value>::type
791 template <
class T,
class F>
792 typename ::std::enable_if<is_canopen<T>::value>::type
795 const ::std::chrono::milliseconds& timeout = {}) {
797 ::std::forward<F>(con), block, timeout));
802 typename ::std::enable_if<is_canopen<T>::value,
bool>::type
804 return Cancel(req, ac);
809 typename ::std::enable_if<is_canopen<T>::value,
bool>::type
835 const ::std::chrono::milliseconds& timeout = {}) {
838 exec, idx, subidx, ::std::forward<T>(value),
840 ::std::error_code ec)
mutable {
845 p.set(util::success());
848 return p.get_future();
868 SdoFuture<void> AsyncDownloadDcf(
869 ev_exec_t* exec,
const uint8_t* begin,
const uint8_t* end,
870 const ::std::chrono::milliseconds& timeout = {});
886 SdoFuture<void> AsyncDownloadDcf(
888 const ::std::chrono::milliseconds& timeout = {});
908 typename ::std::enable_if<is_canopen<T>::value, SdoFuture<T>>::type
910 const ::std::chrono::milliseconds& timeout = {}) {
920 p.set(util::success(::std::move(value)));
923 return p.get_future();
927 void Submit(detail::SdoRequestBase& req);
938 bool Cancel(detail::SdoRequestBase& req, SdoErrc ac);
947 ::std::size_t CancelAll(SdoErrc ac);
956 bool Abort(detail::SdoRequestBase& req);
964 ::std::size_t AbortAll();
968 ::std::unique_ptr<Impl_> impl_;
A series of SDO download (i.e., write) requests corresponding to the entries in a concise DCF.
void(uint8_t id, uint16_t idx, uint8_t subidx, ::std::error_code ec) Signature
The signature of the callback function invoked when all SDO download requests are successfully comple...
SdoDownloadDcfRequest(ev_exec_t *exec, F &&con)
Constructs an empty SDO download DCF request.
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< is_canopen< T >::value, bool >::type AbortUpload(SdoUploadRequest< T > &req)
Aborts an SDO upload request.
typename::std::enable_if< is_canopen< T >::value >::type SubmitDownload(SdoDownloadRequest< T > &req)
Queues an SDO download request.
typename::std::enable_if< is_canopen< T >::value >::type SubmitUpload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, F &&con, bool block=false, const ::std::chrono::milliseconds &timeout={})
Queues an SDO upload request.
Sdo()
Default-constructs an invalid Client-SDO queue.
typename::std::enable_if< is_canopen< T >::value, bool >::type CancelDownload(SdoDownloadRequest< T > &req, SdoErrc ac)
Cancels an SDO download request.
typename::std::enable_if< is_canopen< T >::value, bool >::type CancelUpload(SdoUploadRequest< T > &req, SdoErrc ac)
Cancels an SDO upload request.
bool AbortDownloadDcf(SdoDownloadDcfRequest &req)
Aborts an SDO download DCF request.
typename::std::enable_if< is_canopen< U >::value, SdoFuture< void > >::type AsyncDownload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, T &&value, bool block=false, 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< is_canopen< T >::value, SdoFuture< T > >::type AsyncUpload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, bool block=false, const ::std::chrono::milliseconds &timeout={})
Queues an asynchronous SDO upload request and creates a future which becomes ready once the request c...
void SubmitDownloadDcf(ev_exec_t *exec, const uint8_t *begin, const uint8_t *end, F &&con, const ::std::chrono::milliseconds &timeout={})
Queues an SDO download DCF request.
typename::std::enable_if< is_canopen< T >::value >::type SubmitUpload(SdoUploadRequest< T > &req)
Queues an SDO upload request.
void SubmitDownloadDcf(SdoDownloadDcfRequest &req)
Queues an SDO download DCF request.
~Sdo()
Destructs the Client-SDO queue.
void SubmitDownloadDcf(ev_exec_t *exec, const char *path, F &&con, const ::std::chrono::milliseconds &timeout={})
Queues an SDO download DCF request.
typename::std::enable_if< is_canopen< T >::value, bool >::type AbortDownload(SdoDownloadRequest< T > &req)
Aborts an SDO download request.
typename::std::enable_if< is_canopen< U >::value >::type SubmitDownload(ev_exec_t *exec, uint16_t idx, uint8_t subidx, T &&value, F &&con, bool block=false, const ::std::chrono::milliseconds &timeout={})
Queues an SDO download request.
bool CancelDownloadDcf(SdoDownloadDcfRequest &req, SdoErrc ac)
Cancels an SDO download request.
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.
bool block
A flag specifying whether the request should use a block SDO instead of a segmented (or expedited) SD...
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*.
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< void > make_empty_sdo_future()
Returns an SDO future with a shared state that is immediately ready, containing a successful result o...
detail::SdoUploadRequestWrapper< T > * make_sdo_upload_request(ev_exec_t *exec, uint16_t idx, uint8_t subidx, F &&con, bool block=false, const ::std::chrono::milliseconds &timeout={})
Creates an SDO upload request with a completion task.
SdoErrc
The SDO abort codes.
detail::SdoDownloadDcfRequestWrapper * make_sdo_download_dcf_request(ev_exec_t *exec, const uint8_t *begin, const uint8_t *end, F &&con, const ::std::chrono::milliseconds &timeout={})
Creates a series of SDO download requests, corresponding to the entries in a concise DCF,...
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...
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...
::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.