![]() |
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/PERwithMIMO.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(PERwithMIMO, 00037 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategy, 00038 "PERwithMIMO", 00039 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategyCreator); 00040 00041 PERwithMIMO::PERwithMIMO( 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 perForGoingDown(_config.get<double>("perForGoingDown")), 00052 perForGoingUp(_config.get<double>("perForGoingUp")), 00053 phyModeIncreaseOnAntennaDecrease(_config.get<unsigned int>("phyModeIncreaseOnAntennaDecrease")), 00054 phyModeDecreaseOnAntennaIncrease(_config.get<unsigned int>("phyModeDecreaseOnAntennaIncrease")), 00055 myReceiver(_receiver), 00056 logger(_logger) 00057 { 00058 friends.phyUser = _phyUser; 00059 friends.manager = _manager; 00060 curPhyMode = _config.getView("initialPhyMode"); 00061 } 00062 00063 wifimac::convergence::PhyMode 00064 PERwithMIMO::getPhyMode(size_t numTransmissions, const wns::Ratio /*lqm*/) const 00065 { 00066 return(this->getPhyMode(numTransmissions)); 00067 } 00068 00069 wifimac::convergence::PhyMode 00070 PERwithMIMO::getPhyMode(size_t numTransmissions) const 00071 { 00072 unsigned int numTx = friends.manager->getNumAntennas(); 00073 unsigned int numRx = 1; 00074 if(wifimac::management::TheVCIBService::Instance().getVCIB()->knows(myReceiver, "numAntennas")) 00075 { 00076 numRx = wifimac::management::TheVCIBService::Instance().getVCIB()->get<int>(myReceiver, "numAntennas"); 00077 } 00078 unsigned int maxNumSS = (numTx < numRx) ? numTx : numRx; 00079 00080 wifimac::convergence::PhyMode pm = curPhyMode; 00081 00082 if(not per->knowsPER(myReceiver)) 00083 { 00084 assure(numTransmissions >= 1, "Must have at least one transmission"); 00085 00086 // if no information about the PER is available (due to a recent change), 00087 // we return the current phyMode 00088 00089 return(pm); 00090 } 00091 00092 double curPER = per->getPER(myReceiver); 00093 00094 if(curPER > perForGoingDown) 00095 { 00096 reducePhyMode(pm, maxNumSS); 00097 } 00098 00099 if(curPER < perForGoingUp) 00100 { 00101 // nearly all frames are successful -> go up 00102 increasePhyMode(pm, maxNumSS); 00103 } 00104 00105 return(pm); 00106 } 00107 00108 void 00109 PERwithMIMO::reducePhyMode(wifimac::convergence::PhyMode& pm, unsigned int maxNumSS) const 00110 { 00111 if(friends.phyUser->getPhyModeProvider()->hasLowestMCS(pm)) 00112 { 00113 if(pm.getNumberOfSpatialStreams() > 1) 00114 { 00115 pm.setUniformMCS(pm.getSpatialStreams()[0], pm.getNumberOfSpatialStreams() - 1); 00116 for(int i = 0; i < phyModeIncreaseOnAntennaDecrease; ++i) 00117 { 00118 friends.phyUser->getPhyModeProvider()->mcsUp(pm); 00119 } 00120 } 00121 } 00122 else 00123 { 00124 friends.phyUser->getPhyModeProvider()->mcsDown(pm); 00125 } 00126 } 00127 00128 void 00129 PERwithMIMO::increasePhyMode(wifimac::convergence::PhyMode& pm, unsigned int maxNumSS) const 00130 { 00131 // nearly all frames are successful -> go up 00132 if(friends.phyUser->getPhyModeProvider()->hasHighestMCS(pm)) 00133 { 00134 if(pm.getNumberOfSpatialStreams() < maxNumSS) 00135 { 00136 pm.setUniformMCS(pm.getSpatialStreams()[0], pm.getNumberOfSpatialStreams() + 1); 00137 for(int i = 0; i < phyModeDecreaseOnAntennaIncrease; ++i) 00138 { 00139 friends.phyUser->getPhyModeProvider()->mcsDown(pm); 00140 } 00141 } 00142 } 00143 else 00144 { 00145 friends.phyUser->getPhyModeProvider()->mcsUp(pm); 00146 } 00147 } 00148 00149 00150 00151 void 00152 PERwithMIMO::setCurrentPhyMode(wifimac::convergence::PhyMode pm) 00153 { 00154 00155 if(curPhyMode != pm) 00156 { 00157 unsigned int numTx = friends.manager->getNumAntennas(); 00158 unsigned int numRx = 1; 00159 if(wifimac::management::TheVCIBService::Instance().getVCIB()->knows(myReceiver, "numAntennas")) 00160 { 00161 numRx = wifimac::management::TheVCIBService::Instance().getVCIB()->get<int>(myReceiver, "numAntennas"); 00162 } 00163 if(per->knowsPER(myReceiver)) 00164 { 00165 MESSAGE_BEGIN(NORMAL, *logger, m, "RA"); 00166 m << " to receiver " << myReceiver; 00167 m << " per: " << per->getPER(myReceiver); 00168 m << " numTx: " << numTx; 00169 m << " numRx: " << numRx; 00170 m << " going from " << curPhyMode; 00171 m << " to " << pm; 00172 MESSAGE_END(); 00173 per->reset(myReceiver); 00174 } 00175 else 00176 { 00177 MESSAGE_BEGIN(NORMAL, *logger, m, "RA"); 00178 m << " to receiver " << myReceiver; 00179 m << " , no currently known PER, "; 00180 m << " numTx: " << numTx; 00181 m << " numRx: " << numRx; 00182 m << " going from " << curPhyMode; 00183 m << " to " << pm; 00184 MESSAGE_END(); 00185 } 00186 curPhyMode = pm; 00187 } 00188 }
1.5.5