22 #ifndef LELY_COAPP_SDO_HPP_ 23 #define LELY_COAPP_SDO_HPP_ 25 #include <lely/aio/exec.hpp> 26 #include <lely/aio/future.hpp> 56 class RequestBase_ :
public aio_task {
60 RequestBase_(aio::ExecutorBase& exec, aio_task_func_t* func)
61 : aio_task AIO_TASK_INIT(exec, func) {}
63 RequestBase_(aio::ExecutorBase& exec, aio_task_func_t* func, uint16_t idx_,
64 uint8_t subidx_,
const duration& timeout_)
65 : aio_task AIO_TASK_INIT(exec, func),
70 RequestBase_(
const RequestBase_&) =
delete;
72 RequestBase_& operator=(
const RequestBase_&) =
delete;
74 virtual ~RequestBase_() =
default;
77 GetExecutor() const noexcept {
78 return aio::ExecutorBase(exec);
87 virtual void OnRequest(Impl_* impl) noexcept = 0;
91 class DownloadRequestBase_ :
public RequestBase_ {
93 DownloadRequestBase_(aio::ExecutorBase& exec, aio_task_func_t* func)
94 : RequestBase_(exec, func) {}
97 DownloadRequestBase_(aio::ExecutorBase& exec, aio_task_func_t* func,
98 uint16_t idx, uint8_t subidx, U&& value_,
100 : RequestBase_(exec, func, idx, subidx, timeout),
101 value(::
std::forward<U>(value_)) {}
107 class UploadRequestBase_ :
public RequestBase_ {
111 using RequestBase_::RequestBase_;
128 ::std::error_code ec);
147 : DownloadRequestBase_<T>(exec, &Func_), con_(::
std::forward<F>(con)) {}
165 template <
class U,
class F>
167 aio::ExecutorBase& exec, F&& con,
const duration& timeout)
168 : DownloadRequestBase_<T>(exec, &Func_, idx, subidx,
169 ::
std::forward<U>(value), timeout),
170 con_(::
std::forward<F>(con)) {}
173 void OnRequest(
Impl_* impl) noexcept
override;
175 static void Func_(aio_task* task) noexcept;
177 ::std::function<DownloadSignature> con_{
nullptr};
193 ::std::error_code ec, T value);
212 : UploadRequestBase_<T>(exec, &Func_), con_(::
std::forward<F>(con)) {}
232 : UploadRequestBase_<T>(exec, &Func_, idx, subidx, timeout),
233 con_(::
std::forward<F>(con)) {}
236 void OnRequest(
Impl_* impl) noexcept
override;
238 static void Func_(aio_task* task) noexcept;
240 ::std::function<UploadSignature<T>> con_{
nullptr};
280 Sdo& operator=(
const Sdo&) =
delete;
290 explicit operator bool() const noexcept {
return !!impl_; }
294 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
296 Submit(static_cast<RequestBase_&>(req));
314 template <class T, class F, class U = typename ::std::decay<T>::type>
315 typename ::std::enable_if<
318 aio::ExecutorBase& exec, F&& con,
const duration& timeout) {
320 new DownloadRequestWrapper<U>(idx, subidx, ::std::forward<T>(value),
321 exec, ::std::forward<F>(con), timeout);
332 typename ::std::enable_if<detail::IsCanopenType<T>::value,
340 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
342 Submit(static_cast<RequestBase_&>(req));
359 template <
class T,
class F>
360 typename ::std::enable_if<detail::IsCanopenType<T>::value>::type
361 SubmitUpload(uint16_t idx, uint8_t subidx, aio::ExecutorBase& exec, F&& con,
363 auto req =
new UploadRequestWrapper<T>(idx, subidx, exec,
364 ::std::forward<F>(con), timeout);
375 typename ::std::enable_if<detail::IsCanopenType<T>::value,
404 template <class T, class U = typename ::std::decay<T>::type>
405 typename ::std::enable_if<detail::IsCanopenType<U>::value,
406 aio::Future<::std::error_code>>::type
408 uint8_t subidx, T&& value,
const duration& timeout) {
409 auto req =
new AsyncDownloadRequest<U>(loop, exec, idx, subidx,
410 ::std::forward<T>(value), timeout);
412 return req->GetFuture();
432 typename ::std::enable_if<
434 aio::Future<::std::tuple<::std::error_code, T>>>::type
435 AsyncUpload(aio::LoopBase& loop, aio::ExecutorBase& exec, int16_t idx,
436 uint8_t subidx,
const duration& timeout) {
437 auto req =
new AsyncUploadRequest<T>(loop, exec, idx, subidx, timeout);
439 return req->GetFuture();
444 class DownloadRequestWrapper :
public DownloadRequestBase_<T> {
446 template <
class U,
class F>
447 DownloadRequestWrapper(uint16_t idx, int8_t subidx, U&& value,
448 aio::ExecutorBase& exec, F&& con,
450 : DownloadRequestBase_<T>(exec, &Func_, idx, subidx,
451 ::
std::forward<U>(value), timeout),
452 con_(::
std::forward<F>(con)) {}
455 ~DownloadRequestWrapper() =
default;
457 void OnRequest(Impl_* impl) noexcept
override;
459 static void Func_(aio_task* task) noexcept;
461 ::std::function<DownloadSignature> con_{
nullptr};
465 class UploadRequestWrapper :
public UploadRequestBase_<T> {
468 UploadRequestWrapper(uint16_t idx, uint8_t subidx, aio::ExecutorBase& exec,
470 : UploadRequestBase_<T>(exec, &Func_, idx, subidx, timeout),
471 con_(::
std::forward<F>(con)) {}
474 ~UploadRequestWrapper() =
default;
476 void OnRequest(Impl_* impl) noexcept
override;
478 static void Func_(aio_task* task) noexcept;
480 ::std::function<UploadSignature<T>> con_{
nullptr};
484 class AsyncDownloadRequest :
public DownloadRequestBase_<T> {
487 AsyncDownloadRequest(aio::LoopBase& loop, aio::ExecutorBase& exec,
488 uint16_t idx, int8_t subidx, U&& value,
490 : DownloadRequestBase_<T>(exec, &Func_, idx, subidx,
491 ::
std::forward<U>(value), timeout),
492 promise_(loop, exec) {}
494 aio::Future<::std::error_code>
495 GetFuture() noexcept {
496 return promise_.GetFuture();
500 ~AsyncDownloadRequest() =
default;
502 void OnRequest(Impl_* impl) noexcept
override;
504 static void Func_(aio_task* task) noexcept;
506 aio::Promise<::std::error_code> promise_;
510 class AsyncUploadRequest :
public UploadRequestBase_<T> {
512 AsyncUploadRequest(aio::LoopBase& loop, aio::ExecutorBase& exec,
513 uint16_t idx, int8_t subidx,
const duration& timeout)
514 : UploadRequestBase_<T>(exec, &Func_, idx, subidx, timeout),
515 promise_(loop, exec) {}
517 aio::Future<::std::tuple<::std::error_code, T>>
518 GetFuture() noexcept {
519 return promise_.GetFuture();
523 ~AsyncUploadRequest() =
default;
525 void OnRequest(Impl_* impl) noexcept
override;
527 static void Func_(aio_task* task) noexcept;
529 aio::Promise<::std::tuple<::std::error_code, T>> promise_;
532 void Submit(RequestBase_& req);
536 ::std::unique_ptr<Impl_> impl_;
543 #endif // LELY_COAPP_SDO_HPP_ The internal implementation of the Client-SDO queue.
typename ::std::enable_if< detail::IsCanopenType< T >::value, ::std::size_t >::type CancelDownload(DownloadRequest< T > &req, SdoErrc ac)
Aborts an SDO download request.
This header file is part of the C++ CANopen application library; it contains the SDO error declaratio...
UploadRequest(aio::ExecutorBase &exec, F &&con)
Constructs an empty SDO upload request.
typename ::std::enable_if< detail::IsCanopenType< typename ::std::decay< U >::type >::value >::type SubmitDownload(uint16_t idx, uint8_t subidx, T &&value, aio::ExecutorBase &exec, F &&con, const duration &timeout)
Queues an SDO download request.
Sdo()
Default-constructs an invalid Client-SDO queue.
An opaque CANopen Client-SDO service type.
typename ::std::enable_if< detail::IsCanopenType< T >::value >::type SubmitDownload(DownloadRequest< T > &req)
Queues an SDO download request.
An opaque CANopen device type.
typename ::std::enable_if< detail::IsCanopenType< T >::value >::type SubmitUpload(uint16_t idx, uint8_t subidx, aio::ExecutorBase &exec, F &&con, const duration &timeout)
Queues an SDO upload request.
If T is one of the CANopen basic or array types, provides the member constant value equal to true...
::std::chrono::milliseconds duration
The type used to represent an SDO timeout duration.
typename ::std::enable_if< detail::IsCanopenType< T >::value, ::std::size_t >::type CancelUpload(UploadRequest< T > &req, SdoErrc ac)
Aborts an SDO upload request.
SdoErrc
The SDO abort codes.
~Sdo()
Destructs the Client-SDO queue.
typename ::std::enable_if< detail::IsCanopenType< T >::value, aio::Future<::std::tuple<::std::error_code, T > > >::type AsyncUpload(aio::LoopBase &loop, aio::ExecutorBase &exec, int16_t idx, uint8_t subidx, const duration &timeout)
Queues an asynchronous SDO upload request and returns a future.
typename ::std::enable_if< detail::IsCanopenType< U >::value, aio::Future<::std::error_code > >::type AsyncDownload(aio::LoopBase &loop, aio::ExecutorBase &exec, int16_t idx, uint8_t subidx, T &&value, const duration &timeout)
Queues an asynchronous SDO download request and returns a future.
This header file is part of the C++ CANopen application library; it contains the CANopen type traits...
UploadRequest(uint16_t idx, uint8_t subidx, aio::ExecutorBase &exec, F &&con, const duration &timeout)
Constructs an SDO upload request.
void(uint16_t idx, uint8_t subidx, ::std::error_code ec, T value) UploadSignature
The signature of the callback function invoked on completion of an SDO upload request.
typename ::std::enable_if< detail::IsCanopenType< T >::value >::type SubmitUpload(UploadRequest< T > &req)
Queues an SDO upload request.
::std::size_t Cancel(SdoErrc ac)
Aborts the ongoing and all pending SDO requests.
Global namespace for the Lely Industries N.V. libraries.
An opaque CAN network interface type.
DownloadRequest(uint16_t idx, uint8_t subidx, U &&value, aio::ExecutorBase &exec, F &&con, const duration &timeout)
Constructs an SDO download request.
DownloadRequest(aio::ExecutorBase &exec, F &&con)
Constructs an empty SDO download request.
void(uint16_t idx, uint8_t subidx, ::std::error_code ec) DownloadSignature
The signature of the callback function invoked on completion of an SDO download request.