![]() |
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/scheduler/DLCallback.hpp> 00027 00028 #include <WNS/scheduler/RegistryProxyInterface.hpp> 00029 #include <WNS/scheduler/MapInfoEntry.hpp> 00030 #include <WNS/scheduler/SchedulingMap.hpp> 00031 #include <WNS/scheduler/strategy/Strategy.hpp> 00032 #include <WNS/ldk/Layer.hpp> 00033 //#include <WNS/ldk/CompoundPtr.hpp> 00034 00035 #include <WIMAC/Logger.hpp> 00036 00037 #include <WIMAC/Component.hpp> 00038 #include <WIMAC/Utilities.hpp> 00039 #include <WIMAC/PhyAccessFunc.hpp> 00040 #include <WIMAC/PhyUser.hpp> 00041 #include <WIMAC/PhyUserCommand.hpp> 00042 00043 #include <boost/bind.hpp> 00044 00045 STATIC_FACTORY_REGISTER_WITH_CREATOR( 00046 wimac::scheduler::DLCallback, 00047 wimac::scheduler::Callback, 00048 "wimac.scheduler.DLCallback", 00049 wns::ldk::FUNConfigCreator ); 00050 00051 using namespace wimac::scheduler; 00052 00053 DLCallback::DLCallback(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00054 Callback(fun, config), 00055 fun_(fun), 00056 beamforming(config.get<bool>("beamforming")), 00057 slotLength_(config.get<wns::simulator::Time>("slotLength")), 00058 tbCounter_(0) 00059 {} 00060 00061 void DLCallback::deliverNow(wns::ldk::Connector* connector) 00062 { 00063 LOG_INFO(fun_->getLayer()->getName(), " DLCallback::deliverNow() "); 00064 wns::simulator::Time now = wns::simulator::getEventScheduler()->getTime(); 00065 00066 while (!scheduledPDUs.empty()) 00067 { 00068 wns::ldk::CompoundPtr compound = scheduledPDUs.front(); 00069 PhyUserCommand* phyUserCommand = 00070 friends_.phyUser->getCommand( compound->getCommandPool() ); 00071 00072 00073 PhyAccessFunc* func = 00074 dynamic_cast<PhyAccessFunc*>(phyUserCommand->local.pAFunc_.get()); 00075 00076 func->transmissionStart_ += now; 00077 func->transmissionStop_ += now; 00078 00079 frameOffsetDelayProbe_->put(compound, func->transmissionStart_ - lastScheduling_); 00080 transmissionDelayProbe_->put(compound, func->transmissionStop_ - func->transmissionStart_); 00081 00082 if ( connector->hasAcceptor(scheduledPDUs.front() ) ) 00083 { 00084 connector->getAcceptor(scheduledPDUs.front())->sendData(scheduledPDUs.front()); 00085 scheduledPDUs.pop(); 00086 } 00087 else 00088 { 00089 throw wns::Exception( "Lower FU is not accepting scheduled PDU but is supposed to do so" ); 00090 } 00091 } 00092 } 00093 00094 void 00095 DLCallback::callBack(wns::scheduler::SchedulingMapPtr schedulingMap) 00096 { 00097 tbCounter_++; 00098 00099 lastScheduling_ = wns::simulator::getEventScheduler()->getTime(); 00100 00101 for(wns::scheduler::SubChannelVector::iterator iterSubChannel = schedulingMap->subChannels.begin(); 00102 iterSubChannel != schedulingMap->subChannels.end(); ++iterSubChannel) 00103 { 00104 wns::scheduler::SchedulingSubChannel& subChannel = *iterSubChannel; 00105 for(wns::scheduler::SchedulingTimeSlotPtrVector::iterator iterTimeSlot = 00106 subChannel.temporalResources.begin(); 00107 iterTimeSlot != subChannel.temporalResources.end(); ++iterTimeSlot) 00108 { 00109 wns::scheduler::SchedulingTimeSlotPtr timeSlotPtr = *iterTimeSlot; 00110 for( wns::scheduler::PhysicalResourceBlockVector::iterator iterPRB = 00111 timeSlotPtr->physicalResources.begin(); 00112 iterPRB != timeSlotPtr->physicalResources.end(); ++iterPRB) 00113 { 00114 if ( iterPRB->hasScheduledCompounds() ) 00115 { 00116 wns::scheduler::ScheduledCompoundsList::const_iterator it; 00117 00118 for(it = iterPRB->scheduledCompoundsBegin(); 00119 it != iterPRB->scheduledCompoundsEnd(); 00120 it++) 00121 { // for every compound in subchannel: 00122 processPacket(*it, timeSlotPtr); 00123 } // for (all scheduledCompounds) 00124 iterPRB->clearScheduledCompounds(); 00125 } // if there were compounds in this resource 00126 } // forall beams 00127 } // end for ( timeSlots ) 00128 } // forall subChannels 00129 } 00130 00131 void 00132 DLCallback::processPacket(const wns::scheduler::SchedulingCompound & compound, 00133 wns::scheduler::SchedulingTimeSlotPtr& timeSlotPtr) 00134 { 00135 simTimeType startTime = compound.startTime; 00136 simTimeType endTime = compound.endTime; 00137 wns::scheduler::UserID user = compound.userID; 00138 int userID = user.getNodeID(); 00139 int fSlot = compound.subChannel; 00140 int timeSlot = compound.timeSlot; 00141 int beam = compound.spatialLayer; //beam; 00142 wns::Power txPower = compound.txPower; 00143 wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr = compound.phyModePtr; 00144 wns::service::phy::ofdma::PatternPtr pattern = compound.pattern; 00145 00146 simTimeType timeSlotOffset = timeSlot * slotLength_; 00147 startTime += timeSlotOffset; 00148 endTime += timeSlotOffset; 00149 00150 if(scheduleStartProbe_->hasObservers()) 00151 { 00152 // Probe userID for start and stop to get nice sample and hold curve 00153 wns::simulator::getEventScheduler()->schedule( 00154 boost::bind(&Callback::probeScheduleStart, this, timeSlot, fSlot, beam, userID), startTime); 00155 } 00156 if(scheduleStopProbe_->hasObservers()) 00157 { 00158 wns::simulator::getEventScheduler()->schedule( 00159 boost::bind(&Callback::probeScheduleStop, this, timeSlot, fSlot, beam, userID), endTime); 00160 } 00161 00162 wns::scheduler::ChannelQualityOnOneSubChannel estimatedCQI = compound.estimatedCQI; 00163 00164 double rate = phyModePtr->getDataRate(); 00165 wns::ldk::CompoundPtr pdu = compound.compoundPtr; 00166 simTimeType pduDuration = pdu->getLengthInBits() / rate; 00167 // TODO 00168 assure(pdu != wns::ldk::CompoundPtr(), "Invalid empty PDU"); 00169 //assure(beam < maxBeams, "Too many beams"); 00170 //assure(endTime > startTime, "Scheduled PDU must end after it starts"); 00171 //assure(endTime <= this->getDuration(), "PDU overun the maximum duration of the frame phase!"); 00172 //assure(fSlot < freqChannels, "Invalid frequency channel"); 00173 00174 #ifndef WNS_NO_LOGGING 00175 std::stringstream m; 00176 m << ": direction: DL \n" 00177 << " PDU scheduled for user: " << colleagues.registry->getNameForUser(user) << "\n" 00178 << " Frequency Slot: " << fSlot << "\n" 00179 << " Time Slot: " << timeSlot <<" slotLength: "<<slotLength_<<"\n" 00180 << " StartTime: " << startTime<< "\n" 00181 << " EndTime: " << endTime<< "\n" 00182 << " Beamforming: " << beamforming << "\n" 00183 << " Beam: " << beam << "\n" 00184 << " Tx Power: " << txPower << "\n" 00185 << " valid pattern: " << (pattern != wns::service::phy::ofdma::PatternPtr()); 00186 LOG_INFO(fun_->getLayer()->getName(), m.str()); 00187 #endif 00188 00189 PhyAccessFunc* func = 0; 00190 00191 if(beamforming && (pattern != wns::service::phy::ofdma::PatternPtr())) 00192 { 00193 LOG_INFO(fun_->getLayer()->getName(), " DLCallback::processPacket() create BeamformingPhyAccessFunc"); 00194 BeamformingPhyAccessFunc* sdmaFunc = new BeamformingPhyAccessFunc; 00195 sdmaFunc->destination_ = user.getNode(); 00196 sdmaFunc->transmissionStart_ = startTime; 00197 sdmaFunc->transmissionStop_ = 00198 startTime + pduDuration - Utilities::getComputationalAccuracyFactor(); 00199 sdmaFunc->subBand_ = fSlot; 00200 sdmaFunc->beam_ = beam; 00201 sdmaFunc->timeSlot_ = timeSlot; 00202 sdmaFunc->pattern_ = pattern; 00203 sdmaFunc->requestedTxPower_ = txPower; 00204 func = sdmaFunc; 00205 } 00206 else if(user.isValid()) 00207 { 00208 LOG_INFO(fun_->getLayer()->getName(), " DLCallback::processPacket() create OmniUnicastPhyAccessFunc"); 00209 OmniUnicastPhyAccessFunc* omniUnicastFunc = new OmniUnicastPhyAccessFunc; 00210 omniUnicastFunc->destination_ = user.getNode(); 00211 omniUnicastFunc->transmissionStart_ = startTime; 00212 omniUnicastFunc->transmissionStop_ = 00213 startTime + pduDuration - Utilities::getComputationalAccuracyFactor(); 00214 omniUnicastFunc->subBand_ = fSlot; 00215 omniUnicastFunc->beam_ = beam; 00216 omniUnicastFunc->requestedTxPower_ = txPower; 00217 func = omniUnicastFunc; 00218 } 00219 else 00220 { 00221 LOG_INFO(fun_->getLayer()->getName(), " ULMasterCallback::deliverNow() create BroadcastPhyAccessFunc"); 00222 BroadcastPhyAccessFunc* broadcastFunc = new BroadcastPhyAccessFunc; 00223 broadcastFunc->transmissionStart_ = startTime; 00224 broadcastFunc->transmissionStop_ = 00225 startTime + pduDuration - Utilities::getComputationalAccuracyFactor(); 00226 broadcastFunc->subBand_ = fSlot; 00227 broadcastFunc->beam_ = beam; 00228 broadcastFunc->timeSlot_ = timeSlot; 00229 func = broadcastFunc; 00230 } 00231 00232 00233 // set PhyUser command 00234 wimac::PhyUserCommand* phyCommand = dynamic_cast<wimac::PhyUserCommand*>( 00235 fun_->getProxy()->activateCommand( pdu->getCommandPool(), friends_.phyUser ) ); 00236 00237 phyCommand->local.pAFunc_.reset( func ); 00238 00239 phyCommand->local.pAFunc_->phyMode_ = phyModePtr; 00240 00241 00242 phyCommand->peer.destination_ = user.getNode(); 00243 wimac::Component* wimacComponent = dynamic_cast<wimac::Component*>(fun_->getLayer()); 00244 phyCommand->peer.cellID_ = wimacComponent->getCellID(); 00245 phyCommand->peer.source_ = wimacComponent->getNode(); 00246 phyCommand->peer.phyModePtr = phyModePtr; 00247 phyCommand->peer.measureInterference_ = true; // measureInterference; 00248 phyCommand->peer.estimatedCQI = estimatedCQI; 00249 phyCommand->magic.sourceComponent_ = wimacComponent; 00250 00251 colleagues.harq->storeSchedulingTimeSlot(tbCounter_, timeSlotPtr); 00252 00253 phyCommand->magic.schedulingTimeSlot = wns::scheduler::SchedulingTimeSlotPtr( 00254 new wns::scheduler::SchedulingTimeSlot(*timeSlotPtr)); 00255 00256 scheduledPDUs.push(pdu); 00257 } 00258
1.5.5