![]() |
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/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
1.5.5