User Manual, Developers Guide and API Documentation

PhyUser.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/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 

Generated on Sun May 27 03:32:04 2012 for openWNS by  doxygen 1.5.5