31#include <lely/aio/queue.h>
41ErrorCode(
int errc, uint32_t ac) {
43 return ::std::error_code(errc, ::std::system_category());
45 return static_cast<SdoErrc>(ac);
60 void Submit(RequestBase_& req);
62 ::std::size_t Cancel(RequestBase_* req,
SdoErrc ac);
64 template <
class T,
class U>
65 void OnRequest(uint16_t idx, uint8_t subidx, U&& value);
68 void OnRequest(uint16_t idx, uint8_t subidx);
70 void OnDnCon(
COCSDO*, uint16_t idx, uint8_t subidx, uint32_t ac)
noexcept;
73 void OnUpCon(
COCSDO*, uint16_t idx, uint8_t subidx, uint32_t ac,
76 void OnTaskFinished(RequestBase_& op)
noexcept;
79 ::std::shared_ptr<COCSDO> sdo;
85 impl->OnRequest<T>(this->idx, this->subidx, this->value);
94 self->con_(self->idx, self->subidx, ErrorCode(self->errc, self->ac));
99Sdo::UploadRequest<T>::OnRequest(Impl_* impl)
noexcept {
100 impl->OnRequest<T>(this->idx, this->subidx);
105Sdo::UploadRequest<T>::Func_(aio_task* task)
noexcept {
106 auto self =
static_cast<Sdo::UploadRequest<T>*
>(task);
109 self->con_(self->idx, self->subidx, ErrorCode(self->errc, self->ac),
110 ::std::move(self->value));
115Sdo::DownloadRequestWrapper<T>::OnRequest(Impl_* impl)
noexcept {
116 impl->OnRequest<T>(this->idx, this->subidx, this->value);
121Sdo::DownloadRequestWrapper<T>::Func_(aio_task* task)
noexcept {
122 auto self =
static_cast<Sdo::DownloadRequestWrapper<T>*
>(task);
124 ::std::function<DownloadSignature> con = ::std::move(self->con_);
125 auto idx = self->idx;
126 auto subidx = self->subidx;
127 auto ec = ErrorCode(self->errc, self->ac);
130 if (con) con(idx, subidx, ec);
135Sdo::UploadRequestWrapper<T>::OnRequest(Impl_* impl)
noexcept {
136 impl->OnRequest<T>(this->idx, this->subidx);
141Sdo::UploadRequestWrapper<T>::Func_(aio_task* task)
noexcept {
142 auto self =
static_cast<Sdo::UploadRequestWrapper<T>*
>(task);
144 ::std::function<UploadSignature<T>> con = ::std::move(self->con_);
145 auto idx = self->idx;
146 auto subidx = self->subidx;
147 auto ec = ErrorCode(self->errc, self->ac);
148 T value = ::std::move(self->value);
151 if (con) con(idx, subidx, ec, ::std::move(value));
156Sdo::AsyncDownloadRequest<T>::OnRequest(Impl_* impl)
noexcept {
157 impl->OnRequest<T>(this->idx, this->subidx, this->value);
162Sdo::AsyncDownloadRequest<T>::Func_(aio_task* task)
noexcept {
163 auto self =
static_cast<Sdo::AsyncDownloadRequest<T>*
>(task);
165 aio::Promise<::std::error_code> promise = ::std::move(self->promise_);
166 auto ec = ErrorCode(self->errc, self->ac);
169 promise.SetValue(ec);
174Sdo::AsyncUploadRequest<T>::OnRequest(Impl_* impl)
noexcept {
175 impl->OnRequest<T>(this->idx, this->subidx);
180Sdo::AsyncUploadRequest<T>::Func_(aio_task* task)
noexcept {
181 auto self =
static_cast<Sdo::AsyncUploadRequest<T>*
>(task);
183 aio::Promise<::std::tuple<::std::error_code, T>> promise =
184 ::std::move(self->promise_);
185 auto value = ::std::make_tuple(ErrorCode(self->errc, self->ac),
186 ::std::move(self->value));
189 promise.SetValue(value);
192#ifndef DOXYGEN_SHOULD_SKIP_THIS
195template class Sdo::DownloadRequest<bool>;
196template class Sdo::UploadRequest<bool>;
197template class Sdo::DownloadRequestWrapper<bool>;
198template class Sdo::UploadRequestWrapper<bool>;
199template class Sdo::AsyncDownloadRequest<bool>;
200template class Sdo::AsyncUploadRequest<bool>;
203template class Sdo::DownloadRequest<int8_t>;
204template class Sdo::UploadRequest<int8_t>;
205template class Sdo::DownloadRequestWrapper<int8_t>;
206template class Sdo::UploadRequestWrapper<int8_t>;
207template class Sdo::AsyncDownloadRequest<int8_t>;
208template class Sdo::AsyncUploadRequest<int8_t>;
211template class Sdo::DownloadRequest<int16_t>;
212template class Sdo::UploadRequest<int16_t>;
213template class Sdo::DownloadRequestWrapper<int16_t>;
214template class Sdo::UploadRequestWrapper<int16_t>;
215template class Sdo::AsyncDownloadRequest<int16_t>;
216template class Sdo::AsyncUploadRequest<int16_t>;
219template class Sdo::DownloadRequest<int32_t>;
220template class Sdo::UploadRequest<int32_t>;
221template class Sdo::DownloadRequestWrapper<int32_t>;
222template class Sdo::UploadRequestWrapper<int32_t>;
223template class Sdo::AsyncDownloadRequest<int32_t>;
224template class Sdo::AsyncUploadRequest<int32_t>;
227template class Sdo::DownloadRequest<uint8_t>;
228template class Sdo::UploadRequest<uint8_t>;
229template class Sdo::DownloadRequestWrapper<uint8_t>;
230template class Sdo::UploadRequestWrapper<uint8_t>;
231template class Sdo::AsyncDownloadRequest<uint8_t>;
232template class Sdo::AsyncUploadRequest<uint8_t>;
235template class Sdo::DownloadRequest<uint16_t>;
236template class Sdo::UploadRequest<uint16_t>;
237template class Sdo::DownloadRequestWrapper<uint16_t>;
238template class Sdo::UploadRequestWrapper<uint16_t>;
239template class Sdo::AsyncDownloadRequest<uint16_t>;
240template class Sdo::AsyncUploadRequest<uint16_t>;
243template class Sdo::DownloadRequest<uint32_t>;
244template class Sdo::UploadRequest<uint32_t>;
245template class Sdo::DownloadRequestWrapper<uint32_t>;
246template class Sdo::UploadRequestWrapper<uint32_t>;
247template class Sdo::AsyncDownloadRequest<uint32_t>;
248template class Sdo::AsyncUploadRequest<uint32_t>;
251template class Sdo::DownloadRequest<float>;
252template class Sdo::UploadRequest<float>;
253template class Sdo::DownloadRequestWrapper<float>;
254template class Sdo::UploadRequestWrapper<float>;
255template class Sdo::AsyncDownloadRequest<float>;
256template class Sdo::AsyncUploadRequest<float>;
259template class Sdo::DownloadRequest<::std::string>;
260template class Sdo::UploadRequest<::std::string>;
261template class Sdo::DownloadRequestWrapper<::std::string>;
262template class Sdo::UploadRequestWrapper<::std::string>;
263template class Sdo::AsyncDownloadRequest<::std::string>;
264template class Sdo::AsyncUploadRequest<::std::string>;
267template class Sdo::DownloadRequest<::std::vector<uint8_t>>;
268template class Sdo::UploadRequest<::std::vector<uint8_t>>;
269template class Sdo::DownloadRequestWrapper<::std::vector<uint8_t>>;
270template class Sdo::UploadRequestWrapper<::std::vector<uint8_t>>;
271template class Sdo::AsyncDownloadRequest<::std::vector<uint8_t>>;
272template class Sdo::AsyncUploadRequest<::std::vector<uint8_t>>;
275template class Sdo::DownloadRequest<::std::basic_string<char16_t>>;
276template class Sdo::UploadRequest<::std::basic_string<char16_t>>;
277template class Sdo::DownloadRequestWrapper<::std::basic_string<char16_t>>;
278template class Sdo::UploadRequestWrapper<::std::basic_string<char16_t>>;
279template class Sdo::AsyncDownloadRequest<::std::basic_string<char16_t>>;
280template class Sdo::AsyncUploadRequest<::std::basic_string<char16_t>>;
288template class Sdo::DownloadRequest<double>;
289template class Sdo::UploadRequest<double>;
290template class Sdo::DownloadRequestWrapper<double>;
291template class Sdo::UploadRequestWrapper<double>;
292template class Sdo::AsyncDownloadRequest<double>;
293template class Sdo::AsyncUploadRequest<double>;
300template class Sdo::DownloadRequest<int64_t>;
301template class Sdo::UploadRequest<int64_t>;
302template class Sdo::DownloadRequestWrapper<int64_t>;
303template class Sdo::UploadRequestWrapper<int64_t>;
304template class Sdo::AsyncDownloadRequest<int64_t>;
305template class Sdo::AsyncUploadRequest<int64_t>;
313template class Sdo::DownloadRequest<uint64_t>;
314template class Sdo::UploadRequest<uint64_t>;
315template class Sdo::DownloadRequestWrapper<uint64_t>;
316template class Sdo::UploadRequestWrapper<uint64_t>;
317template class Sdo::AsyncDownloadRequest<uint64_t>;
318template class Sdo::AsyncUploadRequest<uint64_t>;
327 : impl_(new
Impl_(net, dev, num)) {}
331Sdo& Sdo::operator=(
Sdo&&) =
default;
336Sdo::Submit(RequestBase_& op) {
342 return impl_->Cancel(&op, ac);
347 return impl_->Cancel(
nullptr, ac);
350Sdo::Impl_::Impl_(
CANNet* net,
CODev* dev, uint8_t num)
352 aio_queue_init(&queue);
355Sdo::Impl_::Impl_(
COCSDO* sdo_,
int timeout)
356 : sdo(sdo_, [=](
COCSDO* sdo) { sdo->setTimeout(timeout); }) {
357 aio_queue_init(&queue);
363Sdo::Impl_::Submit(RequestBase_& req) {
365 req.GetExecutor().OnTaskStarted();
373 bool first = aio_queue_empty(&queue);
374 aio_queue_push(&queue, &req);
375 if (first) req.OnRequest(
this);
380Sdo::Impl_::Cancel(RequestBase_* req,
SdoErrc ac) {
382 aio_queue_init(&queue_);
384 if (!req || req != aio_queue_front(&queue)) {
385 auto task = aio_queue_pop(&queue);
386 aio_queue_move(&queue_, &queue, req);
387 if (task) aio_queue_push(&queue, task);
388 req = task && !req ?
static_cast<RequestBase_*
>(task) :
nullptr;
392 assert(req == aio_queue_front(&queue));
393 sdo->abortReq(
static_cast<uint32_t
>(ac));
397 if (req) n += n < ::std::numeric_limits<
decltype(n)>::max();
401template <
class T,
class U>
403Sdo::Impl_::OnRequest(uint16_t idx, uint8_t subidx, U&& value) {
404 constexpr auto N = co_type_traits_T<T>::index;
406 auto task = aio_queue_front(&queue);
408 auto& req = *
static_cast<Sdo::RequestBase_*
>(task);
411 if (sdo->dnReq<N, Impl_, &Impl_::OnDnCon>(
412 idx, subidx, ::std::forward<U>(value),
this) == -1) {
420Sdo::Impl_::OnRequest(uint16_t idx, uint8_t subidx) {
421 auto task = aio_queue_front(&queue);
423 auto& req = *
static_cast<Sdo::RequestBase_*
>(task);
426 if (sdo->upReq<T, Impl_, &Impl_::OnUpCon<T>>(idx, subidx,
this) == -1) {
433Sdo::Impl_::OnDnCon(COCSDO*, uint16_t idx, uint8_t subidx,
434 uint32_t ac)
noexcept {
435 auto task = aio_queue_pop(&queue);
437 auto& req = *
static_cast<Sdo::RequestBase_*
>(task);
449Sdo::Impl_::OnUpCon(COCSDO*, uint16_t idx, uint8_t subidx, uint32_t ac,
451 auto task = aio_queue_pop(&queue);
453 auto& req = *
static_cast<Sdo::UploadRequestBase_<T>*
>(task);
459 req.value = ::std::move(value);
465Sdo::Impl_::OnTaskFinished(RequestBase_& req)
noexcept {
466 auto exec = req.GetExecutor();
468 exec.OnTaskFinished();
470 auto task = aio_queue_front(&queue);
471 if (task)
static_cast<Sdo::RequestBase_*
>(task)->OnRequest(
this);
This header file is part of the C++ CANopen application library; it contains the timeout conversion f...
An opaque CAN network interface type.
An opaque CANopen Client-SDO service type.
An opaque CANopen device type.
Sdo()
Default-constructs an invalid Client-SDO queue.
::std::size_t Cancel(SdoErrc ac)
Aborts the ongoing and all pending SDO requests.
~Sdo()
Destructs the Client-SDO queue.
This header file is part of the CANopen library; it contains the C++ interface of the Client-SDO decl...
int errnum2c(errnum_t errnum)
Transforms a platform-independent error number to a native error code.
@ ERRNUM_INPROGRESS
Operation in progress.
@ ERRNUM_CANCELED
Operation canceled.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
int ToTimeout(const ::std::chrono::duration< Rep, Period > &d)
Converts a duration to an SDO timeout.
SdoErrc
The SDO abort codes.
@ NO_SDO
Resource not available: SDO connection.
Global namespace for the Lely Industries N.V. libraries.
inline ::std::shared_ptr< T > make_shared_c(Args &&... args)
Creates an instance of a trivial, standard layout or incomplete C type and wraps it in a std::shared_...
This header file is part of the C++ CANopen master library; it contains the Client-SDO queue declarat...
This is the internal header file of the C++ CANopen application library.
The internal implementation of the Client-SDO queue.