User Manual, Developers Guide and API Documentation

PiggyBacker.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 <WNS/ldk/arq/PiggyBacker.hpp>
00029 #include <WNS/ldk/fun/FUN.hpp>
00030 #include <WNS/StaticFactory.hpp>
00031 
00032 using namespace wns::ldk;
00033 using namespace wns::ldk::arq;
00034 
00035 
00036 STATIC_FACTORY_REGISTER_WITH_CREATOR(PiggyBacker, FunctionalUnit, "wns.arq.PiggyBacker", FUNConfigCreator);
00037 
00038 
00039 PiggyBacker::PiggyBacker(fun::FUN* fuNet, const pyconfig::View& config) :
00040         wns::ldk::fu::Plain<PiggyBacker, PiggyBackerCommand>(fuNet),
00041 
00042         arqName(config.get<std::string>("arq")),
00043         bitsIfPiggyBacked(config.get<Bit>("bitsIfPiggyBacked")),
00044         bitsIfNotPiggyBacked(config.get<Bit>("bitsIfNotPiggyBacked")),
00045         addACKPDUSize(config.get<bool>("addACKPDUSize")),
00046 
00047         i(),
00048         rr(),
00049         inControl(false),
00050         logger("WNS", "PiggyBacker")
00051 {
00052 }
00053 
00054 
00055 void
00056 PiggyBacker::onFUNCreated()
00057 {
00058     friends.arq = getFUN()->findFriend<ARQ*>(arqName);
00059     assure(friends.arq, "PiggyBacker requires an ARQ friend with name '" + arqName + "'");
00060 }
00061 
00062 
00063 bool
00064 PiggyBacker::doIsAccepting(const CompoundPtr& compound) const
00065 {
00066     ARQCommand* arqPCI = getARQPCI(compound);
00067 
00068     if(arqPCI->isACK()) {
00069         return rr == CompoundPtr();
00070     } else {
00071         return i == CompoundPtr();
00072     }
00073 } // isAccepting
00074 
00075 
00076 void
00077 PiggyBacker::doSendData(const CompoundPtr& compound)
00078 {
00079     assure(isAccepting(compound), "sendData called although PiggyBacker is not accepting.");
00080 
00081     activateCommand(compound->getCommandPool());
00082 
00083     ARQCommand* arqPCI = getARQPCI(compound);
00084     if(arqPCI->isACK()) {
00085         rr = compound;
00086     } else {
00087         i = compound;
00088     }
00089 
00090     if(inControl)
00091         return;
00092 
00093     wakeup();
00094 } // doSendData
00095 
00096 
00097 void
00098 PiggyBacker::doOnData(const CompoundPtr& compound)
00099 {
00100     PiggyBackerCommand* command = getCommand(compound->getCommandPool());
00101 
00102     if(command->peer.piggyBacked) {
00103         getDeliverer()->getAcceptor(compound)->onData(command->peer.piggyBacked);
00104     }
00105 
00106     getDeliverer()->getAcceptor(compound)->onData(compound);
00107 } // doOnData
00108 
00109 
00110 void
00111 PiggyBacker::doWakeup()
00112 {
00113     inControl = true;
00114     {
00115         if(!i) {
00116             friends.arq->preferACK(false);
00117             getReceptor()->wakeup();
00118             friends.arq->preferACK(true);
00119         }
00120         if(i && !rr) {
00121             getReceptor()->wakeup();
00122         }
00123     }
00124     inControl = false;
00125 
00126     tryToSend();
00127 } // wakeup
00128 
00129 
00130 void
00131 PiggyBacker::calculateSizes(const CommandPool* commandPool, Bit& commandPoolSize, Bit& sduSize) const
00132 {
00133     //What are the sizes in the upper Layers
00134     getFUN()->calculateSizes(commandPool, commandPoolSize, sduSize, this);
00135 
00136     PiggyBackerCommand* command = getCommand(commandPool);
00137     if(command->peer.piggyBacked) {
00138         commandPoolSize += bitsIfPiggyBacked;
00139 
00140         if(addACKPDUSize) {
00141             Bit ackPCISize;
00142             Bit ackSDUSize;
00143             getFUN()->calculateSizes(command->peer.piggyBacked->getCommandPool(), ackPCISize, ackSDUSize, this);
00144 
00145             commandPoolSize += ackPCISize + ackSDUSize;
00146         }
00147     } else {
00148         commandPoolSize += bitsIfNotPiggyBacked;
00149     }
00150 } // calculateSizes
00151 
00152 
00153 void
00154 PiggyBacker::tryToSend()
00155 {
00156     CompoundPtr it = CompoundPtr();
00157 
00158     MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName());
00159     if(rr || i) {
00160         m << " send (";
00161         if(i)
00162             m << "i ";
00163         if(rr)
00164             m << "rr";
00165         m << ")";
00166     }
00167     MESSAGE_END();
00168 
00169     if(rr && i) {
00170         PiggyBackerCommand* command = getCommand(i->getCommandPool());
00171         command->peer.piggyBacked = rr;
00172 
00173         it = i;
00174 
00175     } else if(i) {
00176         it = i;
00177 
00178     } else if(rr) {
00179         it = rr;
00180 
00181     } else {
00182         return;
00183     }
00184 
00185     if(!getConnector()->hasAcceptor(it))
00186         return;
00187 
00188     getConnector()->getAcceptor(it)->sendData(it);
00189     rr = CompoundPtr();
00190     i = CompoundPtr();
00191 } // tryToSend
00192 
00193 
00194 ARQCommand*
00195 PiggyBacker::getARQPCI(const CompoundPtr& compound) const
00196 {
00197     ARQCommand* arqPCI = dynamic_cast<ARQCommand*>(friends.arq->getCommand(compound->getCommandPool()));
00198     assure(arqPCI, "Expected an ARQCommand instance.");
00199 
00200     return arqPCI;
00201 } // getARQPCI
00202 
00203 
00204 

Generated on Fri May 25 03:31:39 2012 for openWNS by  doxygen 1.5.5