26 #if !LELY_NO_COAPP_SLAVE
50 netid()
const noexcept {
51 return self->dev()->getNetid();
56 return self->dev()->getId();
59 void OnLgInd(
CONMT*
nmt,
int state) noexcept;
67 static constexpr uint32_t Key(uint16_t idx, uint8_t subidx) noexcept;
68 static uint32_t Key(
const COSub* sub) noexcept;
72 ::std::map<uint32_t, ::std::function<uint32_t(
COSub*,
void*)>> dn_ind;
73 ::std::map<uint32_t, ::std::function<uint32_t(
const COSub*,
void*)>> up_ind;
75 ::std::function<void(
bool)> on_life_guarding;
80 const ::std::string& dcf_bin, uint8_t
id)
81 :
Node(exec, timer, chan, dcf_txt, dcf_bin, id),
84 BasicSlave::~BasicSlave() =
default;
88 ::std::lock_guard<util::BasicLockable>
lock(*
this);
89 impl_->on_life_guarding = on_life_guarding;
93 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
95 ::std::function<OnReadSignature<T>> ind) {
97 OnRead<T>(idx, subidx, ::std::move(ind), ec);
98 if (ec)
throw SdoError(impl_->id(), idx, subidx, ec);
103 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
104 typename ::std::enable_if<detail::is_canopen_basic<T>::value,
105 ::std::error_code>::type
110 return ind(sub->getObj()->getIdx(), sub->getSubidx(), val);
116 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
117 typename ::std::enable_if<detail::is_canopen_array<T>::value,
118 ::std::error_code>::type
119 OnUpInd(
const COSub* sub, COVal<N>& val,
const F& ind) {
124 auto ec = ind(sub->getObj()->getIdx(), sub->getSubidx(), value);
125 if (!ec) val = ::std::move(value);
135 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
137 ::std::function<OnReadSignature<T>> ind,
138 ::std::error_code& ec) {
139 constexpr
auto N = co_type_traits_T<T>::index;
141 auto obj =
dev()->find(idx);
147 auto sub = obj->find(subidx);
158 auto key = Impl_::Key(sub);
160 impl_->up_ind[key] = [
this, ind](
const COSub* sub,
void* p) {
161 auto ec = OnUpInd<T>(sub, *
static_cast<COVal<N>*
>(p), ind);
162 return static_cast<uint32_t
>(ec.value());
164 sub->setUpInd<N, Impl_, &Impl_::OnUpInd>(impl_.get());
166 if (impl_->up_ind.erase(key)) sub->setUpInd(
nullptr,
nullptr);
171 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
173 uint8_t n = (*this)[idx][0];
174 for (uint8_t i = 1; i <= n; i++) OnRead<T>(idx, i, ind);
178 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
180 ::std::error_code& ec) {
181 uint8_t n = (*this)[idx][0].Get<uint8_t>(ec);
182 for (uint8_t i = 1; i <= n && !ec; i++) OnRead<T>(idx, i, ind, ec);
186 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
188 ::std::function<OnWriteSignature<T>> ind) {
189 ::std::error_code ec;
190 OnWrite<T>(idx, subidx, ::std::move(ind), ec);
191 if (ec)
throw SdoError(impl_->id(), idx, subidx, ec);
196 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
197 typename ::std::enable_if<detail::is_canopen_basic<T>::value,
198 ::std::error_code>::type
199 OnDnInd(COSub* sub, COVal<N>& val,
const F& ind) {
203 return ind(sub->getObj()->getIdx(), sub->getSubidx(), val,
210 template <class T, class F, uint16_t N = co_type_traits_T<T>::index>
211 typename ::std::enable_if<detail::is_canopen_array<T>::value,
212 ::std::error_code>::type
213 OnDnInd(COSub* sub, COVal<N>& val,
const F& ind) {
218 auto ec = ind(sub->getObj()->getIdx(), sub->getSubidx(), value);
219 if (!ec) val = ::std::move(value);
229 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
231 ::std::function<OnWriteSignature<T>> ind,
232 ::std::error_code& ec) {
233 constexpr
auto N = co_type_traits_T<T>::index;
235 auto obj =
dev()->find(idx);
241 auto sub = obj->find(subidx);
252 auto key = Impl_::Key(sub);
254 impl_->dn_ind[key] = [
this, ind](COSub* sub,
void* p) {
255 auto ec = OnDnInd<T>(sub, *
static_cast<COVal<N>*
>(p), ind);
256 return static_cast<uint32_t
>(ec.value());
258 sub->setDnInd<N, Impl_, &Impl_::OnDnInd>(impl_.get());
260 if (impl_->dn_ind.erase(key)) sub->setDnInd(
nullptr,
nullptr);
265 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
267 uint8_t n = (*this)[idx][0];
268 for (uint8_t i = 1; i <= n; i++) OnWrite<T>(idx, i, ind);
272 typename ::std::enable_if<detail::is_canopen_type<T>::value>::type
274 ::std::error_code& ec) {
275 uint8_t n = (*this)[idx][0].Get<uint8_t>(ec);
276 for (uint8_t i = 1; i <= n && !ec; i++) OnWrite<T>(idx, i, ind, ec);
279 #ifndef DOXYGEN_SHOULD_SKIP_THIS
282 template void BasicSlave::OnRead<bool>(uint16_t, uint8_t,
283 ::std::function<OnReadSignature<bool>>);
284 template void BasicSlave::OnRead<bool>(uint16_t, uint8_t,
285 ::std::function<OnReadSignature<bool>>,
287 template void BasicSlave::OnRead<bool>(uint16_t,
288 ::std::function<OnReadSignature<bool>>);
289 template void BasicSlave::OnRead<bool>(uint16_t,
290 ::std::function<OnReadSignature<bool>>,
292 template void BasicSlave::OnWrite<bool>(
293 uint16_t, uint8_t, ::std::function<OnWriteSignature<bool>>);
294 template void BasicSlave::OnWrite<bool>(uint16_t, uint8_t,
295 ::std::function<OnWriteSignature<bool>>,
297 template void BasicSlave::OnWrite<bool>(
298 uint16_t, ::std::function<OnWriteSignature<bool>>);
299 template void BasicSlave::OnWrite<bool>(uint16_t,
300 ::std::function<OnWriteSignature<bool>>,
304 template void BasicSlave::OnRead<int8_t>(
305 uint16_t, uint8_t, ::std::function<OnReadSignature<int8_t>>);
306 template void BasicSlave::OnRead<int8_t>(
307 uint16_t, uint8_t, ::std::function<OnReadSignature<int8_t>>,
309 template void BasicSlave::OnRead<int8_t>(
310 uint16_t, ::std::function<OnReadSignature<int8_t>>);
311 template void BasicSlave::OnRead<int8_t>(
312 uint16_t, ::std::function<OnReadSignature<int8_t>>, ::std::error_code&);
313 template void BasicSlave::OnWrite<int8_t>(
314 uint16_t, uint8_t, ::std::function<OnWriteSignature<int8_t>>);
315 template void BasicSlave::OnWrite<int8_t>(
316 uint16_t, uint8_t, ::std::function<OnWriteSignature<int8_t>>,
318 template void BasicSlave::OnWrite<int8_t>(
319 uint16_t, ::std::function<OnWriteSignature<int8_t>>);
320 template void BasicSlave::OnWrite<int8_t>(
321 uint16_t, ::std::function<OnWriteSignature<int8_t>>, ::std::error_code&);
324 template void BasicSlave::OnRead<int16_t>(
325 uint16_t, uint8_t, ::std::function<OnReadSignature<int16_t>>);
326 template void BasicSlave::OnRead<int16_t>(
327 uint16_t, uint8_t, ::std::function<OnReadSignature<int16_t>>,
329 template void BasicSlave::OnRead<int16_t>(
330 uint16_t, ::std::function<OnReadSignature<int16_t>>);
331 template void BasicSlave::OnRead<int16_t>(
332 uint16_t, ::std::function<OnReadSignature<int16_t>>, ::std::error_code&);
333 template void BasicSlave::OnWrite<int16_t>(
334 uint16_t, uint8_t, ::std::function<OnWriteSignature<int16_t>>);
335 template void BasicSlave::OnWrite<int16_t>(
336 uint16_t, uint8_t, ::std::function<OnWriteSignature<int16_t>>,
338 template void BasicSlave::OnWrite<int16_t>(
339 uint16_t, ::std::function<OnWriteSignature<int16_t>>);
340 template void BasicSlave::OnWrite<int16_t>(
341 uint16_t, ::std::function<OnWriteSignature<int16_t>>, ::std::error_code&);
344 template void BasicSlave::OnRead<int32_t>(
345 uint16_t, uint8_t, ::std::function<OnReadSignature<int32_t>>);
346 template void BasicSlave::OnRead<int32_t>(
347 uint16_t, uint8_t, ::std::function<OnReadSignature<int32_t>>,
349 template void BasicSlave::OnRead<int32_t>(
350 uint16_t, ::std::function<OnReadSignature<int32_t>>);
351 template void BasicSlave::OnRead<int32_t>(
352 uint16_t, ::std::function<OnReadSignature<int32_t>>, ::std::error_code&);
353 template void BasicSlave::OnWrite<int32_t>(
354 uint16_t, uint8_t, ::std::function<OnWriteSignature<int32_t>>);
355 template void BasicSlave::OnWrite<int32_t>(
356 uint16_t, uint8_t, ::std::function<OnWriteSignature<int32_t>>,
358 template void BasicSlave::OnWrite<int32_t>(
359 uint16_t, ::std::function<OnWriteSignature<int32_t>>);
360 template void BasicSlave::OnWrite<int32_t>(
361 uint16_t, ::std::function<OnWriteSignature<int32_t>>, ::std::error_code&);
364 template void BasicSlave::OnRead<uint8_t>(
365 uint16_t, uint8_t, ::std::function<OnReadSignature<uint8_t>>);
366 template void BasicSlave::OnRead<uint8_t>(
367 uint16_t, uint8_t, ::std::function<OnReadSignature<uint8_t>>,
369 template void BasicSlave::OnRead<uint8_t>(
370 uint16_t, ::std::function<OnReadSignature<uint8_t>>);
371 template void BasicSlave::OnRead<uint8_t>(
372 uint16_t, ::std::function<OnReadSignature<uint8_t>>, ::std::error_code&);
373 template void BasicSlave::OnWrite<uint8_t>(
374 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint8_t>>);
375 template void BasicSlave::OnWrite<uint8_t>(
376 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint8_t>>,
378 template void BasicSlave::OnWrite<uint8_t>(
379 uint16_t, ::std::function<OnWriteSignature<uint8_t>>);
380 template void BasicSlave::OnWrite<uint8_t>(
381 uint16_t, ::std::function<OnWriteSignature<uint8_t>>, ::std::error_code&);
384 template void BasicSlave::OnRead<uint16_t>(
385 uint16_t, uint8_t, ::std::function<OnReadSignature<uint16_t>>);
386 template void BasicSlave::OnRead<uint16_t>(
387 uint16_t, uint8_t, ::std::function<OnReadSignature<uint16_t>>,
389 template void BasicSlave::OnRead<uint16_t>(
390 uint16_t, ::std::function<OnReadSignature<uint16_t>>);
391 template void BasicSlave::OnRead<uint16_t>(
392 uint16_t, ::std::function<OnReadSignature<uint16_t>>, ::std::error_code&);
393 template void BasicSlave::OnWrite<uint16_t>(
394 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint16_t>>);
395 template void BasicSlave::OnWrite<uint16_t>(
396 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint16_t>>,
398 template void BasicSlave::OnWrite<uint16_t>(
399 uint16_t, ::std::function<OnWriteSignature<uint16_t>>);
400 template void BasicSlave::OnWrite<uint16_t>(
401 uint16_t, ::std::function<OnWriteSignature<uint16_t>>, ::std::error_code&);
404 template void BasicSlave::OnRead<uint32_t>(
405 uint16_t, uint8_t, ::std::function<OnReadSignature<uint32_t>>);
406 template void BasicSlave::OnRead<uint32_t>(
407 uint16_t, uint8_t, ::std::function<OnReadSignature<uint32_t>>,
409 template void BasicSlave::OnRead<uint32_t>(
410 uint16_t, ::std::function<OnReadSignature<uint32_t>>);
411 template void BasicSlave::OnRead<uint32_t>(
412 uint16_t, ::std::function<OnReadSignature<uint32_t>>, ::std::error_code&);
413 template void BasicSlave::OnWrite<uint32_t>(
414 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint32_t>>);
415 template void BasicSlave::OnWrite<uint32_t>(
416 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint32_t>>,
418 template void BasicSlave::OnWrite<uint32_t>(
419 uint16_t, ::std::function<OnWriteSignature<uint32_t>>);
420 template void BasicSlave::OnWrite<uint32_t>(
421 uint16_t, ::std::function<OnWriteSignature<uint32_t>>, ::std::error_code&);
424 template void BasicSlave::OnRead<float>(
425 uint16_t, uint8_t, ::std::function<OnReadSignature<float>>);
426 template void BasicSlave::OnRead<float>(uint16_t, uint8_t,
427 ::std::function<OnReadSignature<float>>,
429 template void BasicSlave::OnRead<float>(
430 uint16_t, ::std::function<OnReadSignature<float>>);
431 template void BasicSlave::OnRead<float>(uint16_t,
432 ::std::function<OnReadSignature<float>>,
434 template void BasicSlave::OnWrite<float>(
435 uint16_t, uint8_t, ::std::function<OnWriteSignature<float>>);
436 template void BasicSlave::OnWrite<float>(
437 uint16_t, uint8_t, ::std::function<OnWriteSignature<float>>,
439 template void BasicSlave::OnWrite<float>(
440 uint16_t, ::std::function<OnWriteSignature<float>>);
441 template void BasicSlave::OnWrite<float>(
442 uint16_t, ::std::function<OnWriteSignature<float>>, ::std::error_code&);
445 template void BasicSlave::OnRead<::std::string>(
446 uint16_t, uint8_t, ::std::function<OnReadSignature<::std::string>>);
447 template void BasicSlave::OnRead<::std::string>(
448 uint16_t, uint8_t, ::std::function<OnReadSignature<::std::string>>,
450 template void BasicSlave::OnRead<::std::string>(
451 uint16_t, ::std::function<OnReadSignature<::std::string>>);
452 template void BasicSlave::OnRead<::std::string>(
453 uint16_t, ::std::function<OnReadSignature<::std::string>>,
455 template void BasicSlave::OnWrite<::std::string>(
456 uint16_t, uint8_t, ::std::function<OnWriteSignature<::std::string>>);
457 template void BasicSlave::OnWrite<::std::string>(
458 uint16_t, uint8_t, ::std::function<OnWriteSignature<::std::string>>,
460 template void BasicSlave::OnWrite<::std::string>(
461 uint16_t, ::std::function<OnWriteSignature<::std::string>>);
462 template void BasicSlave::OnWrite<::std::string>(
463 uint16_t, ::std::function<OnWriteSignature<::std::string>>,
467 template void BasicSlave::OnRead<::std::vector<uint8_t>>(
469 ::std::function<OnReadSignature<::std::vector<uint8_t>>>);
470 template void BasicSlave::OnRead<::std::vector<uint8_t>>(
471 uint16_t, uint8_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>,
473 template void BasicSlave::OnRead<::std::vector<uint8_t>>(
474 uint16_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>);
475 template void BasicSlave::OnRead<::std::vector<uint8_t>>(
476 uint16_t, ::std::function<OnReadSignature<::std::vector<uint8_t>>>,
478 template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
480 ::std::function<OnWriteSignature<::std::vector<uint8_t>>>);
481 template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
483 ::std::function<OnWriteSignature<::std::vector<uint8_t>>>,
485 template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
486 uint16_t, ::std::function<OnWriteSignature<::std::vector<uint8_t>>>);
487 template void BasicSlave::OnWrite<::std::vector<uint8_t>>(
488 uint16_t, ::std::function<OnWriteSignature<::std::vector<uint8_t>>>,
492 template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
494 ::std::function<OnReadSignature<::std::basic_string<char16_t>>>);
495 template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
497 ::std::function<OnReadSignature<::std::basic_string<char16_t>>>,
499 template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
500 uint16_t, ::std::function<OnReadSignature<::std::basic_string<char16_t>>>);
501 template void BasicSlave::OnRead<::std::basic_string<char16_t>>(
502 uint16_t, ::std::function<OnReadSignature<::std::basic_string<char16_t>>>,
504 template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
506 ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>);
507 template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
509 ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>,
511 template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
512 uint16_t, ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>);
513 template void BasicSlave::OnWrite<::std::basic_string<char16_t>>(
514 uint16_t, ::std::function<OnWriteSignature<::std::basic_string<char16_t>>>,
523 template void BasicSlave::OnRead<double>(
524 uint16_t, uint8_t, ::std::function<OnReadSignature<double>>);
525 template void BasicSlave::OnRead<double>(
526 uint16_t, uint8_t, ::std::function<OnReadSignature<double>>,
528 template void BasicSlave::OnRead<double>(
529 uint16_t, ::std::function<OnReadSignature<double>>);
530 template void BasicSlave::OnRead<double>(
531 uint16_t, ::std::function<OnReadSignature<double>>, ::std::error_code&);
532 template void BasicSlave::OnWrite<double>(
533 uint16_t, uint8_t, ::std::function<OnWriteSignature<double>>);
534 template void BasicSlave::OnWrite<double>(
535 uint16_t, uint8_t, ::std::function<OnWriteSignature<double>>,
537 template void BasicSlave::OnWrite<double>(
538 uint16_t, ::std::function<OnWriteSignature<double>>);
539 template void BasicSlave::OnWrite<double>(
540 uint16_t, ::std::function<OnWriteSignature<double>>, ::std::error_code&);
547 template void BasicSlave::OnRead<int64_t>(
548 uint16_t, uint8_t, ::std::function<OnReadSignature<int64_t>>);
549 template void BasicSlave::OnRead<int64_t>(
550 uint16_t, uint8_t, ::std::function<OnReadSignature<int64_t>>,
552 template void BasicSlave::OnRead<int64_t>(
553 uint16_t, ::std::function<OnReadSignature<int64_t>>);
554 template void BasicSlave::OnRead<int64_t>(
555 uint16_t, ::std::function<OnReadSignature<int64_t>>, ::std::error_code&);
556 template void BasicSlave::OnWrite<int64_t>(
557 uint16_t, uint8_t, ::std::function<OnWriteSignature<int64_t>>);
558 template void BasicSlave::OnWrite<int64_t>(
559 uint16_t, uint8_t, ::std::function<OnWriteSignature<int64_t>>,
561 template void BasicSlave::OnWrite<int64_t>(
562 uint16_t, ::std::function<OnWriteSignature<int64_t>>);
563 template void BasicSlave::OnWrite<int64_t>(
564 uint16_t, ::std::function<OnWriteSignature<int64_t>>, ::std::error_code&);
572 template void BasicSlave::OnRead<uint64_t>(
573 uint16_t, uint8_t, ::std::function<OnReadSignature<uint64_t>>);
574 template void BasicSlave::OnRead<uint64_t>(
575 uint16_t, uint8_t, ::std::function<OnReadSignature<uint64_t>>,
577 template void BasicSlave::OnRead<uint64_t>(
578 uint16_t, ::std::function<OnReadSignature<uint64_t>>);
579 template void BasicSlave::OnRead<uint64_t>(
580 uint16_t, ::std::function<OnReadSignature<uint64_t>>, ::std::error_code&);
581 template void BasicSlave::OnWrite<uint64_t>(
582 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint64_t>>);
583 template void BasicSlave::OnWrite<uint64_t>(
584 uint16_t, uint8_t, ::std::function<OnWriteSignature<uint64_t>>,
586 template void BasicSlave::OnWrite<uint64_t>(
587 uint16_t, ::std::function<OnWriteSignature<uint64_t>>);
588 template void BasicSlave::OnWrite<uint64_t>(
589 uint16_t, ::std::function<OnWriteSignature<uint64_t>>, ::std::error_code&);
591 #endif // DOXYGEN_SHOULD_SKIP_THIS
593 BasicSlave::Impl_::Impl_(BasicSlave* self_, CONMT* nmt) : self(self_) {
594 nmt->setLgInd<Impl_, &Impl_::OnLgInd>(
this);
598 BasicSlave::Impl_::OnLgInd(CONMT* nmt,
int state) noexcept {
603 self->OnLifeGuarding(occurred);
604 if (on_life_guarding) {
605 auto f = on_life_guarding;
606 util::UnlockGuard<util::BasicLockable> unlock(*
self);
611 template <u
int16_t N>
613 BasicSlave::Impl_::OnDnInd(COSub* sub, COVal<N>& val) noexcept {
614 auto it = dn_ind.find(Key(sub));
615 if (it == dn_ind.end())
return 0;
616 return it->second(sub,
static_cast<void*
>(&val));
619 template <u
int16_t N>
621 BasicSlave::Impl_::OnUpInd(
const COSub* sub, COVal<N>& val) noexcept {
622 auto it = up_ind.find(Key(sub));
623 if (it == up_ind.end())
return 0;
624 return it->second(sub,
static_cast<void*
>(&val));
628 BasicSlave::Impl_::Key(uint16_t idx, uint8_t subidx) noexcept {
629 return (uint32_t(idx) << 8) | subidx;
633 BasicSlave::Impl_::Key(
const COSub* sub) noexcept {
636 return Key(sub->getObj()->getIdx(), sub->getSubidx());
643 #endif // !LELY_NO_COAPP_SLAVE