User Manual, Developers Guide and API Documentation

Buffer.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WIFIMAC/lowerMAC/Buffer.hpp>
00029 
00030 using namespace wifimac::lowerMAC;
00031 
00032 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00033     Buffer,
00034     wns::ldk::buffer::Buffer,
00035     "wifimac.lowerMAC.Buffer",
00036     wns::ldk::FUNConfigCreator);
00037 
00038 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00039     Buffer,
00040     wns::ldk::FunctionalUnit,
00041     "wifimac.lowerMAC.Buffer",
00042     wns::ldk::FUNConfigCreator);
00043 
00044 Buffer::Buffer(wns::ldk::fun::FUN* fuNet, const wns::pyconfig::View& config) :
00045     wns::ldk::buffer::Buffer(fuNet, config),
00046 
00047     wns::ldk::fu::Plain<Buffer>(fuNet),
00048     wns::ldk::Delayed<Buffer>(),
00049     raName(config.get<std::string>("raName")),
00050     managerName(config.get<std::string>("managerName")),
00051     protocolCalculatorName(config.get<std::string>("protocolCalculatorName")),
00052     buffer(wns::ldk::buffer::dropping::ContainerType()),
00053     maxSize(config.get<int>("size")),
00054     currentSize(0),
00055     sizeCalculator(),
00056     dropper(),
00057     totalPDUs(),
00058     droppedPDUs(),
00059     logger("WNS", config.get<std::string>("name"))
00060 {
00061     {
00062         std::string pluginName = config.get<std::string>("sizeUnit");
00063         sizeCalculator = std::auto_ptr<wns::ldk::buffer::SizeCalculator>(wns::ldk::buffer::SizeCalculator::Factory::creator(pluginName)->create());
00064     }
00065     friends.ra = NULL;
00066     friends.manager = NULL;
00067     protocolCalculator = NULL;
00068     {
00069         std::string pluginName = config.get<std::string>("drop");
00070         dropper = std::auto_ptr<wns::ldk::buffer::dropping::Drop>(wns::ldk::buffer::dropping::Drop::Factory::creator(pluginName)->create());
00071     }
00072 } // Buffer
00073 
00074 Buffer::Buffer(const Buffer& other) :
00075     //wns::ldk::CompoundHandlerInterface<Buffer>(other),
00076     wns::ldk::CommandTypeSpecifierInterface(other),
00077     wns::ldk::HasReceptorInterface(other),
00078     wns::ldk::HasConnectorInterface(other),
00079     wns::ldk::HasDelivererInterface(other),
00080     wns::CloneableInterface(other),
00081     wns::IOutputStreamable(other),
00082     wns::PythonicOutput(other),
00083     wns::ldk::FunctionalUnit(other),
00084     wns::ldk::DelayedInterface(other),
00085     wns::ldk::buffer::Buffer(other),
00086     wns::ldk::fu::Plain<Buffer>(other),
00087     wns::ldk::Delayed<Buffer>(other),
00088     buffer(other.buffer),
00089     maxSize(other.maxSize),
00090     currentSize(other.currentSize),
00091     sizeCalculator(wns::clone(other.sizeCalculator)),
00092     dropper(wns::clone(other.dropper)),
00093     totalPDUs(other.totalPDUs),
00094     droppedPDUs(other.droppedPDUs),
00095     logger(other.logger)
00096 {
00097     friends.ra = other.friends.ra;
00098     friends.manager = other.friends.manager;
00099     protocolCalculator = other.protocolCalculator;
00100 }
00101 
00102 void Buffer::onFUNCreated()
00103 {
00104     MESSAGE_SINGLE(NORMAL, this->logger, "onFUNCreated() started");
00105     friends.ra = getFUN()->findFriend<wifimac::lowerMAC::RateAdaptation*>(raName);
00106     friends.manager = getFUN()->findFriend<wifimac::lowerMAC::Manager*>(managerName);
00107     protocolCalculator = getFUN()->getLayer<dll::ILayer2*>()->getManagementService<wifimac::management::ProtocolCalculator>(protocolCalculatorName);
00108 }
00109 
00110 
00111 Buffer::~Buffer()
00112 {
00113 } // ~Buffer
00114 
00115 
00116 //
00117 // Delayed interface
00118 //
00119 void
00120 Buffer::processIncoming(const wns::ldk::CompoundPtr& compound)
00121 {
00122     getDeliverer()->getAcceptor(compound)->onData(compound);
00123 } // processIncoming
00124 
00125 
00126 bool
00127 Buffer::hasCapacity() const
00128 {
00129     return true;
00130 } // hasCapacity
00131 
00132 
00133 void
00134 Buffer::processOutgoing(const wns::ldk::CompoundPtr& compound)
00135 {
00136     checkLifetime();
00137 
00138     buffer.push_back(compound);
00139     currentSize += (*sizeCalculator)(compound);
00140 
00141     while(currentSize > maxSize)
00142     {
00143         MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName());
00144         m << " dropping a PDU! maxSize reached : " << maxSize;
00145         m << " current size is " << currentSize;
00146         MESSAGE_END();
00147 
00148         wns::ldk::CompoundPtr toDrop = (*dropper)(buffer);
00149         int pduSize = (*sizeCalculator)(toDrop);
00150         currentSize -= pduSize;
00151         increaseDroppedPDUs(pduSize);
00152     }
00153     MESSAGE_SINGLE(NORMAL, this->logger, "Store outgoing compound, size is now " << currentSize);
00154     increaseTotalPDUs();
00155     probe();
00156 } // processOutgoing
00157 
00158 
00159 const wns::ldk::CompoundPtr
00160 Buffer::hasSomethingToSend() const
00161 {
00162     if(buffer.empty())
00163     {
00164         return wns::ldk::CompoundPtr();
00165     }
00166     return buffer.front();
00167 } // somethingToSend
00168 
00169 
00170 wns::ldk::CompoundPtr
00171 Buffer::getSomethingToSend()
00172 {
00173     wns::ldk::CompoundPtr compound = buffer.front();
00174     buffer.pop_front();
00175 
00176     currentSize -= (*sizeCalculator)(compound);
00177     probe();
00178 
00179     checkLifetime();
00180 
00181 
00182     MESSAGE_SINGLE(NORMAL, this->logger, "Send compound, size is now " << currentSize);
00183     return compound;
00184 } // getSomethingToSend
00185 
00186 
00187 void
00188 Buffer::checkLifetime()
00189 {
00190     for (wns::ldk::buffer::dropping::ContainerType::iterator it = buffer.begin();
00191          it != buffer.end();
00192         )
00193     {
00194         wns::ldk::buffer::dropping::ContainerType::iterator next = it;
00195         ++next;
00196 
00197         if(friends.manager->lifetimeExpired((*it)->getCommandPool()))
00198         {
00199             int pduSize = (*sizeCalculator)(*it);
00200             currentSize -= pduSize;
00201             increaseDroppedPDUs(pduSize);
00202             probe();
00203 
00204             buffer.erase(it);
00205 
00206             MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName());
00207             m << "PDU in queue has reached lifetime -> drop!";
00208             m << "New size is " << currentSize;
00209             MESSAGE_END();
00210         }
00211         it = next;
00212     }
00213 }
00214 
00215 //
00216 // Buffer interface
00217 //
00218 
00219 unsigned long int
00220 Buffer::getSize()
00221 {
00222     return currentSize;
00223 } // getSize
00224 
00225 
00226 unsigned long int
00227 Buffer::getMaxSize()
00228 {
00229     return maxSize;
00230 } // getMaxSize
00231 
00232 
00233 wns::simulator::Time 
00234 Buffer::getNextTransmissionDuration()
00235 {
00236     if (buffer.empty())
00237     {
00238         return 0;
00239     }
00240     wifimac::convergence::PhyMode phyMode = friends.ra->getPhyMode(buffer.front());
00241     return(protocolCalculator->getDuration()->MPDU_PPDU(buffer.front()->getLengthInBits(),
00242                                                        phyMode));
00243 }
00244 
00245 wns::service::dll::UnicastAddress
00246 Buffer::getNextReceiver() const
00247 {
00248     if (buffer.empty())
00249     {
00250         return wns::service::dll::UnicastAddress();
00251     }
00252     return friends.manager->getReceiverAddress(buffer.front()->getCommandPool());
00253 }

Generated on Sun May 27 03:31:41 2012 for openWNS by  doxygen 1.5.5