User Manual, Developers Guide and API Documentation

PhyUser.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiMeMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2011
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 5, 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 <WIMEMAC/convergence/PhyUser.hpp>
00030 #include <WNS/ldk/fun/FUN.hpp>
00031 #include <WNS/pyconfig/View.hpp>
00032 #include <WNS/logger/Logger.hpp>
00033 #include <WNS/module/Base.hpp>
00034 #include <WNS/ldk/concatenation/Concatenation.hpp>
00035 
00036 using namespace wimemac::convergence;
00037 
00038 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00039     wimemac::convergence::PhyUser,
00040     wns::ldk::FunctionalUnit,
00041     "wimemac.convergence.PhyUser",
00042     wns::ldk::FUNConfigCreator);
00043 
00044 PhyUser::PhyUser(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& _config) :
00045     wns::ldk::fu::Plain<PhyUser, PhyUserCommand>(fun),
00046     config(_config),
00047     logger(config.get<wns::pyconfig::View>("logger")),
00048     tune(),
00049     dataTransmission(NULL),
00050     notificationService(NULL),
00051     phyModes(config.getView("phyModesDeliverer")),
00052     managerName(config.get<std::string>("managerName")),
00053     txDurationCommandName(config.get<std::string>("txDurationCommandName")),
00054     txrxTurnaroundDelay(config.get<wns::simulator::Time>("txrxTurnaroundDelay")),
00055     phyUserStatus(receiving),
00056     currentTxCompound(),
00057     rxProbe_(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()),
00058                               "wimemac.phyuser.rxPower")),
00059     interferenceProbe_(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()),
00060                               "wimemac.phyuser.interferencePower")),
00061     SINRProbe_(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()),
00062                             "wimemac.phyuser.SINR")),
00063     SINRweightedProbe_(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()),
00064                             "wimemac.phyuser.SINRweighted"))
00065 {
00066     tune.frequency = config.get<double>("initFrequency");
00067     tune.bandwidth = config.get<double>("initBandwidthMHz");
00068     tune.numberOfSubCarrier = 1;
00069 
00070     MESSAGE_SINGLE(NORMAL, logger, "Signal frequency is set to " << tune.frequency);
00071 }
00072 // PhyUser
00073 
00074 
00075 PhyUser::~PhyUser()
00076 {
00077 
00078 }
00079 
00080 void PhyUser::onFUNCreated()
00081 {
00082     friends.manager = getFUN()->findFriend<wimemac::lowerMAC::Manager*>(managerName);
00083 } // onFUNCreated
00084 
00085 bool PhyUser::doIsAccepting(const wns::ldk::CompoundPtr& /* compound */) const
00086 {
00087     // we only accept if we are not currently transmitting
00088     return (phyUserStatus != transmitting);
00089 } // isAccepting
00090 
00091 
00092 
00093 void PhyUser::doSendData(const wns::ldk::CompoundPtr& compound)
00094 {
00095     assure(compound, "sendData called with an invalid compound.");
00096     assure(phyUserStatus != transmitting, "Cannot send data during transmission");
00097 
00098     MESSAGE_SINGLE(NORMAL, logger, "Rx Frequency is set to: " <<  (dataTransmission->getRxTune()).frequency);
00099     MESSAGE_SINGLE(NORMAL, logger, "Tx Frequency is set to: " <<  (dataTransmission->getTxTune()).frequency);
00100 
00101     if(!friends.manager->isPreamble(compound->getCommandPool()))
00102     {
00103         // signal tx start to the MAC
00104         this->wns::Subject<ITxStartEnd>::forEachObserver(OnTxStartEnd(compound, start));
00105     }
00106 
00107     wns::simulator::Time frameTxDuration = getFUN()->getCommandReader(txDurationCommandName)->
00108         readCommand<wimemac::convergence::TxDurationSetterCommand>(compound->getCommandPool())->getDuration();
00109 
00110     PhyUserCommand* command = activateCommand(compound->getCommandPool());
00111 
00112     // generate functor
00113     wimemac::convergence::BroadcastOFDMAAccessFunc* func = new wimemac::convergence::BroadcastOFDMAAccessFunc;
00114 
00115     // transmit now
00116     func->transmissionStart = wns::simulator::getEventScheduler()->getTime();
00117     func->transmissionStop = wns::simulator::getEventScheduler()->getTime() + frameTxDuration;
00118     func->subBand = 1;
00119 
00120     command->local.pAFunc.reset(func);
00121     (*command->local.pAFunc.get())(this, compound);
00122 
00123     MESSAGE_SINGLE(NORMAL, logger, "Transmission, rx disabled for " << frameTxDuration);
00124     if(phyUserStatus == txrxTurnaround)
00125     {
00126         setNewTimeout(frameTxDuration);
00127     }
00128     else
00129     {
00130         setTimeout(frameTxDuration);
00131     }
00132     // we are transmitting!
00133     phyUserStatus = transmitting;
00134 
00135     this->currentTxCompound = compound;
00136 
00137     MESSAGE_SINGLE(NORMAL, logger, "onSendData: Compound  " << *(compound));
00138 
00139 } // doSendData
00140 
00141 void PhyUser::doOnData(const wns::ldk::CompoundPtr& compound)
00142 {
00143     assure(compound, "onData called with an invalid compound.");
00144 
00145     getDeliverer()->getAcceptor(compound)->onData(compound);
00146 } // doOnData
00147 
00148 void PhyUser::onData(wns::osi::PDUPtr pdu, wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurement)
00149 {
00150     assure(wns::dynamicCast<wns::ldk::Compound>(pdu), "not a CompoundPtr");
00151 
00152     if(phyUserStatus != receiving)
00153     {
00154         // During transmission, the receiver is off
00155         return;
00156     }
00157 
00158     // FIRST: create a copy instead of working on the real compound
00159     wns::ldk::CompoundPtr compound = wns::staticCast<wns::ldk::Compound>(pdu)->copy();
00160 
00161     PhyUserCommand* phyCommand = getCommand(compound->getCommandPool());
00162 
00163     // store measured signal into Command
00164     phyCommand->local.rxPower      = rxPowerMeasurement->getRxPower();
00165     phyCommand->local.interference = rxPowerMeasurement->getInterferencePower();
00166 
00167 
00168 //     MESSAGE_SINGLE(NORMAL, logger, "onData: rxPower  " << phyCommand->local.rxPower);
00169 //     MESSAGE_SINGLE(NORMAL, logger, "onData: interference  " << phyCommand->local.interference);
00170 //     MESSAGE_SINGLE(NORMAL, logger, "onData: Compound  " << *(compound));
00171 
00172     // set probe values
00173     if(friends.manager->isForMe(compound->getCommandPool() ) && !friends.manager->isBeacon(compound->getCommandPool() ))
00174     {
00175         wns::Ratio sinr_ = wns::Ratio::from_dB(phyCommand->local.rxPower.get_dBm() - phyCommand->local.interference.get_dBm());
00176 
00177         rxProbe_->put(phyCommand->local.rxPower.get_dBm());
00178         interferenceProbe_->put(phyCommand->local.interference.get_dBm());
00179         SINRProbe_->put(sinr_.get_dB() );
00180 
00181         // Write weighted SINR probe; probe is weighted according to the tx duration in µs
00182         wns::simulator::Time txDuration_ = getFUN()->getCommandReader(txDurationCommandName)->
00183         readCommand<wimemac::convergence::TxDurationSetterCommand>(compound->getCommandPool())->getDuration();
00184 
00185         int weightingFactor_ = ceil(txDuration_*1E6); // weightingFactor = number of µs of tx duration
00186         for (int i = 0; i < weightingFactor_; i++)
00187         {
00188             SINRweightedProbe_->put(sinr_.get_dB() );
00189         }
00190     }
00191 
00192     this->wns::ldk::FunctionalUnit::onData(compound);
00193 } // onData
00194 
00195 void PhyUser::setDataTransmissionService(wns::service::Service* phy)
00196 {
00197     assure(phy, "must be non-NULL");
00198     assureType(phy, wns::service::phy::ofdma::DataTransmission*);
00199     dataTransmission = dynamic_cast<wns::service::phy::ofdma::DataTransmission*>(phy);
00200     dataTransmission->setRxTune(tune);
00201     dataTransmission->setTxTune(tune);
00202 } // setDataTransmissionService
00203 
00204 wns::service::phy::ofdma::DataTransmission* PhyUser::getDataTransmissionService() const
00205 {
00206     assure(dataTransmission, "no ofdma::DataTransmission set. Did you call setDataTransmission()?");
00207     return dataTransmission;
00208 } // getDataTransmissionService
00209 
00210 void PhyUser::setNotificationService(wns::service::Service* phy)
00211 {
00212     assure(phy, "must be non-NULL");
00213     assureType(phy, wns::service::phy::ofdma::Notification*);
00214     notificationService = dynamic_cast<wns::service::phy::ofdma::Notification*>(phy);
00215 
00216     // attach handler (there can be only one)
00217     notificationService->registerHandler(this);
00218 
00219 } // setNotificationService
00220 
00221 wns::service::phy::ofdma::Notification* PhyUser::getNotificationService() const
00222 {
00223     assure(notificationService, "no ofdma::Notification set. Did you call setNotificationService()?");
00224     return notificationService;
00225 } // getNotificationService
00226 
00227 void PhyUser::doWakeup()
00228 {
00229     assure(false, "PhyUser doWakeup will never be called -- nobody is below");
00230 } // doWakeup
00231 
00232 void PhyUser::onTimeout()
00233 {
00234     assure(phyUserStatus != receiving, "Timeout although not transmitting");
00235     if(phyUserStatus == transmitting)
00236     {
00237         // finished transmission, start turnaround
00238         MESSAGE_SINGLE(NORMAL, logger, "Timeout, finished transmission");
00239         phyUserStatus = txrxTurnaround;
00240         setTimeout(txrxTurnaroundDelay);
00241 
00242         assure(this->currentTxCompound, "currentTxCompound is NULL");
00243         if(!friends.manager->isPreamble(this->currentTxCompound->getCommandPool()))
00244         {
00245             // signal tx end to MAC
00246             MESSAGE_SINGLE(NORMAL, logger, "No preamble -> signal tx end");
00247             this->wns::Subject<ITxStartEnd>::forEachObserver(OnTxStartEnd(this->currentTxCompound, end));
00248         }
00249         this->currentTxCompound = wns::ldk::CompoundPtr();
00250 
00251         // wakeup: we are ready to transmit another compound
00252         this->getReceptor()->wakeup();
00253         return;
00254     }
00255 
00256     if(phyUserStatus == txrxTurnaround)
00257     {
00258         // finished turnaround, ready to receive
00259         phyUserStatus = receiving;
00260         return;
00261     }
00262 
00263     assure(false, "Unknown phyUserStatus");
00264 }
00265 
00266 void PhyUser::setFrequency(double frequency)
00267 {
00268     if(dataTransmission == NULL)
00269     {
00270         MESSAGE_SINGLE(NORMAL, logger, "cannot yet set RxFrequency, save for after initialisation");
00271         tune.frequency = frequency;
00272     }
00273     else
00274     {
00275         MESSAGE_SINGLE(NORMAL, logger, "setRxFrequency to f: " << frequency << " MHz");
00276         tune.frequency = frequency;
00277         dataTransmission->setRxTune(tune);
00278         dataTransmission->setTxTune(tune);
00279     }
00280 }
00281 
00282 PhyModeProvider* PhyUser::getPhyModeProvider()
00283 {
00284     return &phyModes;
00285 }
00286 
00287 wns::Power
00288 PhyUser::getRxPower(const wns::ldk::CommandPool* commandPool)
00289 {
00290     PhyUserCommand* phyCommand = getCommand(commandPool);
00291     return phyCommand->local.rxPower;
00292 }
00293 
00294 wns::Power
00295 PhyUser::getInterference(const wns::ldk::CommandPool* commandPool)
00296 {
00297     PhyUserCommand* phyCommand = getCommand(commandPool);
00298     return phyCommand->local.interference;
00299 }
00300 

Generated on Sun May 27 03:32:05 2012 for openWNS by  doxygen 1.5.5