User Manual, Developers Guide and API Documentation

PERwithMIMO.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/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 }

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