User Manual, Developers Guide and API Documentation

ReceptionQueue.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiFiMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2007
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 16, D-52074 Aachen, Germany
00009  * phone: ++49-241-80-27910,
00010  * fax: ++49-241-80-22242
00011  * email: info@openwns.org
00012  * www: http://www.openwns.org
00013  * _____________________________________________________________________________
00014  *
00015  * openWNS is free software; you can redistribute it and/or modify it under the
00016  * terms of the GNU Lesser General Public License version 2 as published by the
00017  * Free Software Foundation;
00018  *
00019  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00020  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00021  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00022  * details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026  *
00027  ******************************************************************************/
00028 
00029 #include <WIFIMAC/draftn/BlockACK.hpp>
00030 #include <WIFIMAC/draftn/ReceptionQueue.hpp>
00031 
00032 using namespace wifimac::draftn;
00033 
00034 ReceptionQueue::ReceptionQueue(BlockACK* parent_, BlockACKCommand::SequenceNumber firstSN_, wns::service::dll::UnicastAddress adr_):
00035     parent(parent_),
00036     adr(adr_),
00037     waitingForSN(firstSN_),
00038     rxStorage(),
00039     rxSNs(),
00040     blockACK()
00041 {
00042     MESSAGE_SINGLE(NORMAL, parent->logger, "RxQ" << adr << " created");
00043 } // ReceptionQueue
00044 
00045 const unsigned int
00046 ReceptionQueue::storageSize() const
00047 {
00048     unsigned int size = 0;
00049 
00050     for(std::map<BlockACKCommand::SequenceNumber, CompoundPtrWithSize>::const_iterator it = rxStorage.begin();
00051         it != rxStorage.end();
00052         it++)
00053     {
00054         size += it->second.second;
00055     }
00056     return(size);
00057 } // ReceptionQueue::size
00058 
00059 void
00060 ReceptionQueue::processIncomingData(const wns::ldk::CompoundPtr& compound, const unsigned int size)
00061 {
00062     assure(this->blockACK == wns::ldk::CompoundPtr(), "Received blockACKreq - cannot process more incoming data");
00063 
00064     BlockACKCommand* baCommand = parent->getCommand(compound->getCommandPool());
00065     assure(baCommand->peer.type == I, "can only process incoming data");
00066 
00067     // store sn for ack
00068     rxSNs.insert(baCommand->peer.sn);
00069 
00070     // process data compound
00071     if(baCommand->peer.sn == this->waitingForSN)
00072     {
00073         MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received SN ");
00074         m << baCommand->peer.sn;
00075         m << ", waiting for " << this->waitingForSN;
00076         m << " --> deliver ";
00077         MESSAGE_END();
00078 
00079         parent->getDeliverer()->getAcceptor(compound)->onData(compound);
00080         ++this->waitingForSN;
00081         // check if other compounds from the rxQueue can be delivered now
00082         this->purgeRxStorage();
00083     }
00084     else
00085     {
00086         // received compound does not match waitingForSN
00087 
00088         if((baCommand->peer.sn < this->waitingForSN) or (rxStorage.find(baCommand->peer.sn) != rxStorage.end()))
00089         {
00090             // received old compound
00091             MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received known SN ");
00092             m << baCommand->peer.sn;
00093             m << ", waiting for " << this->waitingForSN;
00094             m << " --> drop";
00095             MESSAGE_END();
00096         }
00097         else
00098         {
00099             // received new compound
00100             MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received new SN ");
00101             m << baCommand->peer.sn;
00102             m << ", waiting for " << this->waitingForSN;
00103             m << " --> store";
00104             MESSAGE_END();
00105             rxStorage[baCommand->peer.sn] = CompoundPtrWithSize(compound, size);
00106         }
00107     }
00108 
00109 } // ReceptionQueue::processIncomingData
00110 
00111 void
00112 ReceptionQueue::purgeRxStorage()
00113 {
00114    while(not rxStorage.empty())
00115    {
00116        if(rxStorage.begin()->first == this->waitingForSN)
00117        {
00118            MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": New SN allows in-order delivery SN ");
00119            m << this->waitingForSN;
00120            m << " --> deliver";
00121            MESSAGE_END();
00122 
00123            parent->getDeliverer()->getAcceptor(rxStorage.begin()->second.first)->onData(rxStorage.begin()->second.first);
00124            rxStorage.erase(rxStorage.begin());
00125            ++this->waitingForSN;
00126        }
00127        else
00128        {
00129            // gap still exists
00130            return;
00131        }
00132    }
00133 } // ReceptionQueue::purgeRxStorage
00134 
00135 void
00136 ReceptionQueue::processIncomingACKreq(const wns::ldk::CompoundPtr& compound)
00137 {
00138     assure(this->blockACK == wns::ldk::CompoundPtr(), "Already prepared blockACK");
00139 
00140     // the sn in the BAreq gives the minimum SN that shall be acknowledged, all
00141     // frames before that sn are discarded due to maximum lifetime or
00142     // retransmissions
00143     BlockACKCommand::SequenceNumber minSN = parent->getCommand(compound->getCommandPool())->peer.sn;
00144     // stop waiting for everything below the minSN
00145     while((not rxStorage.empty()) and (rxStorage.begin()->first < minSN))
00146     {
00147         MESSAGE_SINGLE(NORMAL, parent->logger, "RxQ" << adr << ": Received BAreq with SN " << minSN << " -> deliver waiting SN " << rxStorage.begin()->first);
00148         parent->getDeliverer()->getAcceptor(rxStorage.begin()->second.first)->onData(rxStorage.begin()->second.first);
00149         rxStorage.erase(rxStorage.begin());
00150     }
00151     // waitingForSN is never reduced
00152     this->waitingForSN = (minSN > this->waitingForSN) ? (minSN) : (this->waitingForSN);
00153     // shift of waitingForSN might free already received frames
00154     this->purgeRxStorage();
00155 
00156     // do not acknowledge old frames
00157     while((not rxSNs.empty()) and (*(rxSNs.begin()) < minSN))
00158     {
00159         rxSNs.erase(rxSNs.begin());
00160     }
00161 
00162     // create BlockACK
00163     wns::simulator::Time fxDur = parent->friends.manager->getFrameExchangeDuration(compound->getCommandPool()) - parent->sifsDuration - parent->maximumACKDuration;
00164     if (fxDur < parent->sifsDuration)
00165     {
00166         fxDur = 0;
00167     }
00168 
00169     MESSAGE_SINGLE(NORMAL,parent->logger,"create BA with exchange duration : " << fxDur);
00170     this->blockACK = parent->friends.manager->createCompound(parent->friends.manager->getMACAddress(),
00171                                                              adr,
00172                                                              ACK,
00173                                                              fxDur,
00174                                                              false);
00175     parent->friends.manager->setPhyMode(this->blockACK->getCommandPool(),
00176                                         parent->blockACKPhyMode);
00177 
00178     // set baCommand information
00179     BlockACKCommand* baCommand = parent->activateCommand(this->blockACK->getCommandPool());
00180     baCommand->peer.type = BA;
00181     baCommand->peer.ackSNs = rxSNs;
00182     if(rxSNs.empty())
00183     {
00184         baCommand->peer.sn = this->waitingForSN;
00185     }
00186     else
00187     {
00188         // take the minimum of waiting for and rxSNs
00189         baCommand->peer.sn = (*(rxSNs.begin())) < this->waitingForSN ? (*(rxSNs.begin())) : this->waitingForSN;
00190     }
00191 
00192     MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received BAreq with SN ");
00193     m << minSN;
00194     m << ", prepare BA with ";
00195     m << " fExDur " << parent->friends.manager->getFrameExchangeDuration(this->blockACK->getCommandPool());
00196     m << " startSN: " << baCommand->peer.sn;
00197     m << " ackSNs:";
00198 #ifndef WNS_NO_LOGGING
00199     for(std::set<BlockACKCommand::SequenceNumber>::iterator snIt = rxSNs.begin();
00200         snIt != rxSNs.end();
00201         snIt++)
00202     {
00203         m << " " << (*snIt);
00204     }
00205 #endif
00206     MESSAGE_END();
00207 
00208     rxSNs.clear();
00209 
00210 } // ReceptionQueue::processIncomingACKreq
00211 
00212 const wns::ldk::CompoundPtr
00213 ReceptionQueue::hasACK() const
00214 {
00215     return(this->blockACK);
00216 } // ReceptionQueue::hasACK
00217 
00218 wns::ldk::CompoundPtr
00219 ReceptionQueue::getACK()
00220 {
00221     assure(hasACK(), "Called getACK although no ack prepared?");
00222     assure(this->blockACK != wns::ldk::CompoundPtr(), "Called getACK but blockACK is empty?");
00223 
00224     wns::ldk::CompoundPtr it = this->blockACK;
00225     this->blockACK = wns::ldk::CompoundPtr();
00226 
00227     MESSAGE_SINGLE(NORMAL, parent->logger, "RxQ" << adr << ": Transmit BA");
00228 
00229     return(it);
00230 } // ReceptionQueue::getACK

Generated on Fri May 25 03:32:09 2012 for openWNS by  doxygen 1.5.5