![]() |
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 00029 #include <WNS/ldk/arq/SelectiveRepeat.hpp> 00030 #include <WNS/ldk/Layer.hpp> 00031 #include <WNS/pyconfig/View.hpp> 00032 #include <WNS/Assure.hpp> 00033 00034 using namespace wns::ldk; 00035 using namespace wns::ldk::arq; 00036 00037 00038 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00039 SelectiveRepeat, 00040 ARQ, 00041 "wns.arq.SelectiveRepeat", 00042 FUNConfigCreator); 00043 00044 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00045 SelectiveRepeat, 00046 FunctionalUnit, 00047 "wns.arq.SelectiveRepeat", 00048 FUNConfigCreator); 00049 00050 SelectiveRepeat::SelectiveRepeat(fun::FUN* fuNet, const wns::pyconfig::View& config) : 00051 ARQ(config), 00052 00053 wns::ldk::fu::Plain<SelectiveRepeat, SelectiveRepeatCommand>(fuNet), 00054 Delayed<SelectiveRepeat>(), 00055 SuspendSupport(fuNet, config), 00056 CanTimeout(), 00057 00058 windowSize(config.get<int>("windowSize")), 00059 sequenceNumberSize(config.get<int>("sequenceNumberSize")), 00060 commandSize(config.get<int>("commandSize")), 00061 NS(0), 00062 NR(0), 00063 LA(0), 00064 activeCompound(CompoundPtr()), 00065 sentPDUs(), 00066 toRetransmit(), 00067 ackPDUs(), 00068 receivedPDUs(), 00069 receivedACKs(), 00070 sendNow(false), 00071 resendTimeout(config.get<double>("resendTimeout")), 00072 retransmissionInterval(resendTimeout), 00073 transmissionAttemptsProbeBus( new wns::probe::bus::ContextCollector( 00074 wns::probe::bus::ContextProviderCollection(&fuNet->getLayer()->getContextProviderCollection()), 00075 config.get<std::string>("probeName"))), 00076 ackDelayProbeBus( new wns::probe::bus::ContextCollector( 00077 wns::probe::bus::ContextProviderCollection(&fuNet->getLayer()->getContextProviderCollection()), 00078 config.get<std::string>("ackDelayProbeName"))), 00079 roundTripTimeProbeBus( new wns::probe::bus::ContextCollector( 00080 wns::probe::bus::ContextProviderCollection(&fuNet->getLayer()->getContextProviderCollection()), 00081 config.get<std::string>("RTTProbeName"))), 00082 delayingDelivery(false), 00083 logger(config.get("logger")) 00084 { 00085 assure(windowSize >= 2, "Invalid windowSize."); 00086 assure(sequenceNumberSize >= 2*windowSize, "Maximum sequence number is to small for chosen windowSize"); 00087 } 00088 00089 00090 SelectiveRepeat::~SelectiveRepeat() 00091 { 00092 // empty internal buffers 00093 ackPDUs.clear(); 00094 sentPDUs.clear(); 00095 toRetransmit.clear(); 00096 receivedPDUs.clear(); 00097 receivedACKs.clear(); 00098 } 00099 00100 00101 bool 00102 SelectiveRepeat::hasCapacity() const 00103 { 00104 /* Make sure we 00105 1. don't have an active PDU we are processing 00106 2. aren't occupied with retransmissions 00107 3. don't exceed the sending window 00108 */ 00109 return (this->activeCompound == CompoundPtr() 00110 && this->retransmissionState() == false 00111 && this->NS - this->LA < this->windowSize); 00112 } 00113 00114 00115 void 00116 SelectiveRepeat::processOutgoing(const CompoundPtr& compound) 00117 { 00118 assure(hasCapacity(), "processOutgoing called although not accepting."); 00119 activeCompound = compound; 00120 00121 SelectiveRepeatCommand* command = activateCommand(compound->getCommandPool()); 00122 this->commitSizes(compound->getCommandPool()); 00123 00124 command->peer.type = SelectiveRepeatCommand::I; 00125 command->setNS(NS); 00126 00127 MESSAGE_BEGIN(NORMAL, logger, m, "processOutgoing NS -> "); 00128 m << command->getNS(); 00129 MESSAGE_END(); 00130 00131 ++NS; 00132 00133 sendNow = true; 00134 } 00135 00136 00137 const wns::ldk::CompoundPtr 00138 SelectiveRepeat::hasACK() const 00139 { 00140 if(ackPDUs.empty() == false) 00141 { 00142 return ackPDUs.front(); 00143 } 00144 00145 return CompoundPtr(); 00146 } 00147 00148 00149 const wns::ldk::CompoundPtr 00150 SelectiveRepeat::hasData() const 00151 { 00152 if(retransmissionState() == true) 00153 { 00154 return toRetransmit.front(); 00155 } 00156 00157 if(activeCompound != CompoundPtr() && sendNow == true) 00158 { 00159 return activeCompound; 00160 } 00161 00162 return CompoundPtr(); 00163 } // hasData 00164 00165 00166 wns::ldk::CompoundPtr 00167 SelectiveRepeat::getACK() 00168 { 00169 assure(hasACK(), getFUN()->getName() + " hasSomethingToSend has not been called to check whether there is something to send."); 00170 00171 CompoundPtr nextACKToBeSent = ackPDUs.front(); 00172 ackPDUs.pop_front(); 00173 00174 MESSAGE_BEGIN(NORMAL, logger, m, "Sent ACK frame "); 00175 m << getCommand(nextACKToBeSent->getCommandPool())->getNS(); 00176 MESSAGE_END(); 00177 00178 return nextACKToBeSent; 00179 } // getACK 00180 00181 00182 wns::ldk::CompoundPtr 00183 SelectiveRepeat::getData() 00184 { 00185 if(retransmissionState() == true) 00186 { 00187 assure( 00188 toRetransmit.empty() == false, 00189 getFUN()->getName() + " is in retransmission state without anything to retransmit."); 00190 00191 MESSAGE_BEGIN(NORMAL, logger, m, "Number of Frames to retransmit: "); 00192 m << toRetransmit.size(); 00193 MESSAGE_END(); 00194 00195 // get first segment to retransmit 00196 CompoundPtr nextPDUToBeRetransmit = toRetransmit.front(); 00197 // keep track of the number of retransmissions 00198 SelectiveRepeatCommand* command = this->getCommand(nextPDUToBeRetransmit); 00199 command->localTransmissionCounter++; 00200 // record the simTime when we made the last attempt to send this compound 00201 command->local.lastSentTime = wns::simulator::getEventScheduler()->getTime(); 00202 00203 // delete from beginning of retransmission buffer and store it 00204 // to the end of the sent buffer 00205 toRetransmit.pop_front(); 00206 sentPDUs.push_back(nextPDUToBeRetransmit); 00207 00208 MESSAGE_BEGIN(NORMAL, logger, m, "Re-Sent I frame "); 00209 m << getCommand(nextPDUToBeRetransmit->getCommandPool())->getNS(); 00210 MESSAGE_END(); 00211 00212 // print out whether we leave retransmission state 00213 if(retransmissionState() == false) 00214 { 00215 MESSAGE_SINGLE(NORMAL, logger, "Leaving retransmission state"); 00216 } 00217 00218 // set the Timer 00219 this->setNewTimeout(resendTimeout); 00220 // and send a copy 00221 return nextPDUToBeRetransmit->copy(); 00222 } 00223 00224 00225 // send a copy 00226 sendNow = false; 00227 setNewTimeout(resendTimeout); 00228 SelectiveRepeatCommand* myCommand = this->getCommand(activeCompound); 00229 // record the simTime when we made the first and the last attempt to send this compound 00230 myCommand->local.firstSentTime = wns::simulator::getEventScheduler()->getTime(); 00231 myCommand->local.lastSentTime = wns::simulator::getEventScheduler()->getTime(); 00232 // keep track of the number of retransmissions 00233 myCommand->localTransmissionCounter++; 00234 CompoundPtr it = activeCompound->copy(); 00235 // store the PDU we now send in the Retransmission FIFO Buffer 00236 sentPDUs.push_back(activeCompound); 00237 // empty the space for new outgoing compounds 00238 activeCompound = CompoundPtr(); 00239 00240 MESSAGE_BEGIN(NORMAL, logger, m, "Sent I frame "); 00241 m << getCommand(it->getCommandPool())->getNS(); 00242 MESSAGE_END(); 00243 00244 return it; 00245 } 00246 00247 00248 void 00249 SelectiveRepeat::onTimeout() 00250 { 00251 assure(sentPDUs.empty() == false, "No timeout without any sent frames possible"); 00252 00253 MESSAGE_SINGLE(NORMAL, logger, "Entering retransmission state on timeout"); 00254 00255 this->prepareRetransmission(); 00256 00257 // initiate retransmissions 00258 this->tryToSend(); 00259 } 00260 00261 00262 void 00263 SelectiveRepeat::processIncoming(const CompoundPtr& compound) 00264 { 00265 SelectiveRepeatCommand *command = this->getCommand(compound); 00266 00267 switch(command->peer.type) 00268 { 00269 case SelectiveRepeatCommand::I: 00270 { 00271 this->onIFrame(compound); 00272 break; 00273 } 00274 00275 case SelectiveRepeatCommand::ACK: 00276 { 00277 this->onACKFrame(compound); 00278 break; 00279 } 00280 } 00281 } 00282 00283 void 00284 SelectiveRepeat::onIFrame(const CompoundPtr& compound) 00285 { 00286 SelectiveRepeatCommand* command = this->getCommand(compound); 00287 00288 MESSAGE_BEGIN(NORMAL, logger, m, "Received I frame."); 00289 m << " expected " << NR 00290 << " received " << command->getNS(); 00291 MESSAGE_END(); 00292 00293 if(command->getNS() == NR && delayingDelivery == false) 00294 { 00295 // this is the I frame we waited for. 00296 MESSAGE_BEGIN(NORMAL, logger, m, "Delivering I frame "); 00297 m << NR; 00298 MESSAGE_END(); 00299 00300 this->getDeliverer()->getAcceptor(compound)->onData(compound); 00301 ++NR; 00302 00303 // check if there are subsequent frames we have already received 00304 while (receivedPDUs.empty() == false) 00305 { 00306 ARQCommand::SequenceNumber toDeliver = getCommand(receivedPDUs.front())->getNS(); 00307 00308 if(toDeliver != NR) 00309 { 00310 break; 00311 } 00312 00313 assure(toDeliver == NR, 00314 "NS must be equal to NR since the loop will not be entered if it's greater zero and it cannot be smaller!!"); 00315 // if so, deliver them 00316 MESSAGE_BEGIN(NORMAL, logger, m, "Delivering I frame "); 00317 m << NR; 00318 MESSAGE_END(); 00319 00320 getDeliverer()->getAcceptor(receivedPDUs.front())->onData(receivedPDUs.front()); 00321 00322 // and remove them from the receivedPDUs list. 00323 receivedPDUs.pop_front(); 00324 MESSAGE_BEGIN(NORMAL, logger, m, "Removing from receivedPDUs: I-Frame "); 00325 m << NR; 00326 MESSAGE_END(); 00327 00328 // adjust received PDU counter 00329 ++NR; 00330 } 00331 } else { 00332 // we received an out-of-sequence frame 00333 if(command->getNS() > NR) { 00334 MESSAGE_BEGIN(NORMAL, logger, m,"Buffering out-of-sequence I frame "); 00335 m << command->getNS(); 00336 MESSAGE_END(); 00337 00338 // store the received frame for later 00339 keepSorted(compound, receivedPDUs); 00340 } else { 00341 /* we received an old frame (ACK got lost) 00342 re-send the ACK and discard the frame */ 00343 } 00344 } 00345 00346 if (delayingDelivery == false || command->getNS() > NR) 00347 { 00348 // acknowledge the received I-Frame 00349 CommandPool* ackPCI = getFUN()->getProxy()->createReply(compound->getCommandPool(), this); 00350 CompoundPtr ack = CompoundPtr(new Compound(ackPCI)); 00351 ackPDUs.push_back(ack); 00352 SelectiveRepeatCommand* ackCommand = activateCommand(ackPCI); 00353 this->commitSizes(ack->getCommandPool()); 00354 00355 ackCommand->peer.type = SelectiveRepeatCommand::ACK; 00356 ackCommand->setNS( getCommand(compound)->getNS() ); 00357 ackCommand->magic.ackSentTime = wns::simulator::getEventScheduler()->getTime(); 00358 00359 MESSAGE_BEGIN(NORMAL, logger, m, "Number of ACKs pending: "); 00360 m << ackPDUs.size(); 00361 MESSAGE_END(); 00362 } 00363 00364 } // onIFrame 00365 00366 void 00367 SelectiveRepeat::onACKFrame(const CompoundPtr& compound) 00368 { 00369 SelectiveRepeatCommand* command = this->getCommand(compound); 00370 00371 // Delete ACKed frame from one of the retransmission buffers 00372 // it may happen, that due to duplicate ACKs the PDU is neither in sentPDUs 00373 // nor in toRetransmit 00374 this->removeACKed(compound, this->sentPDUs); 00375 this->removeACKed(compound, this->toRetransmit); 00376 00377 if(command->getNS() == this->LA ) 00378 { 00379 // received the expected ACK 00380 MESSAGE_BEGIN(NORMAL, this->logger, m, "Received ACK frame."); 00381 m << " expected " << this->LA << " received " << command->getNS(); 00382 MESSAGE_END(); 00383 // adjust counter (advance sending window) 00384 this->LA++; 00385 // probe the time this ACK took to travel back to me 00386 this->ackDelayProbeBus->put( compound, wns::simulator::getEventScheduler()->getTime() - command->magic.ackSentTime ); 00387 00388 // Now check if subsequent ACKs have been received before 00389 while(this->receivedACKs.empty() == false) 00390 { 00391 if(this->getCommand(this->receivedACKs.front())->getNS() == this->LA) 00392 { 00393 this->LA++; 00394 this->receivedACKs.front() = CompoundPtr(); 00395 this->receivedACKs.pop_front(); 00396 } 00397 else 00398 { 00399 break; 00400 } 00401 } 00402 this->trySuspend(); 00403 } 00404 else 00405 { 00406 //received out-of-sequence ACK 00407 MESSAGE_BEGIN(NORMAL, logger, m, "Received Out-of-sequence ACK frame"); 00408 m << " expected " << this->LA << " received " << command->getNS(); 00409 MESSAGE_END(); 00410 00411 // probe the time this ACK took to travel back to me 00412 this->ackDelayProbeBus->put( compound, wns::simulator::getEventScheduler()->getTime() - command->magic.ackSentTime ); 00413 00414 if (command->getNS() > this->LA) 00415 { 00416 // Enter Retransmission State 00417 MESSAGE_SINGLE(NORMAL, logger,"Entering retransmission state on out-of-sequence ACK"); 00418 // push current ACK to the list of received ones 00419 this->keepSorted(compound, this->receivedACKs); 00420 // prepare PDU List for Retransmission 00421 this->prepareRetransmission(); 00422 if (this->retransmissionState() == false) 00423 { 00424 MESSAGE_SINGLE(NORMAL, logger,"Leaving retransmission state, no Retransmissions pending."); 00425 } 00426 } 00427 else 00428 { 00429 MESSAGE_SINGLE(NORMAL, logger, "ACK is a duplicate, discarding ..."); 00430 } 00431 } 00432 00433 if (this->sentPDUs.empty() == true && this->hasTimeoutSet() == true) 00434 { 00435 this->cancelTimeout(); 00436 } 00437 // Take care of pending retransmissions, if any 00438 if (this->retransmissionState()) 00439 { 00440 this->tryToSend(); 00441 } 00442 } // onACKFrame 00443 00444 00445 void 00446 SelectiveRepeat::calculateSizes(const CommandPool* commandPool, Bit& commandPoolSize, Bit& sduSize) const 00447 { 00448 //What are the sizes in the upper Layers 00449 getFUN()->calculateSizes(commandPool, commandPoolSize, sduSize, this); 00450 00451 00452 MESSAGE_SINGLE(VERBOSE, logger, "Size calc - Command: "<<commandPoolSize<<" Payload: "<<sduSize); 00453 00454 MESSAGE_SINGLE(VERBOSE, logger, "Size of SR-ARQ Command: "<<commandSize<<" Bit"); 00455 00456 commandPoolSize += commandSize; 00457 00458 MESSAGE_SINGLE(VERBOSE, logger, "Size calc - Command: "<<commandPoolSize<<" Payload: "<<sduSize); 00459 } // calculateSizes 00460 00461 00462 void 00463 SelectiveRepeat::prepareRetransmission() 00464 { 00465 bool retransmitAll = false; 00466 ARQCommand::SequenceNumber lastACK(0); 00467 if (receivedACKs.empty() == true) 00468 { 00469 // no ACKs received so far 00470 retransmitAll = true; 00471 } 00472 else 00473 { 00474 // remember the last ACK 00475 lastACK = this->getCommand(receivedACKs.back())->getNS(); 00476 } 00477 00478 for (CompoundContainer::iterator it = sentPDUs.begin(); it != sentPDUs.end(); ) 00479 { 00480 SelectiveRepeatCommand* command = this->getCommand(*it); 00481 ARQCommand::SequenceNumber lookingAt = command->getNS(); 00482 if ( lookingAt < lastACK || retransmitAll ) 00483 { 00484 if (command->local.lastSentTime+retransmissionInterval <= wns::simulator::getEventScheduler()->getTime() 00485 || 00486 command->local.lastSentTime==command->local.firstSentTime) 00487 { 00488 MESSAGE_BEGIN(NORMAL, logger, m, "Chosing I-Frame "); 00489 m << lookingAt << " for retransmission:"; 00490 MESSAGE_END(); 00491 00492 CompoundContainer::iterator copyOfIt = it++; 00493 toRetransmit.push_back((*copyOfIt)); 00494 00495 // collect statistics available for other FUs 00496 this->statusCollector->onFailedTransmission((*copyOfIt)); 00497 00498 sentPDUs.erase(copyOfIt); 00499 continue; 00500 } 00501 } 00502 ++it; 00503 } 00504 } // prepareRetransmission 00505 00506 00507 void 00508 SelectiveRepeat::keepSorted(const CompoundPtr& compound, CompoundContainer& container) 00509 { 00510 SelectiveRepeatCommand* command = this->getCommand(compound); 00511 00512 ARQCommand::SequenceNumber toInsert = command->getNS(); 00513 CompoundContainer::iterator it; 00514 CompoundContainer::iterator itEnd = container.end(); 00515 00516 for(it = container.begin(); it != itEnd; ++it) 00517 { 00518 ARQCommand::SequenceNumber lookingAt = getCommand(*it)->getNS(); 00519 00520 if(lookingAt == toInsert) 00521 { 00522 MESSAGE_SINGLE(NORMAL, logger, "Don't need to insert, already in list"); 00523 return; 00524 } 00525 00526 if(lookingAt > toInsert) 00527 { 00528 break; 00529 } 00530 } 00531 container.insert(it, compound); 00532 } // keepSorted 00533 00534 00535 // remove ACKed PDU from list 00536 void 00537 SelectiveRepeat::removeACKed(const CompoundPtr& ackCompound, CompoundContainer& container) 00538 { 00539 SelectiveRepeatCommand* command = getCommand(ackCompound->getCommandPool()); 00540 int NS = command->getNS(); 00541 for(CompoundContainer::iterator iter = container.begin(); iter != container.end(); ++iter ) 00542 { 00543 if(getCommand((*iter)->getCommandPool())->getNS() == NS) 00544 { 00545 // a probe counting the number of transmissions needed 00546 transmissionAttemptsProbeBus->put( ackCompound, getCommand(*iter)->localTransmissionCounter); 00547 // a probe counting the RoundTripTime needed 00548 simTimeType rtt = wns::simulator::getEventScheduler()->getTime() - getCommand((*iter)->getCommandPool())->local.firstSentTime; 00549 roundTripTimeProbeBus->put(ackCompound, rtt); 00550 // adjust min time between retransmissions to two times the RTT 00551 retransmissionInterval = std::min<simTimeType>(2*rtt, retransmissionInterval); 00552 00553 // collect statistics available for other FUs 00554 this->statusCollector->onSuccessfullTransmission((*iter)); 00555 00556 MESSAGE_BEGIN(NORMAL, logger, m, "ACK frame received after "); 00557 m << rtt << " s and " << getCommand(*iter)->localTransmissionCounter << " transmission attempts. RTI is now " << retransmissionInterval; 00558 MESSAGE_END(); 00559 container.erase(iter); 00560 break; 00561 } 00562 } 00563 } 00564 00565 // return whether we are in retransmission mode 00566 bool 00567 SelectiveRepeat::retransmissionState() const 00568 { 00569 return !toRetransmit.empty(); 00570 } 00571 00572 bool 00573 SelectiveRepeat::onSuspend() const 00574 { 00575 return NS == LA; 00576 } // onSuspend 00577 00578 void 00579 SelectiveRepeat::doDelayDelivery() 00580 { 00581 delayingDelivery = true; 00582 } // doDelayDelivery 00583 00584 void 00585 SelectiveRepeat::doDeliver() 00586 { 00587 delayingDelivery = false; 00588 00589 // check if there are subsequent frames we have already received 00590 while (!receivedPDUs.empty()) { 00591 ARQCommand::SequenceNumber toDeliver = getCommand(receivedPDUs.front())->getNS(); 00592 00593 if(toDeliver != NR) 00594 { 00595 break; 00596 } 00597 00598 assure(toDeliver == NR, 00599 "NS must be equal to NR since the loop will not be entered if it's greater zero and it cannot be smaller!!"); 00600 // if so, deliver them 00601 MESSAGE_BEGIN(NORMAL, logger, m, "Delivering I frame "); 00602 m << NR; 00603 MESSAGE_END(); 00604 00605 getDeliverer()->getAcceptor(receivedPDUs.front())->onData(receivedPDUs.front()); 00606 00607 // and remove them from the receivedPDUs list. 00608 receivedPDUs.pop_front(); 00609 MESSAGE_BEGIN(NORMAL, logger, m, "Removing from receivedPDUs: I-Frame "); 00610 m << NR; 00611 MESSAGE_END(); 00612 00613 // adjust received PDU counter 00614 ++NR; 00615 } 00616 00617 } // doDeliver 00618 00619
1.5.5