![]() |
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/controlplane/bch/BCHUnit.hpp> 00029 #include <LTE/timing/ResourceScheduler.hpp> 00030 #include <LTE/controlplane/associationHandler/AssociationHandler.hpp> 00031 #include <LTE/controlplane/flowmanagement/FlowManager.hpp> 00032 #include <LTE/rlc/RLCCommand.hpp> 00033 00034 #include <DLL/Layer2.hpp> 00035 #include <DLL/services/control/Association.hpp> 00036 00037 #include <WNS/ldk/fun/FUN.hpp> 00038 #include <WNS/ldk/helper/FakePDU.hpp> 00039 00040 using namespace lte; 00041 using namespace lte::controlplane::bch; 00042 using namespace wns; 00043 using namespace wns::ldk; 00044 using namespace wns::ldk::fun; 00045 00046 STATIC_FACTORY_REGISTER_WITH_CREATOR(LTEBCHUnitRAP, FunctionalUnit, "lte.controlplane.BCHUnit.RAP", FUNConfigCreator); 00047 STATIC_FACTORY_REGISTER_WITH_CREATOR(LTEBCHUnitUT, FunctionalUnit, "lte.controlplane.BCHUnit.UT", FUNConfigCreator); 00048 STATIC_FACTORY_REGISTER_WITH_CREATOR(NoBCH, FunctionalUnit, "lte.controlplane.BCHUnit.No", FUNConfigCreator); 00049 00050 00051 LTEBCHUnit::LTEBCHUnit(wns::ldk::fun::FUN* fun, const pyconfig::View& config) : 00052 CommandTypeSpecifier<LTEBCHCommand>(fun), 00053 HasReceptor<>(), 00054 HasConnector<>(), 00055 HasDeliverer<>(), 00056 lte::helper::HasModeName(config), 00057 00058 logger(config.get("logger")), 00059 layer2(NULL), 00060 commandSize(config.get<int>("commandSize")) 00061 { 00062 friends.scheduler = NULL; 00063 friends.macg = NULL; 00064 00065 rlcReader = NULL; 00066 } 00067 00068 00069 LTEBCHUnitRAP::LTEBCHUnitRAP(wns::ldk::fun::FUN* fun, const pyconfig::View& config) : 00070 LTEBCHUnit(fun, config), 00071 Cloneable<LTEBCHUnitRAP>(), 00072 txPower(config.get<wns::Power>("txPower")), 00073 accepting(false), 00074 compound(CompoundPtr()), 00075 rlcName(config.get<std::string>("rlcName")), 00076 macgName(config.get<std::string>("macgName")), 00077 flowManagerName(config.get<std::string>("flowManagerName")) 00078 { 00079 } 00080 00081 LTEBCHUnitUT::LTEBCHUnitUT(wns::ldk::fun::FUN* fun, const pyconfig::View& _config) : 00082 LTEBCHUnit(fun, _config), 00083 Cloneable<LTEBCHUnitUT>(), 00084 00085 bchService(NULL), 00086 associationService(NULL), 00087 config(_config), 00088 sinrProbe(NULL), 00089 rxpProbe(NULL), 00090 interfProbe(NULL), 00091 schedulerName(config.get<std::string>("schedulerName")) 00092 { 00093 MESSAGE_SINGLE(NORMAL, logger, "LTEBCHUnit for mode " << modeBase << " started."); 00094 } 00095 00096 LTEBCHUnit::~LTEBCHUnit() 00097 { 00098 layer2 = NULL; 00099 } 00100 00101 LTEBCHUnitRAP::~LTEBCHUnitRAP() 00102 { 00103 compound = CompoundPtr(); 00104 } 00105 00106 LTEBCHUnitUT::~LTEBCHUnitUT() 00107 { 00108 associationService = NULL; 00109 bchService = NULL; 00110 00111 delete sinrProbe; sinrProbe = NULL; 00112 delete rxpProbe; rxpProbe = NULL; 00113 delete interfProbe; interfProbe = NULL; 00114 } 00115 00116 void 00117 LTEBCHUnit::onFUNCreated() 00118 { 00119 layer2 = getFUN()->getLayer<dll::ILayer2*>(); 00120 } 00121 00122 void 00123 LTEBCHUnitRAP::onFUNCreated() 00124 { 00125 LTEBCHUnit::onFUNCreated(); 00126 rlcReader = getFUN()->getCommandReader(rlcName); 00127 friends.macg = getFUN()->findFriend<lte::macg::MACg*>(macgName); 00128 } 00129 00130 void 00131 LTEBCHUnitUT::onFUNCreated() 00132 { 00133 LTEBCHUnit::onFUNCreated(); 00134 00135 bchService = layer2->getControlService<lte::controlplane::bch::BCHService>("BCHSERVICE"+separator+mode); 00136 associationService = layer2->getControlService<dll::services::control::Association>("ASSOCIATION"+modeBase); 00137 00138 wns::node::Interface* node = layer2->getNode(); 00139 wns::probe::bus::ContextProviderCollection localIDs(&node->getContextProviderCollection()); 00140 00141 friends.scheduler = getFUN()->findFriend<lte::timing::ResourceScheduler*>(schedulerName); 00142 00143 // read the localIDs from the config 00144 for (int ii = 0; ii<config.len("localIDs.keys()"); ++ii) 00145 { 00146 std::string key = config.get<std::string>("localIDs.keys()",ii); 00147 uint32_t value = config.get<uint32_t>("localIDs.values()",ii); 00148 localIDs.addProvider(wns::probe::bus::contextprovider::Constant(key, value)); 00149 MESSAGE_SINGLE(VERBOSE, logger, "Using Local IDName '"<<key<<"' with value: "<<value); 00150 } 00151 sinrProbe = new wns::probe::bus::ContextCollector(localIDs, "lte.BCH_SINR"); 00152 rxpProbe = new wns::probe::bus::ContextCollector(localIDs, "lte.BCH_RxPower"); 00153 interfProbe = new wns::probe::bus::ContextCollector(localIDs, "lte.BCH_Interference"); 00154 } 00155 00156 00157 bool 00158 LTEBCHUnitRAP::doIsAccepting(const CompoundPtr& /* compound */) const 00159 { 00160 return accepting; 00161 } // isAccepting 00162 00163 bool 00164 LTEBCHUnitUT::doIsAccepting(const CompoundPtr& /* compound */) const 00165 { 00166 return false; 00167 } 00168 00169 void 00170 LTEBCHUnitRAP::doSendData(const CompoundPtr& _compound) 00171 { 00172 LTEBCHCommand* myCommand; 00173 if (compound == CompoundPtr()) // if first Association ACK 00174 { 00175 compound = CompoundPtr(new Compound(getFUN()->createCommandPool())); 00176 myCommand = activateCommand(compound->getCommandPool()); 00177 myCommand->magic.source = layer2->getDLLAddress(); 00178 myCommand->peer.acknowledgement = true; 00179 myCommand->peer.ackedUTs.push_back(_compound); 00180 } 00181 else // use the existing BCH compound and just append the Association ACK into it 00182 { 00183 myCommand = getCommand(compound->getCommandPool()); 00184 myCommand->peer.ackedUTs.push_back(_compound); 00185 } 00186 } // doSendData 00187 00188 void 00189 LTEBCHUnitUT::doSendData(const CompoundPtr&) 00190 {} 00191 00192 void 00193 LTEBCHUnitRAP::doOnData(const CompoundPtr&) 00194 { 00195 } 00196 00197 void 00198 LTEBCHUnitUT::doOnData(const CompoundPtr& compound) 00199 { 00201 lte::timing::SchedulerCommand* schedulerCommand = friends.scheduler->getCommand(compound->getCommandPool()); 00202 LTEBCHCommand* myCommand = getCommand(compound->getCommandPool()); 00203 00204 wns::service::dll::UnicastAddress comingFrom = myCommand->magic.source; 00206 assure(bchService, "LTEBCHUnit unexpectedly received a BCH compound."); 00207 bchService->storeMeasurement(comingFrom, schedulerCommand->local.phyMeasurementPtr, schedulerCommand->local.subBand); 00208 00209 { // Probe measurement Values 00210 assure(associationService, "Trying to probe BCH Measurement in a RAP."); 00211 00212 if (associationService->hasAssociation()) 00213 if (associationService->getAssociation() == comingFrom) 00214 { 00215 wns::service::phy::power::PowerMeasurementPtr phyMeasurementPtr = schedulerCommand->local.phyMeasurementPtr; 00216 sinrProbe->put(compound, phyMeasurementPtr->getSINR().get_dB()); 00217 rxpProbe->put(compound, phyMeasurementPtr->getRxPower().get_dBm()); 00218 interfProbe->put(compound, phyMeasurementPtr->getInterferencePower().get_dBm()); 00219 } 00220 } 00221 00222 if (myCommand->peer.acknowledgement) 00223 { 00224 assure(!myCommand->peer.ackedUTs.empty(), "BCH compound does not contain Association ACKs, but should do so!"); 00225 // send the Association ACKs tp the AssociationHandler FU. The filtering by the MAC address will be done there 00226 for(std::list<wns::ldk::CompoundPtr>::const_iterator iter = myCommand->peer.ackedUTs.begin(); iter != myCommand->peer.ackedUTs.end(); ++iter) 00227 { 00228 getDeliverer()->getAcceptor(compound)->onData(*iter); 00229 } 00230 myCommand->peer.ackedUTs.clear(); 00231 } 00232 // else the compound is dropped here 00233 } // doOnData 00234 00235 void 00236 LTEBCHUnitRAP::doWakeup() 00237 { 00238 getReceptor()->wakeup(); 00239 } // wakeup 00240 00241 void 00242 LTEBCHUnitUT::doWakeup() 00243 { 00244 } 00245 00246 void 00247 LTEBCHUnit::calculateSizes(const CommandPool* commandPool, Bit& _commandPoolSize, Bit& _dataSize) const 00248 { 00249 getFUN()->getProxy()->calculateSizes(commandPool, _commandPoolSize, _dataSize, this); 00250 _commandPoolSize += this->commandSize; 00251 } 00252 00253 void LTEBCHUnitRAP::sendBCH(simTimeType duration) 00254 { 00255 assure(rlcReader, "You may not use the 'sendBCH' Event without an RLC in your FUN"); 00256 00257 MESSAGE_SINGLE(NORMAL, logger, "sendBCH(): Creating BCH"); 00258 00259 accepting = true; 00260 // if there are pending Association ACKs in the BCH buffer, they will be stored in peer.ackedUTs now 00261 this->wakeup(); 00262 accepting = false; 00263 00264 if (compound == CompoundPtr()) //no compound from associationHandler FU 00265 { 00266 compound = CompoundPtr(new Compound(getFUN()->createCommandPool(), 00267 wns::ldk::helper::FakePDUPtr(new wns::ldk::helper::FakePDU(1)))); 00268 LTEBCHCommand* myCommand = activateCommand(compound->getCommandPool()); 00269 myCommand->magic.source = layer2->getDLLAddress(); 00270 myCommand->peer.acknowledgement = false; 00271 myCommand->peer.ackedUTs.clear(); 00272 } 00273 00274 // set RLC Command 00275 lte::rlc::RLCCommand* rlcCommand = dynamic_cast<lte::rlc::RLCCommand*>(rlcReader->activateCommand(compound->getCommandPool())); 00276 00277 // Downlink 00278 rlcCommand->local.direction = 2; 00279 rlcCommand->peer.source = layer2->getDLLAddress(); 00280 rlcCommand->peer.destination = wns::service::dll::UnicastAddress(); 00281 rlcCommand->peer.qosClass = lte::helper::QoSClasses::PBCH(); 00282 rlcCommand->peer.flowID = layer2->getControlService<lte::controlplane::flowmanagement::FlowManager>(flowManagerName)->getBCHFlowID(); 00283 00284 // set MACg Command 00285 lte::macg::MACgCommand* macgCommand = 00286 dynamic_cast<lte::macg::MACgCommand*>(getFUN()->getProxy()->activateCommand(compound->getCommandPool(), friends.macg )); 00287 macgCommand->peer.source = layer2->getDLLAddress(); 00288 macgCommand->peer.dest = wns::service::dll::UnicastAddress(); 00289 00290 if (getConnector()->hasAcceptor(compound)){ 00291 MESSAGE_SINGLE(NORMAL, logger, "sendBCH(): BCH created"); 00293 //MESSAGE_SINGLE(NORMAL, logger, "sendBCH(): BCH created (PhyMode " << modulation << "-" << coding <<")"); 00294 getConnector()->getAcceptor(compound)->sendData(compound); 00295 } 00296 else 00297 assure(false, "Lower FU is not accepting scheduled PDU but is supposed to do so"); 00298 00299 compound = CompoundPtr(); 00300 }
1.5.5