![]() |
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/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
1.5.5