![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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/lowerMAC/timing/DCF.hpp> 00030 00031 #include <WNS/ldk/Layer.hpp> 00032 #include <WNS/ldk/arq/ARQ.hpp> 00033 #include <WNS/service/phy/ofdma/Notification.hpp> 00034 #include <WNS/container/UntypedRegistry.hpp> 00035 00036 #include <DLL/UpperConvergence.hpp> 00037 00038 using namespace wimemac::lowerMAC::timing; 00039 00040 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00041 wimemac::lowerMAC::timing::DCF, 00042 wns::ldk::FunctionalUnit, 00043 "wimemac.lowerMAC.timing.DCF", 00044 wns::ldk::FUNConfigCreator); 00045 00046 DCF::DCF(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) : 00047 wns::ldk::fu::Plain<DCF, wns::ldk::EmptyCommand>(fun), 00048 csName(config_.get<std::string>("csName")), 00049 rxStartEndName(config_.get<std::string>("rxStartEndName")), 00050 drpSchedulerName(config_.get<std::string>("drpSchedulerName")), 00051 backoffDisabled(config_.get<bool>("myConfig.backoffDisabled")), 00052 backoff(this, config_), 00053 sendNow(false), 00054 logger(config_.get("logger")) 00055 { 00056 } // DCF::DCF 00057 00058 00059 DCF::~DCF() 00060 { 00061 } // DCF::~DCF 00062 00063 void DCF::onFUNCreated() 00064 { 00065 friends.drpScheduler = getFUN()->findFriend<wimemac::drp::IDRPSchedulerServices*>(drpSchedulerName); 00066 00067 if(not backoffDisabled) 00068 { 00069 // backoff observes the channel state 00070 backoff.wns::Observer<wimemac::convergence::IChannelState>::startObserving 00071 (getFUN()->findFriend<wimemac::convergence::ChannelStateNotification*>(csName)); 00072 00073 // backoff gets notified of failed receptions 00074 backoff.wns::Observer<wimemac::convergence::IRxStartEnd>::startObserving 00075 (getFUN()->findFriend<wimemac::convergence::RxStartEndNotification*>(rxStartEndName)); 00076 } 00077 } // DCF::onFUNCreated 00078 00079 void 00080 DCF::doSendData(const wns::ldk::CompoundPtr& compound) 00081 { 00082 assure(sendNow, 00083 "called doSendData, but sendNow is false"); 00084 sendNow = false; 00085 00086 assure(getConnector()->hasAcceptor(compound), 00087 "lower FU is not accepting"); 00088 00089 getConnector()->getAcceptor(compound)->sendData(compound); 00090 00091 } 00092 00093 void 00094 DCF::doOnData(const wns::ldk::CompoundPtr& compound) 00095 { 00096 // simply forward to the upper FU 00097 getDeliverer()->getAcceptor(compound)->onData(compound); 00098 } 00099 00100 bool 00101 DCF::doIsAccepting(const wns::ldk::CompoundPtr& compound) const 00102 { 00103 assure(not backoffDisabled, 00104 "Backoff was disabled, hence no frames can be accepted"); 00105 00106 if(sendNow and getConnector()->hasAcceptor(compound)) 00107 { 00108 MESSAGE_SINGLE(NORMAL, logger, "backoff asked, sendNow is " << sendNow); 00109 return true; 00110 } 00111 00112 00113 int numTransmissions = friends.drpScheduler->getNumOfRetransmissions(compound) + 1; // numTransmissions begins with 1 00114 if(numTransmissions > 1) 00115 { 00116 // It was already tried to send this compound 00117 MESSAGE_SINGLE(NORMAL, logger, "Compound retransmission, transmission number " << numTransmissions); 00118 sendNow = backoff.transmissionRequest(numTransmissions); 00119 } 00120 else 00121 { 00122 MESSAGE_SINGLE(NORMAL, logger, "Compound's first transmission"); 00123 sendNow = backoff.transmissionRequest(1); 00124 } 00125 00126 MESSAGE_SINGLE(NORMAL, logger, "backoff asked, sendNow is " << sendNow); 00127 00128 return(sendNow and getConnector()->hasAcceptor(compound)); 00129 } 00130 00131 void 00132 DCF::waitingTransmissions(int numTransmissions) 00133 { 00134 bool directGo = backoff.transmissionRequest(numTransmissions); 00135 } 00136 00137 void 00138 DCF::doWakeup() 00139 { 00140 getReceptor()->wakeup(); 00141 } 00142 00143 void 00144 DCF::onDRPStart() 00145 { 00146 backoff.OnDRPreservationChange(true); 00147 } 00148 00149 void 00150 DCF::onDRPStop() 00151 { 00152 backoff.OnDRPreservationChange(false); 00153 } 00154 00155 void DCF::backoffExpired() 00156 { 00157 MESSAGE_SINGLE(NORMAL, logger, "Backoff expired, startPCAtransmission"); 00158 this->sendNow = true; 00159 00160 // Trigger start of a PCA transmission 00161 if(!friends.drpScheduler->startPCAtransmission()) 00162 { 00163 MESSAGE_SINGLE(NORMAL, logger, "PCA transmission could not be started immediately -> reset sendNow"); 00164 this->sendNow = false; 00165 } 00166 }
1.5.5