User Manual, Developers Guide and API Documentation

DLCallback.cpp

Go to the documentation of this file.
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 

Generated on Tue May 22 03:32:10 2012 for openWNS by  doxygen 1.5.5