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