OpenCores
URL https://opencores.org/ocsvn/w11/w11/trunk

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.61/] [tools/] [src/] [librlink/] [RlinkConnect.cpp] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 25 wfjm
// $Id: RlinkConnect.cpp 575 2014-07-27 20:55:41Z mueller $
2 10 wfjm
//
3 25 wfjm
// Copyright 2011-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4 10 wfjm
//
5
// This program is free software; you may redistribute and/or modify it under
6
// the terms of the GNU General Public License as published by the Free
7
// Software Foundation, either version 2, or at your option any later version.
8
//
9
// This program is distributed in the hope that it will be useful, but
10
// WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
// or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
// for complete details.
13
// 
14
// Revision History: 
15
// Date         Rev Version  Comment
16 25 wfjm
// 2014-07-27   575   1.3.3  ExecPart(): increase packet tout from 5 to 15 sec
17 20 wfjm
// 2013-04-21   509   1.3.2  add SndAttn() method
18 19 wfjm
// 2013-03-01   493   1.3.1  add Server(Active..|SignalAttn)() methods
19
// 2013-02-23   492   1.3    use scoped_ptr for Port; Close allways allowed
20
//                           use RlinkContext, add Context(), Exec(..., cntx)
21
// 2013-02-22   491   1.2    use new RlogFile/RlogMsg interfaces
22
// 2013-02-03   481   1.1.2  use Rexception
23
// 2013-01-13   474   1.1.1  add PollAttn() method
24 12 wfjm
// 2011-04-25   380   1.1    use boost::(mutex&lock), implement Lockable IF
25
// 2011-04-22   379   1.0.1  add Lock(), Unlock(), lock connect in Exec()
26 10 wfjm
// 2011-04-02   375   1.0    Initial version
27
// 2011-01-15   356   0.1    First draft
28
// ---------------------------------------------------------------------------
29
 
30
/*!
31
  \file
32 25 wfjm
  \version $Id: RlinkConnect.cpp 575 2014-07-27 20:55:41Z mueller $
33 10 wfjm
  \brief   Implemenation of RlinkConnect.
34
*/
35
 
36
#include <iostream>
37
 
38 12 wfjm
#include "boost/thread/locks.hpp"
39
 
40 10 wfjm
#include "RlinkPortFactory.hpp"
41
#include "librtools/RosFill.hpp"
42
#include "librtools/RosPrintf.hpp"
43
#include "librtools/RosPrintBvi.hpp"
44 12 wfjm
#include "librtools/Rtools.hpp"
45 19 wfjm
#include "librtools/Rexception.hpp"
46
#include "librtools/RlogMsg.hpp"
47
#include "RlinkServer.hpp"
48 10 wfjm
 
49 19 wfjm
#include "RlinkConnect.hpp"
50
 
51 10 wfjm
using namespace std;
52
 
53
/*!
54
  \class Retro::RlinkConnect
55
  \brief FIXME_docs
56
*/
57
 
