![]() |
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/ReceptionQueue.hpp> 00031 00032 using namespace wifimac::draftn; 00033 00034 ReceptionQueue::ReceptionQueue(BlockACK* parent_, BlockACKCommand::SequenceNumber firstSN_, wns::service::dll::UnicastAddress adr_): 00035 parent(parent_), 00036 adr(adr_), 00037 waitingForSN(firstSN_), 00038 rxStorage(), 00039 rxSNs(), 00040 blockACK() 00041 { 00042 MESSAGE_SINGLE(NORMAL, parent->logger, "RxQ" << adr << " created"); 00043 } // ReceptionQueue 00044 00045 const unsigned int 00046 ReceptionQueue::storageSize() const 00047 { 00048 unsigned int size = 0; 00049 00050 for(std::map<BlockACKCommand::SequenceNumber, CompoundPtrWithSize>::const_iterator it = rxStorage.begin(); 00051 it != rxStorage.end(); 00052 it++) 00053 { 00054 size += it->second.second; 00055 } 00056 return(size); 00057 } // ReceptionQueue::size 00058 00059 void 00060 ReceptionQueue::processIncomingData(const wns::ldk::CompoundPtr& compound, const unsigned int size) 00061 { 00062 assure(this->blockACK == wns::ldk::CompoundPtr(), "Received blockACKreq - cannot process more incoming data"); 00063 00064 BlockACKCommand* baCommand = parent->getCommand(compound->getCommandPool()); 00065 assure(baCommand->peer.type == I, "can only process incoming data"); 00066 00067 // store sn for ack 00068 rxSNs.insert(baCommand->peer.sn); 00069 00070 // process data compound 00071 if(baCommand->peer.sn == this->waitingForSN) 00072 { 00073 MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received SN "); 00074 m << baCommand->peer.sn; 00075 m << ", waiting for " << this->waitingForSN; 00076 m << " --> deliver "; 00077 MESSAGE_END(); 00078 00079 parent->getDeliverer()->getAcceptor(compound)->onData(compound); 00080 ++this->waitingForSN; 00081 // check if other compounds from the rxQueue can be delivered now 00082 this->purgeRxStorage(); 00083 } 00084 else 00085 { 00086 // received compound does not match waitingForSN 00087 00088 if((baCommand->peer.sn < this->waitingForSN) or (rxStorage.find(baCommand->peer.sn) != rxStorage.end())) 00089 { 00090 // received old compound 00091 MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received known SN "); 00092 m << baCommand->peer.sn; 00093 m << ", waiting for " << this->waitingForSN; 00094 m << " --> drop"; 00095 MESSAGE_END(); 00096 } 00097 else 00098 { 00099 // received new compound 00100 MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received new SN "); 00101 m << baCommand->peer.sn; 00102 m << ", waiting for " << this->waitingForSN; 00103 m << " --> store"; 00104 MESSAGE_END(); 00105 rxStorage[baCommand->peer.sn] = CompoundPtrWithSize(compound, size); 00106 } 00107 } 00108 00109 } // ReceptionQueue::processIncomingData 00110 00111 void 00112 ReceptionQueue::purgeRxStorage() 00113 { 00114 while(not rxStorage.empty()) 00115 { 00116 if(rxStorage.begin()->first == this->waitingForSN) 00117 { 00118 MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": New SN allows in-order delivery SN "); 00119 m << this->waitingForSN; 00120 m << " --> deliver"; 00121 MESSAGE_END(); 00122 00123 parent->getDeliverer()->getAcceptor(rxStorage.begin()->second.first)->onData(rxStorage.begin()->second.first); 00124 rxStorage.erase(rxStorage.begin()); 00125 ++this->waitingForSN; 00126 } 00127 else 00128 { 00129 // gap still exists 00130 return; 00131 } 00132 } 00133 } // ReceptionQueue::purgeRxStorage 00134 00135 void 00136 ReceptionQueue::processIncomingACKreq(const wns::ldk::CompoundPtr& compound) 00137 { 00138 assure(this->blockACK == wns::ldk::CompoundPtr(), "Already prepared blockACK"); 00139 00140 // the sn in the BAreq gives the minimum SN that shall be acknowledged, all 00141 // frames before that sn are discarded due to maximum lifetime or 00142 // retransmissions 00143 BlockACKCommand::SequenceNumber minSN = parent->getCommand(compound->getCommandPool())->peer.sn; 00144 // stop waiting for everything below the minSN 00145 while((not rxStorage.empty()) and (rxStorage.begin()->first < minSN)) 00146 { 00147 MESSAGE_SINGLE(NORMAL, parent->logger, "RxQ" << adr << ": Received BAreq with SN " << minSN << " -> deliver waiting SN " << rxStorage.begin()->first); 00148 parent->getDeliverer()->getAcceptor(rxStorage.begin()->second.first)->onData(rxStorage.begin()->second.first); 00149 rxStorage.erase(rxStorage.begin()); 00150 } 00151 // waitingForSN is never reduced 00152 this->waitingForSN = (minSN > this->waitingForSN) ? (minSN) : (this->waitingForSN); 00153 // shift of waitingForSN might free already received frames 00154 this->purgeRxStorage(); 00155 00156 // do not acknowledge old frames 00157 while((not rxSNs.empty()) and (*(rxSNs.begin()) < minSN)) 00158 { 00159 rxSNs.erase(rxSNs.begin()); 00160 } 00161 00162 // create BlockACK 00163 wns::simulator::Time fxDur = parent->friends.manager->getFrameExchangeDuration(compound->getCommandPool()) - parent->sifsDuration - parent->maximumACKDuration; 00164 if (fxDur < parent->sifsDuration) 00165 { 00166 fxDur = 0; 00167 } 00168 00169 MESSAGE_SINGLE(NORMAL,parent->logger,"create BA with exchange duration : " << fxDur); 00170 this->blockACK = parent->friends.manager->createCompound(parent->friends.manager->getMACAddress(), 00171 adr, 00172 ACK, 00173 fxDur, 00174 false); 00175 parent->friends.manager->setPhyMode(this->blockACK->getCommandPool(), 00176 parent->blockACKPhyMode); 00177 00178 // set baCommand information 00179 BlockACKCommand* baCommand = parent->activateCommand(this->blockACK->getCommandPool()); 00180 baCommand->peer.type = BA; 00181 baCommand->peer.ackSNs = rxSNs; 00182 if(rxSNs.empty()) 00183 { 00184 baCommand->peer.sn = this->waitingForSN; 00185 } 00186 else 00187 { 00188 // take the minimum of waiting for and rxSNs 00189 baCommand->peer.sn = (*(rxSNs.begin())) < this->waitingForSN ? (*(rxSNs.begin())) : this->waitingForSN; 00190 } 00191 00192 MESSAGE_BEGIN(NORMAL, parent->logger, m, "RxQ" << adr << ": Received BAreq with SN "); 00193 m << minSN; 00194 m << ", prepare BA with "; 00195 m << " fExDur " << parent->friends.manager->getFrameExchangeDuration(this->blockACK->getCommandPool()); 00196 m << " startSN: " << baCommand->peer.sn; 00197 m << " ackSNs:"; 00198 #ifndef WNS_NO_LOGGING 00199 for(std::set<BlockACKCommand::SequenceNumber>::iterator snIt = rxSNs.begin(); 00200 snIt != rxSNs.end(); 00201 snIt++) 00202 { 00203 m << " " << (*snIt); 00204 } 00205 #endif 00206 MESSAGE_END(); 00207 00208 rxSNs.clear(); 00209 00210 } // ReceptionQueue::processIncomingACKreq 00211 00212 const wns::ldk::CompoundPtr 00213 ReceptionQueue::hasACK() const 00214 { 00215 return(this->blockACK); 00216 } // ReceptionQueue::hasACK 00217 00218 wns::ldk::CompoundPtr 00219 ReceptionQueue::getACK() 00220 { 00221 assure(hasACK(), "Called getACK although no ack prepared?"); 00222 assure(this->blockACK != wns::ldk::CompoundPtr(), "Called getACK but blockACK is empty?"); 00223 00224 wns::ldk::CompoundPtr it = this->blockACK; 00225 this->blockACK = wns::ldk::CompoundPtr(); 00226 00227 MESSAGE_SINGLE(NORMAL, parent->logger, "RxQ" << adr << ": Transmit BA"); 00228 00229 return(it); 00230 } // ReceptionQueue::getACK
1.5.5