mirror of
https://github.com/wfjm/w11.git
synced 2026-03-10 04:54:26 +00:00
src/librlink add Nak handling
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkConnect.cpp 1185 2019-07-12 17:29:12Z mueller $
|
||||
// $Id: RlinkConnect.cpp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2011-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 2.8.6 add Nak handling
|
||||
// 2019-03-10 1121 2.8.5 DecodeResponse(): rblk expect check over BlockDone
|
||||
// 2018-12-22 1091 2.8.4 Open(): (-Wpessimizing-move fix); add BadPort()
|
||||
// 2018-12-19 1090 2.8.3 use RosPrintf(bool)
|
||||
@@ -152,6 +153,7 @@ RlinkConnect::RlinkConnect()
|
||||
fStats.Define(kStatNErrCmd, "NErrCmd", "decode: command mismatch");
|
||||
fStats.Define(kStatNErrLen, "NErrLen", "decode: length mismatch");
|
||||
fStats.Define(kStatNErrCrc, "NErrCrc", "decode: crc mismatch");
|
||||
fStats.Define(kStatNErrNak, "NErrNak", "decode: nak seen");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
@@ -874,7 +876,7 @@ int RlinkConnect::DecodeResponse(RlinkCommandList& clist, size_t ibeg,
|
||||
size_t iend)
|
||||
{
|
||||
size_t ncmd = 0;
|
||||
|
||||
|
||||
for (size_t i=ibeg; i<=iend; i++) {
|
||||
RlinkCommand& cmd = clist[i];
|
||||
uint8_t ccode = cmd.Command();
|
||||
@@ -888,7 +890,24 @@ int RlinkConnect::DecodeResponse(RlinkCommandList& clist, size_t ibeg,
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME_code: handle NAK properly !!
|
||||
if (fRcvPkt.CheckNak()) { // NAK seen
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrNak);
|
||||
fStats.Inc(kStatNErrNak);
|
||||
RlogMsg lmsg(*fspLog, 'E');
|
||||
lmsg << "DecodeResponse: NAK seen, code ";
|
||||
switch (fRcvPkt.NakCode()) {
|
||||
case RlinkPacketBufRcv::kNcCcrc: lmsg << "Ccrc"; break;
|
||||
case RlinkPacketBufRcv::kNcDcrc: lmsg << "Dcrc"; break;
|
||||
case RlinkPacketBufRcv::kNcFrame: lmsg << "Frame"; break;
|
||||
case RlinkPacketBufRcv::kNcUnused: lmsg << "Unused"; break;
|
||||
case RlinkPacketBufRcv::kNcCmd: lmsg << "Cmd"; break;
|
||||
case RlinkPacketBufRcv::kNcCnt: lmsg << "Cnt"; break;
|
||||
case RlinkPacketBufRcv::kNcRtOvlf: lmsg << "RtOvlf"; break;
|
||||
case RlinkPacketBufRcv::kNcRtWblk: lmsg << "RtWblk"; break;
|
||||
case RlinkPacketBufRcv::kNcInval: lmsg << "Inval"; break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!fRcvPkt.CheckSize(cmd.RcvSize())) { // not enough data for cmd
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrDec);
|
||||
@@ -899,7 +918,7 @@ int RlinkConnect::DecodeResponse(RlinkCommandList& clist, size_t ibeg,
|
||||
}
|
||||
|
||||
fRcvPkt.GetWithCrc(rdata8);
|
||||
if (rdata8 != cmd.Request()) { // command mismatch
|
||||
if (rdata8 != cmd.Request()) { // command mismatch
|
||||
cmd.SetFlagBit(RlinkCommand::kFlagErrDec);
|
||||
fStats.Inc(kStatNErrCmd);
|
||||
RlogMsg lmsg(*fspLog, 'E');
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkConnect.hpp 1186 2019-07-12 17:49:59Z mueller $
|
||||
// $Id: RlinkConnect.hpp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2011-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 2.8.5 add Nak handling
|
||||
// 2019-06-07 1160 2.8.4 *Stats() not longer const
|
||||
// 2018-12-23 1091 2.8.3 add BadPort()
|
||||
// 2018-12-17 1085 2.8.2 use std::recursive_mutex instead of boost
|
||||
@@ -217,6 +218,7 @@ namespace Retro {
|
||||
kStatNErrCmd, //!< decode: command mismatch
|
||||
kStatNErrLen, //!< decode: length mismatch
|
||||
kStatNErrCrc, //!< decode: crc mismatch
|
||||
kStatNErrNak, //!< decode: nak seen
|
||||
kDimStat
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkPacketBuf.cpp 1186 2019-07-12 17:49:59Z mueller $
|
||||
// $Id: RlinkPacketBuf.cpp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2011-2017 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 2.0.4 add kNc* definitions
|
||||
// 2017-04-07 868 2.0.1 Dump(): add detail arg
|
||||
// 2014-11-23 606 2.0 re-organize for rlink v4
|
||||
// 2013-04-21 509 1.0.4 add SndAttn() method
|
||||
@@ -60,6 +61,15 @@ const uint8_t RlinkPacketBuf::kEcXoff;
|
||||
const uint8_t RlinkPacketBuf::kEcFill;
|
||||
const uint8_t RlinkPacketBuf::kEcEsc;
|
||||
const uint8_t RlinkPacketBuf::kEcClobber;
|
||||
const uint8_t RlinkPacketBuf::kNcCcrc;
|
||||
const uint8_t RlinkPacketBuf::kNcDcrc;
|
||||
const uint8_t RlinkPacketBuf::kNcFrame;
|
||||
const uint8_t RlinkPacketBuf::kNcUnused;
|
||||
const uint8_t RlinkPacketBuf::kNcCmd;
|
||||
const uint8_t RlinkPacketBuf::kNcCnt;
|
||||
const uint8_t RlinkPacketBuf::kNcRtOvlf;
|
||||
const uint8_t RlinkPacketBuf::kNcRtWblk;
|
||||
const uint8_t RlinkPacketBuf::kNcInval;
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! Default constructor
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkPacketBuf.hpp 1186 2019-07-12 17:49:59Z mueller $
|
||||
// $Id: RlinkPacketBuf.hpp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2011-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 2.0.4 add kNc* definitions
|
||||
// 2019-06-07 1160 2.0.3 Stats() not longer const
|
||||
// 2018-12-16 1084 2.0.2 use =delete for noncopyable instead of boost
|
||||
// 2017-04-07 868 2.0.1 Dump(): add detail arg
|
||||
@@ -74,7 +75,16 @@ namespace Retro {
|
||||
static const uint8_t kEcXoff = 0x05; //!< VHDL def ec_xoff 101
|
||||
static const uint8_t kEcFill = 0x06; //!< VHDL def ec_fill 110
|
||||
static const uint8_t kEcEsc = 0x07; //!< VHDL def ec_esc 111
|
||||
static const uint8_t kEcClobber = 0xff; //!< invalid Ecode
|
||||
static const uint8_t kEcClobber = 0xff; //!< invalid Ecode
|
||||
static const uint8_t kNcCcrc = 0x00; //!< VHDL def nak_ccrc 000
|
||||
static const uint8_t kNcDcrc = 0x01; //!< VHDL def nak_dcrc 001
|
||||
static const uint8_t kNcFrame = 0x02; //!< VHDL def nak_frame 010
|
||||
static const uint8_t kNcUnused = 0x03; //!< VHDL def nak_unused 011
|
||||
static const uint8_t kNcCmd = 0x04; //!< VHDL def nak_cmd 100
|
||||
static const uint8_t kNcCnt = 0x05; //!< VHDL def nak_cnt 101
|
||||
static const uint8_t kNcRtOvlf = 0x06; //!< VHDL def nak_rtovfl 110
|
||||
static const uint8_t kNcRtWblk = 0x07; //!< VHDL def nak_rtwblk 111
|
||||
static const uint8_t kNcInval = 0x08; //!< invalid NAK
|
||||
|
||||
protected:
|
||||
void SetFlagBit(uint32_t mask);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkPacketBufRcv.cpp 1186 2019-07-12 17:49:59Z mueller $
|
||||
// $Id: RlinkPacketBufRcv.cpp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2014-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 1.2.3 add Nak handling
|
||||
// 2019-06-14 1163 1.2.2 ReadData(): coverity fixup (logically dead code)
|
||||
// 2018-12-23 1091 1.2.1 ReadData(): remove port open check, done at caller
|
||||
// 2018-12-08 1079 1.2 use ref not ptr for RlinkPort
|
||||
@@ -20,6 +21,8 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "RlinkPacketBufRcv.hpp"
|
||||
|
||||
#include "librtools/RosFill.hpp"
|
||||
@@ -47,17 +50,27 @@ RlinkPacketBufRcv::RlinkPacketBufRcv()
|
||||
fNDone(0),
|
||||
fEscSeen(false),
|
||||
fNakIndex(-1),
|
||||
fNakCode(0),
|
||||
fDropData()
|
||||
{
|
||||
// Statistic setup
|
||||
fStats.Define(kStatNRxPktByt, "NRxPktByt", "Rx packet bytes rcvd");
|
||||
fStats.Define(kStatNRxDrop, "NRxDrop", "Rx bytes dropped");
|
||||
fStats.Define(kStatNRxSop, "NRxSop", "Rx SOP commas seen");
|
||||
fStats.Define(kStatNRxEop, "NRxEop", "Rx EOP commas seen");
|
||||
fStats.Define(kStatNRxNak, "NRxNak", "Rx NAK commas seen");
|
||||
fStats.Define(kStatNRxAttn, "NRxAttn", "Rx ATTN commas seen");
|
||||
fStats.Define(kStatNRxEsc, "NRxEsc", "Rx data escapes");
|
||||
fStats.Define(kStatNRxClobber,"NRxClobber","Rx clobbered escapes");
|
||||
fStats.Define(kStatNRxPktByt, "NRxPktByt", "Rx packet bytes rcvd");
|
||||
fStats.Define(kStatNRxDrop, "NRxDrop", "Rx bytes dropped");
|
||||
fStats.Define(kStatNRxSop, "NRxSop", "Rx SOP commas seen");
|
||||
fStats.Define(kStatNRxEop, "NRxEop", "Rx EOP commas seen");
|
||||
fStats.Define(kStatNRxNak, "NRxNak", "Rx NAK commas seen");
|
||||
fStats.Define(kStatNRxAttn, "NRxAttn", "Rx ATTN commas seen");
|
||||
fStats.Define(kStatNRxEsc, "NRxEsc", "Rx data escapes");
|
||||
fStats.Define(kStatNRxClobber, "NRxClobber", "Rx clobbered escapes");
|
||||
fStats.Define(kStatNRxNakCcrc, "NRxNakCcrc", "Rx NAK Ccrc seen");
|
||||
fStats.Define(kStatNRxNakDcrc, "NRxNakDcrc", "Rx NAK Dcrc seen");
|
||||
fStats.Define(kStatNRxNakFrame, "NRxNakFrame", "Rx NAK Frame seen");
|
||||
fStats.Define(kStatNRxNakUnused, "NRxNakUnused", "Rx NAK Unused seen");
|
||||
fStats.Define(kStatNRxNakCmd, "NRxNakCmd", "Rx NAK Cmd seen");
|
||||
fStats.Define(kStatNRxNakCnt, "NRxNakCnt", "Rx NAK Cnt seen");
|
||||
fStats.Define(kStatNRxNakRtOvlf, "NRxNakRtOvlf", "Rx NAK RtOvlf seen");
|
||||
fStats.Define(kStatNRxNakRtWblk, "NRxNakRtWblk", "Rx NAK RtWblk seen");
|
||||
fStats.Define(kStatNRxNakInval, "NRxNakInval", "Rx NAK invalid seen");
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
@@ -134,6 +147,7 @@ void RlinkPacketBufRcv::AcceptPacket()
|
||||
fRcvState = kRcvIdle;
|
||||
fNDone = 0;
|
||||
fNakIndex = -1;
|
||||
fNakCode = 0;
|
||||
fDropData.clear();
|
||||
return;
|
||||
}
|
||||
@@ -158,7 +172,7 @@ RlinkPacketBufRcv::pkt_state RlinkPacketBufRcv::PacketState()
|
||||
if (fRcvState==kRcvDone) return TestFlag(kFlagSopSeen) ? kPktResp : kPktAttn;
|
||||
return kPktError;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
@@ -187,6 +201,7 @@ void RlinkPacketBufRcv::Dump(std::ostream& os, int ind, const char* text,
|
||||
os << bl << " fNDone: " << RosPrintf(fNDone,"d",4) << endl;
|
||||
os << bl << " fEscSeen: " << RosPrintf(fEscSeen) << endl;
|
||||
os << bl << " fNakIndex: " << RosPrintf(fNakIndex,"d",4) << endl;
|
||||
os << bl << " fNakCode: " << RosPrintf(fNakCode,"d",4) << endl;
|
||||
|
||||
os << bl << " fDropData.size:" << RosPrintf(fDropData.size(),"d",4);
|
||||
size_t ncol = max(1, (80-ind-4-6)/(2+1));
|
||||
@@ -276,8 +291,30 @@ void RlinkPacketBufRcv::ProcessDataFill()
|
||||
fRcvState = kRcvError;
|
||||
return;
|
||||
} // else 1st NAK
|
||||
|
||||
SetFlagBit(kFlagNakSeen); // -> set flag and index; continue
|
||||
fNakIndex = fPktBuf.size();
|
||||
if (fRawBufDone+1 < fRawBufSize) {
|
||||
uint8_t nc = fRawBuf[fRawBufDone];
|
||||
uint8_t ncpre = nc & 0xc0;
|
||||
uint8_t ncneg = ((~nc)>>3) & 0x07;
|
||||
uint8_t ncpos = nc & 0x07;
|
||||
fNakCode = (ncpre == 0x80 && ncneg == ncpos) ? ncpos : kNcInval;
|
||||
} else {
|
||||
fNakCode = kNcInval;
|
||||
}
|
||||
switch (fNakCode) {
|
||||
case kNcCcrc: fStats.Inc(kStatNRxNakCcrc); break; // NAK Ccrc seen
|
||||
case kNcDcrc: fStats.Inc(kStatNRxNakDcrc); break; // NAK Dcrc seen
|
||||
case kNcFrame: fStats.Inc(kStatNRxNakFrame); break; // NAK Frame seen
|
||||
case kNcUnused: fStats.Inc(kStatNRxNakUnused); break; // NAK Unused seen
|
||||
case kNcCmd: fStats.Inc(kStatNRxNakCmd); break; // NAK Cmd seen
|
||||
case kNcCnt: fStats.Inc(kStatNRxNakCnt); break; // NAK Cnt seen
|
||||
case kNcRtOvlf: fStats.Inc(kStatNRxNakRtOvlf); break; // NAK RtOvlf seen
|
||||
case kNcRtWblk: fStats.Inc(kStatNRxNakRtWblk); break; // NAK RtWblk seen
|
||||
case kNcInval: fStats.Inc(kStatNRxNakInval); break; // NAK invalid seen
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// data escapes seen: add escaped char and continue
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkPacketBufRcv.hpp 1186 2019-07-12 17:49:59Z mueller $
|
||||
// $Id: RlinkPacketBufRcv.hpp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2014-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Copyright 2014-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 1.2.1 add Nak handling
|
||||
// 2018-12-08 1079 1.2 use ref not ptr for RlinkPort
|
||||
// 2017-04-07 868 1.1.1 Dump(): add detail arg
|
||||
// 2017-02-19 853 1.1 use Rtime
|
||||
@@ -41,10 +42,11 @@ namespace Retro {
|
||||
kPktPend=0, //!< pending, still being filled
|
||||
kPktResp, //!< response packet (SOP+EOP)
|
||||
kPktAttn, //!< attn notify packet (ATTN+EOP)
|
||||
kPktError //!< errorous packet
|
||||
kPktError //!< erroneous packet
|
||||
};
|
||||
pkt_state PacketState();
|
||||
|
||||
bool CheckNak() const;
|
||||
bool CheckSize(size_t nbyte) const;
|
||||
void GetWithCrc(uint8_t& data);
|
||||
void GetWithCrc(uint16_t& data);
|
||||
@@ -52,6 +54,7 @@ namespace Retro {
|
||||
bool CheckCrc();
|
||||
|
||||
int NakIndex() const;
|
||||
uint8_t NakCode() const;
|
||||
|
||||
void Dump(std::ostream& os, int ind=0, const char* text=0,
|
||||
int detail=0) const;
|
||||
@@ -65,7 +68,16 @@ namespace Retro {
|
||||
kStatNRxNak, //!< Rx NAK commas seen
|
||||
kStatNRxAttn, //!< Rx ATTN commas seen
|
||||
kStatNRxEsc, //!< Rx data escapes
|
||||
kStatNRxClobber //!< Rx clobbered escapes
|
||||
kStatNRxClobber, //!< Rx clobbered escapes
|
||||
kStatNRxNakCcrc, //!< Rx NAK Ccrc seen
|
||||
kStatNRxNakDcrc, //!< Rx NAK Dcrc seen
|
||||
kStatNRxNakFrame, //!< Rx NAK Frame seen
|
||||
kStatNRxNakUnused, //!< Rx NAK Unused seen
|
||||
kStatNRxNakCmd, //!< Rx NAK Cmd seen
|
||||
kStatNRxNakCnt, //!< Rx NAK Cnt seen
|
||||
kStatNRxNakRtOvlf, //!< Rx NAK RtOvlf seen
|
||||
kStatNRxNakRtWblk, //!< Rx NAK RtWblk seen
|
||||
kStatNRxNakInval //!< Rx NAK invalid seen
|
||||
};
|
||||
|
||||
protected:
|
||||
@@ -88,6 +100,7 @@ namespace Retro {
|
||||
size_t fNDone; //!< number of pkt bytes processed
|
||||
bool fEscSeen; //!< last char was Escape
|
||||
int fNakIndex; //!< index of active nak (-1 if no)
|
||||
uint8_t fNakCode; //!< code of active nak
|
||||
std::vector<uint8_t> fDropData; //!< dropped data buffer
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// $Id: RlinkPacketBufRcv.ipp 1186 2019-07-12 17:49:59Z mueller $
|
||||
// $Id: RlinkPacketBufRcv.ipp 1198 2019-07-27 19:08:31Z mueller $
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// Copyright 2014- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
// Copyright 2014-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
|
||||
//
|
||||
// Revision History:
|
||||
// Date Rev Version Comment
|
||||
// 2019-07-27 1198 1.0.1 add Nak handling
|
||||
// 2014-11-23 606 1.0 Initial version
|
||||
// 2014-11-02 600 0.1 First draft (re-organize PacketBuf for rlink v4)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -18,6 +19,14 @@ namespace Retro {
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkPacketBufRcv::CheckNak() const
|
||||
{
|
||||
return fNakIndex >= 0 && int(fNDone) == fNakIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline bool RlinkPacketBufRcv::CheckSize(size_t nbyte) const
|
||||
{
|
||||
return fPktBuf.size()-fNDone >= nbyte;
|
||||
@@ -63,4 +72,12 @@ inline int RlinkPacketBufRcv::NakIndex() const
|
||||
return fNakIndex;
|
||||
}
|
||||
|
||||
//------------------------------------------+-----------------------------------
|
||||
//! FIXME_docs
|
||||
|
||||
inline uint8_t RlinkPacketBufRcv::NakCode() const
|
||||
{
|
||||
return fNakCode;
|
||||
}
|
||||
|
||||
} // end namespace Retro
|
||||
|
||||
Reference in New Issue
Block a user