User Manual, Developers Guide and API Documentation

SINRwithMIMO.cpp

Go to the documentation of this file.
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 }

Generated on Fri May 25 03:32:09 2012 for openWNS by  doxygen 1.5.5