![]() |
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 #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
1.5.5