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_;
An opaque CAN network interface type.
An opaque CANopen Client-SDO service type.
An opaque CANopen device type.
DownloadRequest(aio::ExecutorBase &exec, F &&con)
Constructs an empty SDO download request.
DownloadRequest(uint16_t idx, uint8_t subidx, U &&value, aio::ExecutorBase &exec, F &&con, const duration &timeout)
Constructs an SDO download request.
UploadRequest(aio::ExecutorBase &exec, F &&con)
Constructs an empty SDO upload request.
UploadRequest(uint16_t idx, uint8_t subidx, aio::ExecutorBase &exec, F &&con, const duration &timeout)
Constructs an SDO upload request.
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.
::std::chrono::milliseconds duration
The type used to represent an SDO timeout duration.
typename::std::enable_if< detail::IsCanopenType< T >::value >::type SubmitUpload(UploadRequest< T > &req)
Queues an SDO upload request.
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.
Sdo()
Default-constructs an invalid Client-SDO queue.
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,::std::size_t >::type CancelDownload(DownloadRequest< T > &req, SdoErrc ac)
Aborts an SDO download request.
::std::size_t Cancel(SdoErrc ac)
Aborts the ongoing and all pending SDO requests.
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.
typename::std::enable_if< detail::IsCanopenType< T >::value >::type SubmitDownload(DownloadRequest< T > &req)
Queues an SDO download request.
~Sdo()
Destructs the Client-SDO queue.
typename::std::enable_if< detail::IsCanopenType< T >::value,::std::size_t >::type CancelUpload(UploadRequest< T > &req, SdoErrc ac)
Aborts an 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.
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.
SdoErrc
The SDO abort codes.
Global namespace for the Lely Industries N.V. libraries.
This header file is part of the C++ CANopen application library; it contains the SDO error declaratio...
The internal implementation of the Client-SDO queue.
If T is one of the CANopen basic or array types, provides the member constant value equal to true.
This header file is part of the C++ CANopen application library; it contains the CANopen type traits.