1
0
mirror of https://github.com/wfjm/w11.git synced 2026-03-09 20:48:30 +00:00

src/librlink add Nak handling

This commit is contained in:
wfjm
2019-08-09 18:17:15 +02:00
parent 9f13421caa
commit 2837308cbe
7 changed files with 132 additions and 24 deletions

View File

@@ -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');

View File

@@ -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
};

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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
};

View File

@@ -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