![]() |
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/convergence/PreambleGenerator.hpp> 00030 #include <DLL/Layer2.hpp> 00031 00032 using namespace wimemac::convergence; 00033 00034 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00035 wimemac::convergence::PreambleGenerator, 00036 wns::ldk::FunctionalUnit, 00037 "wimemac.convergence.PreambleGenerator", 00038 wns::ldk::FUNConfigCreator); 00039 00040 PreambleGenerator::PreambleGenerator(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) : 00041 wns::ldk::fu::Plain<PreambleGenerator, PreambleGeneratorCommand>(fun), 00042 phyUserName(config_.get<std::string>("phyUserName")), 00043 managerName(config_.get<std::string>("managerName")), 00044 logger(config_.get("logger")), 00045 pendingCompound(), 00046 pendingPreamble() 00047 { 00048 MESSAGE_SINGLE(NORMAL, this->logger, "created"); 00049 friends.manager = NULL; 00050 friends.phyUser = NULL; 00051 } 00052 00053 PreambleGenerator::~PreambleGenerator() 00054 { 00055 00056 } 00057 00058 void 00059 PreambleGenerator::onFUNCreated() 00060 { 00061 MESSAGE_SINGLE(NORMAL, this->logger, "onFUNCreated() started"); 00062 00063 friends.phyUser = getFUN()->findFriend<wimemac::convergence::IPhyServices*>(phyUserName); 00064 friends.manager = getFUN()->findFriend<wimemac::lowerMAC::IManagerServices*>(managerName); 00065 } 00066 00067 void 00068 PreambleGenerator::processIncoming(const wns::ldk::CompoundPtr& compound) 00069 { 00070 if((friends.manager->isPreamble(compound->getCommandPool())) && (friends.manager->hasPayload(compound->getCommandPool()))) 00071 { 00072 MESSAGE_SINGLE(NORMAL, this->logger, "Received PREAMBLE -> drop"); 00073 // Save preambletype for following incoming compound with type payload 00074 lastReceivedCompoundType = friends.manager->getCompoundType(compound->getCommandPool()); 00075 } 00076 else if((friends.manager->isPreamble(compound->getCommandPool())) && (!friends.manager->hasPayload(compound->getCommandPool()))) 00077 { 00078 wimemac::CompoundType compoundType_ = friends.manager->getCompoundType(compound->getCommandPool()); 00079 MESSAGE_SINGLE(NORMAL, this->logger, "Received PREAMBLE without PAYLOAD of type : " << compoundType_); 00080 // Change compoundtype from preamble to the actual type and deliver it 00081 if (compoundType_ == ACK_PREAMBLE) 00082 { 00083 friends.manager->setCompoundType(compound->getCommandPool(), ACK); 00084 getDeliverer()->getAcceptor(compound)->onData(compound); 00085 } 00086 else assure(false, "CompoundType : " << compoundType_ << "should have a payload!"); 00087 } 00088 else 00089 { 00090 if (lastReceivedCompoundType == BEACON_PREAMBLE) 00091 { 00092 friends.manager->setCompoundType(compound->getCommandPool(), BEACON); 00093 } 00094 else if (lastReceivedCompoundType == DATA_PREAMBLE) 00095 { 00096 friends.manager->setCompoundType(compound->getCommandPool(), DATA); 00097 } 00098 else assure(false, "Last received compound type was : " << lastReceivedCompoundType << ". This compound is of type payload and should not follow such a compound!"); 00099 // deliver frame 00100 getDeliverer()->getAcceptor(compound)->onData(compound); 00101 lastReceivedCompoundType == PAYLOAD; 00102 } 00103 } 00104 00105 void 00106 PreambleGenerator::processOutgoing(const wns::ldk::CompoundPtr& compound) 00107 { 00108 // compute transmission duration of the frame, dependent on the mcs 00109 wimemac::convergence::PhyMode phyMode = 00110 friends.manager->getPhyMode(compound->getCommandPool()); 00111 wns::simulator::Time psduDuration = 00112 friends.manager->getProtocolCalculator()->getDuration()->MSDU_PSDU(compound->getLengthInBits(), phyMode); // FCS and pad bits were not added yet 00113 00114 // First we generate a preamble 00115 this->pendingPreamble = compound->copy(); 00116 // set preamble compoundType according to outgoing compoundType 00117 wimemac::CompoundType outgoingCompoundType_ = friends.manager->getCompoundType(compound->getCommandPool()); 00118 00119 if (outgoingCompoundType_ == ACK) 00120 { 00121 friends.manager->setCompoundType(this->pendingPreamble->getCommandPool(), 00122 ACK_PREAMBLE); 00123 } 00124 else if (outgoingCompoundType_ == BEACON) 00125 { 00126 friends.manager->setCompoundType(this->pendingPreamble->getCommandPool(), 00127 BEACON_PREAMBLE); 00128 } 00129 else if (outgoingCompoundType_ == DATA or outgoingCompoundType_ == DATA_TXOP) 00130 { 00131 friends.manager->setCompoundType(this->pendingPreamble->getCommandPool(), 00132 DATA_PREAMBLE); 00133 } 00134 else assure(false, "Outgoing compound has no valid compoundType : " << outgoingCompoundType_); 00135 00136 friends.manager->setPhyMode(this->pendingPreamble->getCommandPool(), 00137 friends.phyUser->getPhyModeProvider()->getPreamblePhyMode(phyMode)); 00138 if (friends.manager->hasPayload(compound->getCommandPool())) 00139 { 00140 wns::simulator::Time frameExchangeDuration = friends.manager->getFrameExchangeDuration(compound->getCommandPool()); 00141 00142 if(frameExchangeDuration == 0) 00143 { 00144 // Special compounds that may have not been initialized with a frameExchangeDuration 00145 friends.manager->setFrameExchangeDuration(this->pendingPreamble->getCommandPool(), psduDuration); 00146 } 00147 else friends.manager->setFrameExchangeDuration(this->pendingPreamble->getCommandPool(), frameExchangeDuration + psduDuration); 00148 00149 friends.manager->setpsduDuration(this->pendingPreamble->getCommandPool(), psduDuration); 00150 } 00151 else 00152 { 00153 friends.manager->setFrameExchangeDuration(this->pendingPreamble->getCommandPool(), friends.manager->getFrameExchangeDuration(compound->getCommandPool())); 00154 00155 friends.manager->setpsduDuration(this->pendingPreamble->getCommandPool(), 0); 00156 } 00157 00158 PreambleGeneratorCommand* preambleCommand = activateCommand(this->pendingPreamble->getCommandPool()); 00159 preambleCommand->peer.frameId = compound->getBirthmark(); 00160 00161 MESSAGE_SINGLE(NORMAL, logger, "Outgoing preamble with frame tx duration " << friends.manager->getProtocolCalculator()->getDuration()->preamble(phyMode)); 00162 00163 PreambleGeneratorCommand* compoundCommand = activateCommand(compound->getCommandPool()); 00164 00165 friends.manager->setCompoundType(compound->getCommandPool(), 00166 PAYLOAD); 00167 this->pendingCompound = compound; 00168 } 00169 00170 const wns::ldk::CompoundPtr 00171 PreambleGenerator::hasSomethingToSend() const 00172 { 00173 if(this->pendingPreamble) 00174 { 00175 assure(this->pendingCompound, "Pending preamble but no pending compound"); 00176 return(this->pendingPreamble); 00177 } 00178 return(this->pendingCompound); 00179 } 00180 00181 wns::ldk::CompoundPtr 00182 PreambleGenerator::getSomethingToSend() 00183 { 00184 assure(this->pendingCompound, "Called getSomethingToSend without pending compound"); 00185 00186 wns::ldk::CompoundPtr myFrame; 00187 if(this->pendingPreamble) 00188 { 00189 assure(this->pendingCompound, "Pending preamble but no pending compound"); 00190 myFrame = this->pendingPreamble; 00191 this->pendingPreamble = wns::ldk::CompoundPtr(); 00192 MESSAGE_SINGLE(NORMAL, logger, "Sending preamble"); 00193 00194 // If compound has no payload delete pending compound 00195 if (!friends.manager->hasPayload(this->pendingCompound->getCommandPool())) 00196 { 00197 this->pendingCompound = wns::ldk::CompoundPtr(); 00198 MESSAGE_SINGLE(NORMAL, logger, "Compound without payload was dropped"); 00199 } 00200 } 00201 else 00202 { 00203 myFrame = this->pendingCompound; 00204 this->pendingCompound = wns::ldk::CompoundPtr(); 00205 MESSAGE_SINGLE(NORMAL, logger, "Sending psdu"); 00206 } 00207 return(myFrame); 00208 } 00209 00210 bool 00211 PreambleGenerator::hasCapacity() const 00212 { 00213 return(this->pendingCompound == wns::ldk::CompoundPtr()); 00214 } 00215 00216 void 00217 PreambleGenerator::calculateSizes(const wns::ldk::CommandPool* commandPool, Bit& commandPoolSize, Bit& dataSize) const 00218 { 00219 if(friends.manager->isPreamble(commandPool)) 00220 { 00221 dataSize = 0; 00222 if (friends.manager->getPreambleMode(commandPool) == "STANDARD") commandPoolSize = 700; 00223 else if (friends.manager->getPreambleMode(commandPool) == "BURST") commandPoolSize = 500; 00224 00225 } 00226 else 00227 { 00228 getFUN()->getProxy()->calculateSizes(commandPool, commandPoolSize, dataSize, this); 00229 00230 Bit psdusize_ = friends.manager->getProtocolCalculator()->getFrameLength()->getPSDU(commandPoolSize + dataSize, friends.manager->getPhyMode(commandPool).getInfoBitsPer6Symbols()); 00231 00232 commandPoolSize = 0; 00233 dataSize = psdusize_; 00234 } 00235 }
1.5.5