![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /******************************************************************************* 00002 * This file is part of openWNS (open Wireless Network Simulator) 00003 * _____________________________________________________________________________ 00004 * 00005 * Copyright (C) 2004-2009 00006 * Chair of Communication Networks (ComNets) 00007 * Kopernikusstr. 5, D-52074 Aachen, Germany 00008 * email: info@openwns.org 00009 * www: http://www.openwns.org 00010 * _____________________________________________________________________________ 00011 * 00012 * openWNS is free software; you can redistribute it and/or modify it under the 00013 * terms of the GNU Lesser General Public License version 2 as published by the 00014 * Free Software Foundation; 00015 * 00016 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00017 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00018 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00019 * details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 * 00024 ******************************************************************************/ 00025 00026 #include <WIMAC/frame/DLMapCollector.hpp> 00027 00028 #include <WNS/ldk/Compound.hpp> 00029 #include <WNS/ldk/fcf/TimingControl.hpp> 00030 00031 #include <WIMAC/Component.hpp> 00032 #include <WIMAC/PhyUser.hpp> 00033 #include <WIMAC/PhyUserCommand.hpp> 00034 #include <WIMAC/PhyAccessFunc.hpp> 00035 #include <WIMAC/PhyAccessFunc.hpp> 00036 #include <WIMAC/Utilities.hpp> 00037 #include <WIMAC/frame/DataCollector.hpp> 00038 #include <WIMAC/scheduler/Scheduler.hpp> 00039 #include <WIMAC/parameter/PHY.hpp> 00040 00041 using namespace wimac::frame; 00042 00043 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00044 wimac::frame::DLMapCollector, 00045 wns::ldk::FunctionalUnit, 00046 "wimac.frame.DLMapCollector", 00047 wns::ldk::FUNConfigCreator ); 00048 00049 00050 DLMapCollector::DLMapCollector( wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config ) : 00051 wns::ldk::fcf::CompoundCollector( config ), 00052 wns::ldk::CommandTypeSpecifier<DLMapCommand>(fun), 00053 dlScheduler_(0), 00054 dlSchedulerName_(), 00055 phyUser_(0), 00056 phyMode(wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> 00057 (wns::service::phy::phymode::createPhyMode( config.getView("phyMode") ) ) ) 00058 { 00059 if ( !config.isNone("dlSchedulerName") ) 00060 dlSchedulerName_ = config.get<std::string>("dlSchedulerName"); 00061 } 00062 00063 void DLMapCollector::onFUNCreated() 00064 { 00065 wns::ldk::fcf::CompoundCollector::onFUNCreated(); 00066 00067 assureType(getFUN()->getLayer(), wimac::Component*); 00068 component_ = dynamic_cast<wimac::Component*>(getFUN()->getLayer()); 00069 00070 if ( dlSchedulerName_ != "" ) { 00071 dlScheduler_ = dynamic_cast<wimac::scheduler::Scheduler*> 00072 (getFUN()->findFriend<DataCollector*>(dlSchedulerName_)->getTxScheduler()); 00073 assure( dlScheduler_, "Downlink Scheduler not present in FUN" ); 00074 } 00075 00076 phyUser_ = getFUN()->findFriend<wimac::PhyUser*>("phyUser"); 00077 assure( phyUser_, "PhyUser is not of type wimac::PhyUser"); 00078 00079 connectionManager_ = 00080 getFUN()->getLayer()->getManagementService<service::ConnectionManager> 00081 ("connectionManager"); 00082 00083 setFrameBuilder( getFUN()->findFriend<wns::ldk::fcf::FrameBuilder*>("frameBuilder") ); 00084 CompoundCollector::onFUNCreated(); 00085 } 00086 00087 void DLMapCollector::doStart(int mode) 00088 { 00089 switch (mode) { 00090 case Sending: 00091 { 00092 assure(dlScheduler_, "DLMapCollector can not send, no DL Scheduler set"); 00093 00094 // create the MAP and send it 00095 wns::ldk::CompoundPtr compound 00096 ( new wns::ldk::Compound( getFUN()->getProxy()->createCommandPool() ) ); 00097 00098 DLMapCommand* command = activateCommand( compound->getCommandPool() ); 00099 command->peer.phaseDuration = 00100 dlScheduler_->getDuration(); 00101 command->peer.baseStationID = 00102 component_->getID(); 00103 command->local.numBursts = 00104 dlScheduler_->getNumBursts(); 00105 command->local.mapDuration = 00106 getCurrentDuration() - Utilities::getComputationalAccuracyFactor(); 00107 00108 LOG_INFO("MAP duration is ", command->local.mapDuration, 00109 ", phase duration is ", 00110 this->getMaximumDuration()); 00111 assure( command->local.mapDuration <= this->getMaximumDuration(), 00112 "DLMapWriter: PDU overun the maximum duration of the frame phase!"); 00113 00114 PhyUserCommand* phyCommand = 00115 dynamic_cast<PhyUserCommand*>( 00116 getFUN()->getProxy()->activateCommand( compound->getCommandPool(), 00117 phyUser_ ) ); 00118 00119 phyCommand->peer.destination_ = 0; 00120 phyCommand->peer.cellID_ = component_->getCellID(); 00121 phyCommand->peer.source_ = component_->getNode(); 00122 assureNotNull(&phyMode); 00123 phyCommand->peer.phyModePtr = phyMode; 00124 phyCommand->magic.sourceComponent_ = component_; 00125 00126 00127 wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime(); 00128 phyCommand->local.pAFunc_.reset 00129 ( new BroadcastPhyAccessFunc ); 00130 phyCommand->local.pAFunc_->transmissionStart_ = now; 00131 phyCommand->local.pAFunc_->transmissionStop_ = 00132 now + getCurrentDuration() - Utilities::getComputationalAccuracyFactor(); 00133 phyCommand->local.pAFunc_->phyMode_ = phyMode; 00134 00135 setTimeout( getCurrentDuration() ); 00136 LOG_INFO("Sending DL MAP in ", getFUN()->getName(), 00137 " and setting timeout to ", getCurrentDuration()); 00138 getConnector()->getAcceptor( compound )->sendData( compound ); 00139 break; 00140 } 00141 case Receiving: 00142 /* wait and do nothing */ 00143 break; 00144 default: 00145 throw wns::Exception("Unknown activation mode in DLMapCollector"); 00146 } 00147 } 00148 00149 void 00150 DLMapCollector::calculateSizes( const wns::ldk::CommandPool* commandPool, 00151 Bit& commandPoolSize, Bit& dataSize ) const 00152 { 00153 // What are the sizes in the upper Layers 00154 getFUN()->getProxy()->calculateSizes(commandPool, commandPoolSize, dataSize, this); 00155 00156 DLMapCommand* command = getCommand( commandPool ); 00157 commandPoolSize += ( 56 + command->local.numBursts * 48 ); 00158 } 00159 00160 void 00161 DLMapCollector::onTimeout() 00162 { 00163 getFrameBuilder()->finishedPhase( this ); 00164 } 00165 00166 wns::simulator::Time DLMapCollector::getCurrentDuration() const 00167 { 00168 double dataRate = 00169 phyMode->getDataRate(); 00170 00171 Bit compoundSize = 00172 56 + dlScheduler_->getNumBursts(); /* *48*/; 00173 00174 wns::simulator::Time symbolDuration = parameter::ThePHY::getInstance()->getSymbolDuration(); 00175 wns::simulator::Time roundedDuration = 00176 ceil( (compoundSize / dataRate ) / symbolDuration ) * symbolDuration; 00177 //fixme(bmw) (fixed map overhead of one symbol due to wrong calculation of map duration with subchannels) 00178 return symbolDuration; //roundedDuration; 00179 } 00180 00181 void DLMapCollector::doOnData( const wns::ldk::CompoundPtr& compound ) 00182 { 00183 MapCommand* command = 00184 getCommand( compound->getCommandPool() ); 00185 00186 if(command->peer.baseStationID != 00187 connectionManager_->getConnectionWithID( 0 )->baseStation_ ) 00188 { 00189 throw wns::Exception 00190 ("DLMapRetriever::doOnData: compound is not from associated BaseStation"); 00191 } 00192 00193 LOG_INFO( getFUN()->getLayer()->getName(), 00194 ": received DL-MAP from station:", 00195 command->peer.baseStationID); 00196 00197 dlPhaseDuration_ = command->peer.phaseDuration; 00198 00199 getFrameBuilder()->getTimingControl()->finishedPhase( this ); 00200 }
1.5.5