Lely core libraries  2.3.4
sdo.cpp
Go to the documentation of this file.
1 
24 #include "coapp.hpp"
25 
26 #if !LELY_NO_CO_CSDO
27 #include <lely/co/csdo.h>
28 #endif
29 #include <lely/co/val.h>
30 #include <lely/coapp/sdo.hpp>
31 
32 #include <limits>
33 #include <memory>
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 #include <cassert>
39 
40 namespace lely {
41 
42 namespace canopen {
43 
45 struct Sdo::Impl_ {
46  Impl_(__can_net* net, __co_dev* dev, uint8_t num);
47  Impl_(__co_csdo* sdo, int timeout);
48  Impl_(const Impl_&) = delete;
49  Impl_& operator=(const Impl_&) = delete;
50  ~Impl_();
51 
52  void Submit(detail::SdoRequestBase& req);
53  ::std::size_t Cancel(detail::SdoRequestBase* req, SdoErrc ac);
54  ::std::size_t Abort(detail::SdoRequestBase* req);
55 
56 #if !LELY_NO_CO_CSDO
57  bool Pop(detail::SdoRequestBase* req, sllist& queue);
58 
59  template <class T>
60  void OnDownload(detail::SdoDownloadRequestBase<T>& req) noexcept;
61  void OnDownloadDcf(detail::SdoDownloadDcfRequestBase& req) noexcept;
62  template <class T>
63  void OnUpload(detail::SdoUploadRequestBase<T>& req) noexcept;
64 
65  void OnDnCon(__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac) noexcept;
66  template <class T>
67  void OnUpCon(__co_csdo*, uint16_t idx, uint8_t subidx, uint32_t ac,
68  const void* ptr, size_t n) noexcept;
69 
70  void OnCompletion(detail::SdoRequestBase& req) noexcept;
71 
72  ::std::shared_ptr<__co_csdo> sdo;
73 
74  sllist queue;
75 #endif
76 };
77 
78 namespace detail {
79 
80 #if !LELY_NO_STDIO
81 void
83  begin = nullptr;
84  end = nullptr;
85  if (dom_) {
87  dom_ = nullptr;
88  }
89 
90  if (!co_val_read_file(CO_DEFTYPE_DOMAIN, &dom_, path))
91  util::throw_errc("ReadFile");
92 
93  begin =
94  static_cast<const uint8_t*>(co_val_addressof(CO_DEFTYPE_DOMAIN, &dom_));
96 }
97 #endif
98 
99 SdoDownloadDcfRequestBase::~SdoDownloadDcfRequestBase() {
100  if (dom_) co_val_fini(CO_DEFTYPE_DOMAIN, &dom_);
101 }
102 
103 template <class T>
104 void
105 SdoDownloadRequestWrapper<T>::operator()() noexcept {
106  auto id = this->id;
107  auto idx = this->idx;
108  auto subidx = this->subidx;
109  auto ec = this->ec;
110  ::std::function<Signature> con;
111  con.swap(this->con_);
112  delete this;
113  if (con) con(id, idx, subidx, ec);
114 }
115 
116 template <class T>
117 void
118 SdoDownloadRequestWrapper<T>::OnRequest(void* data) noexcept {
119 #if LELY_NO_CO_CSDO
120  (void)data;
121 #else
122  static_cast<Sdo::Impl_*>(data)->OnDownload(*this);
123 #endif
124 }
125 
126 void
127 SdoDownloadDcfRequestWrapper::operator()() noexcept {
128  auto id = this->id;
129  auto idx = this->idx;
130  auto subidx = this->subidx;
131  auto ec = this->ec;
132  ::std::function<Signature> con;
133  con.swap(this->con_);
134  delete this;
135  if (con) con(id, idx, subidx, ec);
136 }
137 
138 void
139 SdoDownloadDcfRequestWrapper::OnRequest(void* data) noexcept {
140 #if LELY_NO_CO_CSDO
141  (void)data;
142 #else
143  static_cast<Sdo::Impl_*>(data)->OnDownloadDcf(*this);
144 #endif
145 }
146 
147 template <class T>
148 void
149 SdoUploadRequestWrapper<T>::operator()() noexcept {
150  auto id = this->id;
151  auto idx = this->idx;
152  auto subidx = this->subidx;
153  auto ec = this->ec;
154  T value = ::std::move(this->value);
155  ::std::function<Signature> con;
156  con.swap(this->con_);
157  delete this;
158  if (con) con(id, idx, subidx, ec, ::std::move(value));
159 }
160 
161 template <class T>
162 void
163 SdoUploadRequestWrapper<T>::OnRequest(void* data) noexcept {
164 #if LELY_NO_CO_CSDO
165  (void)data;
166 #else
167  static_cast<Sdo::Impl_*>(data)->OnUpload(*this);
168 #endif
169 }
170 
171 #ifndef DOXYGEN_SHOULD_SKIP_THIS
172 
173 // BOOLEAN
174 template class SdoDownloadRequestWrapper<bool>;
175 template class SdoUploadRequestWrapper<bool>;
176 
177 // INTEGER8
178 template class SdoDownloadRequestWrapper<int8_t>;
179 template class SdoUploadRequestWrapper<int8_t>;
180 
181 // INTEGER16
182 template class SdoDownloadRequestWrapper<int16_t>;
183 template class SdoUploadRequestWrapper<int16_t>;
184 
185 // INTEGER32
186 template class SdoDownloadRequestWrapper<int32_t>;
187 template class SdoUploadRequestWrapper<int32_t>;
188 
189 // UNSIGNED8
190 template class SdoDownloadRequestWrapper<uint8_t>;
191 template class SdoUploadRequestWrapper<uint8_t>;
192 
193 // UNSIGNED16
194 template class SdoDownloadRequestWrapper<uint16_t>;
195 template class SdoUploadRequestWrapper<uint16_t>;
196 
197 // UNSIGNED32
198 template class SdoDownloadRequestWrapper<uint32_t>;
199 template class SdoUploadRequestWrapper<uint32_t>;
200 
201 // REAL32
202 template class SdoDownloadRequestWrapper<float>;
203 template class SdoUploadRequestWrapper<float>;
204 
205 // VISIBLE_STRING
206 template class SdoDownloadRequestWrapper<::std::string>;
207 template class SdoUploadRequestWrapper<::std::string>;
208 
209 // OCTET_STRING
210 template class SdoDownloadRequestWrapper<::std::vector<uint8_t>>;
211 template class SdoUploadRequestWrapper<::std::vector<uint8_t>>;
212 
213 // UNICODE_STRING
214 template class SdoDownloadRequestWrapper<::std::basic_string<char16_t>>;
215 template class SdoUploadRequestWrapper<::std::basic_string<char16_t>>;
216 
217 // TIME_OF_DAY
218 // TIME_DIFFERENCE
219 // DOMAIN
220 // INTEGER24
221 
222 // REAL64
223 template class SdoDownloadRequestWrapper<double>;
224 template class SdoUploadRequestWrapper<double>;
225 
226 // INTEGER40
227 // INTEGER48
228 // INTEGER56
229 
230 // INTEGER64
231 template class SdoDownloadRequestWrapper<int64_t>;
232 template class SdoUploadRequestWrapper<int64_t>;
233 
234 // UNSIGNED24
235 // UNSIGNED40
236 // UNSIGNED48
237 // UNSIGNED56
238 
239 // UNSIGNED64
240 template class SdoDownloadRequestWrapper<uint64_t>;
241 template class SdoUploadRequestWrapper<uint64_t>;
242 
243 #endif // !DOXYGEN_SHOULD_SKIP_THIS
244 
245 } // namespace detail
246 
247 template <class T>
248 void
249 SdoDownloadRequest<T>::operator()() noexcept {
250  if (con_) con_(this->id, this->idx, this->subidx, this->ec);
251 }
252 
253 template <class T>
254 void
255 SdoDownloadRequest<T>::OnRequest(void* data) noexcept {
256 #if LELY_NO_CO_CSDO
257  (void)data;
258 #else
259  static_cast<Sdo::Impl_*>(data)->OnDownload(*this);
260 #endif
261 }
262 
263 void
264 SdoDownloadDcfRequest::operator()() noexcept {
265  if (con_) con_(this->id, this->idx, this->subidx, this->ec);
266 }
267 
268 void
269 SdoDownloadDcfRequest::OnRequest(void* data) noexcept {
270 #if LELY_NO_CO_CSDO
271  (void)data;
272 #else
273  static_cast<Sdo::Impl_*>(data)->OnDownloadDcf(*this);
274 #endif
275 }
276 
277 template <class T>
278 void
279 SdoUploadRequest<T>::operator()() noexcept {
280  if (con_)
281  con_(this->id, this->idx, this->subidx, this->ec, ::std::move(this->value));
282 }
283 
284 template <class T>
285 void
286 SdoUploadRequest<T>::OnRequest(void* data) noexcept {
287 #if LELY_NO_CO_CSDO
288  (void)data;
289 #else
290  static_cast<Sdo::Impl_*>(data)->OnUpload(*this);
291 #endif
292 }
293 
294 #ifndef DOXYGEN_SHOULD_SKIP_THIS
295 
296 // BOOLEAN
297 template class SdoDownloadRequest<bool>;
298 template class SdoUploadRequest<bool>;
299 
300 // INTEGER8
301 template class SdoDownloadRequest<int8_t>;
302 template class SdoUploadRequest<int8_t>;
303 
304 // INTEGER16
305 template class SdoDownloadRequest<int16_t>;
306 template class SdoUploadRequest<int16_t>;
307 
308 // INTEGER32
309 template class SdoDownloadRequest<int32_t>;
310 template class SdoUploadRequest<int32_t>;
311 
312 // UNSIGNED8
313 template class SdoDownloadRequest<uint8_t>;
314 template class SdoUploadRequest<uint8_t>;
315 
316 // UNSIGNED16
317 template class SdoDownloadRequest<uint16_t>;
318 template class SdoUploadRequest<uint16_t>;
319 
320 // UNSIGNED32
321 template class SdoDownloadRequest<uint32_t>;
322 template class SdoUploadRequest<uint32_t>;
323 
324 // REAL32
325 template class SdoDownloadRequest<float>;
326 template class SdoUploadRequest<float>;
327 
328 // VISIBLE_STRING
329 template class SdoDownloadRequest<::std::string>;
330 template class SdoUploadRequest<::std::string>;
331 
332 // OCTET_STRING
333 template class SdoDownloadRequest<::std::vector<uint8_t>>;
334 template class SdoUploadRequest<::std::vector<uint8_t>>;
335 
336 // UNICODE_STRING
337 template class SdoDownloadRequest<::std::basic_string<char16_t>>;
338 template class SdoUploadRequest<::std::basic_string<char16_t>>;
339 
340 // TIME_OF_DAY
341 // TIME_DIFFERENCE
342 // DOMAIN
343 // INTEGER24
344 
345 // REAL64
346 template class SdoDownloadRequest<double>;
347 template class SdoUploadRequest<double>;
348 
349 // INTEGER40
350 // INTEGER48
351 // INTEGER56
352 
353 // INTEGER64
354 template class SdoDownloadRequest<int64_t>;
355 template class SdoUploadRequest<int64_t>;
356 
357 // UNSIGNED24
358 // UNSIGNED40
359 // UNSIGNED48
360 // UNSIGNED56
361 
362 // UNSIGNED64
363 template class SdoDownloadRequest<uint64_t>;
364 template class SdoUploadRequest<uint64_t>;
365 
366 #endif // !DOXYGEN_SHOULD_SKIP_THIS
367 
368 Sdo::Sdo() = default;
369 
370 Sdo::Sdo(__can_net* net, uint8_t id) : Sdo(net, nullptr, id) {}
371 
372 Sdo::Sdo(__can_net* net, __co_dev* dev, uint8_t num)
373  : impl_(new Impl_(net, dev, num)) {}
374 
376 #if LELY_NO_CO_CSDO
377  : impl_(new Impl_(sdo, 0))
378 #else
379  : impl_(new Impl_(sdo, co_csdo_get_timeout(sdo)))
380 #endif
381 {
382 }
383 
384 Sdo& Sdo::operator=(Sdo&&) = default;
385 
386 Sdo::~Sdo() = default;
387 
389 Sdo::AsyncDownloadDcf(ev_exec_t* exec, const uint8_t* begin, const uint8_t* end,
390  const ::std::chrono::milliseconds& timeout) {
393  exec, begin, end,
394  [p](uint8_t id, uint16_t idx, uint8_t subidx,
395  ::std::error_code ec) mutable {
396  if (ec)
397  p.set(util::failure(
398  make_sdo_exception_ptr(id, idx, subidx, ec, "AsyncDownloadDcf")));
399  else
400  p.set(util::success());
401  },
402  timeout);
403  return p.get_future();
404 }
405 
407 Sdo::AsyncDownloadDcf(ev_exec_t* exec, const char* path,
408  const ::std::chrono::milliseconds& timeout) {
411  exec, path,
412  [p](uint8_t id, uint16_t idx, uint8_t subidx,
413  ::std::error_code ec) mutable {
414  if (ec)
415  p.set(util::failure(
416  make_sdo_exception_ptr(id, idx, subidx, ec, "AsyncDownloadDcf")));
417  else
418  p.set(util::success());
419  },
420  timeout);
421  return p.get_future();
422 }
423 
424 void
426  impl_->Submit(req);
427 }
428 
429 bool
431  return impl_->Cancel(&req, ac) != 0;
432 }
433 
434 ::std::size_t
436  return impl_->Cancel(nullptr, ac);
437 }
438 
439 bool
441  return impl_->Abort(&req) != 0;
442 }
443 
444 ::std::size_t
446  return impl_->Abort(nullptr);
447 }
448 
449 Sdo::Impl_::Impl_(__can_net* net, __co_dev* dev, uint8_t num)
450 #if LELY_NO_CO_CSDO
451 {
452  (void)net;
453  (void)dev;
454  (void)num;
455 #else
456  : sdo(co_csdo_create(net, dev, num),
457  [=](__co_csdo* sdo) noexcept { co_csdo_destroy(sdo); }) {
458  sllist_init(&queue);
459 #endif
460 }
461 
462 Sdo::Impl_::Impl_(__co_csdo* sdo_, int timeout)
463 #if LELY_NO_CO_CSDO
464 {
465  (void)sdo_;
466  (void)timeout;
467 #else
468  : sdo(sdo_,
469  [=](__co_csdo* sdo) noexcept { co_csdo_set_timeout(sdo, timeout); }) {
470  sllist_init(&queue);
471 #endif
472 }
473 
474 Sdo::Impl_::~Impl_() { Cancel(nullptr, SdoErrc::NO_SDO); }
475 
476 void
477 Sdo::Impl_::Submit(detail::SdoRequestBase& req) {
478  assert(req.exec);
479  ev::Executor exec(req.exec);
480 
481 #if !LELY_NO_CO_CSDO
482  exec.on_task_init();
483  if (!sdo) {
484 #endif
485  req.id = 0;
486  req.ec = SdoErrc::NO_SDO;
487  exec.post(req);
488 #if !LELY_NO_CO_CSDO
489  exec.on_task_fini();
490  } else {
491  req.id = co_csdo_get_par(sdo.get())->id;
492  bool first = sllist_empty(&queue);
493  sllist_push_back(&queue, &req._node);
494  if (first) req.OnRequest(this);
495  }
496 #endif
497 }
498 
499 ::std::size_t
500 Sdo::Impl_::Cancel(detail::SdoRequestBase* req, SdoErrc ac) {
501 #if LELY_NO_CO_CSDO
502  (void)req;
503  (void)ac;
504 
505  return 0;
506 #else
507  sllist queue;
508  sllist_init(&queue);
509 
510  // Cancel all matching requests, except for the first (ongoing) request.
511  if (Pop(req, queue))
512  // Stop the ongoing request, if any.
513  co_csdo_abort_req(sdo.get(), static_cast<uint32_t>(ac));
514 
515  ::std::size_t n = 0;
516  slnode* node;
517  while ((node = sllist_pop_front(&queue))) {
518  req = static_cast<detail::SdoRequestBase*>(ev_task_from_node(node));
519  req->ec = ac;
520 
521  auto exec = req->GetExecutor();
522  exec.post(*req);
523  exec.on_task_fini();
524 
525  n += n < ::std::numeric_limits<::std::size_t>::max();
526  }
527  return n;
528 #endif
529 }
530 
531 ::std::size_t
532 Sdo::Impl_::Abort(detail::SdoRequestBase* req) {
533 #if LELY_NO_CO_CSDO
534  (void)req;
535 
536  return 0;
537 #else
538  sllist queue;
539  sllist_init(&queue);
540 
541  // Abort all matching requests, except for the first (ongoing) request.
542  Pop(req, queue);
543 
544  return ev_task_queue_abort(&queue);
545 #endif
546 }
547 
548 #if !LELY_NO_CO_CSDO
549 
550 bool
551 Sdo::Impl_::Pop(detail::SdoRequestBase* req, sllist& queue) {
552  if (!req) {
553  // Cancel all pending requests except for the first (ongoing) request.
554  auto node = sllist_pop_front(&this->queue);
555  sllist_append(&queue, &this->queue);
556  if (node) {
557  sllist_push_front(&this->queue, node);
558  req = static_cast<detail::SdoRequestBase*>(ev_task_from_node(node));
559  }
560  } else if (&req->_node != sllist_first(&this->queue)) {
561  if (sllist_remove(&queue, &req->_node))
562  sllist_push_back(&this->queue, &req->_node);
563  req = nullptr;
564  }
565  // Return true if the first request matched (but was not removed).
566  return req != nullptr;
567 }
568 
569 template <class T>
570 void
571 Sdo::Impl_::OnDownload(detail::SdoDownloadRequestBase<T>& req) noexcept {
572  assert(&req._node == sllist_first(&queue));
573 
574  using traits = canopen_traits<T>;
575 
576  auto val = traits::to_c_type(req.value, req.ec);
577  if (req.ec) {
578  OnCompletion(req);
579  } else {
580  int errsv = get_errc();
581  set_errc(0);
582 
583  co_csdo_set_timeout(sdo.get(), detail::to_sdo_timeout(req.timeout));
584 
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);
588  };
589  int result = req.block
590  ? co_csdo_blk_dn_val_req(sdo.get(), req.idx, req.subidx,
591  traits::index, &val, con, this)
592  : co_csdo_dn_val_req(sdo.get(), req.idx, req.subidx,
593  traits::index, &val, con, this);
594  if (result == -1) {
595  req.ec = util::make_error_code();
596  OnCompletion(req);
597  }
598 
599  set_errc(errsv);
600  traits::destroy(val);
601  }
602 }
603 
604 void
605 Sdo::Impl_::OnDownloadDcf(detail::SdoDownloadDcfRequestBase& req) noexcept {
606  assert(&req._node == sllist_first(&queue));
607 
608  int errsv = get_errc();
609  set_errc(0);
610 
611  co_csdo_set_timeout(sdo.get(), detail::to_sdo_timeout(req.timeout));
612  if (co_csdo_dn_dcf_req(
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);
617  },
618  this) == -1) {
619  req.ec = util::make_error_code();
620  OnCompletion(req);
621  }
622 
623  set_errc(errsv);
624 }
625 
626 template <class T>
627 void
628 Sdo::Impl_::OnUpload(detail::SdoUploadRequestBase<T>& req) noexcept {
629  assert(&req._node == sllist_first(&queue));
630 
631  int errsv = get_errc();
632  set_errc(0);
633 
634  co_csdo_set_timeout(sdo.get(), detail::to_sdo_timeout(req.timeout));
635 
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);
639  };
640  int result =
641  req.block
642  ? co_csdo_blk_up_req(sdo.get(), req.idx, req.subidx, 0, con, this)
643  : co_csdo_up_req(sdo.get(), req.idx, req.subidx, con, this);
644  if (result == -1) {
645  req.ec = util::make_error_code();
646  OnCompletion(req);
647  }
648 
649  set_errc(errsv);
650 }
651 
652 void
653 Sdo::Impl_::OnDnCon(__co_csdo*, uint16_t idx, uint8_t subidx,
654  uint32_t ac) noexcept {
655  auto task = ev_task_from_node(sllist_first(&queue));
656  assert(task);
657  auto req = static_cast<detail::SdoRequestBase*>(task);
658 
659  req->idx = idx;
660  req->subidx = subidx;
661  req->ec = SdoErrc(ac);
662 
663  OnCompletion(*req);
664 }
665 
666 template <class T>
667 void
668 Sdo::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;
672 
673  auto task = ev_task_from_node(sllist_first(&queue));
674  assert(task);
675  auto req = static_cast<detail::SdoUploadRequestBase<T>*>(task);
676 
677  auto val = c_type();
678  if (!ac) {
679  ::std::error_code ec;
680  val = traits::construct(ptr, n, ec);
681  if (ec) ac = static_cast<uint32_t>(sdo_errc(ec));
682  }
683 
684  req->idx = idx;
685  req->subidx = subidx;
686  req->ec = SdoErrc(ac);
687  req->value = ac ? T() : traits::from_c_type(val);
688 
689  traits::destroy(val);
690 
691  OnCompletion(*req);
692 }
693 
694 void
695 Sdo::Impl_::OnCompletion(detail::SdoRequestBase& req) noexcept {
696  assert(&req._node == sllist_first(&queue));
697  sllist_pop_front(&queue);
698 
699  ev::Executor exec(req.exec);
700  exec.post(req);
701  exec.on_task_fini();
702 
703  auto task = ev_task_from_node(sllist_first(&queue));
704  if (task) static_cast<detail::SdoRequestBase*>(task)->OnRequest(this);
705 }
706 
707 #endif // !LELY_NO_CO_CSDO
708 
709 } // namespace canopen
710 
711 } // namespace lely
lely::canopen::detail::SdoRequestBase
Definition: sdo.hpp:162
co_csdo_blk_up_req
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.
Definition: csdo.c:1356
co_csdo_abort_req
void co_csdo_abort_req(co_csdo_t *sdo, co_unsigned32_t ac)
Submits an abort transfer request to a remote Server-SDO.
Definition: csdo.c:1211
ev_task_from_node
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.
Definition: task.c:32
ev_exec_t
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
lely::canopen::Sdo::~Sdo
~Sdo()
Destructs the Client-SDO queue.
sllist_remove
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
Definition: sllist.c:46
__co_csdo::idx
co_unsigned16_t idx
The current object index.
Definition: csdo.c:91
co_val_read_file
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.
Definition: val.c:671
sllist_first
struct slnode * sllist_first(const struct sllist *list)
Returns a pointer to the first node in a singly-linked list.
Definition: sllist.h:271
val.h
co_val_fini
void co_val_fini(co_unsigned16_t type, void *val)
Finalizes a value of the specified data type.
Definition: val.c:249
lely::ev::Promise
A promise.
Definition: future.hpp:60
co_val_addressof
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.
Definition: val.c:260
co_csdo_get_par
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.
Definition: csdo.c:1126
lely::canopen::Sdo::CancelAll
::std::size_t CancelAll(SdoErrc ac)
Cancels all pending SDO requests and stops the ongoing request, if any.
Definition: sdo.cpp:435
sllist_push_front
void sllist_push_front(struct sllist *list, struct slnode *node)
Pushes a node to the front of a singly-linked list.
Definition: sllist.h:221
get_errc
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
lely::ev::Promise::get_future
Future< T, E > get_future() const noexcept
Returns a lely::ev::Future with (a reference to) the same shared state as *this.
Definition: future.hpp:188
CO_DEFTYPE_DOMAIN
#define CO_DEFTYPE_DOMAIN
The data type (and object index) of an arbitrary large block of data.
Definition: type.h:77
lely::canopen::detail::SdoDownloadRequestBase
Definition: sdo.hpp:217
sllist_append
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
Definition: sllist.h:257
lely::canopen::detail::SdoRequestBase::idx
uint16_t idx
The object index.
Definition: sdo.hpp:193
lely::canopen::detail::SdoUploadRequestBase
Definition: sdo.hpp:269
lely::canopen::detail::SdoRequestBase::ec
::std::error_code ec
The SDO abort code (0 on success).
Definition: sdo.hpp:208
set_errc
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
sllist_empty
int sllist_empty(const struct sllist *list)
Returns 1 if the singly-linked list is empty, and 0 if not.
Definition: sllist.h:202
lely::canopen::Sdo::AbortAll
::std::size_t AbortAll()
Aborts all pending SDO requests.
Definition: sdo.cpp:445
co_csdo_get_timeout
int co_csdo_get_timeout(const co_csdo_t *sdo)
Returns the timeout (in milliseconds) of a Client-SDO.
Definition: csdo.c:1134
co_csdo_create
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.
Definition: csdo.c:997
ev_task_queue_abort
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.
Definition: task.c:55
lely::ev::Future
A future.
Definition: future.hpp:50
co_val_sizeof
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.
Definition: val.c:269
co_csdo_destroy
void co_csdo_destroy(co_csdo_t *sdo)
Destroys a CANopen Client-SDO service.
Definition: csdo.c:1024
lely::canopen::detail::SdoDownloadDcfRequestBase::begin
const uint8_t * begin
A pointer the the first byte in a concise DCF (see object 1F22 in CiA 302-3 version 4....
Definition: sdo.hpp:256
sllist_init
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
Definition: sllist.h:194
lely::canopen::SdoErrc
SdoErrc
The SDO abort codes.
Definition: sdo_error.hpp:42
sllist_pop_front
struct slnode * sllist_pop_front(struct sllist *list)
Pops a node from the front of a singly-linked list.
Definition: sllist.h:243
coapp.hpp
lely::canopen::Sdo::Submit
void Submit(detail::SdoRequestBase &req)
Queues an LSS request.
Definition: sdo.cpp:425
co_csdo_blk_dn_val_req
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.
Definition: csdo.c:1332
lely::canopen::detail::SdoDownloadDcfRequestBase
Definition: sdo.hpp:232
sllist
A singly-linked list.
Definition: sllist.h:52
__co_dev
A CANopen device.
Definition: dev.h:30
co_csdo_up_req
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.
Definition: csdo.c:1294
co_csdo_set_timeout
void co_csdo_set_timeout(co_csdo_t *sdo, int timeout)
Sets the timeout of a Client-SDO.
Definition: csdo.c:1142
co_csdo_dn_dcf_req
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.
Definition: csdo.c:1265
lely::canopen::Sdo::Abort
bool Abort(detail::SdoRequestBase &req)
Aborts a pending SDO request.
Definition: sdo.cpp:440
lely::canopen::make_sdo_exception_ptr
::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 ...
Definition: sdo_error.cpp:209
co_sdo_par::id
co_unsigned8_t id
Node-ID of SDO's client resp. server.
Definition: sdo.h:53
lely::canopen::Sdo::AsyncDownloadDcf
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...
Definition: sdo.cpp:389
__co_csdo
A CANopen Client-SDO.
Definition: csdo.c:71
lely::canopen::Sdo::SubmitDownloadDcf
void SubmitDownloadDcf(SdoDownloadDcfRequest &req)
Queues an SDO download DCF request.
Definition: sdo.hpp:705
lely::canopen::SdoErrc::NO_SDO
@ NO_SDO
Resource not available: SDO connection.
lely::canopen::detail::to_sdo_timeout
int to_sdo_timeout(const ::std::chrono::duration< Rep, Period > &d)
Converts a duration to an SDO timeout.
Definition: sdo.hpp:148
sdo.hpp
csdo.h
lely::canopen::sdo_errc
SdoErrc sdo_errc(::std::error_code ec)
Returns the SDO abort code corresponding to an error code.
Definition: sdo_error.cpp:180
lely::canopen::detail::SdoDownloadDcfRequestBase::Read
void Read(const char *path)
Reads a concise DCF from the specified path.
Definition: sdo.cpp:82
slnode
A node in a singly-linked list.
Definition: sllist.h:40
lely::canopen::make_error_code
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
lely::canopen::Sdo::Sdo
Sdo()
Default-constructs an invalid Client-SDO queue.
lely::canopen::detail::SdoRequestBase::id
uint8_t id
The node-ID.
Definition: sdo.hpp:191
sllist_push_back
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
Definition: sllist.h:232
lely::canopen::detail::SdoRequestBase::subidx
uint8_t subidx
The object sub-index.
Definition: sdo.hpp:195
lely::canopen::detail::SdoDownloadDcfRequestBase::end
const uint8_t * end
A pointer to one past the last byte in the concise DCF.
Definition: sdo.hpp:262
lely::ev::Promise::set
bool set(U &&u)
Satisfies a promise, if it was not aready satisfied, and stores the specified value as the result in ...
Definition: future.hpp:166
co_csdo_dn_val_req
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.
Definition: csdo.c:1241
lely::canopen::Sdo::Impl_
The internal implementation of the Client-SDO queue.
Definition: sdo.cpp:45
__can_net
A CAN network interface.
Definition: net.c:37
lely::canopen::Sdo::Cancel
bool Cancel(detail::SdoRequestBase &req, SdoErrc ac)
Cancels a pending SDO request.
Definition: sdo.cpp:430
lely::canopen::Sdo
A Client-SDO queue.
Definition: sdo.hpp:588