#include <ThruputMeteringChannel.h>
The display can be customised with the "format" attribute. In the format string, the following characters will get expanded:
"Current" actually means the last measurement interval, which is 10 packets or 0.1s, whichever comes first.
PROBLEM: display only gets updated if there's traffic! (For example, a high pk/sec value might stay displayed even when the link becomes idle!)
Public Member Functions | |
| ThruputMeteringChannel (const char *name=NULL) | |
| ThruputMeteringChannel (const ThruputMeteringChannel &ch) | |
| virtual | ~ThruputMeteringChannel () |
| ThruputMeteringChannel & | operator= (const ThruputMeteringChannel &ch) |
| virtual cPolymorphic * | dup () const |
| virtual cPar & | addPar (const char *s) |
| virtual cPar & | addPar (cPar *p) |
| virtual bool | deliver (cMessage *msg, simtime_t at) |
Protected Member Functions | |
| void | beginNewInterval (simtime_t now) |
| void | updateDisplay () |
Protected Attributes | |
| cPar * | fmtp |
| int | batchSize |
| int | maxInterval |
| long | numPackets |
| double | numBits |
| simtime_t | intvlStartTime |
| simtime_t | intvlLastPkTime |
| unsigned long | intvlNumPackets |
| unsigned long | intvlNumBits |
| double | currentBitPerSec |
| double | currentPkPerSec |
|
|
Constructor. 00023 : cBasicChannel(name)
00024 {
00025 fmtp = NULL;
00026 batchSize = 10; // packets
00027 maxInterval = 0.1; // seconds
00028
00029 numPackets = 0;
00030 numBits = 0;
00031
00032 intvlStartTime = intvlLastPkTime = 0;
00033 intvlNumPackets = intvlNumBits = 0;
00034 }
|
|
|
Copy constructor. 00036 : cBasicChannel()
00037 {
00038 setName(ch.name());
00039 operator=(ch);
00040 cArray& parlist = _parList();
00041 fmtp = (cPar *)parlist.get("format");
00042 }
|
|
|
Destructor. 00045 {
00046 }
|
|
|
Redefined to add an extra attribute 00066 {
00067 cBasicChannel::addPar(p);
00068 const char *s = p->name();
00069 if (!opp_strcmp(s,"format"))
00070 fmtp = p;
00071 return *p;
00072 }
|
|
|
Redefined to add an extra attribute 00058 {
00059 cPar *p = &cBasicChannel::addPar(s);
00060 if (!opp_strcmp(s,"format"))
00061 fmtp = p;
00062 return *p;
00063 }
|
|
|
00097 {
00098 simtime_t duration = now - intvlStartTime;
00099
00100 // record measurements
00101 currentBitPerSec = intvlNumBits/duration;
00102 currentPkPerSec = intvlNumPackets/duration;
00103
00104 // restart counters
00105 intvlStartTime = now;
00106 intvlNumPackets = intvlNumBits = 0;
00107 }
|
|
||||||||||||
|
Performs bit error rate, delay and transmission time modelling. 00075 {
00076 bool ret = cBasicChannel::deliver(msg, t);
00077
00078 // count packets and bits
00079 numPackets++;
00080 numBits += msg->length();
00081
00082 // packet should be counted to new interval
00083 if (intvlNumPackets >= batchSize || t-intvlStartTime >= maxInterval)
00084 beginNewInterval(t);
00085
00086 intvlNumPackets++;
00087 intvlNumBits += msg->length();
00088 intvlLastPkTime = t;
00089
00090 // update display string
00091 updateDisplay();
00092
00093 return ret;
00094 }
|
|
|
Creates and returns an exact copy of this object. See cObject for more details. 00101 {return new ThruputMeteringChannel(*this);}
|
|
|
Assignment 00049 {
00050 if (this==&ch) return *this;
00051 cBasicChannel::operator=(ch);
00052 numPackets = ch.numPackets;
00053 numBits = ch.numBits;
00054 return *this;
00055 }
|
|
|
00110 {
00111 // retrieve format string
00112 const char *fmt = fmtp ? fmtp->stringValue() : "B";
00113
00114 // produce label, based on format string
00115 char buf[200];
00116 char *p = buf;
00117 simtime_t tt = transmissionFinishes();
00118 if (tt==0) tt = simulation.simTime();
00119 double bps = (tt==0) ? 0 : numBits/tt;
00120 double bytes;
00121 for (const char *fp = fmt; *fp && buf+200-p>20; fp++)
00122 {
00123 switch (*fp)
00124 {
00125 case 'N': // number of packets
00126 p += sprintf(p, "%ld", numPackets);
00127 break;
00128 case 'V': // volume (in bytes)
00129 bytes = floor(numBits/8);
00130 if (bytes<1024)
00131 p += sprintf(p, "%gB", bytes);
00132 else if (bytes<1024*1024)
00133 p += sprintf(p, "%.3gKB", bytes/1024);
00134 else
00135 p += sprintf(p, "%.3gMB", bytes/1024/1024);
00136 break;
00137
00138 case 'p': // current packet/sec
00139 p += sprintf(p, "%.3gpps", currentPkPerSec);
00140 break;
00141 case 'b': // current bandwidth
00142 if (currentBitPerSec<1000000)
00143 p += sprintf(p, "%.3gk", currentBitPerSec/1000);
00144 else
00145 p += sprintf(p, "%.3gM", currentBitPerSec/1000000);
00146 break;
00147 case 'u': // current channel utilization (%)
00148 if (datarate()==0)
00149 p += sprintf(p, "n/a");
00150 else
00151 p += sprintf(p, "%.3g%%", currentBitPerSec/datarate()*100.0);
00152 break;
00153
00154 case 'P': // average packet/sec on [0,now)
00155 p += sprintf(p, "%.3gpps", tt==0 ? 0 : numPackets/tt);
00156 break;
00157 case 'B': // average bandwidth on [0,now)
00158 if (bps<1000000)
00159 p += sprintf(p, "%.3gk", bps/1000);
00160 else
00161 p += sprintf(p, "%.3gM", bps/1000000);
00162 break;
00163 case 'U': // average channel utilization (%) on [0,now)
00164 if (datarate()==0)
00165 p += sprintf(p, "n/a");
00166 else
00167 p += sprintf(p, "%.3g%%", bps/datarate()*100.0);
00168 break;
00169 default:
00170 *p++ = *fp;
00171 }
00172 }
00173 *p = '\0';
00174
00175 // display label
00176 fromGate()->displayString().setTagArg("t", 0, buf);
00177 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1.4.1