User Manual, Developers Guide and API Documentation

RACH.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-2007
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <LTE/macr/RACH.hpp>
00029 #include <LTE/macr/PhyUser.hpp>
00030 #include <LTE/controlplane/RRHandler.hpp>
00031 #include <LTE/controlplane/bch/BCHService.hpp>
00032 #include <LTE/main/Layer2.hpp>
00033 
00034 #include <DLL/Layer2.hpp>
00035 #include <DLL/services/control/Association.hpp>
00036 #include <WNS/StaticFactory.hpp>
00037 
00038 using namespace lte::macr;
00039 
00040 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::macr::RACHUT,
00041                      wns::ldk::FunctionalUnit,
00042                      "lte.macr.RACH.UT",
00043                      wns::ldk::FUNConfigCreator);
00044 
00045 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::macr::RACHBS,
00046                      wns::ldk::FunctionalUnit,
00047                      "lte.macr.RACH.BS",
00048                      wns::ldk::FUNConfigCreator);
00049 
00050 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::macr::RACHShortcutUT,
00051                                      wns::ldk::FunctionalUnit,
00052                                      "lte.macr.RACH.ShortcutUT",
00053                                      wns::ldk::FUNConfigCreator);
00054 
00055 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::macr::RACHShortcutBS,
00056                                      wns::ldk::FunctionalUnit,
00057                                      "lte.macr.RACH.ShortcutBS",
00058                                      wns::ldk::FUNConfigCreator);
00059 
00060 RACH::RACH(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) :
00061     wns::ldk::CommandTypeSpecifier<>(fun),
00062     wns::ldk::HasReceptor<>(),
00063     wns::ldk::HasConnector<>(),
00064     wns::ldk::HasDeliverer<>(),
00065     helper::HasModeName(config),
00066     associationService(NULL),
00067     phyModePtr(wns::service::phy::phymode::createPhyMode(config.getView("phyMode"))),
00068     logger(config.get("logger"))
00069 {
00070     MESSAGE_SINGLE(NORMAL, logger, "RACHUnit: will use PhyMode " << *phyModePtr );
00071 }
00072 
00073 RACH::~RACH()
00074 {}
00075 
00076 void
00077 RACH::onFUNCreated()
00078 {
00079     wns::ldk::fun::FUN* fun = getFUN();
00080 
00081     dll::ILayer2* layer2 = fun->getLayer<dll::ILayer2*>();
00082     associationService = layer2->getControlService<dll::services::control::Association>("ASSOCIATION"+modeBase);
00083 
00084     // The phyUser is needed to set its command
00085     friends.phyUser = fun->findFriend<lte::macr::PhyUser*>(modeBase+separator+"phyUser");
00086 }
00087 
00088 void
00089 RACHUT::onFUNCreated()
00090 {
00091     RACH::onFUNCreated();
00092     rrh = getFUN()->findFriend<lte::controlplane::RRHandlerUT*>(mode+separator+"RRHandler");
00093     bchService = NULL;
00094 }
00095 
00096 void
00097 RACHBS::doSendData(const wns::ldk::CompoundPtr&)
00098 {
00099     MESSAGE_SINGLE(NORMAL, logger, "doSendData()");
00100     assure(false, "RACHBS: sendData should never be called!");
00101 }
00102 
00103 void
00104 RACHUT::doSendData(const wns::ldk::CompoundPtr& compound)
00105 {
00106     // set PhyUser Command
00107     lte::macr::PhyCommand* phyCommand =
00108         dynamic_cast<lte::macr::PhyCommand*>(
00109             getFUN()->getProxy()->activateCommand( compound->getCommandPool(),
00110                                    friends.phyUser ));
00111 
00112     simTimeType startTime = wns::simulator::getEventScheduler()->getTime(); // now
00113 
00114     phyCommand->local.beamforming = false;
00115     phyCommand->local.pattern = wns::service::phy::ofdma::PatternPtr(); // NULL Pointer
00116     phyCommand->local.start = startTime;
00117     phyCommand->local.stop = stopTime;
00118     phyCommand->local.subBand = subBandCounter++;
00119     phyCommand->local.modeRxTx = lte::macr::PhyCommand::Tx;
00120     phyCommand->local.phyModePtr = phyModePtr;
00121     phyCommand->magic.destination = NULL;
00122     phyCommand->magic.source = getFUN()->getLayer<dll::ILayer2*>()->getNode();
00123     phyCommand->magic.txp = txPower;
00124 
00125 
00126     if (getConnector()->hasAcceptor(compound)){
00127         assure(phyModePtr->dataRateIsValid(),"invalid PhyMode dataRate");
00128         MESSAGE_SINGLE(NORMAL, logger, "sent RACH compound ("<< *phyModePtr <<")");
00129         getConnector()->getAcceptor(compound)->sendData(compound);
00130     }
00131     else
00132         assure(false, "Lower FU is not accepting scheduled PDU but is supposed to do so");
00133 
00134 }
00135 
00136 void
00137 RACHBS::doOnData(const wns::ldk::CompoundPtr& compound)
00138 {
00139     MESSAGE_SINGLE(NORMAL, logger, "doOnData()");
00140     getDeliverer()->getAcceptor(compound)->onData(compound);
00141 }
00142 
00143 void
00144 RACHUT::doOnData(const wns::ldk::CompoundPtr&)
00145 {
00146     MESSAGE_SINGLE(NORMAL, logger, "doOnData()");
00147     assure(false, "RACHUT: onData should never be called!");
00148 }
00149 
00150 void
00151 RACHUT::startTx(simTimeType duration)
00152 {
00153     if (bchService == NULL)
00154         bchService = getFUN()->getLayer<dll::ILayer2*>()->getControlService<lte::controlplane::bch::BCHService>("BCHSERVICE_"+modeBase);
00155 
00156     MESSAGE_SINGLE(NORMAL, logger, "startTx(): RACH opened");
00157 
00158     // We have to wait for a RACH reception first
00159     lte::controlplane::bch::BCHRecordPtr best = bchService->getBest().entry;
00160 
00161     // if there is no 'best', i.e. no BCH at all:
00162     if (best == lte::controlplane::bch::BCHRecordPtr()) {
00163         MESSAGE_SINGLE(NORMAL, logger, "startTx(): never received a BCH");
00164         return;
00165     }
00166 
00167     assure(friends.phyUser, "You may not use the  'RACH::startTx' method without a PhyUser in your FUN");
00168     assure(friends.phyUser->checkIdle(), "PhyUser not ready!");
00169 
00170     // when RACH Tx starts, the phy has to be switched to UT-like operation
00171     friends.phyUser->utTuning();
00172 
00173     if (!rrh->hasResourcesGranted()) {
00174         MESSAGE_SINGLE(NORMAL, logger, "startTx(): RACH triggers createRRCompound...");
00175         rrh->createRRCompound();
00176     }
00177     subBandCounter = best->subBand;
00178     accepting = true;
00179     wns::events::scheduler::Interface* es = wns::simulator::getEventScheduler();
00180     stopTime = es->getTime()+duration;
00181     this->wakeup();
00182 
00183     // queue stopEvent
00184     es->schedule(StopEvent(this), stopTime);
00185 }
00186 
00187 void
00188 RACHUT::stopTx()
00189 {
00190     accepting = false;
00191 }
00192 
00193 void
00194 RACHBS::startRx(simTimeType /*duration*/)
00195 {
00196     assure(friends.phyUser, "You may not use the  'RACH::startRx' method without a PhyUser in your FUN");
00197     assure(friends.phyUser->checkIdle(), "PhyUser not ready!");
00198 
00199     // when RACH Rx starts, the phy has to be switched to RAP-like operation
00200     friends.phyUser->rapTuning();
00201 }
00202 
00203 void
00204 RACHBS::stopRx()
00205 {
00206 }
00207 
00208 bool
00209 RACHBS::doIsAccepting(const wns::ldk::CompoundPtr& /* compound */) const
00210 {
00211     return false;
00212 } // doIsAccepting
00213 
00214 bool
00215 RACHUT::doIsAccepting(const wns::ldk::CompoundPtr& compound) const
00216 {
00217     // Check whether we are outside the RAP phase
00218     if (accepting == false) return false;
00219 
00220     // how much of the overall RACH duration is left?
00221     simTimeType duration = stopTime - wns::simulator::getEventScheduler()->getTime();
00222     assure(duration >= 0, "RACH Timing mismatch.");
00223 
00224     // Check whether the packet can be transmitted in the remaining time of
00225     // this RACH phase
00226     assure(phyModePtr->dataRateIsValid(),"!dataRateIsValid");
00227     int capacity = phyModePtr->getBitCapacityFractional(duration);
00228     bool compoundFits = (capacity >= compound->getLengthInBits());
00229 
00230     if (compoundFits == true)
00231     {
00232         return true;
00233     }
00234     else
00235     {
00236         MESSAGE_BEGIN(NORMAL, logger, m, "Deferring RACH compound until next RACH phase (not enough capacity left).");
00237         m << " Capacity needed=" << compound->getLengthInBits();
00238         m << ", capacity available=" << capacity;
00239         MESSAGE_END();
00240         return false;
00241     }
00242 } // doIsAccepting
00243 
00244 
00245 void
00246 RACHBS::doWakeup()
00247 {} // doWakeup
00248 
00249 void
00250 RACHUT::doWakeup()
00251 {
00252     if(!inWakeup) {
00253         inWakeup = true;
00254         getReceptor()->wakeup();
00255         inWakeup = false;
00256     }
00257 } // doWakeup
00258 
00259 RACHShortcut::RACHShortcut(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config):
00260     wns::ldk::CommandTypeSpecifier<>(fun),
00261     wns::ldk::ShortcutFU<wns::service::dll::UnicastAddress, RACHShortcut*>(fun, config)
00262 {
00263 }
00264 
00265 RACHShortcut::~RACHShortcut()
00266 {
00267 }
00268 
00269 wns::service::dll::UnicastAddress
00270 RACHShortcut::getSourceAddress()
00271 {
00272     lte::main::Layer2* layer = dynamic_cast<lte::main::Layer2*>(getFUN()->getLayer());
00273     assure(layer!=NULL, "No layer 2 found.");
00274     return  layer->getDLLAddress();
00275 }
00276 
00277 wns::service::dll::UnicastAddress
00278 RACHShortcut::getDestinationAddress(const wns::ldk::CompoundPtr&)
00279 {
00280     assure(false, "All RACH compounds are broadcast. Cannot get a Destination adddress");
00281 }
00282 
00283 bool
00284 RACHShortcut::isBroadcast(const wns::ldk::CompoundPtr&)
00285 {
00286     return true;
00287 }
00288 
00289 RACHShortcutBS::RACHShortcutBS(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config):
00290     RACHShortcut(fun, config)
00291 {
00292 }
00293 
00294 bool
00295 RACHShortcutBS::isReceiver()
00296 {
00297     return true;
00298 }
00299 
00300 RACHShortcutUT::RACHShortcutUT(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config):
00301     RACHShortcut(fun, config)
00302 {
00303 }
00304 
00305 bool
00306 RACHShortcutUT::isReceiver()
00307 {
00308     return false;
00309 }

Generated on Fri May 25 03:32:06 2012 for openWNS by  doxygen 1.5.5