User Manual, Developers Guide and API Documentation

TrafficEstimation_mean.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiMeMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2011
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 5, D-52074 Aachen, Germany
00009  * phone: ++49-241-80-27910,
00010  * fax: ++49-241-80-22242
00011  * email: info@openwns.org
00012  * www: http://www.openwns.org
00013  * _____________________________________________________________________________
00014  *
00015  * openWNS is free software; you can redistribute it and/or modify it under the
00016  * terms of the GNU Lesser General Public License version 2 as published by the
00017  * Free Software Foundation;
00018  *
00019  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00020  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00021  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00022  * details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026  *
00027  ******************************************************************************/
00028 
00029 #include <WIMEMAC/upperMAC/TrafficEstimation_mean.hpp>
00030 
00031 using namespace wimemac::upperMAC;
00032 
00033 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00034     wimemac::upperMAC::TrafficEstimation_mean,
00035     wns::ldk::FunctionalUnit,
00036     "wimemac.upperMAC.TrafficEstimation_mean",
00037     wns::ldk::FUNConfigCreator);
00038 
00039 
00040 TrafficEstimation_mean::TrafficEstimation_mean(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) :
00041     wns::ldk::fu::Plain<TrafficEstimation_mean, wns::ldk::EmptyCommand>(fun),
00042     managerName(config.get<std::string>("managerName")),
00043     logger(config.get("logger")),
00044     averageOverSFs(config.get<int>("averageOverSFs")),
00045     datathroughputProbe(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()), "wimemac.traffic.incoming.throughput")),
00046     bitsPerSF(0)
00047 {
00048     trafficEstimationConfig.CompoundspSF = config.get<int>("CompoundspSF");
00049     trafficEstimationConfig.BitspSF = config.get<int>("BitspSF");
00050     trafficEstimationConfig.MaxCompoundSize = config.get<int>("MaxCompoundSize");
00051     trafficEstimationConfig.overWriteEstimation = config.get<bool>("overWriteEstimation");
00052 
00053     friends.keyReader = fun->getProxy()->getCommandReader("upperConvergence");
00054     MESSAGE_SINGLE(NORMAL, this->logger, "Created instance of TrafficEstimation_mean");
00055 
00056     measuringSince = wns::simulator::getEventScheduler()->getTime();
00057 }
00058 
00059 
00060 TrafficEstimation_mean::~TrafficEstimation_mean()
00061 {
00062 
00063 }
00064 
00065 void
00066 TrafficEstimation_mean::onFUNCreated()
00067 {
00068     friends.manager = getFUN()->findFriend<wimemac::lowerMAC::IManagerServices*>(managerName);
00069     scheduler = wns::simulator::getEventScheduler();
00070 
00071     wns::simulator::Time SFDuration = 65.536E-3;
00072     startPeriodicTimeout(SFDuration, SFDuration);
00073 }
00074 
00075 bool
00076 TrafficEstimation_mean::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00077 {
00078     // Accept everytime to estimate the traffic correctly
00079     return true;
00080 }
00081 
00082 
00083 void
00084 TrafficEstimation_mean::doSendData(const wns::ldk::CompoundPtr& compound)
00085 {
00086     wns::ldk::CommandPool* commandPool = compound->getCommandPool();
00087     dll::UpperCommand* unicastcommand =
00088     friends.keyReader->readCommand<dll::UpperCommand>(commandPool);
00089     wns::service::dll::UnicastAddress currentAddress = unicastcommand->peer.targetMACAddress;
00090 
00091     if (windowedTrafficPerAddress.find(currentAddress) == windowedTrafficPerAddress.end())//current address is a new address
00092     {
00093         //wns::events::scheduler::Callable call = boost::bind(&TrafficEstimation_mean::QueueEval, this, currentAddress);
00094         //wns::simulator::Time FrameDuration = 65.536E-3;
00095         //scheduler->scheduleDelay(call, 10*FrameDuration);
00096         
00097         MESSAGE_SINGLE(NORMAL, this->logger, "Beginning traffic measurement for " << averageOverSFs << " frames for address " << currentAddress);
00098 
00099         //Initialization of the measurement variables
00100         measurementDatapSF currentData;
00101         currentData.sentCompounds = 1;
00102         currentData.maxCompoundSize = compound->getLengthInBits();
00103         currentData.bitsTotal = compound->getLengthInBits();
00104 
00105         windowedTrafficPerAddress[currentAddress].push_back(currentData);
00106     }
00107     else    //current address is already in addressList
00108     {
00109         //adjustment of the measurement variables
00110         int size = compound->getLengthInBits();
00111         (windowedTrafficPerAddress[currentAddress].back()).sentCompounds++;
00112         (windowedTrafficPerAddress[currentAddress].back()).bitsTotal += size;
00113         if(size > (windowedTrafficPerAddress[currentAddress].back()).maxCompoundSize)
00114             (windowedTrafficPerAddress[currentAddress].back()).maxCompoundSize = size;
00115             
00116         //MESSAGE_SINGLE(NORMAL, this->logger, "Address " << currentAddress << "; sent compounds: " << addressList.find(currentAddress)->second.sentCompounds << "; biggest compound: " << addressList.find(currentAddress)->second.maxCompoundSize);
00117     }
00118 
00119     if(this->getConnector()->hasAcceptor(compound))
00120     {
00121         this->getConnector()->getAcceptor(compound)->sendData(compound);
00122     }
00123     else
00124     {
00125         MESSAGE_SINGLE(NORMAL, this->logger, "Dropping compound. Receiver is not ready");
00126     }
00127 }
00128 
00129 void
00130 TrafficEstimation_mean::doWakeup()
00131 {
00132     // simply forward the wakeup call
00133     this->getReceptor()->wakeup();
00134 }
00135 
00136 void
00137 TrafficEstimation_mean::periodically()
00138 {
00139     // Put traffic received in last SF into probe
00140     wns::simulator::Time now_ = wns::simulator::getEventScheduler()->getTime();
00141 
00142     datathroughputProbe->put( bitsPerSF / (now_ - measuringSince) );
00143     bitsPerSF = 0;
00144     measuringSince = now_;
00145     
00146     // Evaluate Traffic each SF
00147     std::map<wns::service::dll::UnicastAddress, std::deque<measurementDatapSF> >::iterator it;
00148     for(it = windowedTrafficPerAddress.begin(); it != windowedTrafficPerAddress.end() ;++it)
00149     {
00150         wns::service::dll::UnicastAddress rx = (*it).first;
00151         // There is no estimation done yet or a new estimation needs to be done
00152         if((lastSetTrafficPerAddress.find(rx) == lastSetTrafficPerAddress.end()) ||
00153             (NeedsNewEstimatePerAddress[rx] == true))
00154         {
00155             // Delete the first evaluation since the traffic may have started other than at the beginning of the SF
00156             if(NeedsNewEstimatePerAddress.find(rx) == NeedsNewEstimatePerAddress.end())
00157             {
00158                 // This means this is the first evaluation for the specified address
00159                 MESSAGE_SINGLE(NORMAL, logger, "First window element is deleted due to different start of traffic generation and SF");
00160                 while((*it).second.size() > 0)
00161                     (*it).second.pop_front();
00162                     
00163                 NeedsNewEstimatePerAddress[rx] == true;
00164             }
00165         
00166             // If enough SFs have been evaluated -> estimate traffic
00167             int windowedSFs = (*it).second.size();
00168             if(windowedSFs >= averageOverSFs)
00169             {
00170                 MESSAGE_SINGLE(NORMAL, logger, "Enough SFs for evaluation: " << windowedSFs << " for address " << rx);
00171                 measurementDatapSF currentData;
00172                 currentData.sentCompounds = 0;
00173                 currentData.maxCompoundSize = 0;
00174                 currentData.bitsTotal = 0;
00175 
00176                 // Sum up windowed values and calculate mean traffic
00177                 for(int i = 0; i < windowedSFs; i++)
00178                 {
00179                     measurementDatapSF tmpData = (*it).second.at(i);
00180                     currentData.sentCompounds += tmpData.sentCompounds;
00181                     currentData.bitsTotal += tmpData.bitsTotal;
00182                     if(tmpData.maxCompoundSize > currentData.maxCompoundSize)
00183                         currentData.maxCompoundSize = tmpData.maxCompoundSize;
00184                 }
00185 
00186                 estimatedTraffic currentTraffic;
00187                 currentTraffic.CompoundspSF = ceil((double) currentData.sentCompounds / (double) windowedSFs);
00188                 currentTraffic.BitspSF = ceil((double) currentData.bitsTotal / (double) windowedSFs);
00189                 currentTraffic.MaxCompoundSize = currentData.maxCompoundSize;
00190 
00191                 currentTrafficPerAddress[rx] = currentTraffic;
00192                 if(friends.manager->getDRPchannelAccess()) // If DRP channel access is off don't prepare a connection
00193                 {
00194                     if(!trafficEstimationConfig.overWriteEstimation)
00195                     {
00196                         if(lastSetTrafficPerAddress.find(rx) == lastSetTrafficPerAddress.end())
00197                         {
00198                             // This is the first traffic estimation for this target
00199                             MESSAGE_SINGLE(NORMAL, logger, "Traffic measurement finished for this connection. Number of compounds: "
00200                             << currentTraffic.CompoundspSF
00201                             <<"; Bits per SF: "
00202                             << currentTraffic.BitspSF
00203                             << "; Maximum compound size : "
00204                             << currentTraffic.MaxCompoundSize);
00205                         
00206                             friends.manager->prepareDRPConnection(rx, currentTraffic.CompoundspSF, currentTraffic.BitspSF, currentTraffic.MaxCompoundSize);
00207                         }
00208                         else
00209                         {
00210                             MESSAGE_SINGLE(NORMAL, logger, "Traffic measurement updated for this connection. Number of compounds: "
00211                             << currentTraffic.CompoundspSF
00212                             <<"; Bits per SF: "
00213                             << currentTraffic.BitspSF
00214                             << "; Maximum compound size : "
00215                             << currentTraffic.MaxCompoundSize);
00216                             
00217                             friends.manager->updateDRPConnection(rx, currentTraffic.CompoundspSF, currentTraffic.BitspSF, currentTraffic.MaxCompoundSize);
00218                         }
00219                     }
00220                     else
00221                     {
00222                         MESSAGE_SINGLE(NORMAL, logger, "Traffic measurement overwritten by manual values: "
00223                         << trafficEstimationConfig.CompoundspSF
00224                         <<"; Bits per SF: "
00225                         << trafficEstimationConfig.BitspSF
00226                         << "; Maximum compound size : "
00227                         << trafficEstimationConfig.MaxCompoundSize);
00228                     
00229                         friends.manager->prepareDRPConnection(rx, trafficEstimationConfig.CompoundspSF, trafficEstimationConfig.BitspSF, trafficEstimationConfig.MaxCompoundSize);
00230                     }
00231                     
00232                     // Save last set traffic characteristics
00233                     lastSetTrafficPerAddress[rx] = currentTraffic;
00234                 }
00235                 
00236                 // Once filled keep window at constant size
00237                 while((*it).second.size() >= averageOverSFs)
00238                     (*it).second.pop_front();
00239                 
00240                 // Mark estimation as done
00241                 NeedsNewEstimatePerAddress[rx] = false;
00242             }
00243             else MESSAGE_SINGLE(NORMAL, logger, "So far only " << windowedSFs << " SFs are evaluated for address " << rx);
00244             
00245         }
00246 
00247         // A traffic estimation was already done 
00248         else
00249         {
00250             // check if traffic differs from estimated traffic
00251             measurementDatapSF thisSFData = (*it).second.back();
00252             estimatedTraffic lastSetData = lastSetTrafficPerAddress[rx];
00253             if((thisSFData.sentCompounds > lastSetData.CompoundspSF*1.05) || (thisSFData.bitsTotal > lastSetData.BitspSF*1.05))
00254             {
00255                 MESSAGE_SINGLE(NORMAL, logger, "DEBUG : ThisSF SentCompd " << thisSFData.sentCompounds << " | LastSet ComppSF " << lastSetData.CompoundspSF);
00256                 MESSAGE_SINGLE(NORMAL, logger, "DEBUG : ThisSF TotalBits " << thisSFData.bitsTotal << " | LastSet BitspSF " << lastSetData.BitspSF);
00257             
00258                 MESSAGE_SINGLE(NORMAL, logger, "The current traffic differs from the last set traffic characteristic by " << (thisSFData.sentCompounds / lastSetData.CompoundspSF -1.0)*100 << " % in compounds and " << (thisSFData.bitsTotal / lastSetData.BitspSF -1.0)*100 << " % in total bits");
00259                 
00260                 // The current SF has different characteristic than the last set traffic characteristic
00261                 NeedsNewEstimatePerAddress[rx] = true;
00262                 // Remove all evaluated SFs from the window so that the estimation is done when enough SFs are evaluated again
00263                 while((*it).second.size() > 0)
00264                     (*it).second.pop_front();
00265             }
00266         }
00267 
00268         // initialize a new window element
00269         measurementDatapSF emptyData;
00270         emptyData.sentCompounds = 0;
00271         emptyData.maxCompoundSize = 0;
00272         emptyData.bitsTotal = 0;
00273         (*it).second.push_back(emptyData);
00274     
00275     }
00276 }
00277 
00278 void
00279 TrafficEstimation_mean::doOnData(const wns::ldk::CompoundPtr& compound)
00280 {
00281     bitsPerSF += compound->getLengthInBits();
00282 
00283     this->getDeliverer()->getAcceptor(compound)->onData(compound);
00284 //     MESSAGE_SINGLE(NORMAL, this->logger, "Receiving compound");
00285 }

Generated on Sat May 26 03:32:13 2012 for openWNS by  doxygen 1.5.5