![]() |
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/draftn/Aggregation.hpp> 00030 00031 #include <WNS/probe/bus/ContextProvider.hpp> 00032 #include <WNS/probe/bus/utils.hpp> 00033 00034 using namespace wifimac::draftn; 00035 00036 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00037 wifimac::draftn::Aggregation, 00038 wns::ldk::FunctionalUnit, 00039 "wifimac.draftn.Aggregation", 00040 wns::ldk::FUNConfigCreator); 00041 00042 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00043 wifimac::draftn::Aggregation, 00044 wns::ldk::probe::Probe, 00045 "wifimac.draftn.Aggregation", 00046 wns::ldk::FUNConfigCreator); 00047 00048 Aggregation::Aggregation(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) : 00049 wns::ldk::concatenation::Concatenation(fun, config_), 00050 wns::ldk::probe::Probe(), 00051 00052 managerName(config_.get<std::string>("managerName")), 00053 impatientTransmission(config_.get<bool>("myConfig.impatient")), 00054 maxDelay(config_.get<wns::simulator::Time>("myConfig.maxDelay")), 00055 sendNow(false), 00056 currentReceiver() 00057 { 00058 MESSAGE_SINGLE(NORMAL, logger, "created"); 00059 00060 friends.manager = NULL; 00061 00062 // read the localIDs from the config 00063 wns::probe::bus::ContextProviderCollection registry(&fun->getLayer()->getContextProviderCollection()); 00064 for(int ii = 0; ii < config_.len("localIDs.keys()"); ++ii) 00065 { 00066 std::string key = config_.get<std::string>("localIDs.keys()",ii); 00067 unsigned int value = config_.get<unsigned int>("localIDs.values()",ii); 00068 registry.addProvider(wns::probe::bus::contextprovider::Constant(key, value)); 00069 MESSAGE_SINGLE(VERBOSE, logger, "Using Local IDName '"<<key<<"' with value: "<<value); 00070 } 00071 00072 aggregationSizeFrames = wns::probe::bus::collector(registry, config_, "aggregationSizeFramesProbeName"); 00073 } 00074 00075 00076 void Aggregation::onFUNCreated() 00077 { 00078 MESSAGE_SINGLE(NORMAL, logger, "onFUNCreated() started"); 00079 00080 friends.manager = getFUN()->findFriend<wifimac::lowerMAC::Manager*>(managerName); 00081 } 00082 00083 void Aggregation::processOutgoing(const wns::ldk::CompoundPtr& compound) 00084 { 00085 assure(friends.manager->getFrameType(compound->getCommandPool()) != ACK, "Cannot handle ACK frames"); 00086 00087 if(not (this->currentCompound == wns::ldk::CompoundPtr())) 00088 { 00089 // ongoing aggregation 00090 assure(this->currentReceiver.isValid(), "Has something to send, but not valid receiver"); 00091 00092 if(friends.manager->getReceiverAddress(compound->getCommandPool()) == this->currentReceiver) 00093 { 00094 if(friends.manager->getReplyTimeout(compound->getCommandPool()) > 0) 00095 { 00096 // requires reply, close the aggregation 00097 this->currentEntries = this->maxEntries-1; 00098 MESSAGE_BEGIN(NORMAL, logger, m, "Compound to "); 00099 m << friends.manager->getReceiverAddress(compound->getCommandPool()); 00100 m << " requires direct reply -> Close aggregation, fake entries to " << this->currentEntries; 00101 MESSAGE_END(); 00102 // mark current compound in the same way 00103 friends.manager->setReplyTimeout(this->currentCompound->getCommandPool(), 00104 friends.manager->getReplyTimeout(compound->getCommandPool())); 00105 sendNow = true; 00106 } 00107 // accepted compound is for the same receiver as the other ones --> 00108 // no differentiation 00109 wns::ldk::concatenation::Concatenation::processOutgoing(compound); 00110 if((not hasCapacity()) or impatientTransmission) 00111 { 00112 // no more capacity -> send, even if patient aggregation 00113 sendNow = true; 00114 } 00115 } 00116 else 00117 { 00118 activateCommand(compound->getCommandPool()); 00119 00120 // accepted compound is for a different receiver --> same as buffer 00121 // full 00122 this->nextCompound = createContainer(compound); 00123 this->sendNow = true; 00124 MESSAGE_BEGIN(NORMAL, logger, m, "Compound is for receiver "); 00125 m << friends.manager->getReceiverAddress(compound->getCommandPool()); 00126 m << ", current receiver is " << this->currentReceiver; 00127 m << " -> No concatenation possible"; 00128 MESSAGE_END(); 00129 00130 this->currentReceiver = friends.manager->getReceiverAddress(compound->getCommandPool()); 00131 } 00132 } 00133 else 00134 { 00135 this->currentReceiver = friends.manager->getReceiverAddress(compound->getCommandPool()); 00136 if((friends.manager->getFrameType(compound->getCommandPool()) == ACK) or impatientTransmission) 00137 { 00138 MESSAGE_BEGIN(NORMAL, logger, m, "New aggregation for receiver "); 00139 m << this->currentReceiver; 00140 m << " send impatiently"; 00141 MESSAGE_END(); 00142 00143 this->sendNow = true; 00144 } 00145 else 00146 { 00147 MESSAGE_BEGIN(NORMAL, logger, m, "New aggregation for receiver "); 00148 m << this->currentReceiver; 00149 m << ", wait for more"; 00150 MESSAGE_END(); 00151 00152 setTimeout(this->maxDelay); 00153 this->sendNow = false; 00154 } 00155 00156 wns::ldk::concatenation::Concatenation::processOutgoing(compound); 00157 } 00158 } 00159 00160 void 00161 Aggregation::onTimeout() 00162 { 00163 MESSAGE_SINGLE(NORMAL, logger, "Timeout for current aggregation -> send"); 00164 sendNow = true; 00165 tryToSend(); 00166 } 00167 00168 const wns::ldk::CompoundPtr 00169 Aggregation::hasSomethingToSend() const 00170 { 00171 // wait for sendNow indication 00172 if(not sendNow) 00173 { 00174 return wns::ldk::CompoundPtr(); 00175 } 00176 00177 return wns::ldk::concatenation::Concatenation::hasSomethingToSend(); 00178 00179 } // somethingToSend 00180 00181 wns::ldk::CompoundPtr 00182 Aggregation::getSomethingToSend() 00183 { 00184 wns::ldk::CompoundPtr it = wns::ldk::concatenation::Concatenation::getSomethingToSend(); 00185 // reset sendNow for next aggregation 00186 sendNow = false; 00187 if(hasTimeoutSet()) 00188 { 00189 cancelTimeout(); 00190 } 00191 00192 aggregationSizeFrames->put(it, getCommand(it->getCommandPool())->peer.compounds.size()); 00193 00194 wns::ldk::CompoundPtr lastEntry = getCommand(it->getCommandPool())->peer.compounds.back(); 00195 00196 MESSAGE_BEGIN(NORMAL, logger, m, "Send aggregated compound with frame exchange duration set to"); 00197 m << friends.manager->getFrameExchangeDuration(lastEntry->getCommandPool()); 00198 MESSAGE_END(); 00199 00200 // set the frame exchange duration to the value given in the last aggregated compound 00201 friends.manager->setFrameExchangeDuration(it->getCommandPool(), 00202 friends.manager->getFrameExchangeDuration(lastEntry->getCommandPool())); 00203 00204 return(it); 00205 }
1.5.5