User Manual, Developers Guide and API Documentation

BaseState.cpp

Go to the documentation of this file.
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 <GLUE/arqfsm/selectiverepeat/BaseState.hpp>
00014 
00015 using namespace glue::arqfsm::selectiverepeat;
00016 using namespace wns::ldk;
00017 
00018 void
00019 BaseState::deliverCompounds()
00020 {
00021     while (vars().receivedCompounds[vars().leastNR])
00022     {
00023         MESSAGE_BEGIN(NORMAL, vars().logger, m, getFUNName());
00024         m << " Delivering compound "
00025           << vars().leastNR;
00026         MESSAGE_END();
00027 
00028         sendOnData(vars().receivedCompounds[vars().leastNR]);
00029         vars().receivedCompounds[vars().leastNR] = CompoundPtr();
00030 
00031         vars().leastNR = (vars().leastNR + 1) % vars().sequenceNumberSize;
00032     }
00033 } // deliverCompounds
00034 
00035 
00036 void
00037 BaseState::tryToSendACKs()
00038 {
00039     while (!vars().pendingACKsQueue.empty())
00040     {
00041         CompoundPtr ackCompound = vars().pendingACKsQueue.front();
00042         if (isAccepting(ackCompound))
00043         {
00044             vars().pendingACKsQueue.pop_front();
00045             sendSendData(ackCompound->copy());
00046         }
00047         else
00048             break;
00049     }
00050 } // tryToSendACKs
00051 
00052 
00053 void
00054 BaseState::tryToSendIs()
00055 {
00056     while (!vars().pendingCompoundsQueue.empty())
00057     {
00058         CompoundPtr compound = vars().pendingCompoundsQueue.front();
00059         if (isAccepting(compound))
00060         {
00061             vars().pendingCompoundsQueue.pop_front();
00062 
00063             FSMFU* fsmfu = dynamic_cast<FSMFU*>(getFU());
00064             fsmfu->setTimeout(compound, vars().resendTimeout);
00065 
00066             sendSendData(compound->copy());
00067         }
00068         else
00069             break;
00070     }
00071 } // tryToSendIs
00072 
00073 
00074 StateInterface*
00075 BaseState::onI(const CompoundPtr& compound, int sequenceNumber)
00076 {
00077     MESSAGE_BEGIN(NORMAL, vars().logger, m, getFUNName());
00078     m << " Received I frame "
00079       << sequenceNumber;
00080     MESSAGE_END();
00081 
00082     if (sequenceNumber < 0 || sequenceNumber >= vars().sequenceNumberSize)
00083         throw wns::Exception("Sequence number out of bounds");
00084 
00085     if ((sequenceNumber - vars().leastNR + vars().sequenceNumberSize) % vars().sequenceNumberSize
00086        < vars().windowSize)
00087     {
00088         vars().receivedCompounds[sequenceNumber] = compound;
00089 
00090         if (!vars().delayingDelivery)
00091             deliverCompounds();
00092     }
00093 
00094     if ((vars().delayingDelivery &&
00095          (sequenceNumber - vars().leastNR + vars().sequenceNumberSize) % vars().sequenceNumberSize < vars().windowSize) ||
00096         !vars().delayingDelivery)
00097     {
00098         if (!pendingACK(sequenceNumber))
00099         {
00100             CompoundPtr ackCompound = createReply(compound);
00101 
00102             SelectiveRepeatCommand* ackCommand =
00103                 dynamic_cast<SelectiveRepeatCommand*>(getFU()->activateCommand(ackCompound->getCommandPool()));
00104             assure(ackCommand, "Command is not a SelectiveRepeatCommand.");
00105 
00106             ackCommand->peer.type = SelectiveRepeatCommand::ACK;
00107             ackCommand->peer.NS = sequenceNumber;
00108 
00109             vars().pendingACKsQueue.push_back(ackCompound);
00110 
00111             tryToSendACKs();
00112         }
00113     }
00114 
00115     return this;
00116 } // onI
00117 
00118 
00119 bool
00120 BaseState::pendingACK(int sequenceNumber)
00121 {
00122     Variables::CompoundQueue::iterator it;
00123 
00124     for (it = vars().pendingACKsQueue.begin();
00125          it != vars().pendingACKsQueue.end();
00126          ++it)
00127     {
00128         SelectiveRepeatCommand* ackCommand =
00129             dynamic_cast<SelectiveRepeatCommand*>(getFU()->getCommand((*it)->getCommandPool()));
00130         assure(ackCommand, "Command is not a SelectiveRepeatCommand.");
00131 
00132         assure(SelectiveRepeatCommand::ACK == ackCommand->peer.type, "Invalid frame type.");
00133 
00134         if (ackCommand->peer.NS == sequenceNumber)
00135             return true;
00136     }
00137 
00138     return false;
00139 } // pendingACK
00140 
00141 

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