w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
RlinkPacketBufSnd.cpp
Go to the documentation of this file.
1// $Id: RlinkPacketBufSnd.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2014-2018 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2018-12-23 1091 1.2.3 SndRaw(): remove port open check, done at caller
8// 2018-12-19 1090 1.2.2 use RosPrintf(bool)
9// 2018-12-18 1089 1.2.1 use c++ style casts
10// 2018-12-08 1079 1.2 use ref not ptr for RlinkPort
11// 2017-04-07 868 1.1.1 Dump(): add detail arg
12// 2015-04-11 666 1.1 handle xon/xoff escaping, add (Set)XonEscape()
13// 2014-12-25 621 1.0.1 Reorganize packet send/revd stats
14// 2014-11-15 604 1.0 Initial version
15// 2014-11-02 600 0.1 First draft (re-organize PacketBuf for rlink v4)
16// ---------------------------------------------------------------------------
17
22#include <sys/time.h>
23
24#include "RlinkPacketBufSnd.hpp"
25
26#include "librtools/RosFill.hpp"
29
30using namespace std;
31
37// all method definitions in namespace Retro
38namespace Retro {
39
40//------------------------------------------+-----------------------------------
42
44 : fXonEscape(false),
45 fRawBuf()
46{
47 // Statistic setup
48 fStats.Define(kStatNTxPktByt, "NTxPktByt", "Tx packet bytes send");
49 fStats.Define(kStatNTxEsc, "NTxEsc", "Tx esc escapes");
50 fStats.Define(kStatNTxXEsc, "NTxXEsc", "Tx xon escapes");
51}
52
53//------------------------------------------+-----------------------------------
55
57{}
58
59//------------------------------------------+-----------------------------------
61
63{
64 fPktBuf.clear();
65 fRawBuf.clear();
66 fCrc.Clear();
67 fFlags = 0;
68
69 return;
70}
71
72//------------------------------------------+-----------------------------------
74
75void RlinkPacketBufSnd::PutWithCrc(const uint16_t* pdata, size_t count)
76{
77 const uint16_t* pend = pdata + count;
78 while (pdata < pend) PutWithCrc(*pdata++);
79 return;
80}
81
82//------------------------------------------+-----------------------------------
84
86{
87 size_t nesc = 0;
88 size_t nxesc = 0;
89
90 fRawBuf.reserve(2*fPktBuf.size()+4); // max. size of raw data
91 fRawBuf.clear();
92
93 PutRawEsc(kEcSop); // <SOP>
94
95 size_t ni = fPktBuf.size();
96 uint8_t* pi = fPktBuf.data();
97 for (size_t i=0; i<ni; i++) {
98 uint8_t c = *pi++;
99
100 if (c == kSymEsc) {
102 nesc += 1;
103 continue;
104 }
105
106 if (fXonEscape) {
107 if (c == kSymXon) {
109 nxesc += 1;
110 continue;
111 }
112 if (c == kSymXoff) {
114 nxesc += 1;
115 continue;
116 }
117 }
118
119 fRawBuf.push_back(c);
120 }
121
122 PutRawEsc(kEcEop); // <EOP>
123 fStats.Inc(kStatNTxEsc, double(nesc));
124 fStats.Inc(kStatNTxXEsc, double(nxesc));
125
126 bool sndok = SndRaw(port, emsg);
127 if (sndok) fStats.Inc(kStatNTxPktByt, double(PktSize()));
128 return sndok;
129}
130
131//------------------------------------------+-----------------------------------
133
134bool RlinkPacketBufSnd::SndOob(RlinkPort& port, uint16_t addr, uint16_t data,
135 RerrMsg& emsg)
136{
137 Init();
138
139 fRawBuf.clear();
140 fRawBuf.push_back(kSymEsc); // ESC
141 fRawBuf.push_back(kSymEsc); // ESC
142 fRawBuf.push_back(uint8_t( addr & 0x000f)); // ADDR ( 3: 0)
143 fRawBuf.push_back(uint8_t((addr>>4) & 0x000f)); // ADDR ( 7: 4)
144 fRawBuf.push_back(uint8_t( data & 0x000f)); // DATA ( 3: 0)
145 fRawBuf.push_back(uint8_t((data>>4) & 0x000f)); // DATA ( 7: 4)
146 fRawBuf.push_back(uint8_t((data>>8) & 0x000f)); // DATA (11: 8)
147 fRawBuf.push_back(uint8_t((data>>12) & 0x000f)); // DATA (15:12)
148 fRawBuf.push_back(0); // send two filler zero's to ensure that
149 fRawBuf.push_back(0); // comma handlers are in ground state
150
151 return SndRaw(port, emsg);
152}
153
154//------------------------------------------+-----------------------------------
156
158{
159 Init();
160
161 fRawBuf.clear();
162 fRawBuf.push_back(kSymEsc); // ESC
163 fRawBuf.push_back(kSymEsc); // ESC
164
165 return SndRaw(port, emsg);
166}
167
168//------------------------------------------+-----------------------------------
170
172{
173 Init();
174
175 fRawBuf.clear();
176 PutRawEsc(kEcAttn); // <ATTN>
177 return SndRaw(port, emsg);
178}
179
180//------------------------------------------+-----------------------------------
182
184{
185 Init();
186
187 fRawBuf.clear();
188 PutRawEsc(kEcNak); // <NAK>
189 return SndRaw(port, emsg);
190}
191
192//------------------------------------------+-----------------------------------
194
196{
197 Init();
198
199 fRawBuf.clear();
200 PutRawEsc(kEcEop); // <EOP>
201 return SndRaw(port, emsg);
202}
203
204//------------------------------------------+-----------------------------------
206
207void RlinkPacketBufSnd::Dump(std::ostream& os, int ind, const char* text,
208 int detail) const
209{
210 RosFill bl(ind);
211 os << bl << (text?text:"--") << "RlinkPacketBufSnd @ " << this << endl;
212
213 os << bl << " fXonEscape: " << RosPrintf(fXonEscape) << endl;
214
215 size_t rawbufsize = fRawBuf.size();
216 os << bl << " fRawBuf(size): " << RosPrintf(rawbufsize,"d",4);
217 size_t ncol = max(1, (80-ind-4-6)/(2+1));
218 for (size_t i=0; i<rawbufsize; i++) {
219 if (i%ncol == 0) os << "\n" << bl << " " << RosPrintf(i,"d",4) << ": ";
220 os << RosPrintBvi(fRawBuf[i],16) << " ";
221 }
222 os << endl;
223
224 RlinkPacketBuf::Dump(os, ind, " ^", detail);
225
226 return;
227}
228
229//------------------------------------------+-----------------------------------
231
233{
234 size_t rawbufsize = fRawBuf.size();
235 int irc = port.Write(fRawBuf.data(), rawbufsize, emsg);
236 if (irc < 0) return false;
237 if (size_t(irc) != rawbufsize) {
238 emsg.Init("RlinkPacketBufSnd::SndRaw()", "failed to write all data");
239 return false;
240 }
241
242 return true;
243}
244
245} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
void Init(const std::string &meth, const std::string &text)
FIXME_docs.
Definition: RerrMsg.cpp:74
void Clear()
FIXME_docs.
Definition: RlinkCrc16.ipp:29
bool fXonEscape
escape XON/XOFF
std::vector< uint8_t > fRawBuf
raw data buffer
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.
bool SndNak(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
@ kStatNTxPktByt
Tx packet bytes send.
RlinkPacketBufSnd()
Default constructor.
bool SndOob(RlinkPort &port, uint16_t addr, uint16_t data, RerrMsg &emsg)
FIXME_docs.
bool SndKeep(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
void PutRawEsc(uint8_t ec)
FIXME_docs.
bool SndPacket(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
bool SndUnJam(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
bool SndAttn(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
bool SndRaw(RlinkPort &port, RerrMsg &emsg)
FIXME_docs.
static const uint8_t kEcXon
VHDL def ec_xon 100.
static const uint8_t kSymEsc
VHDL def escape 1100 1010.
size_t PktSize() const
FIXME_docs.
static const uint8_t kEcEsc
VHDL def ec_esc 111.
RlinkCrc16 fCrc
crc accumulator
static const uint8_t kEcSop
VHDL def ec_sop 000.
std::vector< uint8_t > fPktBuf
packet buffer
Rstats fStats
statistics
static const uint8_t kEcNak
VHDL def ec_nak 010.
static const uint8_t kEcAttn
VHDL def ec_attn 011.
uint32_t fFlags
request/response flags
static const uint8_t kEcXoff
VHDL def ec_xoff 101.
static const uint8_t kSymXon
VHDL def xon 0001 0001.
static const uint8_t kEcEop
VHDL def ec_eop 001.
static const uint8_t kSymXoff
VHDL def xoff 0001 0011.
void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
FIXME_docs.
Definition: RlinkPort.hpp:45
virtual int Write(const uint8_t *buf, size_t size, RerrMsg &emsg)
FIXME_docs.
Definition: RlinkPort.cpp:166
I/O appicator to generate fill characters.
Definition: RosFill.hpp:24
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
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
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47