58 19 wfjm
// all method definitions in namespace Retro
59
namespace Retro {
60
 
61 10 wfjm
//------------------------------------------+-----------------------------------
62
//! Default constructor
63
 
64
RlinkConnect::RlinkConnect()
65 19 wfjm
  : fpPort(),
66
    fpServ(0),
67 10 wfjm
    fTxPkt(),
68
    fRxPkt(),
69 19 wfjm
    fContext(),
70 10 wfjm
    fAddrMap(),
71
    fStats(),
72
    fLogOpts(),
73 19 wfjm
    fspLog(new RlogFile(&cout, "<cout>")),
74
    fConnectMutex()
75 10 wfjm
{
76
  for (size_t i=0; i<8; i++) fSeqNumber[i] = 0;
77 12 wfjm
 
78
  // Statistic setup
79 10 wfjm
  fStats.Define(kStatNExec,     "NExec",     "Exec() calls");
80
  fStats.Define(kStatNSplitVol, "NSplitVol", "clist splits: Volatile");
81
  fStats.Define(kStatNExecPart, "NExecPart", "ExecPart() calls");
82
  fStats.Define(kStatNCmd,      "NCmd",      "commands executed");
83
  fStats.Define(kStatNRreg,     "NRreg",     "rreg commands");
84
  fStats.Define(kStatNRblk,     "NRblk",     "rblk commands");
85
  fStats.Define(kStatNWreg,     "NWreg",     "wreg commands");
86
  fStats.Define(kStatNWblk,     "NWblk",     "wblk commands");
87
  fStats.Define(kStatNStat,     "NStat",     "stat commands");
88
  fStats.Define(kStatNAttn,     "NAttn",     "attn commands");
89
  fStats.Define(kStatNInit,     "NInit",     "init commands");
90
  fStats.Define(kStatNRblkWord, "NRblkWord", "words rcvd with rblk");
91
  fStats.Define(kStatNWblkWord, "NWblkWord", "words send with wblk");
92
  fStats.Define(kStatNTxPktByt, "NTxPktByt", "Tx packet bytes send");
93
  fStats.Define(kStatNTxEsc,    "NTxEsc",    "Tx escapes");
94
  fStats.Define(kStatNRxPktByt, "NRxPktByt", "Rx packet bytes rcvd");
95
  fStats.Define(kStatNRxEsc,    "NRxEsc",    "Rx escapes");
96
  fStats.Define(kStatNRxAttn,   "NRxAttn",   "Rx ATTN commas seen");
97
  fStats.Define(kStatNRxIdle,   "NRxIdle",   "Rx IDLE commas seen");
98
  fStats.Define(kStatNRxDrop,   "NRxDrop",   "Rx bytes droped");
99
  fStats.Define(kStatNExpData,  "NExpData",  "Expect() for data defined");
100
  fStats.Define(kStatNExpStat,  "NExpStat",  "Expect() for stat defined");
101
  fStats.Define(kStatNChkData,  "NChkData",  "expect data failed");
102
  fStats.Define(kStatNChkStat,  "NChkStat",  "expect stat failed");
103
  fStats.Define(kStatNSndOob,   "NSndOob",   "SndOob() calls");
104
}
105
 
106
//------------------------------------------+-----------------------------------
107
//! Destructor
108
 
109
RlinkConnect::~RlinkConnect()
110
{
111 19 wfjm
  Close();
112 10 wfjm
}
113
 
114
//------------------------------------------+-----------------------------------
115
//! FIXME_docs
116
 
117
bool RlinkConnect::Open(const std::string& name, RerrMsg& emsg)
118
{
119 19 wfjm
  Close();
120 10 wfjm
 
121 19 wfjm
  fpPort.reset(RlinkPortFactory::Open(name, emsg));
122 10 wfjm
  if (!fpPort) return false;
123
 
124 19 wfjm
  fpPort->SetLogFile(fspLog);
125 10 wfjm
  fpPort->SetTraceLevel(fLogOpts.tracelevel);
126
  return true;
127
}
128
 
129
//------------------------------------------+-----------------------------------
130
//! FIXME_docs
131
 
132
void RlinkConnect::Close()
133
{
134 19 wfjm
  if (!fpPort) return;
135 10 wfjm
 
136 19 wfjm
  if (fpServ) fpServ->Stop();               // stop server in case still running
137
 
138
  if (fpPort->Url().FindOpt("keep")) {
139 10 wfjm
    RerrMsg emsg;
140 19 wfjm
    fTxPkt.SndKeep(fpPort.get(), emsg);
141 10 wfjm
  }
142
 
143 19 wfjm
  fpPort.reset();
144 10 wfjm
 
145
  return;
146
}
147
 
148
//------------------------------------------+-----------------------------------
149
//! FIXME_docs
150
 
151 19 wfjm
bool RlinkConnect::ServerActive() const
152
{
153
  return fpServ && fpServ->IsActive();
154
}
155
 
156
//------------------------------------------+-----------------------------------
157
//! FIXME_docs
158
 
159
bool RlinkConnect::ServerActiveInside() const
160
{
161
  return fpServ && fpServ->IsActiveInside();
162
}
163
 
164
//------------------------------------------+-----------------------------------
165
//! FIXME_docs
166
 
167
bool RlinkConnect::ServerActiveOutside() const
168
{
169
  return fpServ && fpServ->IsActiveOutside();
170
}
171
 
172
//------------------------------------------+-----------------------------------
173
//! FIXME_docs
174
 
175
void RlinkConnect::ServerSignalAttn()
176
{
177
  if (fpServ) fpServ->SignalAttn();
178
  return;
179
}
180
 
181
//------------------------------------------+-----------------------------------
182
//! FIXME_docs
183
 
184 12 wfjm
void RlinkConnect::lock()
185
{
186 19 wfjm
  fConnectMutex.lock();
187 12 wfjm
  return;
188
}
189
 
190
//------------------------------------------+-----------------------------------
191
//! FIXME_docs
192
 
193
bool RlinkConnect::try_lock()
194
{
195 19 wfjm
  return fConnectMutex.try_lock();
196 12 wfjm
}
197
 
198
//------------------------------------------+-----------------------------------
199
//! FIXME_docs
200
 
201
void RlinkConnect::unlock()
202
{
203 19 wfjm
  fConnectMutex.unlock();
204 12 wfjm
  return;
205
}
206
 
207
//------------------------------------------+-----------------------------------
208
//! FIXME_docs
209
 
210 19 wfjm
bool RlinkConnect::Exec(RlinkCommandList& clist, RlinkContext& cntx,
211
                        RerrMsg& emsg)
212 12 wfjm
{
213 10 wfjm
  if (clist.Size() == 0)
214 19 wfjm
    throw Rexception("RlinkConnect::Exec()", "Bad state: clist empty");
215 10 wfjm
  if (! IsOpen())
216 19 wfjm
    throw Rexception("RlinkConnect::Exec()", "Bad state: port not open");
217 10 wfjm
 
218 12 wfjm
  boost::lock_guard<RlinkConnect> lock(*this);
219
 
220 10 wfjm
  fStats.Inc(kStatNExec);
221
 
222
  size_t ibeg = 0;
223
  size_t size = clist.Size();
224
 
225
  for (size_t i=0; i<size; i++) {
226
    RlinkCommand& cmd = clist[i];
227
   if (!cmd.TestFlagAny(RlinkCommand::kFlagInit))
228 19 wfjm
     throw Rexception("RlinkConnect::Exec()",
229
                      "BugCheck: command not initialized");
230 10 wfjm
    if (cmd.Command() > RlinkCommand::kCmdInit)
231 19 wfjm
      throw Rexception("RlinkConnect::Exec()",
232
                       "BugCheck: invalid command code");
233
    // trap attn command when server running and outside server thread
234
    if (cmd.Command() == RlinkCommand::kCmdAttn && ServerActiveOutside())
235
      throw Rexception("RlinkConnect::Exec()",
236
                       "attn command not allowed outside avtice server");
237 22 wfjm
 
238 10 wfjm
    cmd.ClearFlagBit(RlinkCommand::kFlagSend   | RlinkCommand::kFlagDone |
239
                     RlinkCommand::kFlagPktBeg | RlinkCommand::kFlagPktEnd |
240
                     RlinkCommand::kFlagRecov  | RlinkCommand::kFlagResend |
241
                     RlinkCommand::kFlagErrNak | RlinkCommand::kFlagErrMiss |
242
                     RlinkCommand::kFlagErrCmd | RlinkCommand::kFlagErrCrc);
243
  }
244
 
245
  while (ibeg < size) {
246
    size_t iend = ibeg;
247
    for (size_t i=ibeg; i<size; i++) {
248
      iend = i;
249
      if (clist[i].TestFlagAll(RlinkCommand::kFlagVol)) {
250
        fStats.Inc(kStatNSplitVol);
251
        break;
252
      }
253
    }
254 19 wfjm
    bool rc = ExecPart(clist, ibeg, iend, emsg, cntx);
255 10 wfjm
    if (!rc) return rc;
256
    ibeg = iend+1;
257
  }
258
 
259
  bool checkseen = false;
260
  bool errorseen = false;
261
 
262
  for (size_t i=0; i<size; i++) {
263
    RlinkCommand& cmd = clist[i];
264
 
265 19 wfjm
    bool checkfound = cmd.TestFlagAny(RlinkCommand::kFlagChkStat |
266
                                      RlinkCommand::kFlagChkData);
267
    bool errorfound = cmd.TestFlagAny(RlinkCommand::kFlagErrNak |
268
                                      RlinkCommand::kFlagErrMiss |
269
                                      RlinkCommand::kFlagErrCmd |
270
                                      RlinkCommand::kFlagErrCrc);
271
    checkseen |= checkfound;
272
    errorseen |= errorfound;
273
    if (checkfound | errorfound) cntx.IncErrorCount();
274 10 wfjm
  }
275
 
276
  size_t loglevel = 3;
277
  if (checkseen) loglevel = 2;
278
  if (errorseen) loglevel = 1;
279 19 wfjm
  if (loglevel <= fLogOpts.printlevel) {
280
    RlogMsg lmsg(*fspLog);
281
    clist.Print(lmsg(), cntx, &AddrMap(), fLogOpts.baseaddr, fLogOpts.basedata,
282 10 wfjm
                fLogOpts.basestat);
283 19 wfjm
  }
284
  if (loglevel <= fLogOpts.dumplevel) {
285
    RlogMsg lmsg(*fspLog);
286
    clist.Dump(lmsg(), 0);
287
  }
288
 
289 10 wfjm
  return true;
290
}
291
 
292
//------------------------------------------+-----------------------------------
293
//! FIXME_docs
294
 
295 19 wfjm
bool RlinkConnect::Exec(RlinkCommandList& clist, RlinkContext& cntx)
296
{
297
  RerrMsg emsg;
298
  bool rc = Exec(clist, cntx, emsg);
299
  if (!rc) {
300
    RlogMsg lmsg(*fspLog, 'E');
301
    lmsg << emsg << endl;
302
    lmsg << "Dump of failed clist:" << endl;
303
    clist.Dump(lmsg(), 0);
304
  }
305
  return rc;
306
}
307
 
308
//------------------------------------------+-----------------------------------
309
//! FIXME_docs
310
 
311 10 wfjm
bool RlinkConnect::ExecPart(RlinkCommandList& clist, size_t ibeg, size_t iend,
312 19 wfjm
                            RerrMsg& emsg, RlinkContext& cntx)
313 10 wfjm
{
314
  if (ibeg<0 || ibeg>iend || iend>=clist.Size())
315 19 wfjm
    throw Rexception("RlinkConnect::ExecPart()",
316
                     "Bad args: ibeg or iend invalid");
317 10 wfjm
  if (!IsOpen())
318 19 wfjm
    throw Rexception("RlinkConnect::ExecPart()","Bad state: port not open");
319 10 wfjm
 
320
  fStats.Inc(kStatNExecPart);
321
 
322
  size_t nrcvtot = 0;
323
  fTxPkt.Init();
324
 
325
  for (size_t i=ibeg; i<=iend; i++) {
326
    RlinkCommand& cmd = clist[i];
327
    uint8_t   ccode = cmd.Command();
328
    size_t    ndata = cmd.BlockSize();
329
    uint16_t* pdata = cmd.BlockPointer();
330
 
331
    fStats.Inc(kStatNCmd);
332
 
333
    cmd.SetSeqNumber(fSeqNumber[ccode]++);
334
    cmd.ClearFlagBit(RlinkCommand::kFlagPktBeg | RlinkCommand::kFlagPktEnd);
335
 
336
    fTxPkt.PutWithCrc(cmd.Request());
337
 
338
    switch(ccode) {
339
      case RlinkCommand::kCmdRreg:
340
        fStats.Inc(kStatNRreg);
341
        cmd.SetRcvSize(1+2+1+1);            // rcv: cmd+data+stat+crc
342
        fTxPkt.PutWithCrc((uint8_t)cmd.Address());
343
        break;
344
 
345
      case RlinkCommand::kCmdRblk:
346
        fStats.Inc(kStatNRblk);
347
        fStats.Inc(kStatNRblkWord, (double) ndata);
348
        cmd.SetRcvSize(1+1+2*ndata+1+1);    // rcv: cmd+nblk+n*data+stat+crc
349
        fTxPkt.PutWithCrc((uint8_t)cmd.Address());
350
        fTxPkt.PutWithCrc((uint8_t)(ndata-1));
351
        break;
352
 
353
      case RlinkCommand::kCmdWreg:
354
        fStats.Inc(kStatNWreg);
355
        cmd.SetRcvSize(1+1+1);              // rcv: cmd+stat+crc
356
        fTxPkt.PutWithCrc((uint8_t)cmd.Address());
357
        fTxPkt.PutWithCrc(cmd.Data());
358
        break;
359
 
360
      case RlinkCommand::kCmdWblk:
361
        fStats.Inc(kStatNWblk);
362
        fStats.Inc(kStatNWblkWord, (double) ndata);
363
        cmd.SetRcvSize(1+1+1);              // rcv: cmd+stat+crc
364
        fTxPkt.PutWithCrc((uint8_t)cmd.Address());
365
        fTxPkt.PutWithCrc((uint8_t)(ndata-1));
366
        fTxPkt.PutCrc();
367
        for (size_t j=0; j<ndata; j++) fTxPkt.PutWithCrc(*pdata++);
368
        break;
369
 
370
      case RlinkCommand::kCmdStat:
371
        fStats.Inc(kStatNStat);
372
        cmd.SetRcvSize(1+1+2+1+1);          // rcv: cmd+ccmd+data+stat+crc
373
        break;
374
      case RlinkCommand::kCmdAttn:
375
        fStats.Inc(kStatNAttn);
376
        cmd.SetRcvSize(1+2+1+1);            // rcv: cmd+data+stat+crc
377
        break;
378
 
379
      case RlinkCommand::kCmdInit:
380
        fStats.Inc(kStatNInit);
381
        cmd.SetRcvSize(1+1+1);              // rcv: cmd+stat+crc
382
        fTxPkt.PutWithCrc((uint8_t)cmd.Address());
383
        fTxPkt.PutWithCrc(cmd.Data());
384
        break;
385
 
386
      default:
387 19 wfjm
        throw Rexception("RlinkConnect::Exec()", "BugCheck: invalid command");
388 10 wfjm
    }
389
 
390
    fTxPkt.PutCrc();
391
    cmd.SetFlagBit(RlinkCommand::kFlagSend);
392
    nrcvtot += cmd.RcvSize();
393
  }
394
 
395
  clist[ibeg].SetFlagBit(RlinkCommand::kFlagPktBeg);
396
  clist[iend].SetFlagBit(RlinkCommand::kFlagPktEnd);
397
 
398
  // FIXME_code: handle send fail properly;
399 19 wfjm
  if (!fTxPkt.SndPacket(fpPort.get(), emsg)) return false;
400 10 wfjm
  fStats.Inc(kStatNTxPktByt, double(fTxPkt.PktSize()));
401
  fStats.Inc(kStatNTxEsc   , double(fTxPkt.Nesc()));
402
 
403
  fRxPkt.Init();
404 19 wfjm
  // FIXME_code: parametrize timeout
405 25 wfjm
  if (!fRxPkt.RcvPacket(fpPort.get(), nrcvtot, 15.0, emsg)) return false;
406 19 wfjm
 
407
  // FIXME_code: handle timeout properly
408
  if (fRxPkt.TestFlag(RlinkPacketBuf::kFlagTout)) {
409
    emsg.Init("RlinkConnect::ExecPart", "timeout from RlinkPacketBuf");
410
    return false;
411
  }
412
 
413
  // if attn seen, signal to server
414
  if (fRxPkt.Nattn()) ServerSignalAttn();
415
 
416 10 wfjm
  fStats.Inc(kStatNRxPktByt, double(fRxPkt.PktSize()));
417
  fStats.Inc(kStatNRxEsc   , double(fRxPkt.Nesc()));
418
  fStats.Inc(kStatNRxAttn  , double(fRxPkt.Nattn()));
419
  fStats.Inc(kStatNRxIdle  , double(fRxPkt.Nidle()));
420
  fStats.Inc(kStatNRxDrop  , double(fRxPkt.Ndrop()));
421
 
422
  size_t ncmd = 0;
423 19 wfjm
  const char* etxt = 0;
424 10 wfjm
 
425
  for (size_t i=ibeg; i<=iend; i++) {
426
    RlinkCommand& cmd = clist[i];
427
    uint8_t   ccode = cmd.Command();
428
    size_t    ndata = cmd.BlockSize();
429
    uint16_t* pdata = cmd.BlockPointer();
430
 
431
    if (!fRxPkt.CheckSize(cmd.RcvSize())) {   // not enough data for cmd
432
      cmd.SetFlagBit(RlinkCommand::kFlagErrMiss);
433 19 wfjm
      etxt = "FlagErrMiss: not enough data for cmd";
434 10 wfjm
      break;
435
    }
436
 
437
    if (fRxPkt.Get8WithCrc() != cmd.Request()) { // command mismatch
438
      cmd.SetFlagBit(RlinkCommand::kFlagErrCmd);
439 19 wfjm
      etxt = "FlagErrCmd: command mismatch";
440 10 wfjm
      break;
441
    }
442
 
443
    // check length mismatch in rblk here (simpler than multi-level break)
444
    if (ccode == RlinkCommand::kCmdRblk) {
445
      if (fRxPkt.Get8WithCrc() != (uint8_t)(ndata-1)) {  // length mismatch
446
        cmd.SetFlagBit(RlinkCommand::kFlagErrCmd);
447 19 wfjm
        etxt = "FlagErrCmd: length mismatch";
448 10 wfjm
        break;
449
      }
450
    }
451
 
452
    switch(ccode) {
453
      case RlinkCommand::kCmdRreg:
454
        cmd.SetData(fRxPkt.Get16WithCrc());
455
        break;
456
 
457
      case RlinkCommand::kCmdRblk:
458
        // length was consumed and tested already before switch()..
459
        for (size_t j=0; j<ndata; j++) *pdata++ = fRxPkt.Get16WithCrc();
460
        break;
461
 
462
      case RlinkCommand::kCmdWreg:
463
      case RlinkCommand::kCmdWblk:
464
        break;
465
 
466
      case RlinkCommand::kCmdStat:
467
        cmd.SetStatRequest(fRxPkt.Get8WithCrc());
468
        cmd.SetData(fRxPkt.Get16WithCrc());
469
        break;
470
 
471
      case RlinkCommand::kCmdAttn:
472
        cmd.SetData(fRxPkt.Get16WithCrc());
473
        break;
474
 
475
      case RlinkCommand::kCmdInit:
476
        break;
477 19 wfjm
    } // switch(ccode)
478 10 wfjm
 
479
    cmd.SetStatus(fRxPkt.Get8WithCrc());
480
    if (!fRxPkt.CheckCrc()) {                 // crc mismatch
481
      cmd.SetFlagBit(RlinkCommand::kFlagErrCrc);
482
      //fStats.Inc(kStatNRxCcrc);
483 19 wfjm
      etxt = "FlagErrCrc: crc mismatch";
484 10 wfjm
      break;
485
    }
486
 
487
    // FIXME_code: proper wblk dcrc handling...
488
    if (ccode == RlinkCommand::kCmdWblk) {
489
      // FIXME_code: check for dcrc flag...
490
      if (false) {
491
        //fStats.Inc(kStatNRxDcrc);
492
        break;
493
      }
494
    }
495
 
496
    cmd.SetFlagBit(RlinkCommand::kFlagDone);
497
    ncmd += 1;
498
 
499 19 wfjm
    if (cmd.Expect()) {                     // expect object attached ?
500 10 wfjm
      RlinkCommandExpect& expect = *cmd.Expect();
501
      if (expect.DataIsChecked() ||
502
          expect.BlockValue().size()>0) fStats.Inc(kStatNExpData);
503
      if (expect.StatusIsChecked())     fStats.Inc(kStatNExpStat);
504
 
505
      if (ccode==RlinkCommand::kCmdRreg || ccode==RlinkCommand::kCmdStat ||
506
          ccode==RlinkCommand::kCmdAttn) {
507
        if (!expect.DataCheck(cmd.Data())) {
508
          fStats.Inc(kStatNChkData);
509
          cmd.SetFlagBit(RlinkCommand::kFlagChkData);
510
        }
511
      } else if (ccode==RlinkCommand::kCmdRblk) {
512
        size_t nerr = expect.BlockCheck(cmd.BlockPointer(), cmd.BlockSize());
513
        if (nerr != 0) {
514
          fStats.Inc(kStatNChkData);
515
          cmd.SetFlagBit(RlinkCommand::kFlagChkData);
516
        }
517
      }
518
      if (!expect.StatusCheck(cmd.Status())) {
519
        fStats.Inc(kStatNChkStat);
520
        cmd.SetFlagBit(RlinkCommand::kFlagChkStat);
521
      }
522 19 wfjm
 
523
    } else {                                // no expect, use context
524
      if (!cntx.StatusCheck(cmd.Status())) {
525
        fStats.Inc(kStatNChkStat);
526
        cmd.SetFlagBit(RlinkCommand::kFlagChkStat);
527
      }
528 10 wfjm
    }
529
 
530
  }
531
 
532
  // FIXME_code: add proper error handling...
533
  if (ncmd != iend-ibeg+1) {
534 19 wfjm
    if (etxt == 0) etxt = "not all commands processed";
535
    emsg.Init("RlinkConnect::ExecPart", etxt);
536 10 wfjm
    return false;
537
  }
538
 
539
  return true;
540
}
541
 
542
//------------------------------------------+-----------------------------------
543
//! FIXME_docs
544
 
545
double RlinkConnect::WaitAttn(double timeout, RerrMsg& emsg)
546
{
547 19 wfjm
  if (ServerActiveOutside())
548
    throw Rexception("RlinkConnect::WaitAttn()",
549
                     "not allowed outside avtice server");
550
 
551
  double rval = fRxPkt.WaitAttn(fpPort.get(), timeout, emsg);
552 10 wfjm
  fStats.Inc(kStatNRxAttn  , double(fRxPkt.Nattn()));
553
  fStats.Inc(kStatNRxIdle  , double(fRxPkt.Nidle()));
554
  fStats.Inc(kStatNRxDrop  , double(fRxPkt.Ndrop()));
555
  return rval;
556
}
557
 
558
//------------------------------------------+-----------------------------------
559
//! FIXME_docs
560
 
561 19 wfjm
int RlinkConnect::PollAttn(RerrMsg& emsg)
562
{
563
  if (ServerActiveOutside())
564
    throw Rexception("RlinkConnect::PollAttn()",
565
                     "not allowed outside avtice server");
566
 
567
  int rval = fRxPkt.PollAttn(fpPort.get(), emsg);
568
  fStats.Inc(kStatNRxAttn  , double(fRxPkt.Nattn()));
569
  fStats.Inc(kStatNRxIdle  , double(fRxPkt.Nidle()));
570
  fStats.Inc(kStatNRxDrop  , double(fRxPkt.Ndrop()));
571
  return rval;
572
}
573
 
574
//------------------------------------------+-----------------------------------
575
//! FIXME_docs
576
 
577 10 wfjm
bool RlinkConnect::SndOob(uint16_t addr, uint16_t data, RerrMsg& emsg)
578
{
579 20 wfjm
  boost::lock_guard<RlinkConnect> lock(*this);
580 10 wfjm
  fStats.Inc(kStatNSndOob);
581 19 wfjm
  return fTxPkt.SndOob(fpPort.get(), addr, data, emsg);
582 10 wfjm
}
583
 
584
//------------------------------------------+-----------------------------------
585
//! FIXME_docs
586
 
587 20 wfjm
bool RlinkConnect::SndAttn(RerrMsg& emsg)
588
{
589
  boost::lock_guard<RlinkConnect> lock(*this);
590
  return fTxPkt.SndAttn(fpPort.get(), emsg);
591
}
592
 
593
//------------------------------------------+-----------------------------------
594
//! FIXME_docs
595
 
596 19 wfjm
void RlinkConnect::SetLogOpts(const LogOpts& opts)
597 10 wfjm
{
598 19 wfjm
  if (opts.baseaddr!=2 && opts.baseaddr!=8 && opts.baseaddr!=16)
599
    throw Rexception("RlinkConnect::SetLogOpts()",
600
                     "Bad args: baseaddr != 2,8,16");
601
  if (opts.basedata!=2 && opts.basedata!=8 && opts.basedata!=16)
602
    throw Rexception("RlinkConnect::SetLogOpts()",
603
                     "Bad args: basedata != 2,8,16");
604
  if (opts.basestat!=2 && opts.basestat!=8 && opts.basestat!=16)
605
    throw Rexception("RlinkConnect::SetLogOpts()",
606
                     "Bad args: basestat != 2,8,16");
607
 
608
  fLogOpts = opts;
609
  if (fpPort) fpPort->SetTraceLevel(opts.tracelevel);
610
  return;
611 10 wfjm
}
612
 
613
//------------------------------------------+-----------------------------------
614
//! FIXME_docs
615
 
616 19 wfjm
bool RlinkConnect::LogOpen(const std::string& name)
617 10 wfjm
{
618 19 wfjm
  if (!fspLog->Open(name)) {
619
    fspLog->UseStream(&cout, "<cout>");
620
    return false;
621
  }
622
  return true;
623 10 wfjm
}
624
 
625
//------------------------------------------+-----------------------------------
626
//! FIXME_docs
627
 
628 19 wfjm
void RlinkConnect::LogUseStream(std::ostream* pstr, const std::string& name)
629 10 wfjm
{
630 19 wfjm
  fspLog->UseStream(pstr, name);
631 10 wfjm
  return;
632
}
633
 
634
//------------------------------------------+-----------------------------------
635
//! FIXME_docs
636
 
637
void RlinkConnect::Print(std::ostream& os) const
638
{
639
  os << "RlinkConnect::Print(std::ostream& os)" << endl;
640
  return;
641
}
642
 
643
//------------------------------------------+-----------------------------------
644
//! FIXME_docs
645
 
646
void RlinkConnect::Dump(std::ostream& os, int ind, const char* text) const
647
{
648
  RosFill bl(ind);
649
  os << bl << (text?text:"--") << "RlinkConnect @ " << this << endl;
650
 
651
  if (fpPort) {
652
    fpPort->Dump(os, ind+2, "fpPort: ");
653
  } else {
654 19 wfjm
    os << bl << "  fpPort:          " <<  fpPort.get() << endl;
655 10 wfjm
  }
656
 
657 19 wfjm
  os << bl << "  fpServ:          " << fpServ << endl;
658 10 wfjm
  os << bl << "  fSeqNumber:      ";
659
  for (size_t i=0; i<8; i++) os << RosPrintBvi(fSeqNumber[i],16) << " ";
660
  os << endl;
661
 
662
  fTxPkt.Dump(os, ind+2, "fTxPkt: ");
663
  fRxPkt.Dump(os, ind+2, "fRxPkt: ");
664 19 wfjm
  fContext.Dump(os, ind+2, "fContext: ");
665 10 wfjm
  fAddrMap.Dump(os, ind+2, "fAddrMap: ");
666
  fStats.Dump(os, ind+2, "fStats: ");
667 19 wfjm
  os << bl << "  fLogOpts.baseaddr   " << fLogOpts.baseaddr << endl;
668
  os << bl << "          .basedata   " << fLogOpts.basedata << endl;
669
  os << bl << "          .basestat   " << fLogOpts.basestat << endl;
670
  os << bl << "          .printlevel " << fLogOpts.printlevel << endl;
671
  os << bl << "          .dumplevel  " << fLogOpts.dumplevel << endl;
672
  os << bl << "          .tracelevel " << fLogOpts.tracelevel << endl;
673
  fspLog->Dump(os, ind+2, "fspLog: ");
674 10 wfjm
  return;
675
}
676
 
677 19 wfjm
} // end namespace Retro

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.