![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5