w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
RtclRlinkPort.cpp
Go to the documentation of this file.
1// $Id: RtclRlinkPort.cpp 1175 2019-06-30 06:13:17Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2019-06-29 1175 1.4.6 DoRaw{Read,Rblk}(): add missing OptValid() call
8// 2019-06-07 1160 1.4.5 use RtclStats::Exec()
9// 2019-02-23 1114 1.4.4 use std::bind instead of lambda
10// 2018-12-22 1091 1.4.3 M_Open(): drop move() (-Wpessimizing-move fix)
11// 2018-12-18 1089 1.4.2 use c++ style casts
12// 2018-12-15 1082 1.4.1 use lambda instead of boost::bind
13// 2018-12-08 1079 1.4 use ref not ptr for RlinkPort
14// 2018-12-01 1076 1.3 use unique_ptr
15// 2017-04-29 888 1.2 LogFileName(): returns now const std::string&
16// drop M_rawio; add M_rawread,M_rawrblk,M_rawwblk
17// 2017-04-02 865 1.1.1 M_dump: use GetArgsDump and Dump detail
18// 2017-02-19 853 1.1 use Rtime
19// 2015-01-09 632 1.0.4 add M_get, M_set, remove M_config
20// 2014-08-22 584 1.0.3 use nullptr
21// 2013-02-23 492 1.0.2 use RlogFile.Name();
22// 2013-02-22 491 1.0.1 use new RlogFile/RlogMsg interfaces
23// 2013-01-27 478 1.0 Initial version
24// ---------------------------------------------------------------------------
25
30#include <ctype.h>
31
32#include <iostream>
33#include <functional>
34
35#include "librtcltools/Rtcl.hpp"
42
43#include "RtclRlinkPort.hpp"
44
45using namespace std;
46using namespace std::placeholders;
47
53// all method definitions in namespace Retro
54namespace Retro {
55
56//------------------------------------------+-----------------------------------
58
59RtclRlinkPort::RtclRlinkPort(Tcl_Interp* interp, const char* name)
60 : RtclProxyBase("RlinkPort"),
61 fupObj(),
62 fspLog(new RlogFile(&cout)),
63 fTraceLevel(0),
64 fErrCnt(0),
65 fGets(),
66 fSets()
67{
68 CreateObjectCmd(interp, name);
69 AddMeth("open", bind(&RtclRlinkPort::M_open, this, _1));
70 AddMeth("close", bind(&RtclRlinkPort::M_close, this, _1));
71 AddMeth("errcnt", bind(&RtclRlinkPort::M_errcnt, this, _1));
72 AddMeth("rawread", bind(&RtclRlinkPort::M_rawread, this, _1));
73 AddMeth("rawrblk", bind(&RtclRlinkPort::M_rawrblk, this, _1));
74 AddMeth("rawwblk", bind(&RtclRlinkPort::M_rawwblk, this, _1));
75 AddMeth("stats", bind(&RtclRlinkPort::M_stats, this, _1));
76 AddMeth("log", bind(&RtclRlinkPort::M_log, this, _1));
77 AddMeth("dump", bind(&RtclRlinkPort::M_dump, this, _1));
78 AddMeth("get", bind(&RtclRlinkPort::M_get, this, _1));
79 AddMeth("set", bind(&RtclRlinkPort::M_set, this, _1));
80 AddMeth("$default", bind(&RtclRlinkPort::M_default, this, _1));
81
83}
84
85//------------------------------------------+-----------------------------------
87
89{}
90
91//------------------------------------------+-----------------------------------
93
95{
96 string path;
97
98 if (!args.GetArg("?path", path)) return kERR;
99 if (!args.AllDone()) return kERR;
100
101 RerrMsg emsg;
102 if (args.NOptMiss() == 0) { // open path
103 fupObj = RlinkPortFactory::Open(path, emsg);
104 SetupGetSet();
105 if (!fupObj) return args.Quit(emsg);
106 fupObj->SetLogFile(fspLog);
107 fupObj->SetTraceLevel(fTraceLevel);
108 } else { // open
109 string name = (fupObj && fupObj->IsOpen()) ? fupObj->Url().Url() : string();
110 args.SetResult(name);
111 }
112 return kOK;
113}
114
115//------------------------------------------+-----------------------------------
117
119{
120 if (!args.AllDone()) return kERR;
121 if (!TestPort(args, false)) return kERR;
122 fupObj.reset();
123 SetupGetSet();
124 return kOK;
125}
126
127//------------------------------------------+-----------------------------------
129
131{
132 static RtclNameSet optset("-clear");
133 string opt;
134 bool fclear = false;
135
136 while (args.NextOpt(opt, optset)) {
137 if (opt == "-clear") fclear = true;
138 }
139 if (!args.AllDone()) return kERR;
140
141 args.SetResult(int(fErrCnt));
142 if (fclear) fErrCnt = 0;
143
144 return kOK;
145}
146
147//------------------------------------------+-----------------------------------
149
151{
152 if (!TestPort(args)) return kERR;
153 return DoRawRead(args, *fupObj);
154}
155
156//------------------------------------------+-----------------------------------
158
160{
161 if (!TestPort(args)) return kERR;
162 return DoRawRblk(args, *fupObj, fErrCnt);
163}
164
165//------------------------------------------+-----------------------------------
167
169{
170 if (!TestPort(args)) return kERR;
171 return DoRawWblk(args, *fupObj);
172}
173
174//------------------------------------------+-----------------------------------
176
178{
180
181 if (!TestPort(args, false)) return kERR;
182 if (!RtclStats::GetArgs(args, cntx)) return kERR;
183 if (!RtclStats::Exec(args, cntx, fupObj->Stats())) return kERR;
184 return kOK;
185}
186
187//------------------------------------------+-----------------------------------
189
191{
192 string msg;
193 if (!args.GetArg("msg", msg)) return kERR;
194 if (!args.AllDone()) return kERR;
195 if (fTraceLevel != 0) fspLog->Write(string("# ") + msg);
196 return kOK;
197}
198
199//------------------------------------------+-----------------------------------
201
203{
204 int detail=0;
205 if (!GetArgsDump(args, detail)) return kERR;
206 if (!args.AllDone()) return kERR;
207 if (!TestPort(args, false)) return kERR;
208
209 ostringstream sos;
210 fupObj->Dump(sos, 0, "", 0);
211 args.SetResult(sos);
212 return kOK;
213}
214
215//------------------------------------------+-----------------------------------
217
219{
220 return fGets.M_get(args);
221}
222
223//------------------------------------------+-----------------------------------
225
227{
228 return fSets.M_set(args);
229}
230
231//------------------------------------------+-----------------------------------
233
235{
236 if (!args.AllDone()) return kERR;
237 ostringstream sos;
238
239 sos << "logfile: " << fspLog->Name()
240 << " tracelevel " << fTraceLevel;
241
242 args.AppendResultLines(sos);
243 return kOK;
244}
245
246//------------------------------------------+-----------------------------------
248
250{
251 fGets.Clear();
252 fSets.Clear();
253
254 fGets.Add<const string&> ("logfile",
255 bind(&RtclRlinkPort::LogFileName, this));
256 fSets.Add<const string&> ("logfile",
257 bind(&RtclRlinkPort::SetLogFileName, this, _1));
258
259 if (!fupObj) return;
260 fGets.Add<uint32_t> ("tracelevel",
261 bind(&RlinkPort::TraceLevel, fupObj.get()));
262 fSets.Add<uint32_t> ("tracelevel",
263 bind(&RlinkPort::SetTraceLevel, fupObj.get(), _1));
264}
265
266//------------------------------------------+-----------------------------------
268
269bool RtclRlinkPort::TestPort(RtclArgs& args, bool testopen)
270{
271 if (fupObj && (!testopen || fupObj->IsOpen())) return true;
272 args.AppendResult("-E: port not open", nullptr);
273 return false;
274}
275
276//------------------------------------------+-----------------------------------
278
279void RtclRlinkPort::SetLogFileName(const std::string& name)
280{
281 RerrMsg emsg;
282 if (!fspLog->Open(name, emsg)) {
283 fspLog->UseStream(&cout);
284 throw Rexception("RtclRlinkPort::SetLogFile",
285 emsg.Text() + "', using stdout");
286 }
287 return;
288}
289
290//------------------------------------------+-----------------------------------
292
293const std::string& RtclRlinkPort::LogFileName() const
294{
295 return fspLog->Name();
296}
297
298//------------------------------------------+-----------------------------------
300
302{
303 int32_t rsize;
304 string rvname;
305 vector<uint8_t> rdata;
306 double timeout = 1.;
307
308 if (!args.GetArg("bsize", rsize, 1, 4096)) return kERR;
309 if (!args.GetArg("varData", rvname)) return kERR;
310
311 static RtclNameSet optset("-timeout");
312 string opt;
313 while (args.NextOpt(opt, optset)) {
314 if (opt == "-timeout") { // -timeout tsec ------------------
315 if (!args.GetArg("tsec", timeout, 0.)) return kERR;
316 }
317 }
318 if (!args.OptValid()) return kERR;
319
320 RerrMsg emsg;
321 Rtime tused;
322 rdata.resize(rsize);
323
324 int irc = port.RawRead(rdata.data(), rdata.size(), false, Rtime(timeout),
325 tused, emsg);
326
327 if (irc == RlinkPort::kEof) return args.Quit("-E: RawRead EOF");
328 if (irc == RlinkPort::kTout) return args.Quit("-E: RawRead timeout");
329 if (irc < 0) return args.Quit(emsg);
330
331 rdata.resize(irc);
332
333 RtclOPtr pres(Rtcl::NewListIntObj(rdata));
334 if(!Rtcl::SetVar(args.Interp(), rvname, pres)) return kERR;
335
336 args.SetResult(double(tused));
337
338 return kOK;
339}
340
341//------------------------------------------+-----------------------------------
343
344int RtclRlinkPort::DoRawRblk(RtclArgs& args, RlinkPort& port, size_t& errcnt)
345{
346 int32_t rsize;
347 string rvname;
348 vector<uint8_t> rdata;
349 vector<uint8_t> edata;
350 vector<uint8_t> emask;
351 double timeout = 1.;
352
353 if (!args.GetArg("bsize", rsize, 1, 4096)) return kERR;
354 if (!args.GetArg("??varData", rvname)) return kERR;
355
356 static RtclNameSet optset("-edata|-timeout");
357 string opt;
358 while (args.NextOpt(opt, optset)) {
359 if (opt == "-edata") { // -edata data ?mask --------------
360 if (!args.GetArg("data", edata, 0, rsize)) return kERR;
361 if (!args.GetArg("??mask", emask, 0, rsize)) return kERR;
362 } else if (opt == "-timeout") { // -timeout tsec ------------------
363 if (!args.GetArg("tsec", timeout, 0.)) return kERR;
364 }
365 }
366 if (!args.OptValid()) return kERR;
367
368 RerrMsg emsg;
369 Rtime tused;
370 rdata.resize(rsize);
371
372 int irc = port.RawRead(rdata.data(), rdata.size(), true, Rtime(timeout),
373 tused, emsg);
374 if (irc == RlinkPort::kEof) return args.Quit("-E: RawRead EOF");
375 if (irc == RlinkPort::kTout) return args.Quit("-E: RawRead timeout");
376 if (irc < 0) return args.Quit(emsg);
377
378 if (rvname.length()) {
379 RtclOPtr pres(Rtcl::NewListIntObj(rdata));
380 if(!Rtcl::SetVar(args.Interp(), rvname, pres)) return kERR;
381 }
382 if (edata.size()) {
383 size_t nerr=0;
384 for (size_t i=0; i<rdata.size(); i++) {
385 if (i >= edata.size()) break;
386 uint8_t eval = edata[i];
387 uint8_t emsk = (i < emask.size()) ? emask[i] : 0x00;
388 if ((rdata[i]|emsk) != (eval|emsk)) nerr += 1;
389 }
390 if (nerr) errcnt += 1;
391 }
392 args.SetResult(double(tused));
393
394 return kOK;
395}
396
397//------------------------------------------+-----------------------------------
399
401{
402 vector<uint8_t> wdata;
403 if (!args.GetArg("data", wdata, 1, 4096)) return kERR;
404
405 RerrMsg emsg;
406 int irc = port.RawWrite(wdata.data(), wdata.size(), emsg);
407 if (irc != int(wdata.size())) return args.Quit(emsg);
408
409 return kOK;
410}
411
412
413} // 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
static RlinkPort::port_uptr_t Open(const std::string &url, RerrMsg &emsg)
FIXME_docs.
FIXME_docs.
Definition: RlinkPort.hpp:45
int RawRead(uint8_t *buf, size_t size, bool exactsize, const Rtime &timeout, Rtime &tused, RerrMsg &emsg)
FIXME_docs.
Definition: RlinkPort.cpp:249
int RawWrite(const uint8_t *buf, size_t size, RerrMsg &emsg)
FIXME_docs.
Definition: RlinkPort.cpp:279
static const int kEof
return code: end-of-file
Definition: RlinkPort.hpp:86
void SetTraceLevel(uint32_t level)
FIXME_docs.
Definition: RlinkPort.ipp:76
static const int kTout
return code: time out
Definition: RlinkPort.hpp:87
uint32_t TraceLevel() const
FIXME_docs.
Definition: RlinkPort.ipp:85
FIXME_docs.
Definition: RlogFile.hpp:34
FIXME_docs.
Definition: RtclArgs.hpp:41
bool NextOpt(std::string &val)
FIXME_docs.
Definition: RtclArgs.cpp:368
void AppendResultLines(const std::string &str)
FIXME_docs.
Definition: RtclArgs.cpp:484
bool GetArg(const char *name, Tcl_Obj *&pval)
FIXME_docs.
Definition: RtclArgs.cpp:114
void AppendResult(const char *str,...)
FIXME_docs.
Definition: RtclArgs.cpp:471
bool OptValid() const
FIXME_docs.
Definition: RtclArgs.ipp:52
int Quit(const std::string &str)
FIXME_docs.
Definition: RtclArgs.ipp:157
void SetResult(const std::string &str)
FIXME_docs.
Definition: RtclArgs.ipp:76
size_t NOptMiss() const
FIXME_docs.
Definition: RtclArgs.ipp:68
Tcl_Interp * Interp() const
FIXME_docs.
Definition: RtclArgs.ipp:28
bool AllDone()
FIXME_docs.
Definition: RtclArgs.cpp:447
void AddMeth(const std::string &name, methfo_t &&methfo)
FIXME_docs.
static const int kOK
Definition: RtclCmdBase.hpp:54
bool GetArgsDump(RtclArgs &args, int &detail)
FIXME_docs.
static const int kERR
Definition: RtclCmdBase.hpp:55
int M_get(RtclArgs &args)
FIXME_docs.
Definition: RtclGetList.cpp:73
void Add(const std::string &name, get_uptr_t &&upget)
FIXME_docs.
Definition: RtclGetList.cpp:52
void Clear()
FIXME_docs.
Definition: RtclGetList.cpp:64
Implemenation (inline) of RtclOPtr.
Definition: RtclOPtr.hpp:23
void CreateObjectCmd(Tcl_Interp *interp, const char *name)
FIXME_docs.
int M_errcnt(RtclArgs &args)
FIXME_docs.
int M_dump(RtclArgs &args)
FIXME_docs.
int M_log(RtclArgs &args)
FIXME_docs.
int M_rawread(RtclArgs &args)
FIXME_docs.
static int DoRawWblk(RtclArgs &args, RlinkPort &port)
FIXME_docs.
int M_open(RtclArgs &args)
FIXME_docs.
const std::string & LogFileName() const
FIXME_docs.
bool TestPort(RtclArgs &args, bool testopen=true)
FIXME_docs.
static int DoRawRblk(RtclArgs &args, RlinkPort &port, size_t &errcnt)
FIXME_docs.
int M_default(RtclArgs &args)
FIXME_docs.
int M_rawrblk(RtclArgs &args)
FIXME_docs.
int M_rawwblk(RtclArgs &args)
FIXME_docs.
RlinkPort::port_uptr_t fupObj
uptr to managed port
size_t fErrCnt
error count
RtclRlinkPort(Tcl_Interp *interp, const char *name)
Default constructor.
~RtclRlinkPort()
Destructor.
std::shared_ptr< RlogFile > fspLog
port log file
int M_close(RtclArgs &args)
FIXME_docs.
int M_stats(RtclArgs &args)
FIXME_docs.
void SetupGetSet()
FIXME_docs.
static int DoRawRead(RtclArgs &args, RlinkPort &port)
FIXME_docs.
int M_get(RtclArgs &args)
FIXME_docs.
uint32_t fTraceLevel
0=off,1=buf,2=char
int M_set(RtclArgs &args)
FIXME_docs.
void SetLogFileName(const std::string &name)
FIXME_docs.
void Add(const std::string &name, set_uptr_t &&upset)
FIXME_docs.
Definition: RtclSetList.cpp:52
void Clear()
FIXME_docs.
Definition: RtclSetList.cpp:64
int M_set(RtclArgs &args)
FIXME_docs.
Definition: RtclSetList.cpp:73
static bool Exec(RtclArgs &args, const Context &cntx, Rstats &stats)
FIXME_docs.
Definition: RtclStats.cpp:75
static bool GetArgs(RtclArgs &args, Context &cntx)
FIXME_docs.
Definition: RtclStats.cpp:37
FIXME_docs.
Definition: Rtime.hpp:25
bool SetVar(Tcl_Interp *interp, const std::string &varname, Tcl_Obj *pobj)
Tcl_Obj * NewListIntObj(const uint8_t *data, size_t size)
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47