User Manual, Developers Guide and API Documentation

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

Generated on Mon May 21 03:32:11 2012 for openWNS by  doxygen 1.5.5