#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 }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|