102 fLinkInitDeferred(false),
103 fLinkInitDone(false),
187 if (!
Port().Url().FindOpt(
"noinit")) {
206 if (
IsOpen() &&
Port().Url().FindOpt(
"keep")) {
237 if (!
Exec(clist, emsg))
return false;
247 uint16_t rlstat = clist[ista].Data();
248 uint16_t rlid1 = clist[iid1].Data();
249 uint16_t rlid0 = clist[iid0].Data();
252 fSysId = uint32_t(rlid1)<<16 | uint32_t(rlid0);
258 if ((clist[iua1].Status() & staterr) == 0 &&
259 (clist[iua0].Status() & staterr) == 0) {
264 uint16_t rlua1 = clist[3].Data();
265 uint16_t rlua0 = clist[4].Data();
266 fUsrAcc = uint32_t(rlua1)<<16 | uint32_t(rlua0);
269 if ((clist[irbm].Status() & staterr) == 0) {
343 if (clist.
Size() == 0)
344 throw Rexception(
"RlinkConnect::Exec()",
"Bad state: clist empty");
346 throw Rexception(
"RlinkConnect::Exec()",
"Bad state: port not open");
348 lock_guard<RlinkConnect>
lock(*
this);
356 size_t size = clist.
Size();
358 for (
size_t i=0; i<size; i++) {
362 "BugCheck: command not initialized");
365 "BugCheck: invalid command code");
369 "attn command not allowed outside active server");
388 while (ibeg < size) {
390 for (
size_t i=ibeg; i<size; i++) {
392 if (clist[i].TestFlagAll(RlinkCommand::kFlagVol)) {
397 bool rc =
ExecPart(clist, ibeg, iend, emsg);
403 bool rc =
ExecPart(clist, 0, size-1, emsg);
406 bool checkseen =
false;
407 bool errorseen =
false;
409 for (
size_t i=0; i<size; i++) {
417 checkseen |= checkfound;
418 errorseen |= errorfound;
423 if (checkseen) loglevel = 2;
424 if (errorseen) loglevel = 1;
431 clist.
Dump(lmsg(), 0);
443 bool rc =
Exec(clist, cntx, emsg);
446 lmsg << emsg << endl;
447 lmsg <<
"Dump of failed clist:" << endl;
448 clist.
Dump(lmsg(), 0);
451 throw Rexception(
"RlinkConnect::Exec",
"Exec() failed: ", emsg);
489 "not allowed outside active server");
494 lock_guard<RlinkConnect>
lock(*
this);
507 Rtime tnow(CLOCK_MONOTONIC);
508 Rtime tend = tnow + timeout;
511 while (tnow < tend) {
530 lmsg <<
"WaitAttn: dropped spurious packet";
546 lock_guard<RlinkConnect>
lock(*
this);
557 lock_guard<RlinkConnect>
lock(*
this);
566 if (base!=2 && base!=8 && base!=16)
567 throw Rexception(
"RlinkConnect::SetLogBaseAddr()",
568 "Bad args: base != 2,8,16");
578 if (base!=2 && base!=8 && base!=16)
579 throw Rexception(
"RlinkConnect::SetLogBaseData()",
580 "Bad args: base != 2,8,16");
590 if (base!=2 && base!=8 && base!=16)
591 throw Rexception(
"RlinkConnect::SetLogBaseStat()",
592 "Bad args: base != 2,8,16");
631 throw Rexception(
"RlinkConnect::SetTimeout()",
632 "Bad args: timeout <= 0");
642 if (!
fspLog->Open(name, emsg)) {
654 fspLog->UseStream(pstr, name);
666 emsg.
Text() +
"', using stdout");
676 os <<
"RlinkConnect::Print(std::ostream& os)" << endl;
687 os << bl << (text?text:
"--") <<
"RlinkConnect @ " <<
this << endl;
690 Port().
Dump(os, ind+2,
"fupPort: ", detail);
692 os << bl <<
" fupPort: " <<
fupPort.get() << endl;
698 os << bl <<
" fpServ: " <<
fpServ << endl;
699 os << bl <<
" fSeqNumber: ";
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: ");
738 throw Rexception(
"RlinkConnect::HandleUnsolicitedData()",
739 "only allowed inside active server");
741 lock_guard<RlinkConnect>
lock(*
this);
743 if (!
IsOpen())
BadPort(
"RlinkConnect::HandleUnsolicitedData");
745 if (irc == 0)
return;
748 lmsg <<
"HandleUnsolicitedData: IO error: " << emsg;
760 if (ibeg>iend || iend>=clist.
Size())
762 "Bad args: ibeg or iend invalid");
764 throw Rexception(
"RlinkConnect::ExecPart()",
"Bad state: port not open");
775 if (!ok)
Rexception(
"RlinkConnect::ExecPart()",
"faulty response");
778 if (ncmd !=
int(iend-ibeg+1)) {
780 throw Rexception(
"RlinkConnect::ExecPart()",
"incomplete response");
796 for (
size_t i=ibeg; i<=iend; i++) {
858 throw Rexception(
"RlinkConnect::Exec()",
"BugCheck: invalid command");
880 for (
size_t i=ibeg; i<=iend; i++) {
897 lmsg <<
"DecodeResponse: NAK seen, code ";
916 lmsg <<
"DecodeResponse: not enough data for cmd";
925 lmsg <<
"DecodeResponse: command mismatch";
937 if (rdata != uint16_t(cmd.
BlockSize())) {
941 lmsg <<
"DecodeResponse: rblk length mismatch";
978 lmsg <<
"DecodeResponse: crc mismatch";
992 auto expect = cmd.
Expect();
1004 if (!expect.DataCheck(cmd.
Data())) {
1017 if (!expect.DoneCheck(cmd.
BlockDone())) {
1054 lmsg <<
"DecodeAttnNotify: not enough data for data+crc";
1063 lmsg <<
"DecodeAttnNotify: crc mismatch";
1101 Rtime tnow(CLOCK_MONOTONIC);
1102 Rtime tend = tnow + timeout;
1104 while (tnow < tend) {
1109 lmsg <<
"ReadResponse: IO error or timeout: " << emsg;
1122 lmsg <<
"ReadResponse: dropped spurious packet";
1133 lmsg <<
"ReadResponse: timeout";
1172 lmsg <<
"ProcessUnsolicitedData: dropped spurious packet";
1203 lmsg <<
"ProcessAttnNotify: zero attn notify received";
1209 lmsg <<
"ATTN notify apat = " <<
RosPrintf(apat,
"x0",4)
1213 for (
int i=15; i>=0; i--) {
1214 if (apat & (uint16_t(1)<<i) ) {
1222 Rtime tnow(CLOCK_MONOTONIC);
1236 throw Rexception(meth,
"Bad state: port not open");
const std::string & Text() const
FIXME_docs.
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.
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.
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.
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
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.
bool CheckCrc()
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.
bool ProcessData()
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.
static const int kErr
return code: IO error
static const int kTout
return code: time out
void SetLogFile(const std::shared_ptr< RlogFile > &splog)
FIXME_docs.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
bool IsActiveInside() const
Indicates whether server is active and caller is inside server thread.
bool IsActive() const
Indicates whether server is active.
bool IsActiveOutside() const
Indicates whether server is active and caller is outside server thread.
void SignalAttnNotify(uint16_t apat)
FIXME_docs.
I/O appicator to generate fill characters.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
void Inc(size_t ind, double val=1.)
FIXME_docs.
void Define(size_t ind, const std::string &name, const std::string &text)
FIXME_docs.
bool IsPositive() const
FIXME_docs.
void GetClock(clockid_t clkid)
FIXME_docs.
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.
Declaration of class ReventLoop.