![]() |
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/lowerMAC/Manager.hpp> 00030 #include <WIFIMAC/convergence/ChannelState.hpp> 00031 #include <WIFIMAC/management/VirtualCapabilityInformationBase.hpp> 00032 #include <WIFIMAC/helper/Keys.hpp> 00033 #include <WIFIMAC/Layer2.hpp> 00034 00035 #include <DLL/Layer2.hpp> 00036 #include <WNS/service/dll/StationTypes.hpp> 00037 #include <WNS/ldk/FlowGate.hpp> 00038 00039 using namespace wifimac::lowerMAC; 00040 00041 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00042 wifimac::lowerMAC::Manager, 00043 wns::ldk::FunctionalUnit, 00044 "wifimac.lowerMAC.Manager", 00045 wns::ldk::FUNConfigCreator); 00046 00047 Manager::Manager(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00048 wns::ldk::fu::Plain<Manager, ManagerCommand>(fun), 00049 config_(config), 00050 logger_(config_.get("logger")), 00051 maximumACKDuration(config.get<wns::simulator::Time>("myConfig.maximumACKDuration")), 00052 sifsDuration(config.get<wns::simulator::Time>("myConfig.sifsDuration")), 00053 myMACAddress_(config.get<wns::service::dll::UnicastAddress>("myMACAddress")), 00054 ucName_(config_.get<std::string>("upperConvergenceCommandName")), 00055 numAntennas(config_.get<int>("myConfig.numAntennas")), 00056 msduLifetimeLimit(config_.get<wns::simulator::Time>("myConfig.msduLifetimeLimit")), 00057 associatedTo() 00058 { 00059 MESSAGE_SINGLE(NORMAL, logger_, "created"); 00060 friends.phyUser = NULL; 00061 friends.upperConvergence = NULL; 00062 } 00063 00064 Manager::~Manager() 00065 { 00066 00067 } 00068 00069 void 00070 Manager::onFUNCreated() 00071 { 00072 // set services in my PhyUser to communicate with lower layer 00073 friends.phyUser = getFUN()->findFriend<wifimac::convergence::PhyUser*>(config_.get<std::string>("phyUserName")); 00074 00075 friends.phyUser->setDataTransmissionService( 00076 this->getFUN()->getLayer<dll::ILayer2*>() 00077 ->getService<wns::service::phy::ofdma::DataTransmission*>( config_.get<std::string>("phyDataTransmission") ) ); 00078 friends.phyUser->setNotificationService( 00079 this->getFUN()->getLayer<dll::ILayer2*>() 00080 ->getService<wns::service::phy::ofdma::Notification*>( config_.get<std::string>("phyNotification") ) ); 00081 00082 // set service in ChannelState to observe the CarrierSense 00083 wifimac::convergence::ChannelState* cs = getFUN()->findFriend<wifimac::convergence::ChannelState*>(config_.get<std::string>("channelStateName")); 00084 assure(cs, "Could not get ChannelState from my FUN"); 00085 00086 cs->setCarrierSensingService( 00087 this->getFUN()->getLayer<dll::ILayer2*>() 00088 ->getService<wns::service::phy::ofdma::Notification*>(config_.get<std::string>("phyCarrierSense")) ); 00089 00090 // open the flow gate for my compounds 00091 wns::ldk::FlowGate* rxFilter = getFUN()->findFriend<wns::ldk::FlowGate*>(config_.get<std::string>("receiveFilterName")); 00092 assure(rxFilter, "Could not get receiveFilter from my FUN"); 00093 rxFilter->createFlow(wns::ldk::ConstKeyPtr(new wifimac::helper::LinkByTransmitter(myMACAddress_))); 00094 wns::ldk::ConstKeyPtr key(new wifimac::helper::LinkByTransmitter(myMACAddress_)); 00095 rxFilter->openFlow(key); 00096 00097 // Register manager at Layer2 00098 this->getFUN()->getLayer<wifimac::Layer2*>()->registerManager(this, myMACAddress_); 00099 00100 // find upper convergence 00101 friends.upperConvergence = getFUN()->findFriend<dll::UpperConvergence*>(ucName_); 00102 00103 // set the number of antennas for MIMO 00104 assure(wifimac::management::TheVCIBService::Instance().getVCIB(), "No virtual capability information base service found"); 00105 wifimac::management::TheVCIBService::Instance().getVCIB()->set<int>(myMACAddress_, "numAntennas", numAntennas); 00106 } 00107 00108 00109 void 00110 Manager::processIncoming(const wns::ldk::CompoundPtr& /*compound*/) 00111 { 00112 00113 } 00114 00115 void 00116 Manager::processOutgoing(const wns::ldk::CompoundPtr& compound) 00117 { 00118 assure(getFUN()->getCommandReader(ucName_) 00119 ->readCommand<dll::UpperCommand>(compound->getCommandPool()) 00120 ->peer.sourceMACAddress == myMACAddress_, 00121 "Try to tx compound with source address " << 00122 getFUN()->getCommandReader(ucName_) 00123 ->readCommand<dll::UpperCommand>(compound->getCommandPool()) 00124 ->peer.sourceMACAddress << 00125 " from transceiver with MAC address " << myMACAddress_ ); 00126 00127 // The command has to be activated to be considered in the createReply chain 00128 ManagerCommand* mc = activateCommand(compound->getCommandPool()); 00129 mc->peer.type = DATA; 00130 mc->peer.frameExchangeDuration = this->sifsDuration + this->maximumACKDuration; 00131 if(this->msduLifetimeLimit > 0) 00132 { 00133 mc->local.expirationTime = wns::simulator::getEventScheduler()->getTime() + this->msduLifetimeLimit; 00134 MESSAGE_SINGLE(NORMAL, logger_, "Outgoing command will expire at " << mc->local.expirationTime); 00135 } 00136 else 00137 { 00138 mc->local.expirationTime = 0.0; 00139 MESSAGE_SINGLE(NORMAL, logger_, "Outgoing command, no expiration time"); 00140 } 00141 } 00142 00143 bool 00144 Manager::lifetimeExpired(const wns::ldk::CommandPool* commandPool) const 00145 { 00146 wns::simulator::Time exp = getCommand(commandPool)->local.expirationTime; 00147 if(exp == 0) 00148 { 00149 return false; 00150 } 00151 else 00152 { 00153 return(wns::simulator::getEventScheduler()->getTime() > exp); 00154 } 00155 } 00156 00157 wns::simulator::Time 00158 Manager::getExpirationTime(const wns::ldk::CommandPool* commandPool) const 00159 { 00160 return(getCommand(commandPool)->local.expirationTime); 00161 } 00162 00163 wifimac::convergence::PhyUser* 00164 Manager::getPhyUser() 00165 { 00166 if(friends.phyUser) 00167 { 00168 return(friends.phyUser); 00169 } 00170 else 00171 { 00172 return(getFUN()->findFriend<wifimac::convergence::PhyUser*>(config_.get<std::string>("phyUserName"))); 00173 } 00174 } 00175 00176 dll::ILayer2::StationType 00177 Manager::getStationType() const 00178 { 00179 // simply relayed to Layer2 00180 return(this->getFUN()->getLayer<dll::ILayer2*>()->getStationType()); 00181 } 00182 00183 wns::service::dll::UnicastAddress 00184 Manager::getMACAddress() const 00185 { 00186 return(this->myMACAddress_); 00187 } 00188 00189 void 00190 Manager::associateWith(wns::service::dll::UnicastAddress svrAddress) 00191 { 00192 assure(this->getFUN()->getLayer<dll::ILayer2*>()->getStationType() == wns::service::dll::StationTypes::UT(), 00193 "Called associateWith by non-UT"); 00194 00195 // the association links the layer2 of this STA and the layer2 of the AP - 00196 // not the transceiver 00197 this->getFUN()->getLayer<dll::ILayer2*>()->getControlService<dll::services::control::Association>("ASSOCIATION") 00198 ->associate(this->myMACAddress_, svrAddress); 00199 00200 this->associatedTo = svrAddress; 00201 00202 } 00203 00204 wns::service::dll::UnicastAddress 00205 Manager::getAssociatedTo() const 00206 { 00207 return this->associatedTo; 00208 } 00209 00210 wns::ldk::CommandPool* 00211 Manager::createReply(const wns::ldk::CommandPool* original) const 00212 { 00213 wns::ldk::CommandPool* reply = this->getFUN()->getProxy()->createReply(original, this); 00214 00215 dll::UpperCommand* ucReply = getFUN()->getProxy()->getCommand<dll::UpperCommand>(reply, ucName_); 00216 dll::UpperCommand* ucOriginal = getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(original); 00217 00218 // this cannot be set to this->myAddress_, because it is not defined which 00219 // Manager-entity will be asked for createReply 00220 ucReply->peer.sourceMACAddress = ucOriginal->peer.targetMACAddress; 00221 00222 ManagerCommand* mc = activateCommand(reply); 00223 mc->peer.type = DATA; 00224 if(this->msduLifetimeLimit > 0) 00225 { 00226 mc->local.expirationTime = wns::simulator::getEventScheduler()->getTime() + this->msduLifetimeLimit; 00227 } 00228 else 00229 { 00230 mc->local.expirationTime = 0; 00231 } 00232 00233 00234 MESSAGE_SINGLE(NORMAL, logger_, "create reply done, set sourceMACAddress to " << ucReply->peer.sourceMACAddress); 00235 00236 return(reply); 00237 } 00238 00239 wns::service::dll::UnicastAddress 00240 Manager::getTransmitterAddress(const wns::ldk::CommandPool* commandPool) const 00241 { 00242 return (getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(commandPool)->peer.sourceMACAddress); 00243 } 00244 00245 wns::service::dll::UnicastAddress 00246 Manager::getReceiverAddress(const wns::ldk::CommandPool* commandPool) const 00247 { 00248 return (getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(commandPool)->peer.targetMACAddress); 00249 } 00250 00251 bool 00252 Manager::isForMe(const wns::ldk::CommandPool* commandPool) const 00253 { 00254 if(getFUN()->getCommandReader(ucName_)->commandIsActivated(commandPool)) 00255 { 00256 return(getFUN()->getCommandReader(ucName_)->readCommand<dll::UpperCommand>(commandPool)->peer.targetMACAddress == this->myMACAddress_); 00257 } 00258 else 00259 { 00260 // broadcast -> is for me 00261 return true; 00262 } 00263 } 00264 00265 wifimac::FrameType 00266 Manager::getFrameType(const wns::ldk::CommandPool* commandPool) const 00267 { 00268 return(getCommand(commandPool)->peer.type); 00269 } 00270 00271 wns::ldk::CompoundPtr 00272 Manager::createCompound(const wns::service::dll::UnicastAddress transmitterAddress, 00273 const wns::service::dll::UnicastAddress receiverAddress, 00274 const FrameType type, 00275 const wns::simulator::Time frameExchangeDuration, 00276 const wns::simulator::Time replyTimeout) 00277 { 00278 wns::ldk::CompoundPtr compound(new wns::ldk::Compound(getFUN()->getProxy()->createCommandPool())); 00279 ManagerCommand* mc = activateCommand(compound->getCommandPool()); 00280 dll::UpperCommand* uc = friends.upperConvergence->activateCommand(compound->getCommandPool()); 00281 00282 uc->peer.sourceMACAddress = transmitterAddress; 00283 uc->peer.targetMACAddress = receiverAddress; 00284 mc->peer.type = type; 00285 mc->peer.frameExchangeDuration = frameExchangeDuration; 00286 mc->local.replyTimeout = replyTimeout; 00287 00288 return(compound); 00289 } 00290 00291 void 00292 Manager::setFrameType(const wns::ldk::CommandPool* commandPool, const FrameType type) 00293 { 00294 getCommand(commandPool)->peer.type = type; 00295 } 00296 00297 wifimac::convergence::PhyMode 00298 Manager::getPhyMode(const wns::ldk::CommandPool* commandPool) const 00299 { 00300 return(getCommand(commandPool)->getPhyMode()); 00301 } 00302 00303 void 00304 Manager::setPhyMode(const wns::ldk::CommandPool* commandPool, const wifimac::convergence::PhyMode phyMode) 00305 { 00306 getCommand(commandPool)->peer.phyMode = phyMode; 00307 } 00308 00309 wns::simulator::Time 00310 Manager::getFrameExchangeDuration(const wns::ldk::CommandPool* commandPool) const 00311 { 00312 return(getCommand(commandPool)->peer.frameExchangeDuration); 00313 } 00314 00315 void 00316 Manager::setFrameExchangeDuration(const wns::ldk::CommandPool* commandPool, const wns::simulator::Time duration) 00317 { 00318 getCommand(commandPool)->peer.frameExchangeDuration = duration; 00319 } 00320 00321 wns::simulator::Time 00322 Manager::getReplyTimeout(const wns::ldk::CommandPool* commandPool) const 00323 { 00324 return(getCommand(commandPool)->local.replyTimeout); 00325 } 00326 00327 void 00328 Manager::setReplyTimeout(const wns::ldk::CommandPool* commandPool, wns::simulator::Time replyTimeout) 00329 { 00330 getCommand(commandPool)->local.replyTimeout = replyTimeout; 00331 } 00332 00333 unsigned int 00334 Manager::getNumAntennas() const 00335 { 00336 return this->numAntennas; 00337 }
1.5.5