![]() |
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/SINRwithMIMO.hpp> 00030 #include <WIFIMAC/management/VirtualCapabilityInformationBase.hpp> 00031 00032 using namespace wifimac::draftn::rateAdaptationStrategies; 00033 00034 STATIC_FACTORY_REGISTER_WITH_CREATOR(SINRwithMIMO, 00035 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategy, 00036 "SINRwithMIMO", 00037 wifimac::lowerMAC::rateAdaptationStrategies::IRateAdaptationStrategyCreator); 00038 00039 SINRwithMIMO::SINRwithMIMO( 00040 const wns::pyconfig::View& _config, 00041 wns::service::dll::UnicastAddress _receiver, 00042 wifimac::management::PERInformationBase* _per, 00043 wifimac::management::SINRInformationBase* _sinr, 00044 wifimac::lowerMAC::Manager* _manager, 00045 wifimac::convergence::PhyUser* _phyUser, 00046 wns::logger::Logger* _logger): 00047 ARFwithMIMO(_config, _receiver, _per, _sinr, _manager, _phyUser, _logger), 00048 sinr(dynamic_cast<wifimac::draftn::SINRwithMIMOInformationBase*>(_sinr)), 00049 singleStreamRA(_config, _receiver, _per, _sinr, _manager, _phyUser, _logger), 00050 retransmissionLQMReduction(_config.get<double>("retransmissionLQMReduction")), 00051 myReceiver(_receiver), 00052 logger(_logger) 00053 { 00054 friends.phyUser = _phyUser; 00055 friends.manager = _manager; 00056 curSpatialStreams = 1; 00057 } 00058 00059 wifimac::convergence::PhyMode 00060 SINRwithMIMO::getPhyMode(size_t numTransmissions, const wns::Ratio lqm) const 00061 { 00062 unsigned int numTx = friends.manager->getNumAntennas(); 00063 unsigned int numRx = 1; 00064 if(wifimac::management::TheVCIBService::Instance().getVCIB()->knows(myReceiver, "numAntennas")) 00065 { 00066 numRx = wifimac::management::TheVCIBService::Instance().getVCIB()->get<int>(myReceiver, "numAntennas"); 00067 } 00068 00069 unsigned int maxNumSS = (numTx < numRx) ? numTx : numRx; 00070 00071 MESSAGE_BEGIN(NORMAL, *logger, m, "RA"); 00072 m << " to receiver " << myReceiver; 00073 m << " lqm: " << lqm; 00074 m << " transmissions: " << numTransmissions; 00075 m << " numTx: " << numTx; 00076 m << " numRx: " << numRx; 00077 m << " maxNumSS: " << maxNumSS; 00078 MESSAGE_END(); 00079 00080 wifimac::convergence::PhyMode bestPM = friends.phyUser->getPhyModeProvider()->getDefaultPhyMode(); 00081 bestPM.setUniformMCS(bestPM.getSpatialStreams()[0], 1); 00082 bool foundBestPM = false; 00083 00084 for(unsigned int numSS = maxNumSS; numSS >= 1; --numSS) 00085 { 00086 if(sinr->knowsPeerFactor(myReceiver, numSS)) 00087 { 00088 wifimac::convergence::PhyMode pm = friends.phyUser->getPhyModeProvider()->getDefaultPhyMode(); 00089 std::vector<wifimac::convergence::MCS> mcs; 00090 bool reduceAntennas = false; 00091 00092 std::vector<wns::Ratio> sinrFactor = sinr->getPeerFactor(myReceiver, numSS); 00093 00094 #ifndef WNS_NO_LOGGING 00095 MESSAGE_BEGIN(NORMAL, *logger, m, "peerFactor for "); 00096 m << numSS << " streams is known:"; 00097 for(std::vector<wns::Ratio>::iterator it = sinrFactor.begin(); 00098 it != sinrFactor.end(); 00099 ++it) 00100 { 00101 m << " " << *it; 00102 } 00103 MESSAGE_END(); 00104 #endif 00105 for(std::vector<wns::Ratio>::iterator it = sinrFactor.begin(); 00106 it != sinrFactor.end() and (not reduceAntennas); 00107 ++it) 00108 { 00109 wns::Ratio streamLQM = lqm + *it; 00110 if(streamLQM < friends.phyUser->getPhyModeProvider()->getMinSINR()) 00111 { 00112 MESSAGE_SINGLE(NORMAL, *logger, "lqm of " << streamLQM << " is too small -> reduce antennas"); 00113 reduceAntennas = true; 00114 } 00115 else 00116 { 00117 wifimac::convergence::PhyMode singleStreamPM = singleStreamRA.getPhyMode(numTransmissions, streamLQM); 00118 MESSAGE_SINGLE(NORMAL, *logger, "lqm for stream is " << streamLQM << " -> " << singleStreamPM); 00119 mcs.push_back(singleStreamPM.getSpatialStreams()[0]); 00120 } 00121 } 00122 if(not reduceAntennas) 00123 { 00124 wifimac::convergence::PhyMode pm = friends.phyUser->getPhyModeProvider()->getDefaultPhyMode(); 00125 pm.setSpatialStreams(mcs); 00126 if(pm.getDataBitsPerSymbol() > bestPM.getDataBitsPerSymbol()) 00127 { 00128 MESSAGE_SINGLE(NORMAL, *logger, "Found phyMode: " << pm << " with " << pm.getDataBitsPerSymbol() << "dbps -> new candidate"); 00129 bestPM = pm; 00130 foundBestPM = true; 00131 } 00132 else 00133 { 00134 MESSAGE_SINGLE(NORMAL, *logger, "Found phyMode: " << pm << ", but only " << pm.getDataBitsPerSymbol() << "dbps"); 00135 } 00136 } 00137 } 00138 else 00139 { 00140 MESSAGE_SINGLE(NORMAL, *logger, "peerFactor for " << numSS << " streams is not known"); 00141 } 00142 } 00143 00144 MESSAGE_SINGLE(NORMAL, *logger, "RA selects " << bestPM); 00145 return(bestPM); 00146 } 00147 00148 wifimac::convergence::PhyMode 00149 SINRwithMIMO::getPhyMode(size_t numTransmissions) const 00150 { 00151 if(sinr->knowsPeerSINR(myReceiver)) 00152 { 00153 return(getPhyMode(numTransmissions, sinr->getPeerSINR(myReceiver))); 00154 } 00155 else 00156 { 00157 return(ARFwithMIMO::getPhyMode(numTransmissions)); 00158 } 00159 } 00160 00161 void 00162 SINRwithMIMO::setCurrentPhyMode(wifimac::convergence::PhyMode pm) 00163 { 00164 if(not sinr->knowsPeerSINR(myReceiver)) 00165 { 00166 // no SINR known, phyMode setting is handled by ARF 00167 ARFwithMIMO::setCurrentPhyMode(pm); 00168 } 00169 // otherwise do nothing, no internal state required 00170 }
1.5.5