ThruputMeteringChannel.cc

Go to the documentation of this file.
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