User Manual, Developers Guide and API Documentation

DataCollector.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/frame/DataCollector.hpp>
00027 
00028 #include <WNS/pyconfig/View.hpp>
00029 
00030 #include <WIMAC/scheduler/Scheduler.hpp>
00031 #include <WIMAC/Utilities.hpp>
00032 
00033 #include <boost/bind.hpp>
00034 
00035 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00036     wimac::frame::DataCollector,
00037     wns::ldk::FunctionalUnit,
00038     "wimac.frame.DataCollector",
00039     wns::ldk::FUNConfigCreator );
00040 
00041 using namespace wimac::frame;
00042 
00043 
00044 DataCollector::DataCollector(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) :
00045     wns::ldk::fcf::CompoundCollector(config),
00046     wns::ldk::CommandTypeSpecifier<wns::ldk::EmptyCommand>(fun)
00047 {
00048     if (!config.isNone("txScheduler"))
00049     {
00050         std::string txSchedulerName = config.get<std::string>("txScheduler.__plugin__");
00051         wns::pyconfig::View txSchedulerConfig
00052             ( config.getView("txScheduler") );
00053         wimac::scheduler::SchedulerCreator* txSchedulerCreator
00054             ( wimac::scheduler::SchedulerFactory::creator(txSchedulerName) );
00055         txScheduler.reset(txSchedulerCreator->create(this, txSchedulerConfig));
00056     }
00057 
00058     if (!config.isNone("rxScheduler"))
00059     {
00060         std::string rxSchedulerName = config.get<std::string>("rxScheduler.__plugin__");
00061         wns::pyconfig::View rxSchedulerConfig
00062             ( config.getView("rxScheduler") );
00063         wimac::scheduler::SchedulerCreator* rxSchedulerCreator
00064             ( wimac::scheduler::SchedulerFactory::creator(rxSchedulerName) );
00065         rxScheduler.reset(rxSchedulerCreator->create(this, rxSchedulerConfig));
00066     }
00067 }
00068 
00069 DataCollector::DataCollector(const DataCollector& rhs) :
00070     wns::ldk::fcf::CompoundCollectorInterface(rhs),
00071     wns::ldk::CompoundHandlerInterface<FunctionalUnit>(rhs),
00072     wns::ldk::CommandTypeSpecifierInterface(rhs),
00073     wns::ldk::HasReceptorInterface(rhs),
00074     wns::ldk::HasConnectorInterface(rhs),
00075     wns::ldk::HasDelivererInterface(rhs),
00076     wns::CloneableInterface(rhs),
00077     wns::IOutputStreamable(rhs),
00078     wns::PythonicOutput(rhs),
00079     wns::ldk::FunctionalUnit(rhs),
00080     wns::ldk::fcf::CompoundCollector(rhs),
00081     wns::ldk::CommandTypeSpecifier<wns::ldk::EmptyCommand>(rhs),
00082     wns::ldk::HasConnector<wns::ldk::SingleConnector>(rhs),
00083     wns::ldk::HasReceptor<wns::ldk::SingleReceptor>(rhs),
00084     wns::ldk::HasDeliverer<wns::ldk::SingleDeliverer>(rhs),
00085     wns::Cloneable<wimac::frame::DataCollector>(rhs),
00086     wns::events::CanTimeout(rhs)
00087 {
00088     txScheduler.reset(dynamic_cast<wimac::scheduler::Interface*>
00089                       (dynamic_cast<wns::CloneableInterface*>
00090                        (rhs.txScheduler.get())->clone()));
00091 
00092     rxScheduler.reset(dynamic_cast<wimac::scheduler::Interface*>
00093                       (dynamic_cast<wns::CloneableInterface*>
00094                        (rhs.rxScheduler.get())->clone()));
00095 }
00096 
00097 void
00098 DataCollector::onFUNCreated()
00099 {
00100     if (txScheduler.get())
00101     {
00102         txScheduler->setFUN(getFUN());
00103         txScheduler->setReceptor(getReceptor());
00104     }
00105     else
00106     {
00107         std::string name;
00108         if(getName() == "dlscheduler")
00109             name = "ulscheduler";
00110         else
00111             name = "dlscheduler";
00112 
00113         otherTXScheduler = getFUN()->findFriend<wimac::frame::DataCollector*>(
00114             name)->getTxScheduler();
00115 
00116         assure(otherTXScheduler != NULL, "Cannot find other txScheduler for HARQ");
00117     }
00118 
00119     if (rxScheduler.get())
00120     {
00121         rxScheduler->setFUN(getFUN());
00122         rxScheduler->setReceptor(getReceptor());
00123     }
00124 
00125     phyUser_ = getFUN()->findFriend<wimac::PhyUser*>("phyUser");
00126     assure( phyUser_, "PhyUser is not of type wimac::PhyUser");
00127 }
00128 
00129 void
00130 DataCollector::doOnData(const wns::ldk::CompoundPtr& compound)
00131 {
00132     assure(phyUser_, "PhyUser unknown");
00133     wimac::PhyUserCommand* phyCommand = 
00134         phyUser_->getCommand(compound->getCommandPool());
00135 
00136     assure(phyCommand, "Cannot extract phyCommand");
00137 
00138     assure(otherTXScheduler, "Need pointer to TX scheduler for other direction");
00139 
00140     if(phyCommand->magic.schedulingTimeSlot != NULL 
00141         && otherTXScheduler->getHARQ() != NULL)
00142     {
00143         assure(phyCommand->magic.schedulingTimeSlot
00144             ->physicalResources[0].countScheduledCompounds() == 1, 
00145                 "We only support one PDU per resource");
00146 
00147         int beam = phyCommand->local.pAFunc_->beam_;
00148 
00149         wimac::PhyUserCommand* shedPhyCommand = phyUser_->getCommand(
00150             phyCommand->magic.schedulingTimeSlot
00151                 ->physicalResources[beam].scheduledCompoundsBegin()
00152                     ->compoundPtr->getCommandPool());
00153 
00154         shedPhyCommand->magic.rxMeasurement = phyCommand->magic.rxMeasurement;
00155 
00156         otherTXScheduler->getHARQ()->onTimeSlotReceived(phyCommand->magic.schedulingTimeSlot,
00157             wns::scheduler::harq::HARQInterface::TimeSlotInfo(
00158             phyCommand->magic.rxMeasurement,
00159             phyCommand->local.pAFunc_->subBand_));
00160    
00161         if(deliverReceivedEvent == wns::events::scheduler::IEventPtr())
00162         {
00163             deliverReceivedEvent = wns::simulator::getEventScheduler()->scheduleDelay(
00164                 boost::bind(&DataCollector::deliverReceived, this), 
00165                     Utilities::getComputationalAccuracyFactor());
00166         }
00167     }
00168     else
00169     { 
00170         getDeliverer()->getAcceptor(compound)->onData(compound);
00171     }
00172 }
00173 
00174 void
00175 DataCollector::deliverReceived()
00176 {
00177     deliverReceivedEvent = wns::events::scheduler::IEventPtr();
00178 
00179     assure(otherTXScheduler, "Need pointer to TX scheduler for other direction");
00180 
00181     wns::scheduler::harq::HARQInterface::DecodeStatusContainer compounds;
00182     compounds = otherTXScheduler->getHARQ()->decode();
00183 
00184     wns::scheduler::harq::HARQInterface::DecodeStatusContainer::iterator it;
00185 
00186     for (it = compounds.begin(); it!=compounds.end();++it)
00187     {
00188         if(it->first->harq.successfullyDecoded)
00189         {
00190             wns::scheduler::PhysicalResourceBlockVector::iterator itPRB;
00191             for(itPRB = it->first->physicalResources.begin();
00192                 itPRB != it->first->physicalResources.end();
00193                 ++itPRB)
00194             {
00195                 wns::scheduler::ScheduledCompoundsList::const_iterator compoundIt;
00196 
00197                 // Iterate over all contained compounds
00198                 for (compoundIt = itPRB->scheduledCompoundsBegin();
00199                     compoundIt != itPRB->scheduledCompoundsEnd();
00200                     ++compoundIt)
00201                 {
00202                     wimac::PhyUserCommand* phyCommand = 
00203                         phyUser_->getCommand(compoundIt->compoundPtr->getCommandPool());
00204 
00205                     getDeliverer()->getAcceptor(compoundIt->compoundPtr)
00206                         ->onData(compoundIt->compoundPtr);
00207                 }
00208             }
00209         }
00210         it->first->physicalResources.clear();
00211     }
00212 }
00213 
00214 void
00215 DataCollector::doSendData(const wns::ldk::CompoundPtr& compound)
00216 {
00217     if ( rxScheduler.get() && rxScheduler->isAccepting(compound) )
00218         rxScheduler->schedule(compound);
00219     else if ( txScheduler.get() && txScheduler->isAccepting(compound) )
00220         txScheduler->schedule(compound);
00221     else
00222         throw wns::Exception("No scheduler accepts the compound as requested");
00223 }
00224 
00225 void
00226 DataCollector::doStartCollection(int)
00227 {
00228     wimac::scheduler::Interface* sched;
00229     sched = getCurrentScheduler();
00230     if(sched != NULL)
00231     {
00232         getCurrentScheduler()->setDuration(getMaximumDuration());
00233         getCurrentScheduler()->startScheduling();
00234     }
00235 }
00236 
00237 void
00238 DataCollector::doStart(int)
00239 {
00240     wimac::scheduler::Interface* sched;
00241     sched = getCurrentScheduler();
00242     if(sched != NULL)
00243         getCurrentScheduler()->deliverSchedule(getConnector());
00244     setTimeout( getMaximumDuration() );
00245 }
00246 
00247 wns::simulator::Time
00248 DataCollector::getCurrentDuration() const
00249 {
00250     return getCurrentScheduler()->getDuration();
00251 }
00252 
00253 bool
00254 DataCollector::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00255 {
00256     return (txScheduler.get() && txScheduler->isAccepting(compound))
00257         || ( rxScheduler.get() && rxScheduler->isAccepting(compound) );
00258 }
00259 
00260 void
00261 DataCollector::onTimeout()
00262 {
00263     getFrameBuilder()->finishedPhase( this );
00264 }
00265 
00266 void
00267 DataCollector::finishCollection()
00268 {
00269     wimac::scheduler::Interface* sched;
00270     sched = getCurrentScheduler();
00271     if(sched != NULL)
00272         getCurrentScheduler()->finishScheduling();
00273 }
00274 
00275 wimac::scheduler::Interface*
00276 DataCollector::getCurrentScheduler() const
00277 {
00278     switch (getMode())
00279     {
00280     case Sending:
00281         return txScheduler.get();
00282     case Receiving:
00283         return rxScheduler.get();
00284     default:
00285         throw wns::Exception("Unknown activation mode in DataCollector");
00286     }
00287 }
00288 
00289 

Generated on Sun May 27 03:32:13 2012 for openWNS by  doxygen 1.5.5