![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WNS (Wireless Network Simulator) * 00003 * __________________________________________________________________________ * 00004 * * 00005 * Copyright (C) 2004-2006 * 00006 * Chair of Communication Networks (ComNets) * 00007 * Kopernikusstr. 16, D-52074 Aachen, Germany * 00008 * phone: ++49-241-80-27910 (phone), fax: ++49-241-80-22242 * 00009 * email: wns@comnets.rwth-aachen.de * 00010 * www: http://wns.comnets.rwth-aachen.de * 00011 ******************************************************************************/ 00012 00013 #include <WNS/ldk/arq/StopAndWaitRC.hpp> 00014 #include <WNS/ldk/Port.hpp> 00015 00016 #include <WNS/Assure.hpp> 00017 00018 using namespace wns::ldk::arq; 00019 using namespace wns::ldk; 00020 00021 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00022 wns::ldk::arq::StopAndWaitRC, 00023 wns::ldk::FunctionalUnit, 00024 "wns.arq.StopAndWaitRC", 00025 wns::ldk::FUNConfigCreator); 00026 00027 00028 const std::string Data::name = "Data"; 00029 const std::string Ack::name = "Ack"; 00030 00031 StopAndWaitRC::StopAndWaitRC(fun::FUN* fuNet, const wns::pyconfig::View& config) 00032 : FunctionalUnitRC< StopAndWaitRC >(this), 00033 CommandTypeSpecifier< StopAndWaitRCCommand >(fuNet), 00034 HasUpPort< StopAndWaitRC >(this), 00035 HasDownPort< StopAndWaitRC, Port<Data> >(this), 00036 HasDownPort< StopAndWaitRC, Port<Ack> >(this), 00037 Cloneable< StopAndWaitRC >(), 00038 events::CanTimeout(), 00039 00040 resendTimeout(config.get<double>("resendTimeout")), 00041 bitsPerIFrame(config.get<int>("bitsPerIFrame")), 00042 bitsPerRRFrame(config.get<int>("bitsPerRRFrame")), 00043 00044 NS(0), 00045 NR(0), 00046 activeCompound(CompoundPtr()), 00047 ackCompound(CompoundPtr()), 00048 sendNowData(false), 00049 logger(config.get("logger")) 00050 { 00051 } 00052 00053 StopAndWaitRC::~StopAndWaitRC() 00054 { 00055 } 00056 00057 bool 00058 StopAndWaitRC::doIsAccepting(const CompoundPtr& compound) const 00059 { 00060 if (!activeCompound) 00061 { 00062 CompoundPtr compoundCopy = compound->copy(); 00063 00064 StopAndWaitRCCommand* command = activateCommand(compoundCopy->getCommandPool()); 00065 command->peer.type = StopAndWaitRCCommand::I; 00066 command->peer.NS = NS; 00067 00068 return getPortConnector< Port<Data> >()->hasAcceptor(compoundCopy); 00069 } 00070 00071 return false; 00072 } 00073 00074 void 00075 StopAndWaitRC::doSendData(const CompoundPtr& compound) 00076 { 00077 assure(isAccepting(compound), "sendData called although not accepting!"); 00078 00079 activeCompound = compound; 00080 00081 StopAndWaitRCCommand* command = activateCommand(activeCompound->getCommandPool()); 00082 00083 command->peer.type = StopAndWaitRCCommand::I; 00084 command->peer.NS = NS; 00085 command->localTransmissionCounter = 1; 00086 00087 MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName()); 00088 m << " processOutgoing(compound)," 00089 << " sequence number (NS) of compound: " << command->peer.NS; 00090 MESSAGE_END(); 00091 00092 ++NS; 00093 00094 if (getPortConnector< Port<Data> >()->hasAcceptor(activeCompound)) 00095 { 00096 setTimeout(resendTimeout); 00097 getPortConnector< Port<Data> >()->getAcceptor(activeCompound)->sendData(activeCompound->copy()); 00098 } 00099 else 00100 { 00101 sendNowData = true; 00102 } 00103 } 00104 00105 namespace wns { namespace ldk { namespace arq { 00106 00107 template <> 00108 void 00109 StopAndWaitRC::doWakeup(Port<Data>) 00110 { 00111 if (sendNowData && 00112 getPortConnector< Port<Data> >()->hasAcceptor(activeCompound)) 00113 { 00114 setTimeout(resendTimeout); 00115 getPortConnector< Port<Data> >()->getAcceptor(activeCompound)->sendData(activeCompound->copy()); 00116 00117 sendNowData = false; 00118 } 00119 00120 getReceptor()->wakeup(); 00121 } 00122 00123 template <> 00124 void 00125 StopAndWaitRC::doWakeup(Port<Ack>) 00126 { 00127 if (ackCompound && 00128 getPortConnector< Port<Ack> >()->hasAcceptor(ackCompound)) 00129 { 00130 getPortConnector< Port<Ack> >()->getAcceptor(ackCompound) 00131 ->sendData(ackCompound); 00132 00133 ackCompound = CompoundPtr(); 00134 } 00135 } 00136 00137 template <> 00138 void 00139 StopAndWaitRC::doOnData(const CompoundPtr& compound, Port<Data>) 00140 { 00141 StopAndWaitRCCommand *command = getCommand(compound->getCommandPool()); 00142 assure(command->peer.type == StopAndWaitRCCommand::I, 00143 "Received RR frame via 'Data' port"); 00144 00145 MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName()); 00146 m << " processIncoming(compound), Received I frame " 00147 << " expected (NR) " << NR 00148 << " received (command->peer.NS) " << command->peer.NS; 00149 MESSAGE_END(); 00150 00151 // The I-Frame must be either the one we're expecting (NR) or 00152 // the one before the one we're expecting (NR-1). If it is NR-1 00153 // it is a duplicate, that we've already acknowledged. May be 00154 // our ACK got lost. So we send it again. 00155 if(command->peer.NS == NR || command->peer.NS == NR-1) 00156 { 00157 // As stated above ACK is sent in any case 00158 CommandPool* ackPCI = getFUN()->getProxy()->createReply(compound->getCommandPool(), this); 00159 ackCompound = CompoundPtr(new Compound(ackPCI)); 00160 StopAndWaitRCCommand* ackCommand = activateCommand(ackPCI); 00161 00162 ackCommand->peer.type = StopAndWaitRCCommand::RR; 00163 ackCommand->peer.NS = NR; 00164 MESSAGE_SINGLE(NORMAL, logger, 00165 getFUN()->getName() << " Prepared RR frame (ACK) with NS=" 00166 << ackCommand->peer.NS << " (the next I frame we're expexcting)"); 00167 00168 if (getPortConnector< Port<Ack> >()->hasAcceptor(ackCompound)) 00169 { 00170 getPortConnector< Port<Ack> >()->getAcceptor(ackCompound)->sendData(ackCompound); 00171 00172 ackCompound = CompoundPtr(); 00173 } 00174 00175 if(command->peer.NS == NR) 00176 { 00177 MESSAGE_SINGLE(NORMAL, logger, 00178 getFUN()->getName() << " This was the next expected I frame"); 00179 getDeliverer()->getAcceptor(compound)->onData(compound); 00180 NR++; 00181 } 00182 else 00183 { 00184 MESSAGE_SINGLE(NORMAL, logger, 00185 getFUN()->getName() << " Already received this I frame (duplicate)"); 00186 } 00187 00188 } 00189 else 00190 { 00191 // this can not happen. 00192 wns::Exception e; 00193 e << "StopAndWait-ARQ received an I frame that neither (NR) nor (NR-1). " 00194 << "This cannot happen and is most probably an implementation error"; 00195 throw e; 00196 } 00197 } 00198 00199 template <> 00200 void 00201 StopAndWaitRC::doOnData(const CompoundPtr& compound, Port<Ack>) 00202 { 00203 StopAndWaitRCCommand *command = getCommand(compound->getCommandPool()); 00204 assure(command->peer.type == StopAndWaitRCCommand::RR, 00205 "Received I frame via 'Data' port"); 00206 00207 MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName()); 00208 m << " processIncoming(compound), Received RR frame " 00209 << " expected (this->NS) " << NS 00210 << " received (command->peer.NS) " << command->peer.NS; 00211 MESSAGE_END(); 00212 00213 if(!(command->peer.NS == NS || command->peer.NS == NS-1)) 00214 { 00215 // this can not happen. 00216 wns::Exception e; 00217 e << "StopAndWait-ARQ received an ACK that with neither (NS) nor (NS-1). " 00218 << "This cannot happen and is most probably an implementation error"; 00219 // stop here 00220 throw e; 00221 } 00222 00223 // only compounds with NS == NS or NS == NS-1 are left 00224 if(command->peer.NS == NS-1) 00225 { 00226 // duplicate ACK (must be due to duplicate I) 00227 MESSAGE_BEGIN(NORMAL, logger, m, getFUN()->getName()); 00228 m << " Unexpected RR frame (due to duplicate I frame)."; 00229 m << "\nHINT: Check your resend timeout. This indicates it is too short."; 00230 MESSAGE_END(); 00231 } 00232 else 00233 { 00234 // this is the ACK we've been waiting for -> we can stop 00235 // the timeout 00236 MESSAGE_SINGLE(NORMAL, logger, getFUN()->getName() 00237 << " This is the RR frame (ACK) for the last sent I frame (compound)"); 00238 // statusCollector->onSuccessfullTransmission(activeCompound); 00239 00240 activeCompound = CompoundPtr(); 00241 00242 if (hasTimeoutSet() == true) 00243 { 00244 MESSAGE_SINGLE(VERBOSE, logger, getFUN()->getName() << "Stopping timeout."); 00245 cancelTimeout(); 00246 } 00247 00248 MESSAGE_SINGLE(VERBOSE, logger, getFUN()->getName() 00249 << " Ready for next compound from higher FU."); 00250 00251 getReceptor()->wakeup(); 00252 } 00253 } 00254 } //arq 00255 } //ldk 00256 } //wns 00257 00258 void 00259 StopAndWaitRC::onTimeout() 00260 { 00261 assure(activeCompound || !sendNowData, "Unexpected timeout."); 00262 00263 // statusCollector->onFailedTransmission(activeCompound); 00264 00265 StopAndWaitRCCommand* command = getCommand(activeCompound); 00266 command->localTransmissionCounter++; 00267 00268 MESSAGE_SINGLE(NORMAL, logger, 00269 "Timeout for compound with sequence number (NS) " << command->peer.NS << 00270 ". Increased transmission counter to " << command->localTransmissionCounter); 00271 00272 if (getPortConnector< Port<Data> >()->hasAcceptor(activeCompound)) 00273 { 00274 setTimeout(resendTimeout); 00275 getPortConnector< Port<Data> >()->getAcceptor(activeCompound)->sendData(activeCompound->copy()); 00276 } 00277 else 00278 { 00279 sendNowData = true; 00280 } 00281 } 00282 00283 void 00284 StopAndWaitRC::calculateSizes(const CommandPool* commandPool, Bit& commandPoolSize, Bit& sduSize) const 00285 { 00286 //What are the sizes in the upper Layers 00287 getFUN()->calculateSizes(commandPool, commandPoolSize, sduSize, this); 00288 00289 StopAndWaitRCCommand* command = getCommand(commandPool); 00290 00291 switch(command->peer.type) 00292 { 00293 case StopAndWaitRCCommand::I: 00294 { 00295 commandPoolSize += bitsPerIFrame; 00296 break; 00297 } 00298 case StopAndWaitRCCommand::RR: 00299 { 00300 commandPoolSize += bitsPerRRFrame; 00301 break; 00302 } 00303 default: 00304 { 00305 wns::Exception e; 00306 e << getFUN()->getName() 00307 << " StopAndWait-ARQ: Unknown frame type in size calculation (" << command->peer.type << ")."; 00308 // stop here 00309 throw e; 00310 break; 00311 } 00312 } 00313 }
1.5.5