65 void OnDnCon(
__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac)
noexcept;
67 void OnUpCon(
__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac,
68 const void* ptr,
size_t n)
noexcept;
72 ::std::shared_ptr<__co_csdo> sdo;
91 util::throw_errc(
"ReadFile");
99SdoDownloadDcfRequestBase::~SdoDownloadDcfRequestBase() {
105SdoDownloadRequestWrapper<T>::operator()() noexcept {
107 auto idx = this->idx;
108 auto subidx = this->subidx;
110 ::std::function<Signature> con;
111 con.swap(this->con_);
113 if (con) con(
id, idx, subidx, ec);
118SdoDownloadRequestWrapper<T>::OnRequest(
void* data)
noexcept {
122 static_cast<Sdo::Impl_*
>(data)->OnDownload(*
this);
127SdoDownloadDcfRequestWrapper::operator()() noexcept {
132 ::std::function<Signature> con;
133 con.swap(this->con_);
139SdoDownloadDcfRequestWrapper::OnRequest(
void* data)
noexcept {
143 static_cast<Sdo::Impl_*
>(data)->OnDownloadDcf(*
this);
149SdoUploadRequestWrapper<T>::operator()() noexcept {
151 auto idx = this->idx;
152 auto subidx = this->subidx;
154 T value = ::std::move(this->value);
155 ::std::function<Signature> con;
156 con.swap(this->con_);
158 if (con) con(
id, idx, subidx, ec, ::std::move(value));
163SdoUploadRequestWrapper<T>::OnRequest(
void* data)
noexcept {
167 static_cast<Sdo::Impl_*
>(data)->OnUpload(*
this);
171#ifndef DOXYGEN_SHOULD_SKIP_THIS
174template class SdoDownloadRequestWrapper<bool>;
175template class SdoUploadRequestWrapper<bool>;
178template class SdoDownloadRequestWrapper<int8_t>;
179template class SdoUploadRequestWrapper<int8_t>;
182template class SdoDownloadRequestWrapper<int16_t>;
183template class SdoUploadRequestWrapper<int16_t>;
186template class SdoDownloadRequestWrapper<int32_t>;
187template class SdoUploadRequestWrapper<int32_t>;
190template class SdoDownloadRequestWrapper<uint8_t>;
191template class SdoUploadRequestWrapper<uint8_t>;
194template class SdoDownloadRequestWrapper<uint16_t>;
195template class SdoUploadRequestWrapper<uint16_t>;
198template class SdoDownloadRequestWrapper<uint32_t>;
199template class SdoUploadRequestWrapper<uint32_t>;
202template class SdoDownloadRequestWrapper<float>;
203template class SdoUploadRequestWrapper<float>;
206template class SdoDownloadRequestWrapper<::std::string>;
207template class SdoUploadRequestWrapper<::std::string>;
210template class SdoDownloadRequestWrapper<::std::vector<uint8_t>>;
211template class SdoUploadRequestWrapper<::std::vector<uint8_t>>;
214template class SdoDownloadRequestWrapper<::std::basic_string<char16_t>>;
215template class SdoUploadRequestWrapper<::std::basic_string<char16_t>>;
223template class SdoDownloadRequestWrapper<double>;
224template class SdoUploadRequestWrapper<double>;
231template class SdoDownloadRequestWrapper<int64_t>;
232template class SdoUploadRequestWrapper<int64_t>;
240template class SdoDownloadRequestWrapper<uint64_t>;
241template class SdoUploadRequestWrapper<uint64_t>;
249SdoDownloadRequest<T>::operator()() noexcept {
250 if (con_) con_(this->
id, this->idx, this->subidx, this->ec);
255SdoDownloadRequest<T>::OnRequest(
void* data)
noexcept {
259 static_cast<Sdo::Impl_*
>(data)->OnDownload(*
this);
264SdoDownloadDcfRequest::operator()() noexcept {
265 if (con_) con_(this->
id, this->
idx, this->
subidx, this->
ec);
269SdoDownloadDcfRequest::OnRequest(
void* data)
noexcept {
273 static_cast<Sdo::Impl_*
>(data)->OnDownloadDcf(*
this);
279SdoUploadRequest<T>::operator()() noexcept {
281 con_(this->
id, this->idx, this->subidx, this->ec, ::std::move(this->value));
286SdoUploadRequest<T>::OnRequest(
void* data)
noexcept {
290 static_cast<Sdo::Impl_*
>(data)->OnUpload(*
this);
294#ifndef DOXYGEN_SHOULD_SKIP_THIS
297template class SdoDownloadRequest<bool>;
298template class SdoUploadRequest<bool>;
301template class SdoDownloadRequest<int8_t>;
302template class SdoUploadRequest<int8_t>;
305template class SdoDownloadRequest<int16_t>;
306template class SdoUploadRequest<int16_t>;
309template class SdoDownloadRequest<int32_t>;
310template class SdoUploadRequest<int32_t>;
313template class SdoDownloadRequest<uint8_t>;
314template class SdoUploadRequest<uint8_t>;
317template class SdoDownloadRequest<uint16_t>;
318template class SdoUploadRequest<uint16_t>;
321template class SdoDownloadRequest<uint32_t>;
322template class SdoUploadRequest<uint32_t>;
325template class SdoDownloadRequest<float>;
326template class SdoUploadRequest<float>;
329template class SdoDownloadRequest<::std::string>;
330template class SdoUploadRequest<::std::string>;
333template class SdoDownloadRequest<::std::vector<uint8_t>>;
334template class SdoUploadRequest<::std::vector<uint8_t>>;
337template class SdoDownloadRequest<::std::basic_string<char16_t>>;
338template class SdoUploadRequest<::std::basic_string<char16_t>>;
346template class SdoDownloadRequest<double>;
347template class SdoUploadRequest<double>;
354template class SdoDownloadRequest<int64_t>;
355template class SdoUploadRequest<int64_t>;
363template class SdoDownloadRequest<uint64_t>;
364template class SdoUploadRequest<uint64_t>;
373 : impl_(new
Impl_(net, dev, num)) {}
377 : impl_(
new Impl_(sdo, 0))
384Sdo& Sdo::operator=(
Sdo&&) =
default;
390 const ::std::chrono::milliseconds& timeout) {
394 [p](uint8_t
id, uint16_t idx, uint8_t subidx,
395 ::std::error_code ec)
mutable {
400 p.
set(util::success());
408 const ::std::chrono::milliseconds& timeout) {
412 [p](uint8_t
id, uint16_t idx, uint8_t subidx,
413 ::std::error_code ec)
mutable {
418 p.
set(util::success());
431 return impl_->Cancel(&req, ac) != 0;
436 return impl_->Cancel(
nullptr, ac);
441 return impl_->Abort(&req) != 0;
446 return impl_->Abort(
nullptr);
462Sdo::Impl_::Impl_(
__co_csdo* sdo_,
int timeout)
477Sdo::Impl_::Submit(detail::SdoRequestBase& req) {
479 ev::Executor exec(req.exec);
494 if (first) req.OnRequest(
this);
500Sdo::Impl_::Cancel(detail::SdoRequestBase* req,
SdoErrc ac) {
521 auto exec = req->GetExecutor();
525 n += n < ::std::numeric_limits<::std::size_t>::max();
532Sdo::Impl_::Abort(detail::SdoRequestBase* req) {
551Sdo::Impl_::Pop(detail::SdoRequestBase* req,
sllist& queue) {
566 return req !=
nullptr;
571Sdo::Impl_::OnDownload(detail::SdoDownloadRequestBase<T>& req)
noexcept {
574 using traits = canopen_traits<T>;
576 auto val = traits::to_c_type(req.value, req.ec);
585 auto con = [](
__co_csdo* sdo, uint16_t idx, uint8_t subidx, uint32_t ac,
586 void* data)
noexcept {
587 static_cast<Impl_*
>(data)->OnDnCon(sdo, idx, subidx, ac);
589 int result = req.block
591 traits::index, &val, con,
this)
593 traits::index, &val, con, this);
600 traits::destroy(val);
605Sdo::Impl_::OnDownloadDcf(detail::SdoDownloadDcfRequestBase& req)
noexcept {
613 sdo.get(), req.begin, req.end,
614 [](
__co_csdo* sdo, uint16_t idx, uint8_t subidx, uint32_t ac,
615 void* data)
noexcept {
616 static_cast<Impl_*>(data)->OnDnCon(sdo, idx, subidx, ac);
628Sdo::Impl_::OnUpload(detail::SdoUploadRequestBase<T>& req)
noexcept {
636 auto con = [](
__co_csdo* sdo, uint16_t idx, uint8_t subidx, uint32_t ac,
637 const void* ptr,
size_t n,
void* data)
noexcept {
638 static_cast<Impl_*
>(data)->OnUpCon<T>(sdo, idx, subidx, ac, ptr, n);
653Sdo::Impl_::OnDnCon(
__co_csdo*, uint16_t idx, uint8_t subidx,
654 uint32_t ac)
noexcept {
657 auto req =
static_cast<detail::SdoRequestBase*
>(task);
660 req->subidx = subidx;
668Sdo::Impl_::OnUpCon(
__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac,
669 const void* ptr,
size_t n)
noexcept {
670 using traits = canopen_traits<T>;
671 using c_type =
typename traits::c_type;
675 auto req =
static_cast<detail::SdoUploadRequestBase<T>*
>(task);
679 ::std::error_code ec;
680 val = traits::construct(ptr, n, ec);
681 if (ec) ac =
static_cast<uint32_t
>(
sdo_errc(ec));
685 req->subidx = subidx;
687 req->value = ac ? T() : traits::from_c_type(val);
689 traits::destroy(val);
695Sdo::Impl_::OnCompletion(detail::SdoRequestBase& req)
noexcept {
699 ev::Executor exec(req.exec);
704 if (task)
static_cast<detail::SdoRequestBase*
>(task)->OnRequest(
this);
Sdo()
Default-constructs an invalid Client-SDO queue.
bool Abort(detail::SdoRequestBase &req)
Aborts a pending SDO request.
void Submit(detail::SdoRequestBase &req)
Queues an LSS request.
bool Cancel(detail::SdoRequestBase &req, SdoErrc ac)
Cancels a pending SDO request.
void SubmitDownloadDcf(SdoDownloadDcfRequest &req)
Queues an SDO download DCF request.
~Sdo()
Destructs the Client-SDO queue.
::std::size_t AbortAll()
Aborts all pending SDO requests.
::std::size_t CancelAll(SdoErrc ac)
Cancels all pending SDO requests and stops the ongoing request, if any.
SdoFuture< void > AsyncDownloadDcf(ev_exec_t *exec, const uint8_t *begin, const uint8_t *end, const ::std::chrono::milliseconds &timeout={})
Queues a series asynchronous SDO download requests, corresponding to the entries in the specified con...
const uint8_t * end
A pointer to one past the last byte in the concise DCF.
void Read(const char *path)
Reads a concise DCF from the specified path.
const uint8_t * begin
A pointer the the first byte in a concise DCF (see object 1F22 in CiA 302-3 version 4....
uint16_t idx
The object index.
uint8_t subidx
The object sub-index.
::std::error_code ec
The SDO abort code (0 on success).
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 is the internal header file of the C++ CANopen application library.
This header file is part of the CANopen library; it contains the Client-SDO declarations.
int co_csdo_up_req(co_csdo_t *sdo, co_unsigned16_t idx, co_unsigned8_t subidx, co_csdo_up_con_t *con, void *data)
Submits an upload request to a remote Server-SDO.
void co_csdo_set_timeout(co_csdo_t *sdo, int timeout)
Sets the timeout of a Client-SDO.
int co_csdo_get_timeout(const co_csdo_t *sdo)
Returns the timeout (in milliseconds) of a Client-SDO.
int co_csdo_blk_up_req(co_csdo_t *sdo, co_unsigned16_t idx, co_unsigned8_t subidx, co_unsigned8_t pst, co_csdo_up_con_t *con, void *data)
Submits a block upload request to a remote Server-SDO.
int co_csdo_blk_dn_val_req(co_csdo_t *sdo, co_unsigned16_t idx, co_unsigned8_t subidx, co_unsigned16_t type, const void *val, co_csdo_dn_con_t *con, void *data)
Submits a block download request to a remote Server-SDO.
void co_csdo_abort_req(co_csdo_t *sdo, co_unsigned32_t ac)
Submits an abort transfer request to a remote Server-SDO.
int co_csdo_dn_dcf_req(co_csdo_t *sdo, const uint_least8_t *begin, const uint_least8_t *end, co_csdo_dn_con_t *con, void *data)
Submits a series of download requests to a remote Server-SDO.
const struct co_sdo_par * co_csdo_get_par(const co_csdo_t *sdo)
Returns a pointer to the SDO parameter record of a Client-SDO.
co_csdo_t * co_csdo_create(can_net_t *net, co_dev_t *dev, co_unsigned8_t num)
Creates a new CANopen Client-SDO service.
int co_csdo_dn_val_req(co_csdo_t *sdo, co_unsigned16_t idx, co_unsigned8_t subidx, co_unsigned16_t type, const void *val, co_csdo_dn_con_t *con, void *data)
Submits a download request to a remote Server-SDO.
void co_csdo_destroy(co_csdo_t *sdo)
Destroys a CANopen Client-SDO service.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
int to_sdo_timeout(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.
SdoErrc sdo_errc(::std::error_code ec)
Returns the SDO abort code corresponding to an error code.
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
::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 master library; it contains the Client-SDO queue declarat...
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
void sllist_push_front(struct sllist *list, struct slnode *node)
Pushes a node to the front of a singly-linked list.
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
struct slnode * sllist_first(const struct sllist *list)
Returns a pointer to the first node in a singly-linked list.
co_unsigned16_t idx
The current object index.
co_unsigned8_t id
Node-ID of SDO's client resp. server.
The internal implementation of the Client-SDO queue.
A node in a singly-linked list.
size_t ev_task_queue_abort(struct sllist *queue)
Aborts the tasks in queue by invoking ev_exec_on_task_fini() for each of them.
struct ev_task * ev_task_from_node(struct slnode *node)
Converts a pointer to a node in a queue to the address of the task containing the node.
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
This header file is part of the CANopen library; it contains the CANopen value declarations.
const void * co_val_addressof(co_unsigned16_t type, const void *val)
Returns the address of the first byte in a value of the specified data type.
size_t co_val_sizeof(co_unsigned16_t type, const void *val)
Returns the size (in bytes) of a value of the specified data type.
size_t co_val_read_file(co_unsigned16_t type, void *val, const char *filename)
Reads a value of the specified data type from a file.
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.