![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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
1.5.5