![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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/TransmissionQueue.hpp> 00031 00032 00033 using namespace wifimac::draftn; 00034 00035 TransmissionQueue::TransmissionQueue(BlockACK* parent_, 00036 size_t maxOnAir_, 00037 wns::simulator::Time maxDelay_, 00038 wns::service::dll::UnicastAddress adr_, 00039 BlockACKCommand::SequenceNumber sn_, 00040 wifimac::management::PERInformationBase* perMIB_, 00041 std::auto_ptr<wns::ldk::buffer::SizeCalculator> *sizeCalculator_) : 00042 parent(parent_), 00043 maxOnAir(maxOnAir_), 00044 maxDelay(maxDelay_), 00045 adr(adr_), 00046 txQueue(), 00047 onAirQueue(), 00048 nextSN(sn_), 00049 baREQ(), 00050 waitForACK(false), 00051 baReqRequired(false), 00052 perMIB(perMIB_), 00053 sizeCalculator(sizeCalculator_), 00054 oldestTimestamp() 00055 { 00056 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << " created"); 00057 00058 // prepare Block ACK request 00059 this->baREQ = parent->friends.manager->createCompound(parent->friends.manager->getMACAddress(), 00060 adr, 00061 DATA, 00062 parent->sifsDuration + parent->maximumACKDuration, 00063 parent->ackTimeout); 00064 // block ack settings 00065 BlockACKCommand* baReqCommand = parent->activateCommand(this->baREQ->getCommandPool()); 00066 baReqCommand->peer.type = BAREQ; 00067 baReqCommand->localTransmissionCounter = 1; 00068 00069 } // TransmissionQueue 00070 00071 TransmissionQueue::~TransmissionQueue() 00072 { 00073 onAirQueue.clear(); 00074 this->baREQ = wns::ldk::CompoundPtr(); 00075 } // TransmissionQueue::~TransmissionQueue 00076 00077 00078 const unsigned int 00079 TransmissionQueue::onAirQueueSize() const 00080 { 00081 unsigned int size = 0; 00082 for(std::deque<CompoundPtrWithTime>::const_iterator it = onAirQueue.begin(); 00083 it != onAirQueue.end(); 00084 it++) 00085 { 00086 size += (*(*sizeCalculator))(it->first); 00087 } 00088 return(size); 00089 } 00090 00091 const unsigned int 00092 TransmissionQueue::txQueueSize() const 00093 { 00094 unsigned int size = 0; 00095 for(std::deque<CompoundPtrWithTime>::const_iterator it = txQueue.begin(); 00096 it != txQueue.end(); 00097 it++) 00098 { 00099 size += (*(*sizeCalculator))(it->first); 00100 } 00101 return(size); 00102 } 00103 00104 00105 const unsigned int 00106 TransmissionQueue::storageSize() const 00107 { 00108 return(this->onAirQueueSize() + this->txQueueSize()); 00109 } 00110 00111 void 00112 TransmissionQueue::processOutgoing(const wns::ldk::CompoundPtr& compound) 00113 { 00114 BlockACKCommand* baCommand = parent->activateCommand(compound->getCommandPool()); 00115 baCommand->peer.type = I; 00116 baCommand->peer.sn = this->nextSN++; 00117 baCommand->localTransmissionCounter = 1; 00118 00119 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": Queue outgoing compound with sn " << baCommand->peer.sn); 00120 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": send time for compound is " << wns::simulator::getEventScheduler()->getTime()+this->maxDelay << " maxDelay is " << this->maxDelay << " oldest is " << oldestTimestamp); 00121 txQueue.push_back(CompoundPtrWithTime(compound, wns::simulator::getEventScheduler()->getTime())); 00122 00123 if ((oldestTimestamp == wns::simulator::Time()) or 00124 (wns::simulator::getEventScheduler()->getTime() < oldestTimestamp)) 00125 { 00126 oldestTimestamp = wns::simulator::getEventScheduler()->getTime(); 00127 } 00128 } // TransmissionQueue::processOutgoing 00129 00130 const 00131 wns::ldk::CompoundPtr TransmissionQueue::hasData() const 00132 { 00133 if(waitForACK) 00134 { 00135 MESSAGE_SINGLE(VERBOSE, parent->logger, "TxQ" << adr << ": hasData: Waiting for ACK -> no other transmissions"); 00136 // no other transmissions during waiting for ACK 00137 return(wns::ldk::CompoundPtr()); 00138 } 00139 if((not txQueue.empty()) and (onAirQueueSize()+(*(*sizeCalculator))(txQueue.front().first) <= this->maxOnAir)) 00140 { 00141 // regular frame pending 00142 MESSAGE_SINGLE(VERBOSE, parent->logger, "TxQ" << adr << ": hasData: Regular frame is pending"); 00143 return(txQueue.front().first); 00144 } 00145 00146 // baReq pending 00147 if(this->baReqRequired) 00148 { 00149 // impatient BAreq -> send as soon as required 00150 if(parent->impatientBAreqTransmission) 00151 { 00152 return(this->baREQ); 00153 } 00154 00155 // next compound would exceed on air limit -> send 00156 if((not txQueue.empty()) and 00157 (onAirQueueSize()+(*(*sizeCalculator))(txQueue.front().first) > this->maxOnAir)) 00158 { 00159 return(this->baREQ); 00160 } 00161 00162 // no next compound, but nothing would match anyway -> send 00163 if((txQueue.empty()) and 00164 (onAirQueueSize() == this->maxOnAir)) 00165 { 00166 return(this->baREQ); 00167 } 00168 } 00169 00170 return(wns::ldk::CompoundPtr()); 00171 00172 } // TransmissionQueue::hasData 00173 00174 wns::ldk::CompoundPtr 00175 TransmissionQueue::getData() 00176 { 00177 assure(this->hasData(), "Called getData although hasData is false"); 00178 00179 // compound pending? 00180 if((not txQueue.empty()) and 00181 (onAirQueueSize()+(*(*sizeCalculator))(txQueue.front().first) <= this->maxOnAir)) 00182 { 00183 // transmit another frame 00184 onAirQueue.push_back(txQueue.front()); 00185 wns::ldk::CompoundPtr it = txQueue.front().first; 00186 txQueue.pop_front(); 00187 00188 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": Transmit pending frame with sn " << parent->getCommand(it->getCommandPool())->peer.sn); 00189 this->baReqRequired = true; 00190 00191 return(it->copy()); 00192 } 00193 00194 // no compound pending --> BAreq must be pending 00195 assure(this->baReqRequired, 00196 "No compound pending and no baReqRequired, but hasData is true"); 00197 if(txQueue.empty()) 00198 { 00199 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": No more frames to tx, send BAreq with start-sn " << parent->getCommand(onAirQueue.front().first)->peer.sn); 00200 oldestTimestamp = wns::simulator::Time(); 00201 } 00202 else 00203 { 00204 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": Reached tx window, send BAreq with start-sn " << parent->getCommand(onAirQueue.front().first)->peer.sn); 00205 oldestTimestamp = txQueue.front().second; 00206 } 00207 00208 wns::ldk::CompoundPtr it = this->baREQ->copy(); 00209 // no more BAreq required until next regular frame transmission 00210 this->baReqRequired = false; 00211 // now set start-sn of BA-req to sn of first compound in transmission queue 00212 parent->getCommand(it->getCommandPool())->peer.sn = parent->getCommand(onAirQueue.front().first)->peer.sn; 00213 // stop future transmissions until ACK (or timeout of it) arrives 00214 this->waitForACK = true; 00215 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": Set waitForACK to true"); 00216 return(it); 00217 00218 } // TransmissionQueue::getData 00219 00220 void 00221 TransmissionQueue::processIncomingACK(std::set<BlockACKCommand::SequenceNumber> ackSNs) 00222 { 00223 assure(not onAirQueue.empty(), "Received ACK but onAirQueue is empy"); 00224 assure(this->waitForACK, "Received ACK but not waiting for one"); 00225 this->waitForACK = false; 00226 MESSAGE_SINGLE(NORMAL, parent->logger, "TxQ" << adr << ": Received ACK, iterate through compounds on air"); 00227 00228 bool insertBack = false; 00229 bool blockACKsuccess = true; 00230 std::deque<CompoundPtrWithTime>::iterator txQueueFirst; 00231 unsigned long transmittedBits =0; 00232 00233 if(txQueue.empty()) 00234 { 00235 insertBack = true; 00236 } 00237 else 00238 { 00239 txQueueFirst = txQueue.begin(); 00240 } 00241 00242 std::set<wifimac::draftn::BlockACKCommand::SequenceNumber>::iterator snIt = ackSNs.begin(); 00243 assure(isSortedBySN(onAirQueue), 00244 "onAirQueue is not sorted by SN!"); 00245 00246 for(std::deque<CompoundPtrWithTime>::iterator onAirIt = onAirQueue.begin(); 00247 onAirIt != onAirQueue.end(); 00248 onAirIt++) 00249 { 00250 wifimac::draftn::BlockACKCommand::SequenceNumber onAirSN = parent->getCommand((onAirIt->first)->getCommandPool())->peer.sn; 00251 00252 if((snIt == ackSNs.end()) or (*snIt != onAirSN)) 00253 { 00254 // retransmission 00255 int txCounter = ++(parent->getCommand((onAirIt->first)->getCommandPool())->localTransmissionCounter); 00256 blockACKsuccess = false; 00257 if(parent->getManager()->lifetimeExpired((onAirIt->first)->getCommandPool())) 00258 { 00259 MESSAGE_BEGIN(NORMAL, parent->logger, m, "TxQ" << adr << ": Compound " << onAirSN); 00260 m << ", ackSN " << ((snIt == ackSNs.end()) ? -1 : (*snIt)); 00261 m << " -> " << txCounter; 00262 m << " transmissions, lifetime expired --> drop!"; 00263 MESSAGE_END(); 00264 00265 parent->numTxAttemptsProbe->put(onAirIt->first, txCounter); 00266 } // lifetime expired 00267 else 00268 { 00269 // BlockACK does not drop frames due to their number of 00270 // retransmissions, see IEEE 802.11-2007, 9.10.3 00271 MESSAGE_BEGIN(NORMAL, parent->logger, m, "TxQ" << adr << ": Compound " << onAirSN); 00272 m << ", ackSN " << ((snIt == ackSNs.end()) ? -1 : (*snIt)); 00273 m << " -> " << txCounter; 00274 m << " transmissions, retransmit"; 00275 MESSAGE_END(); 00276 00277 if(insertBack) 00278 { 00279 txQueue.push_back(*onAirIt); 00280 } 00281 else 00282 { 00283 txQueueFirst = txQueue.insert(txQueueFirst, *onAirIt); 00284 txQueueFirst++; 00285 } 00286 } // lifetime not expired 00287 } // SN does not match 00288 else 00289 { 00290 // *snIt is equal to sn from *onAirIt --> success, go to next sn 00291 MESSAGE_BEGIN(NORMAL, parent->logger, m, "TxQ" << adr << ": Compound " << onAirSN); 00292 m << ", ackSN " << (*snIt) << " -> success"; 00293 MESSAGE_END(); 00294 snIt++; 00295 00296 parent->numTxAttemptsProbe->put(onAirIt->first, parent->getCommand((onAirIt->first)->getCommandPool())->localTransmissionCounter); 00297 transmittedBits+=(onAirIt->first)->getCommandPool()->getSDU()->getLengthInBits(); 00298 } // SN matches 00299 } // for-loop over onAirQueue 00300 00301 // signal once per BlockACK 00302 if(blockACKsuccess) 00303 { 00304 perMIB->onSuccessfullTransmission(adr); 00305 } 00306 else 00307 { 00308 perMIB->onFailedTransmission(adr); 00309 } 00310 00311 // nothing is onAir now 00312 for (int i=0; i < parent->observers.size(); i++) 00313 { 00314 parent->observers[i]->onBlockACKReception(blockACKsuccess,transmittedBits); 00315 } 00316 onAirQueue.clear(); 00317 00318 // find oldest timestamp 00319 oldestTimestamp = wns::simulator::Time(); 00320 if (txQueueSize() > 0) 00321 { 00322 oldestTimestamp = txQueue.begin()->second; 00323 for (std::deque<CompoundPtrWithTime>::iterator itr = txQueue.begin(); itr != txQueue.end(); itr++) 00324 { 00325 if (itr->second < oldestTimestamp) 00326 { 00327 oldestTimestamp = itr->second; 00328 } 00329 } 00330 } 00331 } // TransmissionQueue::processACK 00332 00333 bool 00334 TransmissionQueue::isSortedBySN(const std::deque<CompoundPtrWithTime> q) const 00335 { 00336 if(q.empty()) 00337 { 00338 return true; 00339 } 00340 std::deque<CompoundPtrWithTime>::const_iterator it = q.begin(); 00341 wifimac::draftn::BlockACKCommand::SequenceNumber lastSN = parent->getCommand((it->first)->getCommandPool())->peer.sn; 00342 ++it; 00343 MESSAGE_SINGLE(NORMAL,parent->logger,"SN: (+)" << lastSN); 00344 00345 for(; 00346 it != q.end(); 00347 it++) 00348 { 00349 wifimac::draftn::BlockACKCommand::SequenceNumber curSN = parent->getCommand((it->first)->getCommandPool())->peer.sn; 00350 MESSAGE_SINGLE(NORMAL,parent->logger,"SN: " << curSN); 00351 if(curSN < lastSN) 00352 { 00353 return false; 00354 } 00355 lastSN = curSN; 00356 } 00357 return true; 00358 } 00359 00360 const bool 00361 TransmissionQueue::waitsForACK() const 00362 { 00363 return(this->waitForACK); 00364 } 00365 00366 wns::ldk::CompoundPtr 00367 TransmissionQueue::getTxFront() 00368 { 00369 if (txQueue.empty()) 00370 { 00371 return wns::ldk::CompoundPtr(); 00372 } 00373 return txQueue.front().first; 00374 } 00375 00376 00377 std::list<wns::ldk::CompoundPtr> 00378 TransmissionQueue::getAirableCompounds() 00379 { 00380 std::list<wns::ldk::CompoundPtr> ret; 00381 size_t retSize = 0; 00382 for (std::deque<CompoundPtrWithTime>::iterator itr = txQueue.begin(); itr != txQueue.end(); itr++) 00383 { 00384 if (retSize + (*(*sizeCalculator))(itr->first) > maxOnAir) 00385 { 00386 break; 00387 } 00388 ret.push_back(itr->first); 00389 retSize += (*(*sizeCalculator))(itr->first); 00390 } 00391 return ret; 00392 }
1.5.5