![]() |
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/LongTrainingFieldGenerator.hpp> 00030 #include <WIFIMAC/management/VirtualCapabilityInformationBase.hpp> 00031 #include <DLL/Layer2.hpp> 00032 00033 using namespace wifimac::draftn; 00034 00035 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00036 wifimac::draftn::LongTrainingFieldGenerator, 00037 wns::ldk::FunctionalUnit, 00038 "wifimac.draftn.LongTrainingFieldGenerator", 00039 wns::ldk::FUNConfigCreator); 00040 00041 LongTrainingFieldGenerator::LongTrainingFieldGenerator(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) : 00042 wns::ldk::fu::Plain<LongTrainingFieldGenerator, LongTrainingFieldGeneratorCommand>(fun), 00043 phyUserName(config_.get<std::string>("phyUserName")), 00044 protocolCalculatorName(config_.get<std::string>("protocolCalculatorName")), 00045 managerName(config_.get<std::string>("managerName")), 00046 txDurationSetterName(config_.get<std::string>("txDurationSetterName")), 00047 sinrMIBServiceName(config_.get<std::string>("sinrMIBServiceName")), 00048 ltfDuration(config_.get<wns::simulator::Time>("myConfig.ltfDuration")), 00049 reducePreambleByDuration(config_.get<bool>("myConfig.reducePreambleByDuration")), 00050 numLTFsToSend(0), 00051 logger(config_.get("logger")), 00052 pendingCompound() 00053 { 00054 MESSAGE_SINGLE(NORMAL, this->logger, "created"); 00055 friends.manager = NULL; 00056 friends.phyUser = NULL; 00057 friends.txDuration = NULL; 00058 protocolCalculator = NULL; 00059 } 00060 00061 LongTrainingFieldGenerator::~LongTrainingFieldGenerator() 00062 { 00063 00064 } 00065 00066 void 00067 LongTrainingFieldGenerator::onFUNCreated() 00068 { 00069 MESSAGE_SINGLE(NORMAL, this->logger, "onFUNCreated() started"); 00070 00071 friends.phyUser = getFUN()->findFriend<wifimac::convergence::PhyUser*>(phyUserName); 00072 friends.manager = getFUN()->findFriend<wifimac::lowerMAC::Manager*>(managerName); 00073 friends.txDuration = getFUN()->findFriend<wifimac::draftn::DeAggregation*>(txDurationSetterName); 00074 protocolCalculator = getFUN()->getLayer<dll::ILayer2*>()->getManagementService<wifimac::management::ProtocolCalculator>(protocolCalculatorName); 00075 00076 sinrMIB = getFUN()->getLayer<dll::ILayer2*>()->getManagementService<wifimac::draftn::SINRwithMIMOInformationBase>(sinrMIBServiceName); 00077 } 00078 00079 void 00080 LongTrainingFieldGenerator::processIncoming(const wns::ldk::CompoundPtr& compound) 00081 { 00082 if(friends.manager->getFrameType(compound->getCommandPool()) == PREAMBLE) 00083 { 00084 00085 std::vector<wns::Ratio> postSINRFactor = friends.phyUser->getCommand(compound->getCommandPool())->local.postSINRFactor; 00086 sinrMIB->putFactorMeasurement(friends.manager->getTransmitterAddress(compound->getCommandPool()), 00087 postSINRFactor); 00088 00089 MESSAGE_BEGIN(NORMAL, logger, m, "Received Preamble/LTF with "); 00090 m << postSINRFactor.size() << " streams. PostSINRFactor:"; 00091 for(std::vector<wns::Ratio>::iterator it = postSINRFactor.begin(); 00092 it != postSINRFactor.end(); 00093 ++it) 00094 { 00095 m << " " << *it; 00096 } 00097 MESSAGE_END(); 00098 00099 if(friends.manager->getPhyMode(compound->getCommandPool()).getNumberOfSpatialStreams() > 1) 00100 { 00101 // drop LTF 00102 MESSAGE_BEGIN(NORMAL, logger, m, "Dropping incoming LTF with"); 00103 m << friends.manager->getPhyMode(compound->getCommandPool()).getNumberOfSpatialStreams(); 00104 m << "spatial streams"; 00105 MESSAGE_END(); 00106 return; 00107 } 00108 } 00109 00110 // deliver frame 00111 getDeliverer()->getAcceptor(compound)->onData(compound); 00112 } 00113 00114 void 00115 LongTrainingFieldGenerator::processOutgoing(const wns::ldk::CompoundPtr& compound) 00116 { 00117 this->pendingCompound = compound; 00118 00119 if(friends.manager->getFrameType(compound->getCommandPool()) == PREAMBLE) 00120 { 00121 wns::service::dll::UnicastAddress receiver = friends.manager->getReceiverAddress(compound->getCommandPool()); 00122 unsigned int numTx = friends.manager->getNumAntennas(); 00123 unsigned int numRx = numTx; 00124 // unsigned int numRx = 1; 00125 if(wifimac::management::TheVCIBService::Instance().getVCIB()->knows(receiver, "numAntennas")) 00126 { 00127 numRx = wifimac::management::TheVCIBService::Instance().getVCIB()->get<int>(receiver, "numAntennas"); 00128 } 00129 unsigned int maxNumSS = (numTx < numRx) ? numTx : numRx; 00130 numLTFsToSend = maxNumSS - 1; 00131 if(numLTFsToSend > 0) 00132 { 00133 if(reducePreambleByDuration) 00134 { 00135 friends.txDuration->getCommand(compound->getCommandPool())->local.txDuration -= numLTFsToSend*ltfDuration; 00136 } 00137 friends.manager->setFrameExchangeDuration(compound->getCommandPool(), 00138 friends.manager->getFrameExchangeDuration(compound->getCommandPool())+numLTFsToSend*ltfDuration); 00139 00140 MESSAGE_BEGIN(NORMAL, logger, m, "Outgoing preamble to " << receiver); 00141 m << " maxNumSS: " << maxNumSS; 00142 if(reducePreambleByDuration) 00143 { 00144 m << " reduce txDuration to " << friends.txDuration->getCommand(compound->getCommandPool())->local.txDuration << " and"; 00145 } 00146 m << " insert " << numLTFsToSend << " LTFs"; 00147 MESSAGE_END(); 00148 } 00149 } 00150 00151 } 00152 00153 const wns::ldk::CompoundPtr 00154 LongTrainingFieldGenerator::hasSomethingToSend() const 00155 { 00156 return(this->pendingCompound); 00157 } 00158 00159 wns::ldk::CompoundPtr 00160 LongTrainingFieldGenerator::getSomethingToSend() 00161 { 00162 if(this->pendingCompound) 00163 { 00164 wns::ldk::CompoundPtr myFrame = this->pendingCompound; 00165 if(numLTFsToSend == 0) 00166 { 00167 this->pendingCompound = wns::ldk::CompoundPtr(); 00168 MESSAGE_SINGLE(NORMAL, logger, "Sending psdu"); 00169 } 00170 else 00171 { 00172 wns::ldk::CompoundPtr ltf = this->pendingCompound->copy(); 00173 friends.txDuration->getCommand(ltf->getCommandPool())->local.txDuration = ltfDuration; 00174 wifimac::convergence::PhyMode pm = friends.manager->getPhyMode(ltf->getCommandPool()); 00175 pm.setUniformMCS(pm.getSpatialStreams()[0], pm.getNumberOfSpatialStreams()+1); 00176 friends.manager->setPhyMode(ltf->getCommandPool(), pm); 00177 friends.manager->setFrameExchangeDuration(ltf->getCommandPool(), 00178 friends.manager->getFrameExchangeDuration(ltf->getCommandPool())-ltfDuration); 00179 00180 00181 this->pendingCompound = ltf; 00182 00183 --numLTFsToSend; 00184 MESSAGE_SINGLE(NORMAL, logger, "Prepared LTF with " << pm.getNumberOfSpatialStreams() << " spatial streams, to be send after current pending compound"); 00185 } 00186 00187 return(myFrame); 00188 } 00189 } 00190 00191 bool 00192 LongTrainingFieldGenerator::hasCapacity() const 00193 { 00194 return(this->pendingCompound == wns::ldk::CompoundPtr() and (not friends.phyUser->isTransmitting())); 00195 } 00196 00197 void 00198 LongTrainingFieldGenerator::calculateSizes(const wns::ldk::CommandPool* commandPool, Bit& commandPoolSize, Bit& dataSize) const 00199 { 00200 if(friends.manager->getFrameType(commandPool) == PREAMBLE) 00201 { 00202 commandPoolSize = 0; 00203 dataSize = 0; 00204 } 00205 else 00206 { 00207 getFUN()->getProxy()->calculateSizes(commandPool, commandPoolSize, dataSize, this); 00208 } 00209 }
1.5.5