User Manual, Developers Guide and API Documentation

Aggregation.cpp

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

Generated on Mon May 21 03:32:10 2012 for openWNS by  doxygen 1.5.5