User Manual, Developers Guide and API Documentation

Beacon.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/management/Beacon.hpp>
00030 #include <WIFIMAC/convergence/PhyUser.hpp>
00031 #include <WIFIMAC/Layer2.hpp>
00032 #include <WNS/service/dll/StationTypes.hpp>
00033 #include <WNS/Exception.hpp>
00034 #include <DLL/StationManager.hpp>
00035 
00036 using namespace wifimac::management;
00037 
00038 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00039     wifimac::management::Beacon,
00040     wns::ldk::FunctionalUnit,
00041     "wifimac.management.Beacon",
00042     wns::ldk::FUNConfigCreator);
00043 
00044 Beacon::Beacon(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) :
00045     wns::ldk::fu::Plain<Beacon, BeaconCommand>(fun),
00046     config(config_),
00047     logger(config.get("logger")),
00048     currentBeacon(),
00049     phyUserCommandName(config.get<std::string>("phyUserCommandName")),
00050     scanFrequencies(config.getSequence("myConfig.scanFrequencies")),
00051     beaconPhyMode(config.getView("myConfig.beaconPhyMode")),
00052     bssId(config.get<std::string>("myConfig.bssId")),
00053     beaconRxStrength(),
00054     bssFrequencies()
00055 {
00056     friends.manager = NULL;
00057     MESSAGE_SINGLE(NORMAL, this->logger, "created");
00058 }
00059 
00060 Beacon::~Beacon()
00061 {
00062 
00063 }
00064 
00065 void
00066 Beacon::onFUNCreated()
00067 {
00068     friends.manager = getFUN()->findFriend<wifimac::lowerMAC::Manager*>(config.get<std::string>("managerName"));
00069     assure(friends.manager, "Management entity not found");
00070 
00071     if (config.get<bool>("myConfig.enabled"))
00072     {
00073         assure(friends.manager->getStationType() != wns::service::dll::StationTypes::UT(),
00074                "STAs cannot transmit a beacon, as nobody can synchonize to them");
00075         // starting the periodic beacon transmission
00076         wns::simulator::Time delay = config.get<wns::simulator::Time>("myConfig.delay");
00077         wns::simulator::Time period = config.get<wns::simulator::Time>("myConfig.period");
00078         startPeriodicTimeout(period, delay);
00079         MESSAGE_SINGLE(NORMAL, this->logger, "Starting beacon with delay " << delay << " and period " << period);
00080     }
00081 
00082     if (friends.manager->getStationType() == wns::service::dll::StationTypes::UT())
00083     {
00084         scanFrequencies = config.getSequence("myConfig.scanFrequencies");
00085         freqIter = scanFrequencies.begin<double>();
00086         scanDuration = config.get<wns::simulator::Time>("myConfig.scanDuration");
00087         // set the transceiver to the first frequency
00088         MESSAGE_SINGLE(NORMAL, this->logger, "Set scanning frequency to " << *freqIter);
00089         friends.manager->getPhyUser()->setFrequency(*freqIter);
00090         // start scanning for the best beacon for association
00091         this->setTimeout(scanDuration);
00092     }
00093 }
00094 
00095 void Beacon::processIncoming(const wns::ldk::CompoundPtr& compound)
00096 {
00097     assure(friends.manager->getFrameType(compound->getCommandPool()) == BEACON, "Received frame is not a beacon");
00098 
00099     if (friends.manager->getTransmitterAddress(compound->getCommandPool()) == friends.manager->getMACAddress())
00100     {
00101         // Filter out own beacons
00102         return;
00103     }
00104 
00105     // store the received power in case of later association
00106     if(friends.manager->getStationType() == wns::service::dll::StationTypes::UT() and this->hasTimeoutSet())
00107     {
00108 
00109         // to strings are equal if compare returns 0
00110         if(this->bssId.compare(getCommand(compound->getCommandPool())->peer.bssId) == 0)
00111         {
00112             wifimac::convergence::PhyUserCommand* puc =
00113                 getFUN()->getCommandReader(phyUserCommandName)->readCommand<wifimac::convergence::PhyUserCommand>(compound->getCommandPool());
00114             beaconRxStrength[puc->local.rxPower + puc->local.interference] = friends.manager->getTransmitterAddress(compound->getCommandPool());
00115             bssFrequencies[friends.manager->getTransmitterAddress(compound->getCommandPool())] = *freqIter;
00116             MESSAGE_BEGIN(NORMAL, this->logger, m, "Received Beacon from ");
00117             m << friends.manager->getTransmitterAddress(compound->getCommandPool());
00118             m << " with " << (puc->local.rxPower + puc->local.interference);
00119             MESSAGE_END();
00120         }
00121         else
00122         {
00123             MESSAGE_BEGIN(NORMAL, this->logger, m, "Received beacon with bssId");
00124             m << getCommand(compound->getCommandPool())->peer.bssId;
00125             m << " only associate to bssId ";
00126             m << this->bssId;
00127             MESSAGE_END();
00128         }
00129     }
00130 
00131     // announce the link to the observers
00132     // TODO: This should be the task of the LinkQualityMeasurement
00133     this->wns::Subject<ILinkNotification>::forEachObserver(OnLinkIndication(friends.manager->getMACAddress(),
00134                                                                                     friends.manager->getTransmitterAddress(compound->getCommandPool())));
00135 }
00136 
00137 void Beacon::processOutgoing(const wns::ldk::CompoundPtr& /*compound*/)
00138 {
00139     throw wns::Exception("Impossible to call processOutgoing in Beacon FU");
00140 }
00141 
00142 bool Beacon::hasCapacity() const
00143 {
00144     return false;
00145 }
00146 
00147 const wns::ldk::CompoundPtr Beacon::hasSomethingToSend() const
00148 {
00149     return this->currentBeacon;
00150 }
00151 
00152 wns::ldk::CompoundPtr Beacon::getSomethingToSend()
00153 {
00154     wns::ldk::CompoundPtr it = this->currentBeacon;
00155     this->currentBeacon = wns::ldk::CompoundPtr();
00156     return(it);
00157 }
00158 
00159 void
00160 Beacon::periodically()
00161 {
00162     this->currentBeacon = friends.manager->createCompound(friends.manager->getMACAddress(), wns::service::dll::UnicastAddress(), BEACON, 0.0);
00163     friends.manager->setPhyMode(this->currentBeacon->getCommandPool(), beaconPhyMode);
00164     BeaconCommand* bc = this->activateCommand(this->currentBeacon->getCommandPool());
00165     bc->peer.bssId = this->bssId;
00166     tryToSend();
00167 }
00168 
00169 void
00170 Beacon::onTimeout()
00171 {
00172     assure(friends.manager->getStationType() == wns::service::dll::StationTypes::UT(), "Only STAs (UTs) can become associated");
00173 
00174     MESSAGE_SINGLE(NORMAL, this->logger, "Timeout for beacon scanning on frequency " << *freqIter);
00175     ++freqIter;
00176 
00177     if(freqIter != scanFrequencies.end<double>())
00178     {
00179         // set the transceiver to the next frequency
00180         MESSAGE_SINGLE(NORMAL, this->logger, "Set scanning frequency to " << *freqIter);
00181         friends.manager->getPhyUser()->setFrequency(*freqIter);
00182         // start next round of scanning for the best beacon for association
00183         this->setTimeout(scanDuration);
00184 
00185         return;
00186     }
00187 
00188     if(beaconRxStrength.empty())
00189     {
00190         MESSAGE_SINGLE(NORMAL, this->logger, "No beacons received, start scanning again");
00191         freqIter = scanFrequencies.begin<double>();
00192         friends.manager->getPhyUser()->setFrequency(*freqIter);
00193         this->setTimeout(scanDuration);
00194     }
00195     else
00196     {
00197         {
00198             MESSAGE_BEGIN(NORMAL, this->logger, m, "Start association, received beacons: ");
00199             for (std::map<wns::Power, wns::service::dll::UnicastAddress>::reverse_iterator itr = beaconRxStrength.rbegin();
00200                  itr != beaconRxStrength.rend();
00201                  ++itr)
00202             {
00203                 m << "(" << itr->first << " from " << itr->second << " on " << bssFrequencies[itr->second] << "MHz)";
00204             }
00205             MESSAGE_END();
00206         }
00207 
00208         std::map<wns::Power, wns::service::dll::UnicastAddress>::reverse_iterator itr = beaconRxStrength.rbegin();
00209         friends.manager->getPhyUser()->setFrequency(bssFrequencies[itr->second]);
00210         friends.manager->associateWith(itr->second);
00211 
00212         this->getFUN()->getLayer<wifimac::Layer2*>()->updateContext
00213             ("MAC.STAAssociatedToAP",
00214              getFUN()->getLayer<wifimac::Layer2*>()->getStationManager()->getStationByMAC(itr->second)->getID());
00215     }
00216 }
00217 
00218 void
00219 Beacon::calculateSizes(const wns::ldk::CommandPool* /*commandPool*/, Bit& commandPoolSize, Bit& sduSize) const
00220 {
00221     //No upper FUs, no upper sizes
00222     //this->getFUN()->calculateSizes(commandPool, commandPoolSize, sduSize, this);
00223 
00224     // todo: shift values to PyConfig
00225     Bit managementMACHdrSize = 24*8;
00226     Bit timestampSize = 8*8;
00227     Bit beaconIntervalSize = 2*8;
00228     Bit capabilityInformationSize = 2*8;
00229     Bit ssidSize = 2*8;
00230     Bit supportedRatesSize = 3*8;
00231     Bit timSize = 6*8;
00232 
00233     commandPoolSize = managementMACHdrSize + timestampSize + beaconIntervalSize + capabilityInformationSize + ssidSize + supportedRatesSize + timSize;
00234     sduSize = 0;
00235 } // calculateSizes

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