![]() |
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/ULMapCollector.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/Utilities.hpp> 00036 #include <WIMAC/frame/DataCollector.hpp> 00037 #include <WIMAC/scheduler/Scheduler.hpp> 00038 #include <WIMAC/parameter/PHY.hpp> 00039 using namespace wimac::frame; 00040 00041 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00042 wimac::frame::ULMapCollector, 00043 wns::ldk::FunctionalUnit, 00044 "wimac.frame.ULMapCollector", 00045 wns::ldk::FUNConfigCreator ); 00046 00047 00048 struct UserFind : 00049 public std::unary_function<wns::scheduler::MapInfoEntryPtr, bool> 00050 { 00051 explicit UserFind( wns::scheduler::UserID user ) : user_(user){} 00052 bool operator()(const wns::scheduler::MapInfoEntryPtr& mapInfo) 00053 { 00054 return user_ == mapInfo->user; 00055 } 00056 private: 00057 wns::scheduler::UserID user_; 00058 }; 00059 00060 ULMapCollector::ULMapCollector( wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config ) : 00061 wns::ldk::fcf::CompoundCollector( config ), 00062 wns::ldk::CommandTypeSpecifier<ULMapCommand>(fun), 00063 ulSchedulerName_(), 00064 phyUser_(0), 00065 phyMode(wns::SmartPtr<const wns::service::phy::phymode::PhyModeInterface> 00066 (wns::service::phy::phymode::createPhyMode( config.getView("phyMode") ) ) ), 00067 //hasUplinkBurst_(false), 00068 //myBursts_(new wns::scheduler::MapInfoCollection) 00069 ulResourcesAvailable_(false), 00070 scheduledULMap_(wns::scheduler::SchedulingMapPtr()), 00071 estimatedCQI_(wns::scheduler::ChannelQualityOnOneSubChannel()) 00072 00073 { 00074 if (!config.isNone("ulSchedulerName") ) 00075 ulSchedulerName_ = config.get<std::string>("ulSchedulerName"); 00076 } 00077 00078 00079 void ULMapCollector::onFUNCreated() 00080 { 00081 wns::ldk::fcf::CompoundCollector::onFUNCreated(); 00082 00083 assureType(getFUN()->getLayer(), wimac::Component*); 00084 component_ = dynamic_cast<wimac::Component*>(getFUN()->getLayer()); 00085 00086 if ( ulSchedulerName_ != "" ) 00087 { 00088 ulScheduler_ = dynamic_cast<wimac::scheduler::Scheduler*> 00089 (getFUN()->findFriend<DataCollector*>(ulSchedulerName_)->getRxScheduler()); 00090 assure( ulScheduler_, "Uplink Scheduler not present in FUN" ); 00091 } 00092 00093 phyUser_ = getFUN()->findFriend<wimac::PhyUser*>("phyUser"); 00094 assure( phyUser_, "PhyUser is not of type wimac::PhyUser"); 00095 00096 connectionManager_ = 00097 component_->getManagementService<service::ConnectionManager>("connectionManager"); 00098 00099 setFrameBuilder( getFUN()->findFriend<wns::ldk::fcf::FrameBuilder*>("frameBuilder") ); 00100 00101 me_ = wns::scheduler::UserID(component_->getNode()); 00102 00103 CompoundCollector::onFUNCreated(); 00104 } 00105 00106 void ULMapCollector::doStart(int mode) 00107 { 00108 switch (mode) { 00109 case Sending: 00110 { 00111 wns::ldk::CompoundPtr compound 00112 ( new wns::ldk::Compound( getFUN()->getProxy()->createCommandPool() ) ); 00113 ULMapCommand* command = activateCommand( compound->getCommandPool() ); 00114 command->peer.phaseDuration = 00115 ulScheduler_->getDuration(); 00116 command->peer.baseStationID = 00117 component_->getID(); 00118 command->local.numBursts = 00119 ulScheduler_->getNumBursts(); 00120 //command->peer.mapInfo = 00121 // ulScheduler_->getMapInfo(); 00122 command->peer.schedulingMap = 00123 ulScheduler_->getSchedulingMap(); 00124 // map duration is a little shorter than the phase duration 00125 command->local.mapDuration = 00126 getCurrentDuration() - Utilities::getComputationalAccuracyFactor(); 00127 00128 assure( command->local.mapDuration <= this->getMaximumDuration(), 00129 "ULMapCollector: PDU overun the maximum duration of the frame phase!"); 00130 00131 PhyUserCommand* phyCommand = dynamic_cast<wimac::PhyUserCommand*> 00132 ( getFUN()->getProxy()->activateCommand( compound->getCommandPool(), phyUser_) ); 00133 phyCommand->peer.destination_ = 0; 00134 phyCommand->peer.cellID_ = component_->getCellID(); 00135 phyCommand->peer.source_ = component_->getNode(); 00136 assureNotNull(phyMode.getPtr()); 00137 phyCommand->peer.phyModePtr = phyMode; 00138 phyCommand->magic.sourceComponent_ = component_; 00139 00140 wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime(); 00141 phyCommand->local.pAFunc_.reset 00142 ( new BroadcastPhyAccessFunc ); 00143 phyCommand->local.pAFunc_->transmissionStart_ = now; 00144 phyCommand->local.pAFunc_->transmissionStop_ = now + getCurrentDuration() 00145 - Utilities::getComputationalAccuracyFactor(); 00146 phyCommand->local.pAFunc_->phyMode_ = phyMode; 00147 00148 setTimeout( getCurrentDuration() - Utilities::getComputationalAccuracyFactor() ); 00149 LOG_INFO( getFUN()->getLayer()->getName(), " send UL Map of size: ", command->local.numBursts ); 00150 //LOG_INFO( getFUN()->getLayer()->getName(), " send UL Map of size: ", command->local.numBursts, " / ", command->peer.mapInfo->size() ); 00151 getConnector()->getAcceptor( compound )->sendData( compound ); 00152 } 00153 case Receiving: 00154 /* wait and do nothing */ 00155 ulResourcesAvailable_ = false; 00156 break; 00157 default: 00158 throw wns::Exception("Unknown activation mode in DLMapCollector"); 00159 } 00160 } 00161 00162 void 00163 ULMapCollector::onTimeout() 00164 { 00165 getFrameBuilder()->finishedPhase( this ); 00166 } 00167 00168 void 00169 ULMapCollector::calculateSizes( const wns::ldk::CommandPool* commandPool, Bit& commandPoolSize, Bit& dataSize ) const 00170 { 00171 //What are the sizes in the upper Layers 00173 getFUN()->getProxy()->calculateSizes(commandPool, commandPoolSize, dataSize, this); 00174 00175 ULMapCommand* command = getCommand( commandPool ); 00176 commandPoolSize += ( 56 + command->local.numBursts * 48 ); 00177 } 00178 00179 wns::simulator::Time ULMapCollector::getCurrentDuration() const 00180 { 00181 double dataRate = 00182 phyMode->getDataRate(); 00183 00184 Bit compoundSize = 00185 56 + ulScheduler_->getNumBursts(); 00186 wns::simulator::Time symbolDuration = parameter::ThePHY::getInstance()->getSymbolDuration(); 00187 wns::simulator::Time roundedDuration = 00188 ceil( (compoundSize / dataRate ) / symbolDuration ) * symbolDuration; 00189 00190 //fixme(bmw) (fixed map overhead of one symbol due to wrong calculation of map duration with subchannels) 00191 return symbolDuration; //roundedDuration; 00192 } 00193 00194 void ULMapCollector::doOnData( const wns::ldk::CompoundPtr& compound ) 00195 { 00196 assure (compound, "Invalid Map compound received!"); 00197 ULMapCommand* command = getCommand( compound->getCommandPool() ); 00198 00199 if(command->peer.baseStationID != 00200 connectionManager_->getConnectionWithID( 0 )->baseStation_ ) 00201 { 00202 throw wns::Exception( 00203 "ULMapCollector::doOnData: compound is not from associated BaseStation"); 00204 } 00205 00206 //LOG_INFO( getFUN()->getLayer()->getName(), " received UL Map from station: ", command->peer.baseStationID, 00207 // " of size : ", command->peer.mapInfo->size() ); 00208 LOG_INFO( getFUN()->getLayer()->getName(), " received UL Map from station: ", command->peer.baseStationID); 00209 00210 ulPhaseDuration_ = command->peer.phaseDuration; 00211 00212 // check if at least one of the frames contains granted ul resources 00213 ulResourcesAvailable_ = false; 00214 LOG_INFO("ULMAP saving now: "); 00215 scheduledULMap_ = command->peer.schedulingMap; 00216 LOG_INFO("ULMAP = ", scheduledULMap_->toString()); 00217 //Clear old MAPlist 00218 //scheduledULMap_->clear(); 00219 if (scheduledULMap_->hasResourcesForUser(me_)) 00220 { 00221 ulResourcesAvailable_ = true; // assume always true when a MAP comes 00222 LOG_INFO( getFUN()->getLayer()->getName(), " has granted resources" ); 00223 estimatedCQI_ = scheduledULMap_->getEstimatedCQI(me_); 00224 } 00225 00226 getFrameBuilder()->finishedPhase(this); 00227 }
1.5.5