User Manual, Developers Guide and API Documentation

BlockUntilReply.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/BlockUntilReply.hpp>
00030 
00031 using namespace wifimac::draftn;
00032 
00033 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00034     wifimac::draftn::BlockUntilReply,
00035     wns::ldk::FunctionalUnit,
00036     "wifimac.draftn.BlockUntilReply",
00037     wns::ldk::FUNConfigCreator);
00038 
00039 BlockUntilReply::BlockUntilReply(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config):
00040     wns::ldk::fu::Plain<BlockUntilReply, wns::ldk::EmptyCommand>(fun),
00041 
00042     sifsDuration(config.get<wns::simulator::Time>("myConfig.sifsDuration")),
00043     managerName(config.get<std::string>("managerName")),
00044     txStartEndName(config.get<std::string>("txStartEndName")),
00045     rxStartEndName(config.get<std::string>("rxStartEndName")),
00046     blocked(false),
00047     txStatus(finished),
00048     blockedBy(),
00049     logger(config.get("logger"))
00050 {
00051 
00052 }
00053 
00054 BlockUntilReply::~BlockUntilReply()
00055 {
00056 
00057 }
00058 
00059 void BlockUntilReply::onFUNCreated()
00060 {
00061     friends.manager = getFUN()->findFriend<wifimac::lowerMAC::Manager*>(managerName);
00062 
00063     this->wns::Observer<wifimac::convergence::ITxStartEnd>::startObserving
00064         (getFUN()->findFriend<wifimac::convergence::TxStartEndNotification*>(txStartEndName));
00065     this->wns::Observer<wifimac::convergence::IRxStartEnd>::startObserving
00066         (getFUN()->findFriend<wifimac::convergence::RxStartEndNotification*>(rxStartEndName));
00067 }
00068 
00069 void BlockUntilReply::doSendData(const wns::ldk::CompoundPtr& compound)
00070 {
00071     if(friends.manager->getFrameType(compound->getCommandPool()) == ACK)
00072     {
00073         getConnector()->getAcceptor(compound)->sendData(compound);
00074         return;
00075     }
00076     this->blocked = true;
00077     this->txStatus = waiting;
00078     this->blockedBy = compound->getBirthmark();
00079     MESSAGE_SINGLE(NORMAL, logger, "Ougoing data -> block");
00080 
00081     // pass through
00082     getConnector()->getAcceptor(compound)->sendData(compound);
00083 }
00084 
00085 void BlockUntilReply::doOnData(const wns::ldk::CompoundPtr& compound)
00086 {
00087     if(this->blocked and (this->txStatus == finished))
00088     {
00089         this->blocked = false;
00090 
00091         if(hasTimeoutSet())
00092         {
00093             cancelTimeout();
00094         }
00095 
00096         MESSAGE_SINGLE(NORMAL, logger, "Received data -> remove block");
00097     }
00098     // pass through
00099     getDeliverer()->getAcceptor(compound)->onData(compound);
00100 }
00101 
00102 bool BlockUntilReply::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00103 {
00104     if(friends.manager->getFrameType(compound->getCommandPool()) == ACK)
00105     {
00106         return (this->txStatus != transmitting) and (getConnector()->hasAcceptor(compound));
00107     }
00108 
00109     if(this->blocked)
00110     {
00111         return(false);
00112     }
00113     else
00114     {
00115         return getConnector()->hasAcceptor(compound);
00116     }
00117 }
00118 
00119 void BlockUntilReply::doWakeup()
00120 {
00121     if(not this->blocked)
00122     {
00123         getReceptor()->wakeup();
00124     }
00125 }
00126 
00127 void BlockUntilReply::onTxStart(const wns::ldk::CompoundPtr& compound)
00128 {
00129     if(compound->getBirthmark() == this->blockedBy)
00130     {
00131         assure(this->txStatus == waiting, "onTxStart, but status is not waiting");
00132         MESSAGE_SINGLE(NORMAL, logger, "Start of frame transmission");
00133         this->txStatus = transmitting;
00134     }
00135 
00136 }
00137 
00138 void BlockUntilReply::onTxEnd(const wns::ldk::CompoundPtr& compound)
00139 {
00140     if(compound->getBirthmark() != this->blockedBy)
00141     {
00142         return;
00143     }
00144 
00145     assure(this->txStatus == transmitting, "onTxEnd, but status is not transmitting");
00146     this->txStatus = finished;
00147     wns::simulator::Time timeout = friends.manager->getReplyTimeout(compound->getCommandPool());
00148     if(timeout > 0.0)
00149     {
00150         // Timeout for reception
00151         setTimeout(timeout);
00152         MESSAGE_SINGLE(NORMAL, logger, "End frame transmission, requires reply -> wait for " << timeout);
00153     }
00154     else
00155     {
00156         if(this->blocked)
00157         {
00158             this->blocked = false;
00159             MESSAGE_SINGLE(NORMAL, logger, "End frame transmission, remove block");
00160             getReceptor()->wakeup();
00161         }
00162     }
00163 }
00164 
00165 void BlockUntilReply::onTimeout()
00166 {
00167     assure(this->blocked, "timeout, but not blocked");
00168     assure(this->txStatus == finished, "tx is not done, but timeout");
00169 
00170     this->blocked = false;
00171     MESSAGE_SINGLE(NORMAL, logger, "timeout -> remove block");
00172     getReceptor()->wakeup();
00173 }
00174 
00175 void BlockUntilReply::onRxStart(wns::simulator::Time /*expRxTime*/)
00176 {
00177     if(this->blocked and (this->txStatus == finished))
00178     {
00179         MESSAGE_SINGLE(NORMAL, logger, "onRxStart during blocked, wait for frame");
00180         if(hasTimeoutSet())
00181         {
00182             cancelTimeout();
00183         }
00184     }
00185 }
00186 
00187 
00188 void BlockUntilReply::onRxEnd()
00189 {
00190     if(this->blocked and (this->txStatus == finished))
00191     {
00192         setTimeout(10e-9);
00193         MESSAGE_SINGLE(NORMAL, logger, "onRxEnd during blocked, wait for frame");
00194     }
00195 }
00196 
00197 void BlockUntilReply::onRxError()
00198 {
00199     if(this->blocked and (this->txStatus == finished))
00200     {
00201         MESSAGE_SINGLE(NORMAL, logger, "onRxError during blocked, timeout");
00202     if(hasTimeoutSet())
00203     {
00204         cancelTimeout();
00205     }
00206         onTimeout();
00207     }
00208 }

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