![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiFiMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2007 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 16, 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 <WIFIMAC/Layer2.hpp> 00030 #include <WIFIMAC/helper/DestinationSortedWindowProbe.hpp> 00031 #include <WIFIMAC/pathselection/IPathSelection.hpp> 00032 00033 #include <WNS/StaticFactory.hpp> 00034 #include <WNS/probe/bus/utils.hpp> 00035 #include <WNS/service/dll/StationTypes.hpp> 00036 00037 using namespace wifimac::helper; 00038 00039 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00040 DestinationSortedWindowProbe, 00041 wns::ldk::probe::Probe, 00042 "wifimac.helper.DestinationSortedWindowProbe", 00043 wns::ldk::FUNConfigCreator); 00044 00045 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00046 DestinationSortedWindowProbe, 00047 wns::ldk::FunctionalUnit, 00048 "wifimac.helper.DestinationSortedWindowProbe", 00049 wns::ldk::FUNConfigCreator); 00050 00051 DestinationSortedWindowProbe::DestinationSortedWindowProbe(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) : 00052 wns::ldk::probe::bus::Window(fun, config_), 00053 config(config_), 00054 ucReader(NULL), 00055 windowSize(config.get<simTimeType>("windowSize")), 00056 ucCommandName(config.get<std::string>("ucCommandName")) 00057 { 00058 // read the localContext from the config 00059 wns::probe::bus::ContextProviderCollection localContext(&fun->getLayer()->getContextProviderCollection()); 00060 for (int ii = 0; ii<config.len("localIDs.keys()"); ++ii) 00061 { 00062 std::string key = config.get<std::string>("localIDs.keys()",ii); 00063 unsigned long int value = config.get<unsigned long int>("localIDs.values()",ii); 00064 localContext.addProvider(wns::probe::bus::contextprovider::Constant(key, value)); 00065 } 00066 00067 this->bitsIncoming = wns::probe::bus::collector(localContext, config, "incomingBitDestinationSortedWindowProbeName"); 00068 this->bitsAggregated = wns::probe::bus::collector(localContext, config, "aggregatedBitDestinationSortedWindowProbeName"); 00069 this->bitsOutgoing = wns::probe::bus::collector(localContext, config, "outgoingBitDestinationSortedWindowProbeName"); 00070 this->relativeGoodput = wns::probe::bus::collector(localContext, config, "relativeGoodputDestinationSortedWindowProbeName"); 00071 } 00072 00073 DestinationSortedWindowProbe::~DestinationSortedWindowProbe() 00074 { 00075 } 00076 00077 void 00078 DestinationSortedWindowProbe::onFUNCreated() 00079 { 00080 // Obtain upper convergence command reader 00081 ucReader = getFUN()->getCommandReader(ucCommandName); 00082 } 00083 00084 void 00085 DestinationSortedWindowProbe::processIncoming(const wns::ldk::CompoundPtr& compound) 00086 { 00087 // read the addresses 00088 unsigned int sourceAddress = 00089 ucReader->readCommand<dll::UpperCommand>(compound->getCommandPool())->peer.sourceMACAddress.getInteger(); 00090 unsigned int destAddress = 00091 getFUN()->getLayer<wifimac::Layer2*>()->getDLLAddress().getInteger(); 00092 00093 Bit commandPoolSize; 00094 Bit dataSize; 00095 this->getFUN()->calculateSizes(compound->getCommandPool(), commandPoolSize, dataSize, this); 00096 const long int compoundLength = commandPoolSize + dataSize; 00097 00098 this->putProbe(bitsIncomingProbeHolder, sourceAddress, compoundLength); 00099 00100 wns::ldk::probe::bus::WindowCommand* command = this->getCommand(compound->getCommandPool()); 00101 wifimac::helper::DestinationSortedWindowProbe* peerFU = dynamic_cast<wifimac::helper::DestinationSortedWindowProbe*>(command->magic.probingFU); 00102 assure(peerFU != NULL, "Expected wifimac::helper::DestinationSortedWindowProbe as peer!"); 00103 00104 peerFU->putAggregatedProbe(destAddress, compoundLength); 00105 00106 // Now do the general (base class stuff) 00107 this->wns::ldk::probe::bus::Window::processIncoming(compound); 00108 } 00109 00110 void 00111 DestinationSortedWindowProbe::processOutgoing(const wns::ldk::CompoundPtr& compound) 00112 { 00113 // First do the general (base class) stuff 00114 this->wns::ldk::probe::bus::Window::processOutgoing(compound); 00115 00116 wns::service::dll::UnicastAddress destAdr = 00117 ucReader->readCommand<dll::UpperCommand>(compound->getCommandPool())->peer.targetMACAddress; 00118 00119 if((not destAdr.isValid()) and 00120 (this->getFUN()->getLayer<dll::ILayer2*>()->getStationType() == wns::service::dll::StationTypes::UT())) 00121 { 00122 // no destination address and STA -> destination is AP 00123 assure(this->getFUN()->getLayer<dll::ILayer2*>()->getControlService<dll::services::control::Association>("ASSOCIATION")->hasAssociation(), 00124 "Outgoing data, but no association"); 00125 destAdr = 00126 this->getFUN()->getLayer<dll::ILayer2*>()->getControlService<dll::services::control::Association>("ASSOCIATION")->getAssociation(); 00127 } 00128 00129 if((not destAdr.isValid()) and 00130 (this->getFUN()->getLayer<dll::ILayer2*>()->getStationType() == wns::service::dll::StationTypes::FRS())) 00131 { 00132 // no destination address and MP -> destination is portal 00133 wns::service::dll::UnicastAddress sourceAdr = 00134 ucReader->readCommand<dll::UpperCommand>(compound->getCommandPool())->peer.sourceMACAddress; 00135 destAdr = this->getFUN()->getLayer<wifimac::Layer2*>()->getManagementService<wifimac::pathselection::IPathSelection>("PATHSELECTIONOVERVPS")->getPortalFor(sourceAdr); 00136 assure(destAdr.isValid(), "Could not get destAdr from ps service"); 00137 } 00138 00139 assure(destAdr.isValid(), 00140 "Unable to get destination address!"); 00141 00142 Bit commandPoolSize; 00143 Bit dataSize; 00144 this->getFUN()->calculateSizes(compound->getCommandPool(), commandPoolSize, dataSize, this); 00145 const long int compoundLength = commandPoolSize + dataSize; 00146 00147 this->putProbe(bitsOutgoingProbeHolder, destAdr.getInteger(), compoundLength); 00148 } 00149 00150 void 00151 DestinationSortedWindowProbe::putAggregatedProbe(unsigned int adr, 00152 double value) 00153 { 00154 if(this->getFUN()->getLayer<dll::ILayer2*>()->getStationType() == wns::service::dll::StationTypes::UT()) 00155 { 00156 // The STA can only have the associated AP/MP as peer --> change the adr 00157 adr = this->getFUN()->getLayer<dll::ILayer2*>()->getControlService<dll::services::control::Association>("ASSOCIATION")->getAssociation().getInteger(); 00158 } 00159 this->putProbe(bitsAggregatedProbeHolder, adr, value); 00160 } 00161 00162 void 00163 DestinationSortedWindowProbe::putProbe(SlidingWindowMap& probeHolder, 00164 unsigned int adr, 00165 double value) 00166 { 00167 if(not probeHolder.knows(adr)) 00168 { 00169 probeHolder.insert(adr, new wns::SlidingWindow(windowSize)); 00170 } 00171 probeHolder.find(adr)->put(value); 00172 } 00173 00174 void 00175 DestinationSortedWindowProbe::periodically() 00176 { 00177 00178 storeProbes(bitsIncomingProbeHolder, bitsIncoming); 00179 storeProbes(bitsAggregatedProbeHolder, bitsAggregated); 00180 storeProbes(bitsOutgoingProbeHolder, bitsOutgoing); 00181 00182 // relative goodput: aggregated/outgoing to one destination 00183 00184 for(SlidingWindowMap::const_iterator outItr = bitsOutgoingProbeHolder.begin(); 00185 outItr != bitsOutgoingProbeHolder.end(); 00186 ++outItr) 00187 { 00188 bool found = false; 00189 for(SlidingWindowMap::const_iterator aggItr = bitsAggregatedProbeHolder.begin(); 00190 aggItr != bitsAggregatedProbeHolder.end(); 00191 ++aggItr) 00192 { 00193 if(aggItr->first == outItr->first) 00194 { 00195 // set the correct context 00196 if(outItr->second->getPerSecond() > 0) 00197 { 00198 this->getFUN()->getLayer<wifimac::Layer2*>()->updateContext("MAC.WindowProbeAddress", aggItr->first); 00199 relativeGoodput->put(aggItr->second->getPerSecond() / outItr->second->getPerSecond()); 00200 } 00201 found = true; 00202 break; 00203 } 00204 } 00205 if(not found and (outItr->second->getPerSecond() > 0)) 00206 { 00207 // outgoing, but no aggregated 00208 this->getFUN()->getLayer<wifimac::Layer2*>()->updateContext("MAC.WindowProbeAddress", outItr->first); 00209 relativeGoodput->put(0.0); 00210 } 00211 } 00212 00213 // Call base class function 00214 this->wns::ldk::probe::bus::Window::periodically(); 00215 } 00216 00217 void 00218 DestinationSortedWindowProbe::storeProbes(SlidingWindowMap& probeHolder, wns::probe::bus::ContextCollectorPtr& putter) 00219 { 00220 for(SlidingWindowMap::const_iterator probeItr = probeHolder.begin(); probeItr != probeHolder.end(); ++probeItr) 00221 { 00222 // set the correct context 00223 this->getFUN()->getLayer<wifimac::Layer2*>()->updateContext("MAC.WindowProbeAddress", probeItr->first); 00224 00225 putter->put(probeItr->second->getPerSecond()); 00226 } 00227 }
1.5.5