![]() |
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/PhyUser.hpp> 00029 #include <LTE/timing/ResourceSchedulerInterface.hpp> 00030 00031 #include <WNS/service/dll/StationTypes.hpp> 00032 #include <WNS/service/phy/ofdma/DataTransmission.hpp> 00033 #include <WNS/StaticFactory.hpp> 00034 #include <WNS/ldk/helper/FakePDU.hpp> 00035 #include <WNS/ldk/fun/FUN.hpp> 00036 #include <WNS/ldk/sar/Soft.hpp> 00037 #include <WNS/pyconfig/View.hpp> 00038 00039 #include <DLL/services/management/InterferenceCache.hpp> 00040 #include <DLL/Layer2.hpp> 00041 #include <DLL/StationManager.hpp> 00042 00043 #include <boost/bind.hpp> 00044 00045 #include <cmath> 00046 #include <iomanip> 00047 #include <iostream> 00048 00049 using namespace lte::macr; 00050 00051 #define A2N(a) layer2->getStationManager()->getStationByMAC(a)->getName() 00052 00053 STATIC_FACTORY_REGISTER_WITH_CREATOR(PhyUser, wns::ldk::FunctionalUnit, "lte.macr.PhyUser", wns::ldk::FUNConfigCreator); 00054 00055 PhyUser::PhyUser(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& pyConfigView) : 00056 wns::ldk::CommandTypeSpecifier<PhyCommand>(fun), 00057 wns::ldk::HasReceptor<>(), 00058 wns::ldk::HasConnector<>(), 00059 wns::ldk::HasDeliverer<>(), 00060 wns::Cloneable<PhyUser>(), 00061 lte::helper::HasModeName(pyConfigView), 00062 #ifndef NDEBUG 00063 schedulerCommandReader_(NULL), 00064 #endif 00065 config_(pyConfigView), 00066 layer2(NULL), 00067 stateRxTx(Rx), 00068 logger(pyConfigView.get("logger")), 00069 activeSubBands(), 00070 fddCapable((pyConfigView.get<std::string>("plm.mac.duplex") == "FDD")), 00071 safetyFraction(pyConfigView.get<simTimeType>("plm.mac.safetyFraction")), 00072 es(wns::simulator::getEventScheduler()), 00073 iCache(NULL), 00074 bfTransmission(NULL), 00075 transmission(NULL), 00076 notificationService(NULL), 00077 mobility(NULL), 00078 stationManager(NULL), 00079 measurementDelay_(pyConfigView.get<wns::simulator::Time>("measurementDelay")), 00080 sendAllBroadcast(pyConfigView.get<bool>("sendAllBroadcast")), 00081 lastMeasureTime(0.0) 00082 { 00083 MESSAGE_BEGIN(NORMAL, logger, m, "PhyUser() created."); 00084 if (fddCapable) m << " fddCapable"; 00085 MESSAGE_END(); 00086 } // PhyUser 00087 00088 00089 PhyUser::~PhyUser() 00090 { 00091 iCache = NULL; 00092 bfTransmission = NULL; 00093 transmission = NULL; 00094 notificationService = NULL; 00095 mobility = NULL; 00096 stationManager = NULL; 00097 } // ~PhyUser 00098 00099 void 00100 PhyUser::onFUNCreated() 00101 { 00102 wns::ldk::fun::FUN* fun = getFUN(); 00103 layer2 = fun->getLayer<dll::ILayer2*>(); 00104 iCache = layer2->getManagementService<dll::services::management::InterferenceCache>("INTERFERENCECACHE"+modeBase); 00105 stationManager = layer2->getStationManager(); 00106 00107 #ifndef NDEBUG 00108 schedulerCommandReader_ = getFUN()->getCommandReader(config_.get<std::string>("schedulingCommandReaderName")); 00109 #endif 00110 00111 jsonTracingCC_ = wns::probe::bus::ContextCollectorPtr(new wns::probe::bus::ContextCollector(getFUN()->getLayer()->getContextProviderCollection(), "phyTrace")); 00112 00113 } 00114 00115 bool 00116 PhyUser::doIsAccepting(const wns::ldk::CompoundPtr& /*compound*/) const 00117 { 00118 return true; 00119 } // isAccepting 00120 00121 00122 void 00123 PhyUser::doSendData(const wns::ldk::CompoundPtr& compound) 00124 { 00125 assure(compound, "sendData called with an invalid compound."); 00126 assure(getFUN()->getProxy()->commandIsActivated( compound->getCommandPool(), this), 00127 "PhyCommand not specified. PhyUser can not handle this compound!"); 00128 00129 // finally commit CommandPool Size 00130 this->commitSizes(compound->getCommandPool()); 00131 00132 PhyCommand* myCommand = getCommand(compound->getCommandPool()); 00133 if (myCommand->local.modeRxTx == lte::macr::PhyCommand::Tx) 00134 { 00135 MESSAGE_SINGLE(NORMAL, logger,"doSendData(Tx): start=" 00136 << myCommand->local.start <<"s..stop=" 00137 << myCommand->local.stop <<"s => d=" 00138 << (myCommand->local.stop-myCommand->local.start) * 1e6 00139 << "us, subBand=" << myCommand->local.subBand 00140 << ", len="<<compound->getLengthInBits() << "bits"); 00141 00142 simTimeType startTime = myCommand->local.start; 00143 00144 // Will call this->startTransmission at startTime 00145 es->schedule(StartTxEvent(compound, this), startTime); 00146 // Inform FUs that have added a callback that the compound is on air now 00147 if (!myCommand->local.onAirCallback.empty()) 00148 { 00149 myCommand->local.onAirCallback(); 00150 } 00151 } 00152 else 00153 { // reception (Rx) 00154 MESSAGE_SINGLE(NORMAL, logger,"doSendData(Rx): startTime=" 00155 << myCommand->local.start <<", stopTime=" 00156 << myCommand->local.stop << ", subBand=" 00157 << myCommand->local.subBand << ", len=" 00158 << compound->getLengthInBits() << "bits" 00159 << " SHALL NOT OCCUR"); 00160 00161 assure(false,"Tryed to transmit while in RX mode"); 00162 } 00163 // stamp link to my InterferenceCache into the Command 00164 myCommand->magic.remoteCache = iCache; 00165 } // doSendData 00166 00167 00168 void 00169 PhyUser::doOnData(const wns::ldk::CompoundPtr& compound) 00170 { 00171 assure(compound, "onData called with an invalid compound."); 00172 getDeliverer()->getAcceptor(compound)->onData(compound); 00173 } // doOnData 00174 00175 #ifndef NDEBUG 00176 void 00177 PhyUser::traceIncoming(wns::ldk::CompoundPtr compound, wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurement) 00178 { 00179 wns::probe::bus::json::Object objdoc; 00180 00181 PhyCommand* myCommand = getCommand(compound->getCommandPool()); 00182 00183 objdoc["Transmission"]["ReceiverID"] = wns::probe::bus::json::String(getFUN()->getLayer()->getNodeName()); 00184 objdoc["Transmission"]["SenderID"] = wns::probe::bus::json::String(myCommand->magic.source->getName()); 00185 objdoc["Transmission"]["SourceID"] = wns::probe::bus::json::String(myCommand->magic.source->getName()); 00186 00187 if(myCommand->magic.destination == NULL) 00188 { 00189 objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String("Broadcast"); 00190 } 00191 else 00192 { 00193 objdoc["Transmission"]["DestinationID"] = wns::probe::bus::json::String(myCommand->magic.destination->getName()); 00194 } 00195 00196 objdoc["Transmission"]["Start"] = wns::probe::bus::json::Number(myCommand->local.start); 00197 objdoc["Transmission"]["Stop"] = wns::probe::bus::json::Number(myCommand->local.stop); 00198 objdoc["Transmission"]["Subchannel"] = wns::probe::bus::json::Number(myCommand->local.subBand); 00199 objdoc["Transmission"]["TxPower"] = wns::probe::bus::json::Number(myCommand->magic.txp.get_dBm()); 00200 objdoc["Transmission"]["RxPower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getRxPower().get_dBm()); 00201 objdoc["Transmission"]["InterferencePower"] = wns::probe::bus::json::Number(rxPowerMeasurement->getInterferencePower().get_dBm()); 00202 00203 if (myCommand->magic.estimatedSINR.C != wns::Power() && 00204 myCommand->magic.estimatedSINR.I != wns::Power()) 00205 { 00206 objdoc["SINREst"]["C"] = wns::probe::bus::json::Number(myCommand->magic.estimatedSINR.C.get_dBm()); 00207 objdoc["SINREst"]["I"] = wns::probe::bus::json::Number(myCommand->magic.estimatedSINR.I.get_dBm()); 00208 } 00209 00210 if (schedulerCommandReader_->commandIsActivated(compound->getCommandPool())) 00211 { 00212 00213 // Now we have a look at the scheduling time slot 00214 lte::timing::SchedulerCommand* schedCommand = schedulerCommandReader_->readCommand<lte::timing::SchedulerCommand>(compound->getCommandPool()); 00215 00216 wns::scheduler::SchedulingTimeSlotPtr ts = schedCommand->magic.schedulingTimeSlotPtr; 00217 00218 wns::probe::bus::json::Array a; 00219 for (wns::scheduler::PhysicalResourceBlockVector::iterator it= ts->physicalResources.begin(); it != ts->physicalResources.end(); ++it) 00220 { 00221 wns::probe::bus::json::Object pr; 00222 pr["NetBits"] = wns::probe::bus::json::Number(it->getNetBlockSizeInBits()); 00223 a.Insert(pr); 00224 } 00225 objdoc["SchedulingTimeSlot"]["PhysicalResources"] = a; 00226 objdoc["SchedulingTimeSlot"]["HARQ"]["enabled"] = wns::probe::bus::json::Boolean(ts->isHARQEnabled()); 00227 objdoc["SchedulingTimeSlot"]["HARQ"]["ProcessID"] = wns::probe::bus::json::Number(ts->harq.processID); 00228 objdoc["SchedulingTimeSlot"]["HARQ"]["NDI"] = wns::probe::bus::json::Boolean(ts->harq.NDI); 00229 objdoc["SchedulingTimeSlot"]["HARQ"]["TransportBlockID"] = wns::probe::bus::json::Number(ts->harq.transportBlockID); 00230 objdoc["SchedulingTimeSlot"]["HARQ"]["RetryCounter"] = wns::probe::bus::json::Number(ts->harq.retryCounter); 00231 } 00232 wns::probe::bus::json::probeJSON(jsonTracingCC_, objdoc); 00233 } 00234 #endif 00235 00236 void 00237 PhyUser::onData(wns::osi::PDUPtr pdu, wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurement) 00238 { 00239 MESSAGE_BEGIN(VERBOSE, logger, m, "DATAInd"); 00240 m << " while in state: " << getStateRxTx(); 00241 MESSAGE_END(); 00242 00243 // If we are not in receiving state this PDU can't be meant for us. 00244 if (!(stateRxTx==Rx || stateRxTx==BothRxTx)) 00245 return; 00246 00247 assure(wns::dynamicCast<wns::ldk::Compound>(pdu), "Wrong type of PDU!"); 00248 00249 // take a copy! 00250 wns::ldk::CompoundPtr compound = wns::staticCast<wns::ldk::Compound>(pdu)->copy(); 00251 PhyCommand* myCommand = getCommand(compound->getCommandPool()); 00252 00253 //const 00254 wns::node::Interface* source = rxPowerMeasurement->getSourceNode(); 00255 assure(source == myCommand->magic.source,"measurement source mismatch"); 00256 // set receiver Ptr in command pool, for later Probing 00257 compound->getCommandPool()->setReceiver(getFUN()); 00258 00259 wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr = rxPowerMeasurement->getPhyMode(); 00260 assure(myCommand->local.phyModePtr == phyModePtr, "getPhyMode error"); 00261 00262 bool broadcast = (myCommand->magic.destination == NULL); 00263 if (broadcast) { 00264 MESSAGE_SINGLE(NORMAL,logger, "RECEIVED BROADCAST COMPOUND FROM " <<source->getName()); 00265 } 00266 else if(myCommand->magic.destination != layer2->getNode()) 00267 { 00268 // Measure the UL interference from other nodes in eNB 00269 if(layer2->getStationType() == wns::service::dll::StationTypes::eNB()) 00270 { 00271 measureInterference(myCommand, rxPowerMeasurement->getRxPower()); 00272 } 00273 return; 00274 } 00275 00276 // perform the first part of the LL mapping, the second part (Mapping from 00277 // MIB to PER) is performed when all segments belonging to a code-block are 00278 // re-assembled (SAR-FU). 00279 // Store measurements in the phyCommand, e.g. for evaluation in the BCHUnit 00280 myCommand->local.rxPowerMeasurementPtr = rxPowerMeasurement; 00281 00282 MESSAGE_BEGIN(NORMAL, logger, m, "DataInd "); 00283 wns::service::dll::UnicastAddress sourceAddress = 00284 stationManager->getStationByNode(source)->getDLLAddress(); 00285 m << "from " << A2N(sourceAddress) << ":"; 00286 m << " SubBand=" << myCommand->local.subBand; 00287 //m << " SubBand=" << rxPowerMeasurement->getSubChannel(); 00288 m << ", PhyMode=" << *phyModePtr; 00289 m << std::fixed << std::setprecision( 1 ); // Nachkommastellen 00290 m << ", "<<rxPowerMeasurement->getString(); 00291 m << std::fixed << std::setprecision( 2 ); // Nachkommastellen 00292 m << ", MIB=" << rxPowerMeasurement->getMIB(); 00293 m << ", PL=" << rxPowerMeasurement->getPathLoss(); 00294 MESSAGE_END(); 00295 00296 // During Broadcast Phases, Interference is not representative, therefore we 00297 // do not store it, we also do not consider retransmissions 00298 if (broadcast == false && !myCommand->magic.isRetransmission) 00299 { 00300 wns::simulator::getEventScheduler()->scheduleDelay(boost::bind( 00301 &dll::services::management::InterferenceCache::storeMeasurements, 00302 myCommand->magic.remoteCache, 00303 getFUN()->getLayer<dll::ILayer2*>()->getNode(), 00304 rxPowerMeasurement, 00305 dll::services::management::InterferenceCache::Remote, 00306 myCommand->local.subBand), measurementDelay_); 00307 00308 00309 00310 wns::Ratio sinrEstimation = wns::Ratio::from_dB(0.0); 00311 if (myCommand->magic.estimatedSINR.I.get_mW() != 0.0){ 00312 sinrEstimation = myCommand->magic.estimatedSINR.C / myCommand->magic.estimatedSINR.I; 00313 MESSAGE_BEGIN(NORMAL, logger, m, "DataInd: "); 00314 m << "SINR Estimation was: (S=" << myCommand->magic.estimatedSINR.C 00315 << ", I+N=" << myCommand->magic.estimatedSINR.I 00316 << ", Error=" << sinrEstimation-rxPowerMeasurement->getSINR() << ")\n"; 00317 MESSAGE_END(); 00318 } 00319 } 00320 #ifndef NDEBUG 00321 traceIncoming(compound, rxPowerMeasurement); 00322 #endif 00323 // deliver compound 00324 doOnData(compound); 00325 } 00326 00327 void 00328 PhyUser::doWakeup() 00329 { 00330 // calls wakeup method of upper functional unit(s) 00331 getReceptor()->wakeup(); 00332 } // wakeup 00333 00334 00335 void 00336 PhyUser::stopTransmission(wns::osi::PDUPtr pdu, int subBand) 00337 { 00338 transmission->stopTransmission(pdu, subBand); 00339 activeSubBands.remove(std::pair<wns::osi::PDUPtr, int>(pdu, subBand)); 00340 } 00341 00342 void 00343 PhyUser::setReceiveAntennaPattern(wns::node::Interface* destination, wns::service::phy::ofdma::PatternPtr pattern) 00344 { 00345 assure(pattern, "No Beamforming Pattern set."); // set correct pattern in PhyUser 00346 bfTransmission->insertReceivePattern(destination, pattern); 00347 } 00348 00349 void 00350 PhyUser::deleteReceiveAntennaPatterns() 00351 { 00352 // Delete old Rx Antenna Patterns 00353 std::map<wns::node::Interface*, wns::service::phy::ofdma::PatternPtr> emptyMap; 00354 bfTransmission->setCurrentReceivePatterns(emptyMap); 00355 } 00356 00357 bool 00358 PhyUser::checkIdle() 00359 { 00360 return ( activeSubBands.empty() && !transmission->isReceiving() ); 00361 } 00362 00363 void 00364 PhyUser::setStateRxTx(StateRxTx _state) 00365 { 00366 MESSAGE_SINGLE(VERBOSE, logger, "Setting state to " << _state); 00367 switch (_state) 00368 { 00369 case Tx: 00370 assure(!transmission->isReceiving(), "Tried to switch to Tx while still receiving!"); 00371 notificationService->disableReception(); 00372 break; 00373 case Rx: 00374 assure(activeSubBands.empty(), "Tried to switch to Rx while still transmitting!"); 00375 // Cleanup old Antenna Patterns 00376 this->deleteReceiveAntennaPatterns(); 00377 notificationService->enableReception(); 00378 MESSAGE_SINGLE(VERBOSE,logger,"Cleared old Antenna Patterns"); 00379 break; 00380 case BothRxTx: 00381 assure(fddCapable, "only FDD capable stations can set 'state' to 'BothRxTx'!"); 00382 notificationService->enableReception(); 00383 break; 00384 default: 00385 assure(false, "You tried to set an unknown state!"); 00386 break; 00387 } 00388 00389 stateRxTx=_state; 00390 00391 MESSAGE_SINGLE(VERBOSE,logger,"Set PhyUser State to: "+getStateRxTx()); 00392 } 00393 00394 std::string 00395 PhyUser::getStateRxTx() const 00396 { 00397 switch (stateRxTx) 00398 { 00399 case Tx: 00400 return "Tx"; 00401 break; 00402 case Rx: 00403 return "Rx"; 00404 break; 00405 case BothRxTx: 00406 return "BothRxTx"; 00407 break; 00408 default: 00409 assure(false, "Unknown stateTxRx in PhyUser!"); 00410 return ""; 00411 } 00412 return ""; 00413 } 00414 00415 void 00416 PhyUser::rapTuning() 00417 { 00418 if (getFUN()->getLayer<dll::ILayer2*>()->getStationType() == wns::service::dll::StationTypes::FRS()) 00419 transmission->setTxRxSwap(false); 00420 } 00421 00422 void 00423 PhyUser::utTuning() 00424 { 00425 if (getFUN()->getLayer<dll::ILayer2*>()->getStationType() == wns::service::dll::StationTypes::FRS()) 00426 transmission->setTxRxSwap(true); 00427 } 00428 00429 void 00430 PhyUser::startTransmission(const wns::ldk::CompoundPtr& compound) 00431 { 00432 assure(getFUN()->getProxy()->commandIsActivated( compound->getCommandPool(), this), 00433 "PhyCommand not specified. PhyUser can not handle this compound!"); 00434 00435 PhyCommand* myCommand = getCommand(compound->getCommandPool()); 00436 00437 MESSAGE_SINGLE(NORMAL, logger,"startTransmission(): start=" 00438 << myCommand->local.start 00439 << "s..stop=" << myCommand->local.stop 00440 << "s => d=" << myCommand->local.stop-myCommand->local.start 00441 << "s, subBand=" << myCommand->local.subBand); 00442 00443 wns::Power txPower = myCommand->magic.txp; 00444 00445 int subBand = myCommand->local.subBand; 00446 int beam = myCommand->local.beam; 00447 wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr = myCommand->local.phyModePtr; 00448 00449 // duration should be multiple of OFDM symbol length 00450 simTimeType duration = myCommand->local.stop - myCommand->local.start; 00451 00452 assure(myCommand->local.start == es->getTime(), "myCommand->local.start is not now"); 00453 assure(phyModePtr->dataRateIsValid(), "!dataRateIsValid for " << *phyModePtr); 00454 00455 int capacity = phyModePtr->getBitCapacityFractional(duration); 00456 00457 MESSAGE_SINGLE(NORMAL, logger,"PhyMode=" << *phyModePtr 00458 << " supports " << phyModePtr->getBitCapacityFractional(1.0) 00459 << " bit/s/subChannel"); 00460 00461 MESSAGE_BEGIN(NORMAL, logger, m, "startTransmission on subBand="); 00462 m << subBand 00463 << ", PhyMode=" << *phyModePtr 00464 << ", D=" << duration*1e6 << "us" 00465 << ", " << compound->getLengthInBits() << " bit" 00466 << ", cap=" << capacity << " bit" 00467 << ", source=" << myCommand->magic.source->getName() 00468 << ", dest=" << (myCommand->magic.destination == NULL ? "BROADCAST" : myCommand->magic.destination->getName()) 00469 << ", P=" << txPower; 00470 MESSAGE_END(); 00471 00472 assure(compound->getLengthInBits() <= capacity , "SDU too long: len="<<compound->getLengthInBits() 00473 << " <= cap="<<capacity 00474 << " ("<<phyModePtr->getString() 00475 << ", D="<<duration<<"s)"); 00476 00477 if (myCommand->magic.destination == 0 || sendAllBroadcast) 00478 { 00479 // no destination, send broadcast 00480 assure(beam==0,"broadcast is only possible with beam==0, but beam="<<beam); 00481 transmission->startBroadcast(compound, subBand, txPower, phyModePtr); 00482 } 00483 else 00484 { 00485 // we have a destination, this is not a broadcast 00486 if (myCommand->local.beamforming == true) 00487 { 00488 assure(myCommand->local.pattern, "No Beamforming Pattern set."); 00489 // call startTransmission method of dataTransmission service 00490 // which is located in WNS/service/phy/ofdma/Station.cpp: Station::startTransmission 00491 bfTransmission->startTransmission(compound, 00492 myCommand->magic.destination, 00493 subBand, 00494 myCommand->local.pattern, 00495 txPower, 00496 phyModePtr); 00497 } 00498 else 00499 { 00500 transmission->startUnicast(compound, 00501 myCommand->magic.destination, 00502 subBand, 00503 txPower, 00504 phyModePtr); 00505 } 00506 } 00507 activeSubBands.push_back( std::pair<wns::osi::PDUPtr, int>(compound, subBand) ); 00508 // prepare the stopEvent 00509 es->schedule(StopTxEvent(compound, subBand, this), myCommand->local.stop-safetyFraction); 00510 } // startTransmission 00511 00512 void 00513 PhyUser::setDataTransmissionService(wns::service::Service* phy) 00514 { 00515 assure(phy, "must be non-NULL"); 00516 assureType(phy, wns::service::phy::ofdma::DataTransmission*); 00517 00518 wns::service::phy::ofdma::DataTransmission* tmp = 00519 dynamic_cast<wns::service::phy::ofdma::DataTransmission*>(phy); 00520 00521 bfTransmission = tmp; 00522 transmission = tmp; 00523 } 00524 00525 wns::service::phy::ofdma::DataTransmission* 00526 PhyUser::getDataTransmissionService() const 00527 { 00528 assure(transmission, "no ofdma::DataTransmission set. Did you call setDataTransmission()?"); 00529 assureType(transmission, wns::service::phy::ofdma::DataTransmission*); 00530 return dynamic_cast<wns::service::phy::ofdma::DataTransmission*>(transmission); 00531 } 00532 00533 // called by ILayer2 class in lte: 00534 void 00535 PhyUser::setNotificationService(wns::service::Service* phy) 00536 { 00537 MESSAGE_SINGLE(NORMAL, logger, "PhyUser::setNotificationService() called"); 00538 assure(phy, "must be non-NULL"); 00539 assureType(phy, wns::service::phy::ofdma::Notification*); 00540 notificationService = dynamic_cast<wns::service::phy::ofdma::Notification*>(phy); 00541 notificationService->registerHandler(this); 00542 } 00543 00544 // currently not called anywhere: 00545 wns::service::phy::ofdma::Notification* 00546 PhyUser::getNotificationService() const 00547 { 00548 assure(notificationService, "no ofdma::Notification set. Did you call setNotificationService()?"); 00549 return notificationService; 00550 } 00551 00552 void 00553 PhyUser::setMACAddress(const wns::service::dll::UnicastAddress& _address) 00554 { 00555 address = _address; 00556 MESSAGE_SINGLE(NORMAL, logger, "setting my MAC address to: " << address); 00557 } 00558 00559 void 00560 PhyUser::setMobility(wns::PositionableInterface* _mobility) 00561 { 00562 assure(_mobility, "Trying to set invalid mobility Object Pointer"); 00563 mobility = _mobility; 00564 } 00565 00566 bool 00567 PhyUser::isFddCapable() const 00568 { 00569 return fddCapable; 00570 } 00571 00572 void 00573 PhyUser::measureInterference(PhyCommand* myCommand, wns::Power rxPower) 00574 { 00575 int sc = myCommand->local.subBand; 00576 if(es->getTime() > lastMeasureTime) 00577 { 00578 for(std::map<int, wns::Power>::iterator it = interf.begin(); 00579 it != interf.end(); 00580 it++) 00581 { 00582 MESSAGE_SINGLE(NORMAL,logger, "Storing interference for slot: " 00583 << it->first << " " << it->second); 00584 00585 iCache->storeInterference(layer2->getNode(), 00586 it->second, 00587 dll::services::management::InterferenceCache::Local, 00588 it->first); 00589 } 00590 lastMeasureTime = es->getTime(); 00591 interf.clear(); 00592 } 00593 interf[sc] += rxPower; 00594 MESSAGE_SINGLE(NORMAL,logger, "Added interference from: " 00595 << myCommand->magic.source->getName() << " " 00596 << rxPower << " total on SC " << sc << " is " << interf[sc]); 00597 } 00598 00599
1.5.5