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