|
INET Framework for OMNeT++/OMNEST
|
00001 //FIXME to be updated and enabled again 00002 #if 0//XXX 00003 00004 // 00005 // Copyright (C) 2005 Andras Varga 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // This program is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU Lesser General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public License 00018 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00019 // 00020 00021 #include "ThruputMeteringChannel.h" 00022 00023 Register_Class(ThruputMeteringChannel); 00024 00025 ThruputMeteringChannel::ThruputMeteringChannel(const char *name) : cDatarateChannel(name) 00026 { 00027 fmtp = NULL; 00028 batchSize = 10; // packets 00029 maxInterval = 0.1; // seconds 00030 00031 numPackets = 0; 00032 numBits = 0; 00033 00034 intvlStartTime = intvlLastPkTime = 0; 00035 intvlNumPackets = intvlNumBits = 0; 00036 } 00037 00038 ThruputMeteringChannel::ThruputMeteringChannel(const ThruputMeteringChannel& ch) : cDatarateChannel() 00039 { 00040 setName(ch.getName()); 00041 operator=(ch); 00042 cArray& parlist = _parList(); 00043 fmtp = (cPar *)parlist.get("format"); 00044 } 00045 00046 ThruputMeteringChannel::~ThruputMeteringChannel() 00047 { 00048 } 00049 00050 ThruputMeteringChannel& ThruputMeteringChannel::operator=(const ThruputMeteringChannel& ch) 00051 { 00052 if (this==&ch) return *this; 00053 cDatarateChannel::operator=(ch); 00054 numPackets = ch.numPackets; 00055 numBits = ch.numBits; 00056 return *this; 00057 } 00058 00059 cPar& ThruputMeteringChannel::addPar(const char *s) 00060 { 00061 cPar *p = &cDatarateChannel::addPar(s); 00062 if (!opp_strcmp(s,"format")) 00063 fmtp = p; 00064 return *p; 00065 } 00066 00067 cPar& ThruputMeteringChannel::addPar(cPar *p) 00068 { 00069 cDatarateChannel::addPar(p); 00070 const char *s = p->getName(); 00071 if (!opp_strcmp(s,"format")) 00072 fmtp = p; 00073 return *p; 00074 } 00075 00076 bool ThruputMeteringChannel::deliver(cMessage *msg, simtime_t t) 00077 { 00078 bool ret = cDatarateChannel::deliver(msg, t); 00079 00080 // count packets and bits 00081 numPackets++; 00082 numBits += msg->getBitLength(); 00083 00084 // packet should be counted to new interval 00085 if (intvlNumPackets >= batchSize || t-intvlStartTime >= maxInterval) 00086 beginNewInterval(t); 00087 00088 intvlNumPackets++; 00089 intvlNumBits += msg->getBitLength(); 00090 intvlLastPkTime = t; 00091 00092 // update display string 00093 updateDisplay(); 00094 00095 return ret; 00096 } 00097 00098 void ThruputMeteringChannel::beginNewInterval(simtime_t now) 00099 { 00100 simtime_t duration = now - intvlStartTime; 00101 00102 // record measurements 00103 currentBitPerSec = intvlNumBits/duration; 00104 currentPkPerSec = intvlNumPackets/duration; 00105 00106 // restart counters 00107 intvlStartTime = now; 00108 intvlNumPackets = intvlNumBits = 0; 00109 } 00110 00111 void ThruputMeteringChannel::updateDisplay() 00112 { 00113 // retrieve format string 00114 const char *fmt = fmtp ? fmtp->stringValue() : "B"; 00115 00116 // produce label, based on format string 00117 char buf[200]; 00118 char *p = buf; 00119 simtime_t tt = getTransmissionFinishTime(); 00120 if (tt==0) tt = simTime(); 00121 double bps = (tt==0) ? 0 : numBits/tt; 00122 double bytes; 00123 for (const char *fp = fmt; *fp && buf+200-p>20; fp++) 00124 { 00125 switch (*fp) 00126 { 00127 case 'N': // number of packets 00128 p += sprintf(p, "%ld", numPackets); 00129 break; 00130 case 'V': // volume (in bytes) 00131 bytes = floor(numBits/8); 00132 if (bytes<1024) 00133 p += sprintf(p, "%gB", bytes); 00134 else if (bytes<1024*1024) 00135 p += sprintf(p, "%.3gKB", bytes/1024); 00136 else 00137 p += sprintf(p, "%.3gMB", bytes/1024/1024); 00138 break; 00139 00140 case 'p': // current packet/sec 00141 p += sprintf(p, "%.3gpps", currentPkPerSec); 00142 break; 00143 case 'b': // current bandwidth 00144 if (currentBitPerSec<1000000) 00145 p += sprintf(p, "%.3gk", currentBitPerSec/1000); 00146 else 00147 p += sprintf(p, "%.3gM", currentBitPerSec/1000000); 00148 break; 00149 case 'u': // current channel utilization (%) 00150 if (getDatarate()==0) 00151 p += sprintf(p, "n/a"); 00152 else 00153 p += sprintf(p, "%.3g%%", currentBitPerSec/getDatarate()*100.0); 00154 break; 00155 00156 case 'P': // average packet/sec on [0,now) 00157 p += sprintf(p, "%.3gpps", tt==0 ? 0 : numPackets/tt); 00158 break; 00159 case 'B': // average bandwidth on [0,now) 00160 if (bps<1000000) 00161 p += sprintf(p, "%.3gk", bps/1000); 00162 else 00163 p += sprintf(p, "%.3gM", bps/1000000); 00164 break; 00165 case 'U': // average channel utilization (%) on [0,now) 00166 if (getDatarate()==0) 00167 p += sprintf(p, "n/a"); 00168 else 00169 p += sprintf(p, "%.3g%%", bps/getDatarate()*100.0); 00170 break; 00171 default: 00172 *p++ = *fp; 00173 } 00174 } 00175 *p = '\0'; 00176 00177 // display label 00178 getSourceGate()->getDisplayString().setTagArg("t", 0, buf); 00179 } 00180 00181 #endif