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

Subversion Repositories w11

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

Go to most recent revision | Details | Compare with Previous | View Log

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