User Manual, Developers Guide and API Documentation

InnerQueue.cpp

Go to the documentation of this file.
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/scheduler/queue/detail/InnerQueue.hpp>
00029 
00030 #include <WNS/scheduler/queue/ISegmentationCommand.hpp>
00031 #include <WNS/ldk/CommandTypeSpecifier.hpp>
00032 
00033 #include <WNS/simulator/ISimulator.hpp>
00034 #include <WNS/ldk/probe/TickTack.hpp>
00035 
00036 
00037 using namespace wns::scheduler::queue::detail;
00038 
00039 InnerQueue::InnerQueue():
00040     nettoBits_(0),
00041     sequenceNumber_(0),
00042     frontSegmentSentBits_(0)
00043 {
00044 }
00045 
00046 Bit
00047 InnerQueue::queuedNettoBits() const
00048 {
00049     return nettoBits_;
00050 }
00051 
00052 Bit
00053 InnerQueue::queuedBruttoBits(Bit fixedHeaderSize, Bit extensionHeaderSize, bool byteAlignHeader) const
00054 {
00055     if (queuedNettoBits() == 0)
00056     {
00057         return 0;
00058     }
00059     else
00060     {
00061         Bit headerSize = fixedHeaderSize + (pduQueue_.size() - 1) * extensionHeaderSize;
00062         if (byteAlignHeader)
00063         {
00064             headerSize += headerSize % 8;
00065         }
00066         return headerSize + queuedNettoBits();
00067     }
00068 }
00069 
00070 int
00071 InnerQueue::queuedCompounds() const
00072 {
00073     return pduQueue_.size();
00074 }
00075 
00076 bool
00077 InnerQueue::empty() const
00078 {
00079     return pduQueue_.empty();
00080 }
00081 
00082 void
00083 InnerQueue::put(const wns::ldk::CompoundPtr& compound)
00084 {
00085     pduQueue_.push(compound);
00086 
00087     nettoBits_ += compound->getLengthInBits();
00088 }
00089 
00090 wns::ldk::CompoundPtr
00091 InnerQueue::retrieve(Bit requestedBits, Bit fixedHeaderSize, Bit extensionHeaderSize, 
00092     bool usePadding, bool byteAlignHeader, wns::ldk::CommandReaderInterface* reader,
00093     const wns::probe::bus::ContextCollectorPtr& probeCC,
00094     wns::ldk::CommandReaderInterface* probeCmdReader)
00095 {
00096     if (requestedBits <= fixedHeaderSize)
00097     {
00098         throw RequestBelowMinimumSize(requestedBits, fixedHeaderSize);
00099     }
00100 
00101     if (pduQueue_.size() <= 0)
00102     {
00103         throw RetrieveException("Queue is empty");
00104     }
00105 
00106     wns::ldk::CompoundPtr pdu(pduQueue_.front()->copy());
00107 
00108     assure(reader != NULL, "No valid segmentHeaderReader given!");
00109 
00110     reader->activateCommand(pdu->getCommandPool());
00111 
00112     ISegmentationCommand* header = reader->readCommand<ISegmentationCommand>(pdu->getCommandPool());
00113 
00114     header->increaseHeaderSize(fixedHeaderSize);
00115 
00116     header->setSequenceNumber(sequenceNumber_);
00117     sequenceNumber_ += 1;
00118 
00119     (frontSegmentSentBits_ == 0) ? header->setBeginFlag():header->clearBeginFlag();
00120 
00121     while (header->totalSize() < requestedBits)
00122     {
00123         wns::ldk::CompoundPtr c = pduQueue_.front();
00124         Bit length = c->getLengthInBits() - frontSegmentSentBits_; // netto
00125         Bit capacity = requestedBits - header->totalSize(); // netto
00126         if (capacity >= length)
00127         {
00128             // fits in completely
00129             header->addSDU(c->copy());
00130             header->increaseDataSize(length);
00131             probe(c, probeCC, probeCmdReader); 
00132             pduQueue_.pop();
00133             frontSegmentSentBits_ = 0;
00134             nettoBits_ -= length;
00135 
00136             Bit headerPadding = 0;
00137             if ( byteAlignHeader )
00138             {
00139                 headerPadding = (header->headerSize() + extensionHeaderSize) % 8;
00140             }
00141 
00142             if ( (header->totalSize() + extensionHeaderSize + headerPadding < requestedBits) &&
00143                  (pduQueue_.size() > 0))
00144             {
00145                 header->increaseHeaderSize(extensionHeaderSize);
00146             }
00147             else
00148             {
00149                 break;
00150             }
00151         }
00152         else
00153         {
00154             Bit headerPadding = 0;
00155             if ( byteAlignHeader )
00156             {
00157                 headerPadding = header->headerSize() % 8;
00158             }
00159             // only a fraction fits in
00160             header->addSDU(c->copy());
00161             header->increaseDataSize(capacity - headerPadding);
00162             header->increaseHeaderSize(headerPadding);
00163             frontSegmentSentBits_ += capacity - headerPadding;
00164             nettoBits_ -= capacity - headerPadding;
00165             assure(frontSegmentSentBits_ < pduQueue_.front()->getLengthInBits(), "frontSegmentSentBits_ is larger than the front PDU size!");
00166         }
00167     }
00168 
00169     // remaining bits:
00170     if (pduQueue_.size()==0)
00171     {
00172         nettoBits_ = 0;
00173     }
00174 
00175     // Is the last segment in the PDU a fragment? Then clear end flag
00176     (frontSegmentSentBits_ == 0) ? header->setEndFlag():header->clearEndFlag();
00177 
00178     if (byteAlignHeader)
00179     {
00180         header->increaseHeaderSize(header->headerSize() % 8);
00181     }
00182 
00183     // Rest is padding (optional)
00184     if (usePadding) {
00185         header->increasePaddingSize(requestedBits - header->totalSize());
00186     }
00187 
00188     assure(header->totalSize()<=requestedBits,"pdulength="<<header->totalSize()<<" > bits="<<requestedBits);
00189     return pdu;
00190 }
00191 
00192 std::queue<wns::ldk::CompoundPtr> 
00193 InnerQueue::getQueueCopy()
00194 {
00195     return pduQueue_;
00196 }
00197 
00198 void
00199 InnerQueue::probe(const wns::ldk::CompoundPtr& compound,
00200     const wns::probe::bus::ContextCollectorPtr& probeCC,
00201     wns::ldk::CommandReaderInterface* cmdReader)
00202 {
00203     assure(compound != wns::ldk::CompoundPtr(), "No valid compound");
00204 
00205     if(cmdReader == NULL ||
00206         probeCC == wns::probe::bus::ContextCollectorPtr())
00207         return;
00208 
00209     wns::ldk::probe::TickTackCommand* cmd;
00210     cmd = cmdReader->readCommand<wns::ldk::probe::TickTackCommand>(compound->getCommandPool());
00211     assure(cmd != NULL, "Cannot get TickTackCommand to probe delay");
00212 
00213     wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime();
00214     probeCC->put(compound, now - cmd->magic.tickTime);
00215 }
00216 
00217 

Generated on Thu May 24 03:31:49 2012 for openWNS by  doxygen 1.5.5