![]() |
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/rateAdaptationStrategies/ARFwithMIMO.hpp> 00030 #include <WIFIMAC/management/VirtualCapabilityInformationBase.hpp> 00031 00032 #include <algorithm> 00033 00034 using namespace wifimac::draftn::rateAdaptationStrategies; 00035 00036 STATIC_FACTORY_REGISTER_WITH_CREATOR(ARFwithMIMO, 00037 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategy, 00038 "ARFwithMIMO", 00039 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategyCreator); 00040 00041 ARFwithMIMO::ARFwithMIMO( 00042 const wns::pyconfig::View& _config, 00043 wns::service::dll::UnicastAddress _receiver, 00044 wifimac::management::PERInformationBase* _per, 00045 wifimac::management::SINRInformationBase* _sinr, 00046 wifimac::lowerMAC::Manager* _manager, 00047 wifimac::convergence::PhyUser* _phyUser, 00048 wns::logger::Logger* _logger): 00049 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategy(_config, _receiver, _per, _sinr, _manager, _phyUser, _logger), 00050 per(_per), 00051 arfTimer(_config.get<wns::simulator::Time>("arfTimer")), 00052 exponentialBackoff(_config.get<bool>("exponentialBackoff")), 00053 initialSuccessThreshold(_config.get<int>("initialSuccessThreshold")), 00054 maxSuccessThreshold(_config.get<int>("maxSuccessThreshold")), 00055 successThreshold(_config.get<int>("initialSuccessThreshold")), 00056 myReceiver(_receiver), 00057 probePacket(false), 00058 logger(_logger), 00059 curPhyModeId(0), 00060 timeout(false) 00061 { 00062 friends.phyUser = _phyUser; 00063 friends.manager = _manager; 00064 00065 unsigned int numTx = friends.manager->getNumAntennas(); 00066 unsigned int numRx = 1; 00067 if(wifimac::management::TheVCIBService::Instance().getVCIB()->knows(myReceiver, "numAntennas")) 00068 { 00069 numRx = wifimac::management::TheVCIBService::Instance().getVCIB()->get<int>(myReceiver, "numAntennas"); 00070 } 00071 unsigned int maxNumSS = (numTx < numRx) ? numTx : numRx; 00072 00073 // create an ordered list of the available phyModes 00074 wifimac::convergence::PhyMode pm; 00075 std::vector<wifimac::convergence::PhyMode> allPMs; 00076 allPMs.clear(); 00077 for (int i = 1; i <= maxNumSS; i++) 00078 { 00079 pm = friends.manager->getPhyUser()->getPhyModeProvider()->getDefaultPhyMode(); 00080 while(not friends.manager->getPhyUser()->getPhyModeProvider()->hasLowestMCS(pm)) 00081 { 00082 friends.manager->getPhyUser()->getPhyModeProvider()->mcsDown(pm); 00083 } 00084 pm.setUniformMCS(pm.getSpatialStreams()[0], i); 00085 while(!friends.manager->getPhyUser()->getPhyModeProvider()->hasHighestMCS(pm)) 00086 { 00087 allPMs.push_back(pm); 00088 friends.manager->getPhyUser()->getPhyModeProvider()->mcsUp(pm); 00089 } 00090 allPMs.push_back(pm); 00091 00092 } 00093 /*std::vector<wifimac::convergence::PhyMode>::iterator itr; 00094 for (int i = 0; i < pmList.size(); ++i) 00095 { 00096 for (itr = sinrSortedPMs.begin(); itr != sinrSortedPMs.end(); ++itr) 00097 { 00098 if (pmList[i].getMinSINR()-friends.manager->getPhyUser()->getExpectedPostSINRFactor(pmList[i].getNumberOfSpatialStreams(),friends.manager->getNumAntennas()) 00099 < (*itr).getMinSINR()-friends.manager->getPhyUser()->getExpectedPostSINRFactor((*itr).getNumberOfSpatialStreams(),friends.manager->getNumAntennas())) 00100 { 00101 sinrSortedPMs.insert(itr,pmList[i]); 00102 break; 00103 } 00104 } 00105 if (itr == sinrSortedPMs.end()) 00106 { 00107 sinrSortedPMs.push_back(pmList[i]); 00108 } 00109 }*/ 00110 00111 // keep only PhyModes with non-overlapping dbps 00112 unsigned int maxdbps = 0; 00113 pmList.clear(); 00114 for (std::vector<wifimac::convergence::PhyMode>::iterator itr = allPMs.begin(); 00115 itr != allPMs.end(); 00116 itr++) 00117 { 00118 if (maxdbps < (*itr).getDataBitsPerSymbol()) 00119 { 00120 maxdbps = (*itr).getDataBitsPerSymbol(); 00121 pmList.push_back((*itr)); 00122 } 00123 } 00124 00125 assure(successThreshold > 0, "Success threshold must be > 0"); 00126 } 00127 00128 wifimac::convergence::PhyMode 00129 ARFwithMIMO::getPhyMode(size_t numTransmissions, 00130 const wns::Ratio /*lqm*/) const 00131 { 00132 return(this->getPhyMode(numTransmissions)); 00133 } 00134 00135 wifimac::convergence::PhyMode 00136 ARFwithMIMO::getPhyMode(size_t numTransmissions) const 00137 { 00138 if(timeout) 00139 { 00140 if (curPhyModeId < (pmList.size()-1)) 00141 { 00142 return pmList[curPhyModeId+1]; 00143 } 00144 else 00145 { 00146 return pmList[curPhyModeId]; 00147 } 00148 } 00149 00150 if((probePacket and numTransmissions == 2) or (numTransmissions >= 3)) 00151 { 00152 // last frame did not succeed 00153 if (curPhyModeId > 0) 00154 { 00155 return pmList[curPhyModeId-1]; 00156 } 00157 else 00158 { 00159 return pmList[curPhyModeId]; 00160 } 00161 } 00162 00163 if(per->getSuccessfull(myReceiver) == successThreshold) 00164 { 00165 // last frame did not succeed 00166 if (curPhyModeId < (pmList.size()-1)) 00167 { 00168 return pmList[curPhyModeId+1]; 00169 } 00170 else 00171 { 00172 return pmList[curPhyModeId]; 00173 } 00174 } 00175 00176 return pmList[curPhyModeId]; 00177 00178 } 00179 00180 void 00181 ARFwithMIMO::setCurrentPhyMode(wifimac::convergence::PhyMode pm) 00182 { 00183 timeout = false; 00184 00185 int nextPhyModeId = 0; 00186 for(; nextPhyModeId < pmList.size(); nextPhyModeId++) 00187 { 00188 if(pmList[nextPhyModeId] == pm) 00189 { 00190 break; 00191 } 00192 } 00193 assure(nextPhyModeId < pmList.size(), "Trying to set invalid PhyMode!"); 00194 00195 if(curPhyModeId == nextPhyModeId) 00196 { 00197 probePacket = false; 00198 return; 00199 } 00200 else 00201 { 00202 if(this->hasTimeoutSet()) 00203 { 00204 this->cancelTimeout(); 00205 } 00206 00207 if(nextPhyModeId < curPhyModeId) 00208 { 00209 // set new timeout for switching up 00210 this->setTimeout(arfTimer); 00211 00212 if(probePacket) 00213 { 00214 // last one was a probe packet, but did not succeed 00215 probePacket = false; 00216 MESSAGE_SINGLE(NORMAL, *logger, "Last probe packet to " << myReceiver << " did not succeed, going down to MCS "<< pmList[nextPhyModeId]); 00217 if(exponentialBackoff and successThreshold < maxSuccessThreshold) 00218 { 00219 successThreshold = successThreshold*2; 00220 MESSAGE_SINGLE(NORMAL, *logger, "Set successThreshold to " << successThreshold); 00221 } 00222 } 00223 else 00224 { 00225 MESSAGE_SINGLE(NORMAL, *logger, "Failed transmissions to " << myReceiver << " , going down to MCS "<< pmList[nextPhyModeId]); 00226 if(exponentialBackoff) 00227 { 00228 successThreshold = successThreshold / 2; 00229 if(successThreshold < initialSuccessThreshold) 00230 { 00231 successThreshold = initialSuccessThreshold; 00232 } 00233 MESSAGE_SINGLE(NORMAL, *logger, "Set successThreshold to " << successThreshold); 00234 } 00235 } 00236 } 00237 else 00238 { 00239 probePacket = true; 00240 MESSAGE_SINGLE(NORMAL, *logger, per->getSuccessfull(myReceiver) << " successfull transmissions to " << myReceiver << ", sending probe packet with " << pmList[nextPhyModeId]); 00241 } 00242 curPhyModeId = nextPhyModeId; 00243 per->reset(myReceiver); 00244 00245 } 00246 } 00247 00248 void 00249 ARFwithMIMO::onTimeout() 00250 { 00251 if (curPhyModeId == pmList.size()-1) 00252 { 00253 return; 00254 } 00255 timeout = true; 00256 MESSAGE_SINGLE(NORMAL, *logger, "Timeout"); 00257 }
1.5.5