User Manual, Developers Guide and API Documentation

DynamicSAR.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/ldk/sar/DynamicSAR.hpp>
00029 #include <WNS/ldk/fun/FUN.hpp>
00030 #include <WNS/ldk/Layer.hpp>
00031 
00032 #include <WNS/search/ISearch.hpp>
00033 #include <WNS/search/SearchCreator.hpp>
00034 
00035 #include <WNS/Assure.hpp>
00036 
00037 #include <boost/bind.hpp>
00038 #include <algorithm>
00039 
00040 using namespace wns::ldk;
00041 using namespace wns::ldk::sar;
00042 
00043 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00044     DynamicSAR,
00045     FunctionalUnit,
00046     "wns.sar.DynamicSAR",
00047     FUNConfigCreator);
00048 
00049 DynamicSAR::DynamicSAR(fun::FUN* fuNet, const wns::pyconfig::View& config) :
00050     fu::Plain<DynamicSAR, DynamicSARCommand>(fuNet),
00051     maxSegmentSize_(config.get<int>("maxSegmentSize")),
00052     searchAlgo_(wns::search::SearchFactory::creator(config.get<std::string>("searchAlgo"))
00053                 ->create(0, 0, boost::bind(&DynamicSAR::compare, this, _1))),
00054     currentCompound_(),
00055     currentCompoundSize_(0),
00056     currentCompoundSentSize_(0),
00057     segmentNumber_(1),
00058     currentSegInfoPtr_(),
00059     logger_(config.get("logger"))
00060 {
00061     MESSAGE_BEGIN(NORMAL, logger_, m, "");
00062     m << "Instantiating FU...\n"
00063       << "Parameters: max. segment size = " << maxSegmentSize_ << "bit\n"
00064       << "            algorithm to determine current segment size = "
00065       << config.get<std::string>("searchAlgo");
00066     MESSAGE_END();
00067 } // DynamicSAR
00068 
00069 DynamicSAR::~DynamicSAR()
00070 {
00071     delete searchAlgo_;
00072 } // ~DynamicSAR
00073 
00074 void
00075 DynamicSAR::doSendData(const CompoundPtr& compound)
00076 {
00077     currentCompound_ = compound;
00078 
00079     Bit commandPoolSize = 0;
00080     Bit dataSize = 0;
00081 
00082     CompoundPtr compoundCopy = compound->copy();
00083     activateCommand(compoundCopy->getCommandPool());
00084     getFUN()->calculateSizes(compoundCopy->getCommandPool(), commandPoolSize, dataSize, this);
00085 
00086     currentCompoundSize_ = commandPoolSize + dataSize;
00087 
00088     MESSAGE_BEGIN(NORMAL, logger_, m, "");
00089     m << "Segmenting new compound: compound size = " << currentCompoundSize_ << "bit";
00090     MESSAGE_END();
00091 
00092     currentCompoundSentSize_ = 0;
00093 
00094     segmentNumber_ = 1;
00095     currentSegInfoPtr_ = DynamicSARCommand::SegmentationInfoPtr(new DynamicSARCommand::SegmentationInfo());
00096 
00097     sendSegments();
00098 } // doSendData
00099 
00100 void
00101 DynamicSAR::doOnData(const CompoundPtr& compound)
00102 {
00103     DynamicSARCommand* command = getCommand(compound->getCommandPool());
00104 
00105     MESSAGE_BEGIN(NORMAL, logger_, m, "");
00106     Bit commandPoolSize = 0;
00107     Bit dataSize = 0;
00108     calculateSizes(compound->getCommandPool(), commandPoolSize, dataSize);
00109     m << "Receiving segment: segment size = " << commandPoolSize + dataSize << "bit"
00110       << ", segment number = " << command->local.segmentNumber << "\n"
00111       << "                   received segments = [";
00112     for (std::list<int>::iterator it = command->magic.segInfoPtr->receivedSegments.begin();
00113          it != command->magic.segInfoPtr->receivedSegments.end();
00114          it++)
00115     {
00116         if (it != command->magic.segInfoPtr->receivedSegments.begin())
00117             m << ", ";
00118         m << (*it);
00119     }
00120     m << "]";
00121     MESSAGE_END();
00122 
00123     assure(std::find(command->magic.segInfoPtr->receivedSegments.begin(),
00124                      command->magic.segInfoPtr->receivedSegments.end(),
00125                      command->local.segmentNumber)
00126            == command->magic.segInfoPtr->receivedSegments.end(),
00127            "Received same segment twice!");
00128 
00129     command->magic.segInfoPtr->receivedSegments.push_back(command->local.segmentNumber);
00130 
00131     if (command->magic.segInfoPtr->numberSegments
00132         == command->magic.segInfoPtr->receivedSegments.size())
00133     {
00134         MESSAGE_BEGIN(NORMAL, logger_, m, "");
00135         Bit commandPoolSize = 0;
00136         Bit dataSize = 0;
00137         getFUN()->calculateSizes(compound->getCommandPool(), commandPoolSize, dataSize, this);
00138         m << "Delivering reassembled compound: compound size = " << commandPoolSize + dataSize << "bit"
00139           << ", number of segments = " << command->magic.segInfoPtr->numberSegments;
00140         MESSAGE_END();
00141 
00142         getDeliverer()->getAcceptor(compound)->onData(compound);
00143     }
00144 } // doOnData
00145 
00146 
00147 bool
00148 DynamicSAR::doIsAccepting(const CompoundPtr& compound) const
00149 {
00150     if(currentCompound_ != NULL)
00151         return false;
00152 
00153     CompoundPtr compoundCopy = compound->copy();
00154 
00155     activateCommand(compoundCopy->getCommandPool());
00156 
00157     MESSAGE_BEGIN(NORMAL, logger_, m, "");
00158     Bit commandPoolSize = 0;
00159     Bit dataSize = 0;
00160     calculateSizes(compoundCopy->getCommandPool(), commandPoolSize, dataSize);
00161     m << "Checking if compound with size = " << commandPoolSize + dataSize
00162       << "bit is being accepted by lower FU";
00163     MESSAGE_END();
00164 
00165     bool accepting = getConnector()->hasAcceptor(compoundCopy);
00166 
00167     MESSAGE_BEGIN(NORMAL, logger_, m, "");
00168     m << "Lower FU is ";
00169     if (!accepting)
00170         m << "not ";
00171     m << "accepting the compound";
00172     MESSAGE_END();
00173 
00174     return accepting;
00175 } // doIsAccepting
00176 
00177 
00178 void
00179 DynamicSAR::doWakeup()
00180 {
00181     if (currentCompound_ != NULL)
00182         sendSegments();
00183 
00184     getReceptor()->wakeup();
00185 } // doWakeup
00186 
00187 
00188 void
00189 DynamicSAR::calculateSizes(const CommandPool* commandPool, Bit& commandPoolSize, Bit& sduSize) const
00190 {
00191     DynamicSARCommand* command = getCommand(commandPool);
00192 
00193     commandPoolSize = 0;
00194     sduSize = command->magic.segmentSize;
00195 } // calculateSizes
00196 
00197 
00198 bool
00199 DynamicSAR::compare(Bit currentSegmentSize)
00200 {
00201     CompoundPtr compoundCopy = currentCompound_->copy();
00202 
00203     DynamicSARCommand* command = activateCommand(compoundCopy->getCommandPool());
00204     command->magic.segmentSize = currentSegmentSize;
00205 
00206     return getConnector()->hasAcceptor(compoundCopy);
00207 } // compare
00208 
00209 
00210 void
00211 DynamicSAR::sendSegments()
00212 {
00213     while (true)
00214     {
00215         int currentMaxSegmentSize = maxSegmentSize_;
00216 
00217         if (currentCompoundSize_ - currentCompoundSentSize_ < maxSegmentSize_)
00218             currentMaxSegmentSize = currentCompoundSize_ - currentCompoundSentSize_;
00219 
00220         int segmentSize = searchAlgo_->search(currentMaxSegmentSize + 1);
00221         if (segmentSize < 1)
00222             return;
00223 
00224         MESSAGE_BEGIN(NORMAL, logger_, m, "");
00225         m << "Sending segment: current max. segment size = " << currentMaxSegmentSize
00226           << "bit, segment size = " << segmentSize
00227           << "bit, segment number = " << segmentNumber_;
00228         MESSAGE_END();
00229 
00230         currentCompoundSentSize_ += segmentSize;
00231 
00232         CompoundPtr compoundCopy = currentCompound_->copy();
00233         DynamicSARCommand* command = activateCommand(compoundCopy->getCommandPool());
00234         command->local.segmentNumber = segmentNumber_;
00235         command->magic.segmentSize = segmentSize;
00236         command->magic.segInfoPtr = currentSegInfoPtr_;
00237 
00238         if (currentCompoundSentSize_ == currentCompoundSize_)
00239         {
00240             MESSAGE_BEGIN(NORMAL, logger_, m, "");
00241             m << "                 This is the last segment of the current compound!";
00242             MESSAGE_END();
00243 
00244             command->magic.segInfoPtr->numberSegments = segmentNumber_;
00245             currentCompound_ = CompoundPtr();
00246             getConnector()->getAcceptor(compoundCopy)->sendData(compoundCopy);
00247             return;
00248         }
00249 
00250         segmentNumber_++;
00251         getConnector()->getAcceptor(compoundCopy)->sendData(compoundCopy);
00252     }
00253 } // sendSegments

Generated on Wed May 23 03:31:42 2012 for openWNS by  doxygen 1.5.5