w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
RlinkConnect.cpp
Go to the documentation of this file.
1// $Id: RlinkConnect.cpp 1198 2019-07-27 19:08:31Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2011-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2019-07-27 1198 2.8.6 add Nak handling
8// 2019-03-10 1121 2.8.5 DecodeResponse(): rblk expect check over BlockDone
9// 2018-12-22 1091 2.8.4 Open(): (-Wpessimizing-move fix); add BadPort()
10// 2018-12-19 1090 2.8.3 use RosPrintf(bool)
11// 2018-12-18 1089 2.8.2 use c++ style casts
12// 2018-12-17 1085 2.8.1 use std::lock_guard instead of boost
13// 2018-12-08 1079 2.8 add HasPort(); return ref for Port()
14// 2018-12-01 1076 2.7 use unique_ptr instead of scoped_ptr
15// 2018-11-30 1075 2.6.4 use list-init; use range loop
16// 2018-10-27 1059 2.6.3 coverity fixup (uncaught exception in dtor)
17// 2017-04-22 883 2.6.2 add rbus monitor probe, add HasRbmon()
18// 2017-04-07 868 2.6.1 Dump(): add detail arg
19// 2017-02-20 854 2.6 use Rtime, drop TimeOfDayAsDouble
20// 2016-04-02 758 2.5 add USR_ACCESS register support (RLUA0/RLUA1)
21// 2016-03-20 748 2.4 add fTimeout,(Set)Timeout();
22// 2015-05-10 678 2.3.1 WaitAttn(): BUGFIX: return 0. (not -1.) if poll
23// 2015-04-12 666 2.3 add LinkInit,LinkInitDone; transfer xon
24// 2015-04-02 661 2.2 expect logic: stat expect in Command, invert mask
25// 2015-01-06 631 2.1 full rlink v4 implementation
26// 2014-12-10 611 2.0 re-organize for rlink v4
27// 2014-08-26 587 1.5 start accept rlink v4 protocol (partially...)
28// 2014-08-15 583 1.4 rb_mreq addr now 16 bit
29// 2014-07-27 575 1.3.3 ExecPart(): increase packet tout from 5 to 15 sec
30// 2013-04-21 509 1.3.2 add SndAttn() method
31// 2013-03-01 493 1.3.1 add Server(Active..|SignalAttn)() methods
32// 2013-02-23 492 1.3 use scoped_ptr for Port; Close allways allowed
33// use RlinkContext, add Context(), Exec(..., cntx)
34// 2013-02-22 491 1.2 use new RlogFile/RlogMsg interfaces
35// 2013-02-03 481 1.1.2 use Rexception
36// 2013-01-13 474 1.1.1 add PollAttn() method
37// 2011-04-25 380 1.1 use boost::(mutex&lock), implement Lockable IF
38// 2011-04-22 379 1.0.1 add Lock(), Unlock(), lock connect in Exec()
39// 2011-04-02 375 1.0 Initial version
40// 2011-01-15 356 0.1 First draft
41// ---------------------------------------------------------------------------
42
47#include <iostream>
48
49#include "RlinkPortFactory.hpp"
50#include "librtools/RosFill.hpp"
53#include "librtools/Rtools.hpp"
55#include "librtools/RlogMsg.hpp"
56#include "RlinkServer.hpp"
57
58#include "RlinkConnect.hpp"
59
60using namespace std;
61
67// all method definitions in namespace Retro
68namespace Retro {
69
70//------------------------------------------+-----------------------------------
71// constants definitions
72
73const uint16_t RlinkConnect::kRbaddr_RLCNTL;
74const uint16_t RlinkConnect::kRbaddr_RLSTAT;
75const uint16_t RlinkConnect::kRbaddr_RLID1;
76const uint16_t RlinkConnect::kRbaddr_RLID0;
77const uint16_t RlinkConnect::kRbaddr_RLUA1;
78const uint16_t RlinkConnect::kRbaddr_RLUA0;
79const uint16_t RlinkConnect::kRbaddr_RMBASE;
80
84
85const uint16_t RlinkConnect::kRLSTAT_V_LCmd;
86const uint16_t RlinkConnect::kRLSTAT_B_LCmd;
87const uint16_t RlinkConnect::kRLSTAT_M_BAbo;
89
92const uint16_t RlinkConnect::kSBCNTL_V_RBMON;
93
94const uint16_t RlinkConnect::kRbufBlkDelta;
96
97//------------------------------------------+-----------------------------------
99
101 : fupPort(),
102 fLinkInitDeferred(false),
103 fLinkInitDone(false),
104 fpServ(nullptr),
105 fSeqNumber{},
106 fSndPkt(),
107 fRcvPkt(),
108 fContext(),
109 fAddrMap(),
110 fStats(),
111 fLogBaseAddr(16), // addr default radix: hex
112 fLogBaseData(16), // data default radix: hex
113 fLogBaseStat(16), // stat default radix: hex
114 fPrintLevel(2), // default print: error and checks
115 fDumpLevel(0), // default dump: no
116 fTraceLevel(0), // default trace: no
117 fTimeout(10.), // default timeout: 10 sec
118 fspLog(new RlogFile(&cout)),
119 fConnectMutex(),
120 fAttnNotiPatt(0),
121 fTsLastAttnNoti(),
122 fSysId(0xffffffff),
123 fUsrAcc(0x00000000),
124 fRbufSize(2048),
125 fHasRbmon(false)
126{
130
131 // Statistic setup
132 fStats.Define(kStatNExec, "NExec", "Exec() calls");
133 fStats.Define(kStatNExecPart, "NExecPart", "ExecPart() calls");
134 fStats.Define(kStatNCmd, "NCmd", "commands executed");
135 fStats.Define(kStatNRreg, "NRreg", "rreg commands");
136 fStats.Define(kStatNRblk, "NRblk", "rblk commands");
137 fStats.Define(kStatNWreg, "NWreg", "wreg commands");
138 fStats.Define(kStatNWblk, "NWblk", "wblk commands");
139 fStats.Define(kStatNLabo, "NLabo", "labo commands");
140 fStats.Define(kStatNAttn, "NAttn", "attn commands");
141 fStats.Define(kStatNInit, "NInit", "init commands");
142 fStats.Define(kStatNRblkWord, "NRblkWord", "words rcvd with rblk");
143 fStats.Define(kStatNWblkWord, "NWblkWord", "words send with wblk");
144 fStats.Define(kStatNExpData, "NExpData", "expect for data defined");
145 fStats.Define(kStatNExpDone, "NExpDone", "expect for done defined");
146 fStats.Define(kStatNExpStat, "NExpStat", "expect for stat explicit");
147 fStats.Define(kStatNNoExpStat,"NNoExpStat","no expect for stat");
148 fStats.Define(kStatNChkData, "NChkData", "expect data failed");
149 fStats.Define(kStatNChkDone, "NChkDone", "expect done failed");
150 fStats.Define(kStatNChkStat, "NChkStat", "expect stat failed");
151 fStats.Define(kStatNSndOob, "NSndOob", "SndOob() calls");
152 fStats.Define(kStatNErrMiss, "NErrMiss", "decode: missing data");
153 fStats.Define(kStatNErrCmd, "NErrCmd", "decode: command mismatch");
154 fStats.Define(kStatNErrLen, "NErrLen", "decode: length mismatch");
155 fStats.Define(kStatNErrCrc, "NErrCrc", "decode: crc mismatch");
156 fStats.Define(kStatNErrNak, "NErrNak", "decode: nak seen");
157}
158
159//------------------------------------------+-----------------------------------
161
163{
164 Rtools::Catch2Cerr(__func__, [this](){ Close(); } );
165}
166
167//------------------------------------------+-----------------------------------
169
170bool RlinkConnect::Open(const std::string& name, RerrMsg& emsg)
171{
172 Close();
173
174 fupPort = RlinkPortFactory::Open(name, emsg);
175 if (!HasPort()) return false;
176
177 fSndPkt.SetXonEscape(Port().XonEnable()); // transfer XON enable
178
181
182 fLinkInitDone = false;
183 fRbufSize = 2048; // use minimum (2kB) as startup
184 fSysId = 0xffffffff;
185 fUsrAcc = 0x00000000;
186
187 if (! Port().Url().FindOpt("noinit")) {
188 if (!LinkInit(emsg)) {
189 Close();
190 return false;
191 }
192 }
193
194 return true;
195}
196
197//------------------------------------------+-----------------------------------
199
201{
202 if (!HasPort()) return;
203
204 if (fpServ) fpServ->Stop(); // stop server in case still running
205
206 if (IsOpen() && Port().Url().FindOpt("keep")) {
207 RerrMsg emsg;
208 fSndPkt.SndKeep(Port(), emsg);
209 }
210
211 fupPort.reset();
212
213 return;
214}
215
216//------------------------------------------+-----------------------------------
218
220{
221 if (fLinkInitDone) return true;
222
223 RlinkCommandList clist;
224 int ista = clist.AddRreg(kRbaddr_RLSTAT);
225 int iid1 = clist.AddRreg(kRbaddr_RLID1);
226 int iid0 = clist.AddRreg(kRbaddr_RLID0);
227
228 // RLUA0/1 are optional registers, available for 7Series and higher
229 int iua1 = clist.AddRreg(kRbaddr_RLUA1);
230 clist.SetLastExpectStatus(0,0); // disable stat check
231 int iua0 = clist.AddRreg(kRbaddr_RLUA0);
232 clist.SetLastExpectStatus(0,0); // disable stat check
233 // probe for rbus monitor
234 int irbm = clist.AddRreg(kRbaddr_RMBASE);
235 clist.SetLastExpectStatus(0,0); // disable stat check
236
237 if (!Exec(clist, emsg)) return false;
238
239 fLinkInitDone = true;
240
241 // handle rlink core registers: setup mappings, keep data
242 AddrMapInsert("rl.cntl", kRbaddr_RLCNTL);
243 AddrMapInsert("rl.stat", kRbaddr_RLSTAT);
244 AddrMapInsert("rl.id1", kRbaddr_RLID1);
245 AddrMapInsert("rl.id0", kRbaddr_RLID0);
246
247 uint16_t rlstat = clist[ista].Data();
248 uint16_t rlid1 = clist[iid1].Data();
249 uint16_t rlid0 = clist[iid0].Data();
250
251 fRbufSize = size_t(1) << (10 + (rlstat & kRLSTAT_M_RBSize));
252 fSysId = uint32_t(rlid1)<<16 | uint32_t(rlid0);
253
254 // handle rlink optional registers: USR_ACCESS and rbus monitor probe
255 const uint8_t staterr = RlinkCommand::kStat_M_RbTout |
258 if ((clist[iua1].Status() & staterr) == 0 && // RLUA1 ok
259 (clist[iua0].Status() & staterr) == 0) { // RLUA0 ok
260
261 AddrMapInsert("rl.ua1", kRbaddr_RLUA1);
262 AddrMapInsert("rl.ua0", kRbaddr_RLUA0);
263
264 uint16_t rlua1 = clist[3].Data();
265 uint16_t rlua0 = clist[4].Data();
266 fUsrAcc = uint32_t(rlua1)<<16 | uint32_t(rlua0);
267 }
268
269 if ((clist[irbm].Status() & staterr) == 0) { // rbus monitor found
270 fHasRbmon = true; // just remember
271 }
272
273 return true;
274}
275
276//------------------------------------------+-----------------------------------
278
284{
285 return fpServ && fpServ->IsActive();
286}
287
288//------------------------------------------+-----------------------------------
290
295{
296 return fpServ && fpServ->IsActiveInside();
297}
298
299//------------------------------------------+-----------------------------------
301
307{
308 return fpServ && fpServ->IsActiveOutside();
309}
310
311//------------------------------------------+-----------------------------------
313
315{
316 fConnectMutex.lock();
317 return;
318}
319
320//------------------------------------------+-----------------------------------
322
324{
325 return fConnectMutex.try_lock();
326}
327
328//------------------------------------------+-----------------------------------
330
332{
333 fConnectMutex.unlock();
334 return;
335}
336
337//------------------------------------------+-----------------------------------
339
341 RerrMsg& emsg)
342{
343 if (clist.Size() == 0)
344 throw Rexception("RlinkConnect::Exec()", "Bad state: clist empty");
345 if (! IsOpen())
346 throw Rexception("RlinkConnect::Exec()", "Bad state: port not open");
347
348 lock_guard<RlinkConnect> lock(*this);
349
351
352 clist.ClearLaboIndex();
353
354 uint8_t defstatval = cntx.StatusValue();
355 uint8_t defstatmsk = cntx.StatusMask();
356 size_t size = clist.Size();
357
358 for (size_t i=0; i<size; i++) {
359 RlinkCommand& cmd = clist[i];
361 throw Rexception("RlinkConnect::Exec()",
362 "BugCheck: command not initialized");
364 throw Rexception("RlinkConnect::Exec()",
365 "BugCheck: invalid command code");
366 // trap attn command when server running and outside server thread
368 throw Rexception("RlinkConnect::Exec()",
369 "attn command not allowed outside active server");
370
378
379 // setup default status check unless explicit check defined
380 if (!cmd.ExpectStatusSet()) {
381 cmd.SetExpectStatusDefault(defstatval, defstatmsk);
382 }
383 }
384
385 // old split volative logic. Currently dormant
386 // may be later used for rtbuf size prot
387#ifdef NEVER
388 while (ibeg < size) {
389 size_t iend = ibeg;
390 for (size_t i=ibeg; i<size; i++) {
391 iend = i;
392 if (clist[i].TestFlagAll(RlinkCommand::kFlagVol)) {
393 fStats.Inc(kStatNSplitVol);
394 break;
395 }
396 }
397 bool rc = ExecPart(clist, ibeg, iend, emsg);
398 if (!rc) return rc;
399 ibeg = iend+1;
400 }
401#endif
402
403 bool rc = ExecPart(clist, 0, size-1, emsg);
404 if (!rc) return rc;
405
406 bool checkseen = false;
407 bool errorseen = false;
408
409 for (size_t i=0; i<size; i++) {
410 RlinkCommand& cmd = clist[i];
411
412 bool checkfound = cmd.TestFlagAny(RlinkCommand::kFlagChkStat |
415 bool errorfound = cmd.TestFlagAny(RlinkCommand::kFlagErrNak |
417 checkseen |= checkfound;
418 errorseen |= errorfound;
419 if (checkfound | errorfound) cntx.IncErrorCount();
420 }
421
422 size_t loglevel = 3;
423 if (checkseen) loglevel = 2;
424 if (errorseen) loglevel = 1;
425 if (loglevel <= fPrintLevel) {
426 RlogMsg lmsg(*fspLog);
428 }
429 if (loglevel <= fDumpLevel) {
430 RlogMsg lmsg(*fspLog);
431 clist.Dump(lmsg(), 0);
432 }
433
434 return true;
435}
436
437//------------------------------------------+-----------------------------------
439
441{
442 RerrMsg emsg;
443 bool rc = Exec(clist, cntx, emsg);
444 if (!rc) {
445 RlogMsg lmsg(*fspLog, 'F');
446 lmsg << emsg << endl;
447 lmsg << "Dump of failed clist:" << endl;
448 clist.Dump(lmsg(), 0);
449 }
450 if (!rc)
451 throw Rexception("RlinkConnect::Exec", "Exec() failed: ", emsg);
452 return;
453}
454
455//------------------------------------------+-----------------------------------
457
484int RlinkConnect::WaitAttn(const Rtime& timeout, Rtime& twait,
485 uint16_t& apat, RerrMsg& emsg)
486{
488 throw Rexception("RlinkConnect::WaitAttn()",
489 "not allowed outside active server");
490
491 apat = 0;
492 twait.Clear();
493
494 lock_guard<RlinkConnect> lock(*this);
495
496 // harvest pending notifiers
497 if (fAttnNotiPatt != 0) {
498 apat = fAttnNotiPatt;
499 fAttnNotiPatt = 0;
500 return 0;
501 }
502
503 // quit if poll only (zero timeout)
504 if (!timeout.IsPositive()) return 0;
505
506 // wait for new notifier
507 Rtime tnow(CLOCK_MONOTONIC);
508 Rtime tend = tnow + timeout;
509 Rtime tbeg = tnow;
510
511 while (tnow < tend) {
512 if (!IsOpen()) BadPort("RlinkConnect::WaitAttn");
513 int irc = fRcvPkt.ReadData(Port(), tend-tnow, emsg);
514 if (irc == RlinkPort::kTout) return -1;
515 if (irc == RlinkPort::kErr) return -2;
516 tnow.GetClock(CLOCK_MONOTONIC);
517 while (fRcvPkt.ProcessData()) {
518 irc = fRcvPkt.PacketState();
519 if (irc == RlinkPacketBufRcv::kPktPend) break;
520 if (irc == RlinkPacketBufRcv::kPktAttn) {
522 if (fAttnNotiPatt != 0) {
523 apat = fAttnNotiPatt;
524 fAttnNotiPatt = 0;
525 twait = tnow - tbeg;
526 return 1;
527 }
528 } else {
529 RlogMsg lmsg(*fspLog, 'E');
530 lmsg << "WaitAttn: dropped spurious packet";
532 }
533
534 } // while (fRcvPkt.ProcessData())
535 } // while (tnow < tend)
536
537 return -1;
538}
539
540//------------------------------------------+-----------------------------------
542
543bool RlinkConnect::SndOob(uint16_t addr, uint16_t data, RerrMsg& emsg)
544{
545 if (!IsOpen()) BadPort("RlinkConnect::SndOob");
546 lock_guard<RlinkConnect> lock(*this);
548 return fSndPkt.SndOob(Port(), addr, data, emsg);
549}
550
551//------------------------------------------+-----------------------------------
553
555{
556 if (!IsOpen()) BadPort("RlinkConnect::SndAttn");
557 lock_guard<RlinkConnect> lock(*this);
558 return fSndPkt.SndAttn(Port(), emsg);
559}
560
561//------------------------------------------+-----------------------------------
563
565{
566 if (base!=2 && base!=8 && base!=16)
567 throw Rexception("RlinkConnect::SetLogBaseAddr()",
568 "Bad args: base != 2,8,16");
569 fLogBaseAddr = base;
570 return;
571}
572
573//------------------------------------------+-----------------------------------
575
577{
578 if (base!=2 && base!=8 && base!=16)
579 throw Rexception("RlinkConnect::SetLogBaseData()",
580 "Bad args: base != 2,8,16");
581 fLogBaseData = base;
582 return;
583}
584
585//------------------------------------------+-----------------------------------
587
589{
590 if (base!=2 && base!=8 && base!=16)
591 throw Rexception("RlinkConnect::SetLogBaseStat()",
592 "Bad args: base != 2,8,16");
593 fLogBaseStat = base;
594 return;
595}
596
597//------------------------------------------+-----------------------------------
599
601{
602 fPrintLevel = lvl;
603 return;
604}
605
606//------------------------------------------+-----------------------------------
608
610{
611 fDumpLevel = lvl;
612 return;
613}
614
615//------------------------------------------+-----------------------------------
617
619{
620 fTraceLevel = lvl;
621 if (HasPort()) Port().SetTraceLevel(lvl);
622 return;
623}
624
625//------------------------------------------+-----------------------------------
627
628void RlinkConnect::SetTimeout(const Rtime& timeout)
629{
630 if (!timeout.IsPositive())
631 throw Rexception("RlinkConnect::SetTimeout()",
632 "Bad args: timeout <= 0");
633 fTimeout = timeout;
634 return;
635}
636
637//------------------------------------------+-----------------------------------
639
640bool RlinkConnect::LogOpen(const std::string& name, RerrMsg& emsg)
641{
642 if (!fspLog->Open(name, emsg)) {
643 fspLog->UseStream(&cout);
644 return false;
645 }
646 return true;
647}
648
649//------------------------------------------+-----------------------------------
651
652void RlinkConnect::LogUseStream(std::ostream* pstr, const std::string& name)
653{
654 fspLog->UseStream(pstr, name);
655 return;
656}
657
658//------------------------------------------+-----------------------------------
660
661void RlinkConnect::SetLogFileName(const std::string& name)
662{
663 RerrMsg emsg;
664 if (!LogOpen(name, emsg)) {
665 throw Rexception("RlinkConnect::SetLogFile",
666 emsg.Text() + "', using stdout");
667 }
668 return;
669}
670
671//------------------------------------------+-----------------------------------
673
674void RlinkConnect::Print(std::ostream& os) const
675{
676 os << "RlinkConnect::Print(std::ostream& os)" << endl;
677 return;
678}
679
680//------------------------------------------+-----------------------------------
682
683void RlinkConnect::Dump(std::ostream& os, int ind, const char* text,
684 int detail) const
685{
686 RosFill bl(ind);
687 os << bl << (text?text:"--") << "RlinkConnect @ " << this << endl;
688
689 if (HasPort()) {
690 Port().Dump(os, ind+2, "fupPort: ", detail);
691 } else {
692 os << bl << " fupPort: " << fupPort.get() << endl;
693 }
694
695 os << bl << " fLinkInitDeferred:" << RosPrintf(fLinkInitDeferred) << endl;
696 os << bl << " fLinkInitDone: " << RosPrintf(fLinkInitDone) << endl;
697
698 os << bl << " fpServ: " << fpServ << endl;
699 os << bl << " fSeqNumber: ";
700 for (auto& o: fSeqNumber) os << RosPrintBvi(o,16) << " ";
701 os << endl;
702
703 fSndPkt.Dump(os, ind+2, "fSndPkt: ", detail);
704 fRcvPkt.Dump(os, ind+2, "fRcvPkt: ", detail);
705 fContext.Dump(os, ind+2, "fContext: ", detail);
706 fAddrMap.Dump(os, ind+2, "fAddrMap: ", detail-1);
707 fStats.Dump(os, ind+2, "fStats: ", detail-1);
708 os << bl << " fLogBaseAddr: " << fLogBaseAddr << endl;
709 os << bl << " fLogBaseData: " << fLogBaseData << endl;
710 os << bl << " fLogBaseStat: " << fLogBaseStat << endl;
711 os << bl << " fPrintLevel: " << fPrintLevel << endl;
712 os << bl << " fDumpLevel " << fDumpLevel << endl;
713 os << bl << " fTraceLevel " << fTraceLevel << endl;
714 fspLog->Dump(os, ind+2, "fspLog: ");
715 os << bl << " fAttnNotiPatt: " << RosPrintBvi(fAttnNotiPatt,16) << endl;
716 os << bl << " fTsLastAttnNoti: " << fTsLastAttnNoti << endl;
717 os << bl << " fSysId: " << RosPrintBvi(fSysId,16) << endl;
718 os << bl << " fUsrAcc: " << RosPrintBvi(fUsrAcc,16) << endl;
719 os << bl << " fRbufSize: " << RosPrintf(fRbufSize,"d",6) << endl;
720
721 return;
722}
723
724//------------------------------------------+-----------------------------------
726
736{
737 if (!ServerActiveInside())
738 throw Rexception("RlinkConnect::HandleUnsolicitedData()",
739 "only allowed inside active server");
740
741 lock_guard<RlinkConnect> lock(*this);
742 RerrMsg emsg;
743 if (!IsOpen()) BadPort("RlinkConnect::HandleUnsolicitedData");
744 int irc = fRcvPkt.ReadData(Port(), Rtime(), emsg);
745 if (irc == 0) return;
746 if (irc < 0) {
747 RlogMsg lmsg(*fspLog, 'E');
748 lmsg << "HandleUnsolicitedData: IO error: " << emsg;
749 }
751 return;
752}
753
754//------------------------------------------+-----------------------------------
756
757bool RlinkConnect::ExecPart(RlinkCommandList& clist, size_t ibeg, size_t iend,
758 RerrMsg& emsg)
759{
760 if (ibeg>iend || iend>=clist.Size())
761 throw Rexception("RlinkConnect::ExecPart()",
762 "Bad args: ibeg or iend invalid");
763 if (!IsOpen())
764 throw Rexception("RlinkConnect::ExecPart()","Bad state: port not open");
765
767 EncodeRequest(clist, ibeg, iend);
768
769 // FIXME_code: handle send fail properly;
770 if (!fSndPkt.SndPacket(Port(), emsg)) return false;
771
772 // FIXME_code: handle recoveries
773 // FIXME_code: use proper value for timeout (rest time for Exec ?)
774 bool ok = ReadResponse(fTimeout, emsg);
775 if (!ok) Rexception("RlinkConnect::ExecPart()","faulty response");
776
777 int ncmd = DecodeResponse(clist, ibeg, iend);
778 if (ncmd != int(iend-ibeg+1)) {
779 clist.Dump(cout);
780 throw Rexception("RlinkConnect::ExecPart()","incomplete response");
781 }
782
784
785 return true;
786}
787
788//------------------------------------------+-----------------------------------
790
792 size_t iend)
793{
794 fSndPkt.Init();
795
796 for (size_t i=ibeg; i<=iend; i++) {
797 RlinkCommand& cmd = clist[i];
798 uint8_t ccode = cmd.Command();
799 size_t ndata = cmd.BlockSize();
800 uint16_t* pdata = cmd.BlockPointer();
801
803
804 cmd.SetSeqNumber(fSeqNumber[ccode]++);
806
808
809 switch (ccode) {
810 case RlinkCommand::kCmdRreg: // rreg command ---------------
812 cmd.SetRcvSize(1+2+1+2); // rcv: cmd+data+stat+crc
814 break;
815
816 case RlinkCommand::kCmdRblk: // rblk command ---------------
818 fStats.Inc(kStatNRblkWord, double(ndata));
819 cmd.SetRcvSize(1+2+2*ndata+2+1+2); // rcv: cmd+cnt+n*data+dcnt+stat+crc
821 fSndPkt.PutWithCrc(uint16_t(ndata));
822 break;
823
824 case RlinkCommand::kCmdWreg: // wreg command ---------------
826 cmd.SetRcvSize(1+1+2); // rcv: cmd+stat+crc
828 fSndPkt.PutWithCrc(cmd.Data());
829 break;
830
831 case RlinkCommand::kCmdWblk: // wblk command ---------------
833 fStats.Inc(kStatNWblkWord, double(ndata));
834 cmd.SetRcvSize(1+2+1+2); // rcv: cmd+dcnt+stat+crc
836 fSndPkt.PutWithCrc(uint16_t(ndata));
837 fSndPkt.PutCrc();
838 fSndPkt.PutWithCrc(pdata, ndata);
839 break;
840
841 case RlinkCommand::kCmdLabo: // labo command ---------------
843 cmd.SetRcvSize(1+1+1+2); // rcv: cmd+babo+stat+crc
844 break;
845 case RlinkCommand::kCmdAttn: // attn command ---------------
847 cmd.SetRcvSize(1+2+1+2); // rcv: cmd+data+stat+crc
848 break;
849
850 case RlinkCommand::kCmdInit: // init command ---------------
852 cmd.SetRcvSize(1+1+2); // rcv: cmd+stat+crc
854 fSndPkt.PutWithCrc(cmd.Data());
855 break;
856
857 default:
858 throw Rexception("RlinkConnect::Exec()", "BugCheck: invalid command");
859 } // switch (ccode)
860
861 fSndPkt.PutCrc();
863 } // for (size_t i=ibeg; i<=iend; i++)
864
865 // FIXME_code: do we still need kFlagPktBeg,kFlagPktEnd ?
866 clist[ibeg].SetFlagBit(RlinkCommand::kFlagPktBeg);
867 clist[iend].SetFlagBit(RlinkCommand::kFlagPktEnd);
868
869 return;
870}
871
872//------------------------------------------+-----------------------------------
874
876 size_t iend)
877{
878 size_t ncmd = 0;
879
880 for (size_t i=ibeg; i<=iend; i++) {
881 RlinkCommand& cmd = clist[i];
882 uint8_t ccode = cmd.Command();
883 uint16_t rdata;
884 uint8_t rdata8;
885
886 // handle commands after an active labo
887 if (clist.LaboActive()) {
888 ncmd += 1;
890 continue;
891 }
892
893 if (fRcvPkt.CheckNak()) { // NAK seen
896 RlogMsg lmsg(*fspLog, 'E');
897 lmsg << "DecodeResponse: NAK seen, code ";
898 switch (fRcvPkt.NakCode()) {
899 case RlinkPacketBufRcv::kNcCcrc: lmsg << "Ccrc"; break;
900 case RlinkPacketBufRcv::kNcDcrc: lmsg << "Dcrc"; break;
901 case RlinkPacketBufRcv::kNcFrame: lmsg << "Frame"; break;
902 case RlinkPacketBufRcv::kNcUnused: lmsg << "Unused"; break;
903 case RlinkPacketBufRcv::kNcCmd: lmsg << "Cmd"; break;
904 case RlinkPacketBufRcv::kNcCnt: lmsg << "Cnt"; break;
905 case RlinkPacketBufRcv::kNcRtOvlf: lmsg << "RtOvlf"; break;
906 case RlinkPacketBufRcv::kNcRtWblk: lmsg << "RtWblk"; break;
907 case RlinkPacketBufRcv::kNcInval: lmsg << "Inval"; break;
908 }
909 return -1;
910 }
911
912 if (!fRcvPkt.CheckSize(cmd.RcvSize())) { // not enough data for cmd
915 RlogMsg lmsg(*fspLog, 'E');
916 lmsg << "DecodeResponse: not enough data for cmd";
917 return -1;
918 }
919
920 fRcvPkt.GetWithCrc(rdata8);
921 if (rdata8 != cmd.Request()) { // command mismatch
924 RlogMsg lmsg(*fspLog, 'E');
925 lmsg << "DecodeResponse: command mismatch";
926 return -1;
927 }
928
929 switch (ccode) {
930 case RlinkCommand::kCmdRreg: // rreg command ---------------
931 fRcvPkt.GetWithCrc(rdata);
932 cmd.SetData(rdata);
933 break;
934
935 case RlinkCommand::kCmdRblk: // rblk command ---------------
936 fRcvPkt.GetWithCrc(rdata);
937 if (rdata != uint16_t(cmd.BlockSize())) { // length mismatch
940 RlogMsg lmsg(*fspLog, 'E');
941 lmsg << "DecodeResponse: rblk length mismatch";
942 return -1;
943 }
945 fRcvPkt.GetWithCrc(rdata);
946 cmd.SetBlockDone(rdata);
947 break;
948
949 case RlinkCommand::kCmdWreg: // wreg command ---------------
950 break;
951
952 case RlinkCommand::kCmdWblk: // wblk command ---------------
953 fRcvPkt.GetWithCrc(rdata);
954 cmd.SetBlockDone(rdata);
955 break;
956
957 case RlinkCommand::kCmdLabo: // labo command ---------------
958 fRcvPkt.GetWithCrc(rdata8);
959 cmd.SetData(uint16_t(rdata8));
960 break;
961
962 case RlinkCommand::kCmdAttn: // attn command ---------------
963 fRcvPkt.GetWithCrc(rdata);
964 cmd.SetData(rdata);
965 break;
966
967 case RlinkCommand::kCmdInit: // init command ---------------
968 break;
969 } // switch (ccode)
970
971 // crc handling
972 fRcvPkt.GetWithCrc(rdata8);
973 cmd.SetStatus(rdata8);
974 if (!fRcvPkt.CheckCrc()) { // crc mismatch
977 RlogMsg lmsg(*fspLog, 'E');
978 lmsg << "DecodeResponse: crc mismatch";
979 return -1;
980 }
981
982 ncmd += 1;
984
985 // handle active labo command, here we know that crc is ok
986 if (ccode==RlinkCommand::kCmdLabo && cmd.Data()) { // labo active ?
987 clist.SetLaboIndex(i); // set index
988 }
989
990 // expect handling
991 if (cmd.HasExpect()) { // expect object attached ?
992 auto expect = cmd.Expect();
993 if (ccode==RlinkCommand::kCmdRblk ||
994 ccode==RlinkCommand::kCmdWblk) {
995 if (expect.BlockValue().size()>0) fStats.Inc(kStatNExpData);
996 if (expect.DoneIsChecked()) fStats.Inc(kStatNExpDone);
997 } else {
998 if (expect.DataIsChecked()) fStats.Inc(kStatNExpData);
999 }
1000
1001 if (ccode==RlinkCommand::kCmdRreg ||
1002 ccode==RlinkCommand::kCmdLabo ||
1003 ccode==RlinkCommand::kCmdAttn) {
1004 if (!expect.DataCheck(cmd.Data())) {
1007 }
1008 } else if (ccode==RlinkCommand::kCmdRblk) {
1009 size_t nerr = expect.BlockCheck(cmd.BlockPointer(), cmd.BlockDone());
1010 if (nerr != 0) {
1013 }
1014 }
1015 if (ccode==RlinkCommand::kCmdRblk ||
1016 ccode==RlinkCommand::kCmdWblk) {
1017 if (!expect.DoneCheck(cmd.BlockDone())) {
1020 }
1021 }
1022
1023 } // if (cmd.Expect())
1024
1025 // status check, now independent of Expect object
1028 if (!cmd.StatusCheck()) {
1031 }
1032
1033 } // for (size_t i=ibeg; i<=iend; i++)
1034
1035 // FIXME_code: check that all data is consumed !!
1036
1037 return ncmd;
1038}
1039
1040//------------------------------------------+-----------------------------------
1042
1048{
1049 apat = 0;
1050
1051 if (!fRcvPkt.CheckSize(2+2)) { // not enough data for data+crc
1053 RlogMsg lmsg(*fspLog, 'E');
1054 lmsg << "DecodeAttnNotify: not enough data for data+crc";
1055 return false;
1056 }
1057
1058 fRcvPkt.GetWithCrc(apat);
1059
1060 if (!fRcvPkt.CheckCrc()) { // crc mismatch
1062 RlogMsg lmsg(*fspLog, 'E');
1063 lmsg << "DecodeAttnNotify: crc mismatch";
1064 return false;
1065 }
1066
1067 // FIXME_code: check for extra data
1068
1069 return true;
1070}
1071
1072//------------------------------------------+-----------------------------------
1074
1099bool RlinkConnect::ReadResponse(const Rtime& timeout, RerrMsg& emsg)
1100{
1101 Rtime tnow(CLOCK_MONOTONIC);
1102 Rtime tend = tnow + timeout;
1103
1104 while (tnow < tend) {
1105 if (!IsOpen()) BadPort("RlinkConnect::ReadResponse");
1106 int irc = fRcvPkt.ReadData(Port(), tend-tnow, emsg);
1107 if (irc <= 0) {
1108 RlogMsg lmsg(*fspLog, 'E');
1109 lmsg << "ReadResponse: IO error or timeout: " << emsg;
1110 return false;
1111 }
1112
1113 while (fRcvPkt.ProcessData()) {
1114 irc = fRcvPkt.PacketState();
1115 if (irc == RlinkPacketBufRcv::kPktPend) break;
1116 if (irc == RlinkPacketBufRcv::kPktAttn) {
1118 } else if (irc == RlinkPacketBufRcv::kPktResp) {
1119 return true;
1120 } else {
1121 RlogMsg lmsg(*fspLog, 'E');
1122 lmsg << "ReadResponse: dropped spurious packet";
1124 }
1125 } //while (fRcvPkt.ProcessData())
1126
1127 tnow.GetClock(CLOCK_MONOTONIC);
1128
1129 } // while (tnow < tend)
1130
1131 {
1132 RlogMsg lmsg(*fspLog, 'E');
1133 lmsg << "ReadResponse: timeout";
1134 }
1136
1137 return false;
1138}
1139
1140//------------------------------------------+-----------------------------------
1142
1148{
1151 return;
1152}
1153
1154//------------------------------------------+-----------------------------------
1156
1163{
1164 while (fRcvPkt.ProcessData()) {
1165 int irc = fRcvPkt.PacketState();
1166 if (irc == RlinkPacketBufRcv::kPktPend) break;
1167 if (irc == RlinkPacketBufRcv::kPktAttn) {
1169 } else {
1171 RlogMsg lmsg(*fspLog, 'E');
1172 lmsg << "ProcessUnsolicitedData: dropped spurious packet";
1173 }
1174 }
1175 return;
1176}
1177
1178//------------------------------------------+-----------------------------------
1180
1189{
1190 uint16_t apat;
1191 bool ok = DecodeAttnNotify(apat);
1193
1194 if (ok) {
1195 if (apat) {
1196 if (ServerActive()) { // if server active
1197 fpServ->SignalAttnNotify(apat); // handle in RlinkServer
1198 } else { // otherwise
1199 fAttnNotiPatt |= apat; // handle in RlinkConnect
1200 }
1201 } else {
1202 RlogMsg lmsg(*fspLog, 'W');
1203 lmsg << "ProcessAttnNotify: zero attn notify received";
1204 }
1205 }
1206
1207 if (ok && fPrintLevel == 3) {
1208 RlogMsg lmsg(*fspLog, 'I');
1209 lmsg << "ATTN notify apat = " << RosPrintf(apat,"x0",4)
1210 << " lams =";
1211 if (apat) {
1212 char sep = ' ';
1213 for (int i=15; i>=0; i--) {
1214 if (apat & (uint16_t(1)<<i) ) {
1215 lmsg << sep << i;
1216 sep = ',';
1217 }
1218 }
1219 } else {
1220 lmsg << " !NONE!";
1221 }
1222 Rtime tnow(CLOCK_MONOTONIC);
1224 lmsg << " dt=" << RosPrintf(double(tnow-fTsLastAttnNoti),"f",8,6);
1225 fTsLastAttnNoti = tnow;
1226 }
1227 return;
1228}
1229
1230//------------------------------------------+-----------------------------------
1232
1233[[noreturn]]
1234void RlinkConnect::BadPort(const char* meth)
1235{
1236 throw Rexception(meth, "Bad state: port not open");
1237}
1238
1239
1240} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
const std::string & Text() const
FIXME_docs.
Definition: RerrMsg.ipp:47
FIXME_docs.
Definition: Rexception.hpp:29
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
size_t Size() const
FIXME_docs.
void ClearLaboIndex()
FIXME_docs.
void SetLastExpectStatus(uint8_t stat, uint8_t statmsk=0xff)
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void SetLaboIndex(int ind)
FIXME_docs.
size_t AddRreg(uint16_t addr)
FIXME_docs.
void Print(std::ostream &os, const RlinkAddrMap *pamap=0, size_t abase=16, size_t dbase=16, size_t sbase=16) const
FIXME_docs.
bool LaboActive() const
FIXME_docs.
void SetStatus(uint8_t stat)
FIXME_docs.
static const uint32_t kFlagPktEnd
command last in packet
static const uint8_t kCmdInit
command code send initialize
void SetFlagBit(uint32_t mask)
FIXME_docs.
static const uint32_t kFlagSend
command send
uint16_t Data() const
FIXME_docs.
void SetRcvSize(size_t rsize)
FIXME_docs.
uint8_t Request() const
FIXME_docs.
static const uint8_t kCmdRblk
command code read block
void SetExpectStatusDefault(uint8_t stat=0, uint8_t statmsk=0x0)
FIXME_docs.
static const uint32_t kFlagChkStat
stat expect check failed
uint16_t Address() const
FIXME_docs.
size_t RcvSize() const
FIXME_docs.
bool TestFlagAny(uint32_t mask) const
FIXME_docs.
static const uint8_t kStat_M_RbErr
stat: rberr flag set
bool ExpectStatusSet() const
FIXME_docs.
bool StatusIsChecked() const
FIXME_docs.
bool StatusCheck() const
FIXME_docs.
static const uint32_t kFlagErrNak
error: nak abort
static const uint8_t kStat_M_RbNak
stat: rbnak flag set
static const uint8_t kStat_M_RbTout
stat: rbtout flag set
static const uint32_t kFlagDone
command done
static const uint32_t kFlagLabo
command labo'ed
void SetData(uint16_t data)
FIXME_docs.
uint8_t Command() const
FIXME_docs.
size_t BlockSize() const
FIXME_docs.
static const uint8_t kCmdRreg
command code read register
static const uint32_t kFlagChkDone
done expect check failed
static const uint8_t kCmdWreg
command code write register
static const uint32_t kFlagPktBeg
command first in packet
void SetSeqNumber(uint8_t snum)
FIXME_docs.
size_t BlockDone() const
FIXME_docs.
static const uint32_t kFlagErrDec
error: decode error
bool HasExpect() const
FIXME_docs.
void SetBlockDone(uint16_t dcnt)
FIXME_docs.
static const uint32_t kFlagChkData
data expect check failed
static const uint8_t kCmdAttn
command code get attention
static const uint8_t kCmdLabo
command code list abort
const RlinkCommandExpect & Expect() const
FIXME_docs.
uint16_t * BlockPointer()
FIXME_docs.
void ClearFlagBit(uint32_t mask)
FIXME_docs.
static const uint32_t kFlagInit
cmd,addr,data setup
static const uint8_t kCmdWblk
command code write block
static const uint16_t kRLCNTL_M_AnEna
RLCNTL: an enable.
std::recursive_mutex fConnectMutex
mutex to lock whole connect
static const uint16_t kRbaddr_RLCNTL
rlink core reg RLCNTL
void SetTimeout(const Rtime &timeout)
FIXME_docs.
int WaitAttn(const Rtime &timeout, Rtime &twait, uint16_t &apat, RerrMsg &emsg)
Wait for an attention notify.
void SetLogFileName(const std::string &name)
FIXME_docs.
static const uint16_t kRLSTAT_B_LCmd
RLSTAT: lcmd.
bool LogOpen(const std::string &name, RerrMsg &emsg)
FIXME_docs.
void Close()
FIXME_docs.
bool SndAttn(RerrMsg &emsg)
FIXME_docs.
static const uint16_t kRbaddr_RLID1
rlink core reg RLID1
void SetLogBaseAddr(uint32_t base)
FIXME_docs.
void HandleUnsolicitedData()
Handle unsolicited data from port.
uint16_t fAttnNotiPatt
attn notifier pattern
bool AddrMapInsert(const std::string &name, uint16_t addr)
FIXME_docs.
RlinkPacketBufSnd fSndPkt
send packet buffer
static const uint16_t kSBCNTL_V_RLMON
SBCNTL: rlmon enable bit.
void unlock()
FIXME_docs.
uint32_t fTraceLevel
trace 0=off,1=buf,2=char
uint32_t fDumpLevel
dump 0=off,1=err,2=chk,3=all
void SetLogBaseStat(uint32_t base)
FIXME_docs.
bool ServerActiveInside() const
Indicates whether server is active and caller is inside server thread.
static const uint16_t kRbufBlkDelta
rbuf needed for rblk or wblk
RlinkPort::port_uptr_t fupPort
uptr to port
bool Exec(RlinkCommandList &clist, RerrMsg &emsg)
FIXME_docs.
uint32_t fLogBaseData
log: base for data
Rtime fTimeout
response timeout
bool LinkInit(RerrMsg &emsg)
FIXME_docs.
@ kStatNInit
init commands
@ kStatNErrCrc
decode: crc mismatch
@ kStatNWblk
wblk commands
@ kStatNExecPart
ExecPart() calls.
@ kStatNErrMiss
decode: missing data
@ kStatNSndOob
SndOob() calls.
@ kStatNErrLen
decode: length mismatch
@ kStatNAttn
attn commands
@ kStatNChkData
expect data failed
@ kStatNExpStat
expect for stat explicit
@ kStatNNoExpStat
no expect for stat
@ kStatNExpDone
expect for done defined
@ kStatNErrCmd
decode: command mismatch
@ kStatNErrNak
decode: nak seen
@ kStatNExpData
expect for data defined
@ kStatNRblkWord
words rcvd with rblk
@ kStatNChkDone
expect done failed
@ kStatNCmd
commands executed
@ kStatNWreg
wreg commands
@ kStatNExec
Exec() calls.
@ kStatNLabo
labo commands
@ kStatNRreg
rreg commands
@ kStatNChkStat
expect stat failed
@ kStatNRblk
rblk commands
@ kStatNWblkWord
words send with wblk
uint32_t fUsrAcc
USR_ACCESS of connected device.
bool ServerActive() const
Indicates whether server is active.
void lock()
FIXME_docs.
static const uint16_t kRLCNTL_M_AtoVal
RLCNTL: ato value.
bool fLinkInitDeferred
noinit attr seen on Open
void EncodeRequest(RlinkCommandList &clist, size_t ibeg, size_t iend)
FIXME_docs.
~RlinkConnect()
Destructor.
void ProcessUnsolicitedData()
Process data still pending in the input buffer.
static const uint16_t kRLSTAT_V_LCmd
RLSTAT: lcmd.
void SetDumpLevel(uint32_t lvl)
FIXME_docs.
void LogUseStream(std::ostream *pstr, const std::string &name="")
FIXME_docs.
uint8_t fSeqNumber[8]
command sequence number
bool try_lock()
FIXME_docs.
static const uint16_t kRLSTAT_M_BAbo
RLSTAT: babo.
static const uint16_t kRbufPrudentDelta
Rbuf space reserve.
void Print(std::ostream &os) const
FIXME_docs.
Rtime fTsLastAttnNoti
time stamp last attn notify
static const uint16_t kSBCNTL_V_RLBMON
SBCNTL: rlbmon enable bit.
RlinkConnect()
Default constructor.
bool SndOob(uint16_t addr, uint16_t data, RerrMsg &emsg)
FIXME_docs.
uint32_t fSysId
SYSID of connected device.
void ProcessAttnNotify()
Process attention notify packets.
static const uint16_t kRLSTAT_M_RBSize
RLSTAT: rbuf size.
bool ReadResponse(const Rtime &timeout, RerrMsg &emsg)
Read data from port until complete response packet seen.
void BadPort(const char *meth)
Port not connected or not open abort.
RlinkContext fContext
default context
static const uint16_t kSBCNTL_V_RBMON
SBCNTL: rbmon enable bit.
static const uint16_t kRbaddr_RLUA1
rlink opt. reg RLUA1
bool IsOpen() const
FIXME_docs.
static const uint16_t kRbaddr_RLID0
rlink core reg RLID0
RlinkPacketBufRcv fRcvPkt
receive packet buffer
uint32_t fLogBaseAddr
log: base for addr
static const uint16_t kRbaddr_RMBASE
rlink opt. rbd_rbmon
void SetLogBaseData(uint32_t base)
FIXME_docs.
bool ServerActiveOutside() const
Indicates whether server is active and caller is outside server thread.
bool ExecPart(RlinkCommandList &clist, size_t ibeg, size_t iend, RerrMsg &emsg)
FIXME_docs.
static const uint16_t kRbaddr_RLSTAT
rlink core reg RLSTAT
RlinkPort & Port()
FIXME_docs.
void SetPrintLevel(uint32_t lvl)
FIXME_docs.
uint32_t fPrintLevel
print 0=off,1=err,2=chk,3=all
Rstats fStats
statistics
bool HasPort() const
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
RlinkAddrMap fAddrMap
name<->address mapping
bool fHasRbmon
has rbd_rbmon (rbus monitor)
static const uint16_t kRLCNTL_M_AtoEna
RLCNTL: ato enable.
uint32_t fLogBaseStat
log: base for stat
RlinkServer * fpServ
ptr to server (optional)
size_t fRbufSize
Rbuf size (in bytes)
void AcceptResponse()
Accept response packet received with ReadResponse().
const RlinkAddrMap & AddrMap() const
FIXME_docs.
static const uint16_t kRbaddr_RLUA0
rlink opt. reg RLUA0
bool fLinkInitDone
LinkInit done.
void SetTraceLevel(uint32_t lvl)
FIXME_docs.
int DecodeResponse(RlinkCommandList &clist, size_t ibeg, size_t iend)
FIXME_docs.
bool Open(const std::string &name, RerrMsg &emsg)
FIXME_docs.
std::shared_ptr< RlogFile > fspLog
log file ptr
bool DecodeAttnNotify(uint16_t &apat)
Decodes an attention notify packet.
void IncErrorCount(size_t inc=1)
FIXME_docs.
uint8_t StatusValue() const
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void SetStatus(uint8_t stat, uint8_t statmsk=0x00)
FIXME_docs.
uint8_t StatusMask() const
FIXME_docs.
bool CheckNak() const
FIXME_docs.
void GetWithCrc(uint8_t &data)
FIXME_docs.
@ kPktAttn
attn notify packet (ATTN+EOP)
@ kPktPend
pending, still being filled
@ kPktResp
response packet (SOP+EOP)
uint8_t NakCode() const
FIXME_docs.
bool CheckSize(size_t nbyte) const
FIXME_docs.
void AcceptPacket()
FIXME_docs.
pkt_state PacketState()
FIXME_docs.
int ReadData(RlinkPort &port, const Rtime &timeout, RerrMsg &emsg)
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void PutWithCrc(uint8_t data)
FIXME_docs.
void SetXonEscape(bool xon)
FIXME_docs.
bool SndOob(RlinkPort &port, uint16_t addr, uint16_t data, RerrMsg &emsg)
FIXME_docs.
bool SndKeep(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
bool SndPacket(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
bool SndAttn(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
static const uint8_t kNcCnt
VHDL def nak_cnt 101.
static const uint8_t kNcRtWblk
VHDL def nak_rtwblk 111.
static const uint8_t kNcUnused
VHDL def nak_unused 011.
static const uint8_t kNcFrame
VHDL def nak_frame 010.
static const uint8_t kNcCmd
VHDL def nak_cmd 100.
static const uint8_t kNcRtOvlf
VHDL def nak_rtovfl 110.
static const uint8_t kNcDcrc
VHDL def nak_dcrc 001.
static const uint8_t kNcInval
invalid NAK
static const uint8_t kNcCcrc
VHDL def nak_ccrc 000.
static RlinkPort::port_uptr_t Open(const std::string &url, RerrMsg &emsg)
FIXME_docs.
void SetTraceLevel(uint32_t level)
FIXME_docs.
Definition: RlinkPort.ipp:76
static const int kErr
return code: IO error
Definition: RlinkPort.hpp:88
static const int kTout
return code: time out
Definition: RlinkPort.hpp:87
void SetLogFile(const std::shared_ptr< RlogFile > &splog)
FIXME_docs.
Definition: RlinkPort.ipp:67
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
Definition: RlinkPort.cpp:288
bool IsActiveInside() const
Indicates whether server is active and caller is inside server thread.
bool IsActive() const
Indicates whether server is active.
void Stop()
FIXME_docs.
bool IsActiveOutside() const
Indicates whether server is active and caller is outside server thread.
void SignalAttnNotify(uint16_t apat)
FIXME_docs.
FIXME_docs.
Definition: RlogFile.hpp:34
FIXME_docs.
Definition: RlogMsg.hpp:24
I/O appicator to generate fill characters.
Definition: RosFill.hpp:24
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
Definition: Rstats.cpp:178
void Inc(size_t ind, double val=1.)
FIXME_docs.
Definition: Rstats.ipp:29
void Define(size_t ind, const std::string &name, const std::string &text)
FIXME_docs.
Definition: Rstats.cpp:72
FIXME_docs.
Definition: Rtime.hpp:25
bool IsPositive() const
FIXME_docs.
Definition: Rtime.ipp:93
void Clear()
FIXME_docs.
Definition: Rtime.ipp:76
void GetClock(clockid_t clkid)
FIXME_docs.
Definition: Rtime.cpp:41
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Definition: RosPrintf.ipp:38
void Catch2Cerr(const char *msg, std::function< void()> func)
FIXME_docs.
Definition: Rtools.cpp:170
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47