![]() |
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/harq/HARQ.hpp> 00029 #include <WNS/ldk/harq/softcombining/UniformRandomDecoder.hpp> 00030 00031 #include <WNS/ldk/FUNConfigCreator.hpp> 00032 00033 using namespace wns::ldk::harq; 00034 00035 /* 00036 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00037 HARQ, 00038 HARQInterface, 00039 "wns.harq.HARQ", 00040 wns::PyConfigViewCreator); 00041 */ 00042 00043 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00044 HARQFU, 00045 wns::ldk::FunctionalUnit, 00046 "wns.harq.HARQFU", 00047 wns::ldk::FUNConfigCreator); 00048 00049 /* 00050 // HARQ class as required by scheduler integration 00051 HARQ::HARQ(wns::ldk::fun::FUN* fuNet, const wns::pyconfig::View& config) : 00052 numSenderProcesses_(config.get<int>("numSenderProcesses")), 00053 numReceiverProcesses_(config.len("receiverProcesses")), 00054 numRVs_(config.get<int>("numRVs")), 00055 logger_(config.get("logger")) 00056 { 00057 for (int ii=0; ii < numSenderProcesses_; ++ii) 00058 { 00059 senderProcesses_.push_back(HARQSenderProcess(ii, numRVs_, this, logger_)); 00060 } 00061 00062 for (int ii=0; ii < numReceiverProcesses_; ++ii) 00063 { 00064 receiverProcesses_.push_back( 00065 HARQFU::HARQReceiverProcess(config.get("receiverProcesses", ii), ii, this)); 00066 } 00067 } 00068 00069 HARQ::~HARQ() 00070 { 00071 } 00072 00073 void 00074 //HARQ::onFUNCreated() 00075 HARQ::initialize() 00076 { 00077 for (int ii=0; ii < numReceiverProcesses_; ++ii) 00078 { 00079 receiverProcesses_[ii].onFUNCreated(); 00080 } 00081 } // onFUNCreated 00082 */ 00083 00084 // HARQ as a functional unit 00085 HARQFU::HARQSenderProcess::HARQSenderProcess(int processID, 00086 int numRVs, 00087 HARQFU* entity, 00088 wns::logger::Logger logger): 00089 processID_(processID), 00090 numRVs_(numRVs), 00091 entity_(entity), 00092 logger_(logger), 00093 buffer_(), 00094 waitingForFeedback_(false), 00095 retransmissionCounter_(0) 00096 { 00097 assure(entity_!=NULL, "No HARQ entity available. This should not have happened"); 00098 00099 MESSAGE_BEGIN(NORMAL, logger_, m, ""); 00100 m << "Process " << processID_ << " created"; 00101 MESSAGE_END(); 00102 } 00103 00104 bool 00105 HARQFU::HARQSenderProcess::hasCapacity() const 00106 { 00107 00108 if (buffer_ == NULL) 00109 { 00110 return true; 00111 } 00112 00113 return false; 00114 } 00115 00116 void 00117 HARQFU::HARQSenderProcess::enqueueTransmission(const wns::ldk::CompoundPtr& compound) 00118 { 00119 assure(entity_!=NULL, "No HARQ entity available. This should not have happened"); 00120 HARQCommand* command = entity_->getCommand(compound->getCommandPool()); 00121 command->peer.type = HARQCommand::I; 00122 command->peer.NDI = true; 00123 command->peer.processId = processID_; 00124 buffer_ = compound; 00125 00126 entity_->addToSendQueue(buffer_->copy()); 00127 } 00128 00129 void 00130 HARQFU::HARQSenderProcess::ackReceived() 00131 { 00132 buffer_ = wns::ldk::CompoundPtr(); 00133 waitingForFeedback_ = false; 00134 retransmissionCounter_ = 0; 00135 00136 MESSAGE_BEGIN(NORMAL, logger_, m, ""); 00137 m << "Process " << processID_ << " received ACK"; 00138 MESSAGE_END(); 00139 } 00140 00141 void 00142 HARQFU::HARQSenderProcess::nackReceived() 00143 { 00144 waitingForFeedback_ = false; 00145 retransmissionCounter_++; 00146 00147 wns::ldk::CompoundPtr retransmission = buffer_->copy(); 00148 00149 HARQCommand* command = entity_->getCommand(retransmission->getCommandPool()); 00150 command->peer.NDI = false; 00151 command->peer.rv = (command->peer.rv + 1) % numRVs_; 00152 00153 entity_->addToSendQueue(retransmission); 00154 00155 MESSAGE_BEGIN(NORMAL, logger_, m, ""); 00156 m << "Process " << processID_ << " received NACK"; 00157 MESSAGE_END(); 00158 } 00159 00160 HARQFU::HARQReceiverProcess::HARQReceiverProcess(wns::pyconfig::View config, 00161 int processID, 00162 HARQFU* entity): 00163 processID_(processID), 00164 numRVs_(config.get<int>("numRVs")), 00165 entity_(entity), 00166 logger_(config.get("logger")), 00167 receptionBuffer_(config.get<int>("numRVs")) 00168 { 00169 assure(entity_ != NULL, "No HARQ entity available. This should not have happened"); 00170 00171 decoder_ = wns::SmartPtr<softcombining::IDecoder>( 00172 STATIC_FACTORY_NEW_INSTANCE(softcombining::IDecoder, 00173 FUNConfigCreator, config.get("decoder"), 00174 entity_->getFUN(), config.get("decoder"))); 00175 00176 MESSAGE_BEGIN(NORMAL, logger_, m, ""); 00177 m << "Process " << processID_ << " created"; 00178 MESSAGE_END(); 00179 } 00180 00181 void 00182 HARQFU::HARQReceiverProcess::onFUNCreated() 00183 { 00184 decoder_->onFUNCreated(); 00185 } 00186 00187 void 00188 HARQFU::HARQReceiverProcess::receive(const wns::ldk::CompoundPtr& compound) 00189 { 00190 assure(entity_ != NULL, "No HARQ entity available. This should not have happened"); 00191 00192 HARQCommand* command = entity_->getCommand(compound->getCommandPool()); 00193 00194 assure(command->peer.type == HARQCommand::I, "Misrouted ACK/NACK"); 00195 00196 if (command->peer.NDI) 00197 { 00198 receptionBuffer_.clear(); 00199 } 00200 00201 receptionBuffer_.appendEntryForRV(0, command->peer.rv, compound); 00202 00203 CommandPool* ackPCI = entity_->getFUN()->getProxy()->createReply(compound->getCommandPool(), entity_); 00204 wns::ldk::CompoundPtr ack_ = wns::ldk::CompoundPtr(new Compound(ackPCI)); 00205 HARQCommand* harqCommand = entity_->activateCommand(ackPCI); 00206 harqCommand->peer.processId = processID_; 00207 00208 if (decoder_->canDecode(receptionBuffer_)) 00209 { 00210 harqCommand->peer.type = HARQCommand::ACK; 00211 entity_->addToSendQueue(ack_); 00212 00213 if(entity_->getDeliverer()->size()) 00214 entity_->getDeliverer()->getAcceptor(compound)->onData(compound); 00215 00216 receptionBuffer_.clear(); 00217 } 00218 else 00219 { 00220 harqCommand->peer.type = HARQCommand::NACK; 00221 entity_->addToSendQueue(ack_); 00222 } 00223 } 00224 00225 HARQFU::HARQFU(wns::ldk::fun::FUN* fuNet, const wns::pyconfig::View& config) : 00226 fu::Plain<HARQFU, HARQCommand>(fuNet), 00227 numSenderProcesses_(config.get<int>("numSenderProcesses")), 00228 numReceiverProcesses_(config.len("receiverProcesses")), 00229 numRVs_(config.get<int>("numRVs")), 00230 logger_(config.get("logger")) 00231 { 00232 for (int ii=0; ii < numSenderProcesses_; ++ii) 00233 { 00234 senderProcesses_.push_back(HARQSenderProcess(ii, numRVs_, this, logger_)); 00235 } 00236 00237 for (int ii=0; ii < numReceiverProcesses_; ++ii) 00238 { 00239 receiverProcesses_.push_back( 00240 HARQFU::HARQReceiverProcess(config.get("receiverProcesses", ii), ii, this)); 00241 } 00242 } 00243 00244 HARQFU::~HARQFU() 00245 { 00246 } 00247 00248 void 00249 HARQFU::onFUNCreated() 00250 { 00251 for (int ii=0; ii < numReceiverProcesses_; ++ii) 00252 { 00253 receiverProcesses_[ii].onFUNCreated(); 00254 } 00255 } // onFUNCreated 00256 00257 bool 00258 HARQFU::hasCapacity() const 00259 { 00260 for (int ii=0; ii < numSenderProcesses_; ++ii) 00261 { 00262 // Any of my send processes idle? 00263 if (senderProcesses_[ii].hasCapacity()) 00264 { 00265 return true; 00266 } 00267 } 00268 00269 // Damn! All busy 00270 return false; 00271 } 00272 00273 const wns::ldk::CompoundPtr 00274 HARQFU::hasSomethingToSend() const 00275 { 00276 if (!sendQueue_.empty()) 00277 { 00278 return sendQueue_.front(); 00279 } 00280 00281 return wns::ldk::CompoundPtr(); 00282 } 00283 00284 wns::ldk::CompoundPtr 00285 HARQFU::getSomethingToSend() 00286 { 00287 if (!sendQueue_.empty()) 00288 { 00289 wns::ldk::CompoundPtr it = sendQueue_.front(); 00290 sendQueue_.pop_front(); 00291 00292 return it; 00293 } 00294 00295 return wns::ldk::CompoundPtr(); 00296 } 00297 00298 void 00299 HARQFU::processOutgoing(const wns::ldk::CompoundPtr& compound) 00300 { 00301 activateCommand(compound->getCommandPool()); 00302 00303 for (int ii=0; ii < numSenderProcesses_; ++ii) 00304 { 00305 // Any of my send processes idle? 00306 if (senderProcesses_[ii].hasCapacity()) 00307 { 00308 MESSAGE_BEGIN(NORMAL, logger_, m, getFUN()->getName()); 00309 m << " HARQ process " << ii << " is now active"; 00310 MESSAGE_END(); 00311 00312 HARQCommand* command = getCommand(compound->getCommandPool()); 00313 command->peer.NDI = true; 00314 command->peer.processId = ii; 00315 senderProcesses_[ii].enqueueTransmission(compound); 00316 break; 00317 } 00318 } 00319 } 00320 00321 void 00322 HARQFU::processIncoming(const wns::ldk::CompoundPtr& compound) 00323 { 00324 HARQCommand* command = getCommand(compound->getCommandPool()); 00325 00326 int processId = command->peer.processId; 00327 bool ndi = command->peer.NDI; 00328 HARQCommand::FrameType commandType = command->peer.type; 00329 00330 switch(commandType) 00331 { 00332 case HARQCommand::I: 00333 MESSAGE_BEGIN(NORMAL, logger_, m, getFUN()->getName()); 00334 m << " received compound for process " << processId; 00335 if (ndi) 00336 { 00337 m << " (NDI)"; 00338 } 00339 MESSAGE_END(); 00340 00341 assure(processId < numReceiverProcesses_ && processId >= 0, "No receiver process for this ProcessId"); 00342 00343 receiverProcesses_[processId].receive(compound); 00344 00345 break; 00346 00347 case HARQCommand::ACK: 00348 00349 assure(processId < numSenderProcesses_ && processId >= 0, "No receiver process for this ProcessId"); 00350 00351 MESSAGE_BEGIN(NORMAL, logger_, m, getFUN()->getName()); 00352 m << " received ACK compound for process " << processId; 00353 if (ndi) 00354 { 00355 m << " (NDI)"; 00356 } 00357 MESSAGE_END(); 00358 00359 senderProcesses_[processId].ackReceived(); 00360 00361 break; 00362 00363 case HARQCommand::NACK: 00364 00365 assure(processId < numSenderProcesses_ && processId >= 0, "No receiver process for this ProcessId"); 00366 00367 senderProcesses_[processId].nackReceived(); 00368 } 00369 } 00370 00371 void 00372 HARQFU::calculateSizes(const CommandPool* commandPool, Bit& commandPoolSize, Bit& sduSize) const 00373 { 00374 //What are the sizes in the upper Layers 00375 getFUN()->calculateSizes(commandPool, commandPoolSize, sduSize, this); 00376 //commandPoolSize += checkSumLength; 00377 00378 } // calculateSizes 00379 00380 void 00381 HARQFU::addToSendQueue(wns::ldk::CompoundPtr compound) 00382 { 00383 sendQueue_.push_back(compound); 00384 } 00385 00386
1.5.5