81 void OnCsInd(
COLSS*, uint8_t cs) noexcept;
82 void OnErrInd(
COLSS*, uint8_t cs, uint8_t err, uint8_t spec) noexcept;
83 void OnLssIdInd(
COLSS*, uint8_t cs, co_unsigned32_t
id) noexcept;
84 void OnNidInd(
COLSS*, uint8_t cs, uint8_t
id) noexcept;
85 void OnScanInd(
COLSS*, uint8_t cs,
const co_id*
id) noexcept;
87 void OnWait(::std::error_code) noexcept;
103 void* lss_data{
nullptr};
109 co_id id1{4, 0, 0, 0, 0};
110 co_id id2{4, 0, 0, 0, 0};
116 LssSwitchRequestBase::OnRequest(
void* data) noexcept {
117 static_cast<LssMaster::Impl_*
>(data)->OnSwitch(*
this);
121 LssSwitchSelectiveRequestBase::OnRequest(
void* data) noexcept {
122 static_cast<LssMaster::Impl_*
>(data)->OnSwitchSelective(*
this);
126 LssSetIdRequestBase::OnRequest(
void* data) noexcept {
127 static_cast<LssMaster::Impl_*
>(data)->OnSetId(*
this);
131 LssSetBitrateRequestBase::OnRequest(
void* data) noexcept {
132 static_cast<LssMaster::Impl_*
>(data)->OnSetBitrate(*
this);
136 LssSwitchBitrateRequestBase::OnRequest(
void* data) noexcept {
137 static_cast<LssMaster::Impl_*
>(data)->OnSwitchBitrate(*
this);
141 LssStoreRequestBase::OnRequest(
void* data) noexcept {
142 static_cast<LssMaster::Impl_*
>(data)->OnStore(*
this);
146 LssGetVendorIdRequestBase::OnRequest(
void* data) noexcept {
147 static_cast<LssMaster::Impl_*
>(data)->OnGetVendorId(*
this);
151 LssGetProductCodeRequestBase::OnRequest(
void* data) noexcept {
152 static_cast<LssMaster::Impl_*
>(data)->OnGetProductCode(*
this);
156 LssGetRevisionRequestBase::OnRequest(
void* data) noexcept {
157 static_cast<LssMaster::Impl_*
>(data)->OnGetRevision(*
this);
161 LssGetSerialNrRequestBase::OnRequest(
void* data) noexcept {
162 static_cast<LssMaster::Impl_*
>(data)->OnGetSerialNr(*
this);
166 LssGetIdRequestBase::OnRequest(
void* data) noexcept {
167 static_cast<LssMaster::Impl_*
>(data)->OnGetId(*
this);
171 LssIdNonConfigRequestBase::OnRequest(
void* data) noexcept {
172 static_cast<LssMaster::Impl_*
>(data)->OnIdNonConfig(*
this);
176 LssSlowscanRequestBase::OnRequest(
void* data) noexcept {
177 static_cast<LssMaster::Impl_*
>(data)->OnSlowscan(*
this);
181 LssFastscanRequestBase::OnRequest(
void* data) noexcept {
182 static_cast<LssMaster::Impl_*
>(data)->OnFastscan(*
this);
188 : impl_(new
Impl_(this, exec, node, ctrl, node.nmt())) {}
190 LssMaster::~LssMaster() =
default;
207 ::std::chrono::microseconds
209 ::std::lock_guard<Impl_>
lock(*impl_);
210 ::std::chrono::microseconds::rep value = impl_->inhibit;
211 return ::std::chrono::microseconds(value * 100);
216 auto value = inhibit.count();
218 if (value > ::std::numeric_limits<uint16_t>::max() * 100)
219 value = ::std::numeric_limits<uint16_t>::max() * 100;
221 ::std::lock_guard<Impl_>
lock(*impl_);
223 impl_->inhibit = (value + 99) / 100;
224 if (impl_->lss) impl_->lss->setInhibit(impl_->inhibit);
228 ::std::chrono::milliseconds
230 ::std::lock_guard<Impl_>
lock(*impl_);
231 return ::std::chrono::milliseconds(impl_->timeout);
236 auto value = timeout.count();
238 if (value > ::std::numeric_limits<int>::max())
239 value = ::std::numeric_limits<int>::max();
241 ::std::lock_guard<Impl_>
lock(*impl_);
242 impl_->timeout = value;
243 if (impl_->lss) impl_->lss->setTimeout(impl_->timeout);
253 p.
set(ec ? ::std::make_exception_ptr(
254 ::std::system_error(ec,
"AsyncSwitch"))
257 if (preq) *preq = req;
267 exec, address, [p](::std::error_code ec)
mutable {
268 p.
set(ec ? ::std::make_exception_ptr(
269 ::std::system_error(ec,
"AsyncSwitchSelective"))
272 if (preq) *preq = req;
283 p.
set(ec ? ::std::make_exception_ptr(
284 ::std::system_error(ec,
"AsyncSetId"))
287 if (preq) *preq = req;
297 exec, bitrate, [p](::std::error_code ec)
mutable {
298 p.
set(ec ? ::std::make_exception_ptr(
299 ::std::system_error(ec,
"AsyncSetBitrate"))
302 if (preq) *preq = req;
311 p.
set(ec ? ::std::make_exception_ptr(::std::system_error(ec,
"AsyncStore"))
314 if (preq) *preq = req;
324 exec, [p](::std::error_code ec, uint32_t number)
mutable {
326 p.
set(util::failure(::std::make_exception_ptr(
327 ::std::system_error(ec,
"AsyncGetVendorId"))));
329 p.
set(util::success(number));
331 if (preq) *preq = req;
341 exec, [p](::std::error_code ec, uint32_t number)
mutable {
343 p.
set(util::failure(::std::make_exception_ptr(
344 ::std::system_error(ec,
"AsyncGetProductCode"))));
346 p.
set(util::success(number));
348 if (preq) *preq = req;
358 exec, [p](::std::error_code ec, uint32_t number)
mutable {
360 p.
set(util::failure(::std::make_exception_ptr(
361 ::std::system_error(ec,
"AsyncGetRevision"))));
363 p.
set(util::success(number));
365 if (preq) *preq = req;
375 exec, [p](::std::error_code ec, uint32_t number)
mutable {
377 p.
set(util::failure(::std::make_exception_ptr(
378 ::std::system_error(ec,
"AsyncGetSerialNr"))));
380 p.
set(util::success(number));
382 if (preq) *preq = req;
391 exec, [p](::std::error_code ec, uint8_t
id)
mutable {
393 p.
set(util::failure(::std::make_exception_ptr(
394 ::std::system_error(ec,
"AsyncGetId"))));
396 p.
set(util::success(
id));
398 if (preq) *preq = req;
408 exec, [p](::std::error_code ec,
bool found)
mutable {
410 p.
set(util::failure(::std::make_exception_ptr(
411 ::std::system_error(ec,
"AsyncIdNonConfig"))));
413 p.
set(util::success(found));
415 if (preq) *preq = req;
427 [p](::std::error_code ec,
const LssAddress& address)
mutable {
429 p.
set(util::failure(::std::make_exception_ptr(
430 ::std::system_error(ec,
"AsyncSlowscan"))));
432 p.
set(util::success(address));
434 if (preq) *preq = req;
446 [p](::std::error_code ec,
const LssAddress& address)
mutable {
448 p.
set(util::failure(::std::make_exception_ptr(
449 ::std::system_error(ec,
"AsyncFastscan"))));
451 p.
set(util::success(address));
453 if (preq) *preq = req;
460 ::std::lock_guard<util::BasicLockable>
lock(*
this);
467 ::std::lock_guard<Impl_>
lock(*impl_);
468 return impl_->Cancel(&req, ec) != 0;
474 ::std::lock_guard<Impl_>
lock(*impl_);
475 return impl_->Cancel(
nullptr, ec);
480 ::std::lock_guard<Impl_>
lock(*impl_);
481 return impl_->Abort(&req) != 0;
486 ::std::lock_guard<Impl_>
lock(*impl_);
487 return impl_->Abort(
nullptr);
492 int bitrate, ::std::chrono::milliseconds delay,
493 ::std::function<
void(::std::error_code ec)> res) noexcept {
494 if (GetController()) {
498 .AsyncWait(GetExecutor(), delay / 2)
504 GetController()->stop();
507 return GetNode().AsyncWait(GetExecutor(), delay / 2);
514 GetController()->set_bitrate(bitrate);
517 return GetNode().AsyncWait(GetExecutor(), delay);
520 ::std::error_code ec;
525 GetController()->restart();
526 }
catch (::std::system_error& e) {
556 exec(exec_ ? exec_ : static_cast<
ev_exec_t*>(node.GetExecutor())),
561 nmt->getLSSReq(&lss_func, &lss_data);
562 nmt->setLSSReq<Impl_, &Impl_::OnLssReq>(
this);
565 inhibit = lss->getInhibit();
566 timeout = lss->getTimeout();
573 ::std::error_code ec;
574 ctrl->get_bitrate(&bitrate,
nullptr, ec);
578 LssMaster::Impl_::~Impl_() { nmt->setLSSReq(lss_func, lss_data); }
581 LssMaster::Impl_::OnLssReq(CONMT*, COLSS* lss) noexcept {
584 lss->setInhibit(inhibit);
585 lss->setTimeout(timeout);
589 self->GetExecutor().post([
this]() noexcept {
590 self->OnStart([
this](::std::error_code) noexcept {
591 ::std::lock_guard<Impl_>
lock(*
this);
599 LssMaster::Impl_::Submit(detail::LssRequestBase& req) {
600 if (!req.exec) req.exec =
self->GetExecutor();
601 auto exec = req.GetExecutor();
606 if (first) OnRequest(req);
610 LssMaster::Impl_::Cancel(detail::LssRequestBase* req, ::std::error_code ec) {
625 auto exec = req->GetExecutor();
629 n += n < ::std::numeric_limits<::std::size_t>::max();
635 LssMaster::Impl_::Abort(detail::LssRequestBase* req) {
646 LssMaster::Impl_::Pop(detail::LssRequestBase* req,
sllist& queue) {
662 return req !=
nullptr;
666 LssMaster::Impl_::OnSwitch(detail::LssSwitchRequestBase& req) noexcept {
672 ::std::error_code ec;
673 if (!lss->switchReq(
static_cast<int>(req.state)))
683 LssMaster::Impl_::OnSwitchSelective(
684 detail::LssSwitchSelectiveRequestBase& req) noexcept {
688 id1 = {4, req.address.vendor_id, req.address.product_code,
689 req.address.revision, req.address.serial_nr};
696 if (lss->switchSelReq<Impl_, &Impl_::OnCsInd>(id1,
this) == -1) {
705 LssMaster::Impl_::OnSetId(detail::LssSetIdRequestBase& req) noexcept {
714 if (lss->setIdReq<Impl_, &Impl_::OnErrInd>(req.id,
this) == -1) {
723 LssMaster::Impl_::OnSetBitrate(detail::LssSetBitrateRequestBase& req) noexcept {
732 switch (req.bitrate) {
741 if (lss->setRateReq<Impl_, &Impl_::OnErrInd>(req.bitrate / 1000,
this) ==
746 bitrate = req.bitrate;
758 LssMaster::Impl_::OnSwitchBitrate(
759 detail::LssSwitchBitrateRequestBase& req) noexcept {
768 if (!bitrate || req.delay < 0 ||
769 req.delay > ::std::numeric_limits<uint16_t>::max()) {
772 }
else if (lss->switchRateReq(req.delay) == -1) {
779 ::std::chrono::milliseconds delay(req.delay);
781 self->GetExecutor().post([
this, delay]() noexcept {
782 self->OnSwitchBitrate(bitrate, delay, [
this](::std::error_code ec) {
784 ::std::lock_guard<Impl_>
lock(*
this);
787 auto req =
static_cast<detail::LssSwitchBitrateRequestBase*
>(task);
798 LssMaster::Impl_::OnStore(detail::LssStoreRequestBase& req) noexcept {
807 if (lss->storeReq<Impl_, &Impl_::OnErrInd>(
this) == -1) {
816 LssMaster::Impl_::OnGetVendorId(
817 detail::LssGetVendorIdRequestBase& req) noexcept {
827 if (lss->getVendorIdReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
836 LssMaster::Impl_::OnGetProductCode(
837 detail::LssGetProductCodeRequestBase& req) noexcept {
847 if (lss->getProductCodeReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
856 LssMaster::Impl_::OnGetRevision(
857 detail::LssGetRevisionRequestBase& req) noexcept {
867 if (lss->getRevisionReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
876 LssMaster::Impl_::OnGetSerialNr(
877 detail::LssGetSerialNrRequestBase& req) noexcept {
887 if (lss->getSerialNrReq<Impl_, &Impl_::OnLssIdInd>(
this) == -1) {
896 LssMaster::Impl_::OnGetId(detail::LssGetIdRequestBase& req) noexcept {
906 if (lss->getIdReq<Impl_, &Impl_::OnNidInd>(
this) == -1) {
915 LssMaster::Impl_::OnIdNonConfig(
916 detail::LssIdNonConfigRequestBase& req) noexcept {
925 if (lss->idNonCfgSlaveReq<Impl_, &Impl_::OnCsInd>(
this) == -1) {
934 LssMaster::Impl_::OnSlowscan(detail::LssSlowscanRequestBase& req) noexcept {
938 id1 = {4, req.lo.vendor_id, req.lo.product_code, req.lo.revision,
940 id2 = {4, req.hi.vendor_id, req.hi.product_code, req.hi.revision,
948 req.address = {0, 0, 0, 0};
949 if (lss->slowscanReq<Impl_, &Impl_::OnScanInd>(id1, id2,
this) == -1) {
958 LssMaster::Impl_::OnFastscan(detail::LssFastscanRequestBase& req) noexcept {
962 id1 = {4, req.address.vendor_id, req.address.product_code,
963 req.address.revision, req.address.serial_nr};
964 id2 = {4, req.mask.vendor_id, req.mask.product_code, req.mask.revision,
972 if (lss->fastscanReq<Impl_, &Impl_::OnScanInd>(&id1, &id2,
this) == -1) {
981 LssMaster::Impl_::OnCsInd(COLSS*, uint8_t cs) noexcept {
984 auto req =
static_cast<detail::LssSwitchRequestBase*
>(task);
995 LssMaster::Impl_::OnErrInd(COLSS*, uint8_t cs, uint8_t err, uint8_t) noexcept {
998 auto req =
static_cast<detail::LssRequestBase*
>(task);
1045 LssMaster::Impl_::OnLssIdInd(COLSS*, uint8_t cs, co_unsigned32_t
id) noexcept {
1048 auto req =
static_cast<detail::LssGetNumberRequestBase*
>(task);
1061 LssMaster::Impl_::OnNidInd(COLSS*, uint8_t cs, uint8_t
id) noexcept {
1064 auto req =
static_cast<detail::LssGetIdRequestBase*
>(task);
1077 LssMaster::Impl_::OnScanInd(COLSS*, uint8_t cs,
const co_id*
id) noexcept {
1081 auto req =
static_cast<detail::LssScanRequestBase*
>(task);
1085 req->address.vendor_id =
id->vendor_id;
1086 req->address.product_code =
id->product_code;
1087 req->address.revision =
id->revision;
1088 req->address.serial_nr =
id->serial_nr;
1097 LssMaster::Impl_::OnRequest(detail::LssRequestBase& req) noexcept {
1099 req.OnRequest(
this);
1107 LssMaster::Impl_::OnCompletion(detail::LssRequestBase& req) noexcept {
1111 auto exec = req.GetExecutor();
1113 exec.on_task_fini();
1116 if (task) OnRequest(*
static_cast<detail::LssRequestBase*
>(task));