User Manual, Developers Guide and API Documentation

Station.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 <OFDMAPHY/Station.hpp>
00029 #include <OFDMAPHY/Manager.hpp>
00030 #include <OFDMAPHY/receiver/Receiver.hpp>
00031 #include <OFDMAPHY/Component.hpp>
00032 
00033 #include <RISE/scenario/Scenario.hpp>
00034 #include <RISE/receiver/PowerMeasurement.hpp>
00035 #include <RISE/transmissionobjects/unicasttransmissionobject.hpp>
00036 #include <RISE/transmissionobjects/broadcasttransmissionobject.hpp>
00037 #include <RISE/transmissionobjects/transmissionobjectbf.hpp>
00038 #include <RISE/manager/metasystemmanager.hpp>
00039 
00040 #include <WNS/service/phy/power/OFDMAMeasurement.hpp> // to be derived from
00041 #include <WNS/PowerRatio.hpp>
00042 #include <WNS/SmartPtr.hpp>
00043 #include <WNS/node/component/Component.hpp>
00044 
00045 
00046 using namespace ofdmaphy;
00047 
00048 // a new Station is created in constructor of ofdmaphy::Component
00049 Station::Station(Component* _component, const wns::pyconfig::View& pyConfigView) :
00050     rise::Station(pyConfigView),
00051     eirpLimited(pyConfigView.get<bool>("eirpLimited")),
00052     numAntennas(pyConfigView.get<int>("numAntennas")),
00053     logger(pyConfigView.get("logger")),
00054     systemManager(dynamic_cast<SystemManager*>(rise::MetaSystemManager::getInstance()->getSystemManagerBySystemName(pyConfigView.get<std::string>("systemManagerName")))),
00055     transmitter(NULL),
00056     receiver(NULL),
00057     powerAdmission(this),
00058     maxTxPowerPerSubband(pyConfigView.get<wns::Power>("txPower")),
00059     totalPower(pyConfigView.get<wns::Power>("totalPower")),
00060     tuneRx(),
00061     tuneTx(),
00062     reverseState(false),
00063     beamformingAntenna(NULL),
00064     supportsBeamforming(false),
00065     activeTransmissions(),
00066     handler(NULL),
00067     measurementHandler(NULL),
00068     component(_component), // to be removed, only for Node retrieval
00069     isReceptionEnabledFlag(true)
00070 {
00071 //    MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station contruction. total txPower="<<txPower);
00072 
00073     assure(systemManager, "Was not able to acquire SystemManager");
00074 
00075     if (! pyConfigView.isNone("beamformingAntenna"))
00076     {
00077         beamformingAntenna = new rise::antenna::Beamforming(pyConfigView.getView("beamformingAntenna"), this);
00078         supportsBeamforming = true;
00079     }
00080     else
00081     {
00082         supportsBeamforming = false;
00083     }
00084 
00085     assure(pyConfigView.len("receiver") == 1,
00086            "Only one receiver supported at the moment!");
00087 
00088     assure(pyConfigView.len("transmitter") == 1,
00089            "Only one transmitter supported at the moment!");
00090 
00091     this->receiver = new receiver::Receiver(pyConfigView.getView("receiver", 0), this);
00092     this->transmitter = new Transmitter<Station>(pyConfigView.getView("transmitter", 0), this, getAntenna());
00093 
00094     double txFrequency = pyConfigView.get<double>("txFrequency");
00095     double rxFrequency = pyConfigView.get<double>("rxFrequency");
00096     double bandwidth   = pyConfigView.get<double>("bandwidth");
00097     int numberOfSubCarrier = pyConfigView.get<int>("numberOfSubCarrier");
00098 
00099     tuneRx.frequency = rxFrequency;
00100     tuneRx.bandwidth = bandwidth;
00101     tuneRx.numberOfSubCarrier = numberOfSubCarrier;
00102 
00103     tuneTx.frequency = txFrequency;
00104     tuneTx.bandwidth = bandwidth;
00105     tuneTx.numberOfSubCarrier = numberOfSubCarrier;
00106 
00107     this->setRxTune( tuneRx );
00108     this->setTxTune( tuneTx );
00109 
00110     MESSAGE_BEGIN(NORMAL, logger, m, "ofdmaphy::Station constructed: ");
00111     m << "#SC="<<numberOfSubCarrier
00112       <<", fTx="<<txFrequency
00113       <<", fRx="<<rxFrequency
00114       <<", b="<<bandwidth
00115       <<", Ptotal="<<totalPower
00116       <<", PmaxSubband="<<maxTxPowerPerSubband;
00117     // TODO: nominal power per subBand?
00118     MESSAGE_END();
00119 
00120     assure(maxTxPowerPerSubband <= totalPower, "Inconsistent txPower settings.");
00121 
00122 }
00123 
00124 Station::~Station()
00125 {
00126     activeTransmissions.clear();
00127     delete receiver;
00128     delete transmitter;
00129     if (beamformingAntenna)
00130         delete beamformingAntenna;
00131 }
00132 
00133 void
00134 Station::registerRSSHandler(wns::service::phy::ofdma::RSSHandler* _rssHandler)
00135 {
00136     assure(_rssHandler, "must be non-NULL");
00137     rssHandler = _rssHandler;
00138     this->wns::Observer<RSSInterface>::startObserving(this->receiver);
00139 }
00140 
00141 rise::antenna::Beamforming*
00142 Station::getBFAntenna() const {
00143     assure (beamformingEnabled(), "Beamforming is not supported in the current configuration");
00144     assure (beamformingAntenna, "Beamforming is not supported in the current configuration");
00145     return beamformingAntenna;
00146 }
00147 
00148 bool
00149 Station::beamformingEnabled() const
00150 {
00151     return supportsBeamforming;
00152 }
00153 
00154 void
00155 Station::onNodeCreated()
00156 {
00157     if (beamformingEnabled() == false)
00158         return;
00159 
00160     assure(
00161         getAntenna()->getPosition() == getBFAntenna()->getPosition(),
00162         "Both antennas must have the same position since the beamforming"
00163         "algorithm will use the position of the Station::antenna!");
00164 }
00165 
00166 void
00167 Station::startBroadcast(wns::osi::PDUPtr sdu, int subBand, wns::Power requestedPower, wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr)
00168 {
00169     // check the requested txPower (per subBand) (and modify if needed)
00170     wns::Power txPower = this->powerAdmission->admit(requestedPower);
00171     assure(phyModePtr,"phyModePtr==NULL");
00172 
00173     // broadcast transmission (non-beamforming with static antenna)
00174     rise::BroadcastTransmissionObjectPtr bto(
00175         new rise::BroadcastTransmissionObject(transmitter,
00176                                               sdu,
00177                                               txPower,
00178                                               phyModePtr,
00179                                               (unsigned long int)(1)));
00180 
00181     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::startBroadcast(subBand="<<subBand<<",P="<<txPower<<",M&C="<<*phyModePtr<<")");
00182     this->startTransmitting(sdu, bto, subBand);
00183 }
00184 
00185 void
00186 Station::startBroadcast(wns::osi::PDUPtr sdu, int subBand, wns::Power requestedPower, int numberOfSpatialStreams)
00187 {
00188     assure(numberOfSpatialStreams <= this->numAntennas,
00189            "Cannot transmit " << numberOfSpatialStreams << " with only " << numAntennas << " antennas");
00190     // check the requested txPower (per subBand) (and modify if needed)
00191     wns::Power txPower = this->powerAdmission->admit(requestedPower);
00192 
00193     rise::BroadcastTransmissionObjectPtr bto(
00194         new rise::BroadcastTransmissionObject(transmitter,
00195                                               sdu,
00196                                               txPower,
00197                                               1,
00198                                               numberOfSpatialStreams));
00199 
00200     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::startBroadcast(subBand="<<subBand<<",P="<<txPower<<",numSS="<<numberOfSpatialStreams<<")");
00201     this->startTransmitting(sdu, bto, subBand);
00202 }
00203 
00204 void
00205 Station::startTransmitting(wns::osi::PDUPtr sdu, rise::TransmissionObjectPtr txObject, int subBand)
00206 {
00207     assure(activeTransmissions.find(sdu) == activeTransmissions.end(), 
00208            "Transmission for this PDU already active");
00209 
00210     transmitter->startTransmitting(txObject, subBand);
00211     activeTransmissions[sdu] = txObject;
00212 }
00213 
00214 void
00215 Station::startUnicast(wns::osi::PDUPtr sdu, wns::node::Interface* _recipient, int subBand, wns::Power requestedPower, wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr)
00216 {
00217     // unicast transmission (non-beamforming with static antenna)
00218     assure(_recipient != NULL, "Invalid Recipient");
00219     assure(phyModePtr,"phyModePtr==NULL");
00220 
00221     // check the requested txPower (and modify if needed)
00222     wns::Power txPower = powerAdmission->admit(requestedPower);
00223 
00224     Station* recipient = systemManager->getStation(_recipient);
00225 
00226     rise::UnicastTransmissionObjectPtr uto(new rise::UnicastTransmissionObject(transmitter,
00227                                                                                recipient->receiver,
00228                                                                                (unsigned long int)(1),
00229                                                                                sdu,
00230                                                                                txPower,
00231                                                                                phyModePtr));
00232     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::startUnicast(subBand="<<subBand<<",P="<<txPower<<",M&C="<<*phyModePtr<<")");
00233     this->startTransmitting(sdu, uto, subBand);
00234 }
00235 
00236 void
00237 Station::startUnicast(wns::osi::PDUPtr sdu, wns::node::Interface* _recipient, int subBand, wns::Power requestedPower, int numberOfSpatialStreams)
00238 {
00239     assure(numberOfSpatialStreams <= this->numAntennas,
00240            "Cannot transmit " << numberOfSpatialStreams << " with only " << numAntennas << " antennas");
00241     assure(_recipient != NULL, "Invalid Recipient");
00242     wns::Power txPower = powerAdmission->admit(requestedPower);
00243     Station* recipient = systemManager->getStation(_recipient);
00244 
00245     rise::UnicastTransmissionObjectPtr uto(new rise::UnicastTransmissionObject(transmitter,
00246                                                                                recipient->receiver,
00247                                                                                1,
00248                                                                                sdu,
00249                                                                                txPower,
00250                                                                                numberOfSpatialStreams));
00251 
00252     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::startUnicast(subBand="<<subBand<<",P="<<txPower<<",numSS="<<numberOfSpatialStreams<<")");
00253     this->startTransmitting(sdu, uto, subBand);
00254 }
00255 
00256 void
00257 Station::stopTransmission(wns::osi::PDUPtr sdu, int
00258 #ifndef WNS_NO_LOGGING
00259                           subBand
00260 #endif
00261 )
00262 {
00263     assure(activeTransmissions.find(sdu) != activeTransmissions.end(), "No active transmission with this PDU");
00264     assure(activeTransmissions.find(sdu)->second->getPayload() == sdu, "Wrong pdu"); // hoy:???
00265 
00266     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::stopTransmission(subBand=" << subBand << ")");
00267     std::map<wns::osi::PDUPtr, rise::TransmissionObjectPtr>::iterator itr = activeTransmissions.find(sdu);
00268 
00269     // Remove transmission
00270     // Transmission is a SmartPtr -> Transmission() creates NULL pointer
00271     rise::TransmissionObjectPtr t = itr->second;
00272     activeTransmissions.erase(itr);
00273 
00274     transmitter->stopTransmitting(t);
00275 }
00276 
00277 wns::CandI
00278 Station::getCurrentCandI(wns::osi::PDUPtr sdu)
00279 {
00280     //for testing purpose only
00281     assure(activeTransmissions.find(sdu) != activeTransmissions.end(), "No active transmission with this PDU");
00282     assure(activeTransmissions.find(sdu)->second->getPayload() == sdu, "Wrong pdu"); // hoy:???
00283 
00284     std::map<wns::osi::PDUPtr, rise::TransmissionObjectPtr>::iterator itr = activeTransmissions.find(sdu);
00285     wns::CandI candi;
00286 
00287     candi.I = wns::dynamicCast<rise::UnicastTransmissionObject, rise::TransmissionObject>(itr->second)->getReceiver()->getInterference(itr->second);
00288     candi.C = wns::dynamicCast<rise::UnicastTransmissionObject, rise::TransmissionObject>(itr->second)->getReceiver()->getRxPower(itr->second);
00289 
00290     return candi;
00291 }
00292 
00293 rise::SystemManager*
00294 Station::getSystemManager() const
00295 {
00296     return systemManager;
00297 }
00298 
00299 void
00300 Station::receiveData(wns::osi::PDUPtr sdu, wns::service::phy::power::PowerMeasurementPtr rxPowerMeasurementPtr)
00301 {
00302     //MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::receiveData(rxPower="<< rxPowerMeasurementPtr->getRxPower()<<")");
00303     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::receiveData(): calling handler->onData("<<rxPowerMeasurementPtr->getString()<<")");
00304     //rxPowerMeasurementPtr->setSystemManager(systemManager); // needed to determine sourceNode
00305     handler->onData(sdu, rxPowerMeasurementPtr);
00306 }
00307 
00308 void
00309 Station::measurementUpdate(wns::node::Interface* source, wns::service::phy::power::OFDMAMeasurementPtr rxPowerMeasurementPtr)
00310 {
00311     // source == rxPowerMeasurementPtr->source are the same
00312     assure(source == rxPowerMeasurementPtr->getSourceNode(),"measurement source mismatch");
00313     if (source != NULL)
00314         MESSAGE_SINGLE(NORMAL,logger, "Station::measurementUpdate("<<source->getName()<<")");
00315     //assure(measurementHandler != NULL, "no measurementHandler registered (NULL)");
00316     if (measurementHandler!=NULL) { // only if service was requested
00317         measurementHandler->onMeasurementUpdate(source, rxPowerMeasurementPtr);
00318     } else {
00319         MESSAGE_SINGLE(NORMAL,logger, "Station::measurementUpdate: no measurementHandler !!!");
00320     }
00321 }
00322 
00323 void
00324 Station::onNewRSS(wns::Power rss)
00325 {
00326     if(activeTransmissions.empty())
00327     {
00328         MESSAGE_SINGLE(VERBOSE, logger, "onNewRSS() with rss " << rss);
00329         // Relay the information to the observer
00330         this->rssHandler->onRSSChange(rss);
00331         //this->wns::Subject<CarrierSensing>::forEachObserver(OnCS(rss));
00332     }
00333     else
00334     {
00335         MESSAGE_SINGLE(VERBOSE, logger, "onNewRSS() with rss " << rss << ", but own transmission ongoing");
00336     }
00337 
00338 }
00339 
00340 void
00341 Station::updateRequest()
00342 {
00343     this->receiver->updateRequest();
00344 }
00345 
00346 std::map<wns::node::Interface*, wns::Ratio>
00347 Station::calculateSINRsRx(const std::vector<wns::node::Interface*>& combination,
00348                           wns::Power iInterPlusNoise)
00349 {
00350     // prepare empty container for the result
00351     std::map<wns::node::Interface*, wns::Ratio> returnValue;
00352 
00353     // call the function that calculates signal and interference separately
00354     std::map<wns::node::Interface*, wns::CandI > candis = calculateCandIsRx(combination, iInterPlusNoise);
00355 
00356     // calculate SINRs accordingly
00357     for (std::map<wns::node::Interface*, wns::CandI>::iterator itr = candis.begin();
00358          itr != candis.end();
00359          itr++)
00360     {
00361         returnValue[itr->first] = itr->second.C / itr->second.I;
00362     }
00363 
00364     return returnValue;
00365 }
00366 
00367 std::map<wns::node::Interface*, wns::CandI >
00368 Station::calculateCandIsRx(const std::vector<wns::node::Interface*>& combination,
00369                            wns::Power iInterPlusNoise)
00370 {
00371     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00372     assure( beamformingAntenna , "No Beamforming Antenna present");
00373     assure( iInterPlusNoise.get_mW() > 0, "beam pattern calculation requires positive level of omni-directional interference");
00374 
00375     std::map<rise::Station*, wns::CandI > candis;
00376     std::map<wns::node::Interface*, wns::CandI > returnValue;
00377 
00378     std::vector<rise::Station*> vec = std::for_each(combination.begin(),
00379                                                     combination.end(),
00380                                                     ConvertNode<Station*, std::vector<rise::Station*> >(this)).result;
00381 
00382     candis = beamformingAntenna->calculateCandIsRx(vec, iInterPlusNoise);
00383 
00384     for (std::map<rise::Station*, wns::CandI >::iterator itr = candis.begin();
00385          itr != candis.end();
00386          itr++)
00387     {
00388         assureType(itr->first, Station*);
00389         returnValue[static_cast<Station*>(itr->first)->getNode()] = itr->second;
00390     }
00391 
00392     return returnValue;
00393 }
00394 
00395 std::map<wns::node::Interface*, wns::Ratio>
00396 Station::calculateSINRsTx(const std::map<wns::node::Interface*, wns::Power>& Station2NoisePlusIintercell,
00397                           wns::Power x_friendlyness,
00398                           wns::Power intendedTxPower)
00399 {
00400     std::map<wns::node::Interface*, wns::Ratio> returnValue;
00401 
00402     std::map<wns::node::Interface*, wns::CandI > candis = calculateCandIsTx(Station2NoisePlusIintercell,
00403                                                                             x_friendlyness,
00404                                                                             intendedTxPower);
00405 
00406     for (std::map<wns::node::Interface*, wns::CandI>::const_iterator itr = candis.begin();
00407          itr != candis.end();
00408          itr++)
00409     {
00410         returnValue[itr->first] = itr->second.C / itr->second.I;
00411     }
00412 
00413     return returnValue;
00414 }
00415 
00416 std::map<wns::node::Interface*, wns::CandI >
00417 Station::calculateCandIsTx(const std::map<wns::node::Interface*, wns::Power>& Station2NoisePlusIintercell,
00418                            wns::Power x_friendlyness,
00419                            wns::Power intendedTxPower)
00420 {
00421     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00422     assure( beamformingAntenna , "No Beamforming Antenna present");
00423     assure(x_friendlyness.get_mW() > 0, "friendlyness factor to reduce generated interference (sidelobes) must be > 0");
00424 
00425     std::map<rise::Station*, wns::Power> map;
00426     std::map<rise::Station*, wns::CandI > candis;
00427     std::map<wns::node::Interface*, wns::CandI > returnValue;
00428 
00429     for (std::map<wns::node::Interface*, wns::Power>::const_iterator itr = Station2NoisePlusIintercell.begin();
00430          itr != Station2NoisePlusIintercell.end();
00431          itr++)
00432     {
00433         map[systemManager->getStation(itr->first)] = itr->second;
00434     }
00435 
00436     candis = beamformingAntenna->calculateCandIsTx(map, x_friendlyness, intendedTxPower, eirpLimited);
00437 
00438     for (std::map<rise::Station*, wns::CandI>::iterator itr = candis.begin();
00439          itr != candis.end();
00440          itr++)
00441     {
00442         assureType(itr->first, Station*);
00443         returnValue[static_cast<Station*>(itr->first)->getNode()] = itr->second;
00444     }
00445 
00446     return returnValue;
00447 }
00448 
00449 wns::service::phy::ofdma::PatternPtr
00450 Station::calculateAndSetBeam(wns::node::Interface *id,
00451                              const std::vector<wns::node::Interface*>& undesired,
00452                              wns::Power omniPower)
00453 {
00454     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00455     assure( beamformingAntenna , "No Beamforming Antenna present");
00456     assure( omniPower.get_mW() > 0, "beam pattern calculation requires positive level of omni-directional power");
00457 
00458     std::vector<rise::Station*> vec = std::for_each(undesired.begin(),
00459                                                     undesired.end(),
00460                                                     ConvertNode<Station*, std::vector<rise::Station*> >(this)).result;
00461 
00462     Station* r = systemManager->getStation(id);
00463 
00464     return beamformingAntenna->calculateAndSetBeam(r, vec, omniPower);
00465 }
00466 
00467 double
00468 Station::estimateDoA(wns::node::Interface *id)
00469 {
00470     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00471     assure( beamformingAntenna , "No Beamforming Antenna present");
00472     return( beamformingAntenna->estimateDoA(systemManager->getStation(id)));
00473 }
00474 
00475 void
00476 Station::startTransmission(wns::osi::PDUPtr sdu,
00477                            wns::node::Interface* _recipient,
00478                            int subBand,
00479                            wns::service::phy::ofdma::PatternPtr pattern,
00480                            wns::Power requestedTxPower,
00481                            const wns::service::phy::phymode::PhyModeInterfacePtr phyModePtr)
00482 {
00483     // unicast beamforming transmission with beamforming antenna
00484     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00485     assure( beamformingAntenna , "No Beamforming Antenna present");
00486     assure(_recipient != NULL, "Invalid Recipient");
00487     assure(pattern != wns::service::phy::ofdma::PatternPtr(), "not a valid pattern");
00488     assure(phyModePtr,"phyModePtr==NULL");
00489 
00490     // check the requested txPower (and modify if needed)
00491     wns::Power txPower = powerAdmission->admit(requestedTxPower);
00492 
00493     MESSAGE_BEGIN(NORMAL, logger, m, "new PDU with txPower of ");
00494     m << requestedTxPower.get_dBm();
00495     m << " dBm, \n the current sum Tx power is " << this->getSumPower().get_dBm();
00496     m << " dBm, \n the available total Tx power is " << this->getMaxOutputPower().get_dBm() << "dBm";
00497     MESSAGE_END();
00498 
00499     Station* recipient = systemManager->getStation(_recipient);
00500 
00501     rise::BeamformingTransmissionObjectPtr bfto(new rise::TransmissionObjectBF(transmitter,
00502                                                                                recipient->receiver,
00503                                                                                this->getBFAntenna(),
00504                                                                                sdu,
00505                                                                                requestedTxPower,
00506                                                                                phyModePtr,
00507                                                                                pattern,
00508                                                                                (unsigned long int)(1)));
00509     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::startTransmissions(subBand="<<subBand<<",P="<<txPower<<",M&C="<<*phyModePtr<<") BF");
00510     this->startTransmitting(sdu, bfto, subBand);
00511 
00512     // Write Pattern to output file
00513     MESSAGE_BEGIN(NORMAL, logger, m, "Drawing radiation Pattern for transmission from ");
00514     m << this->getNode()->getName() << " to " << _recipient->getName();
00515     std::string fileName = std::string("patterns/")+this->getNode()->getName()+"_"+_recipient->getName()+".pattern";
00516     this->getBFAntenna()->drawRadiationPattern(fileName, pattern);
00517     MESSAGE_END();
00518 }
00519 
00520 void
00521 Station::startTransmission(wns::osi::PDUPtr sdu,
00522                            wns::node::Interface* _recipient,
00523                            int subBand,
00524                            wns::service::phy::ofdma::PatternPtr pattern,
00525                            wns::Power requestedTxPower,
00526                            int numberOfSpatialStreams)
00527 {
00528     // unicast beamforming transmission with beamforming antenna
00529     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00530     assure( beamformingAntenna , "No Beamforming Antenna present");
00531     assure(_recipient != NULL, "Invalid Recipient");
00532     assure(pattern != wns::service::phy::ofdma::PatternPtr(), "not a valid pattern");
00533 
00534 
00535     // check the requested txPower (and modify if needed)
00536     wns::Power txPower = powerAdmission->admit(requestedTxPower);
00537 
00538     MESSAGE_BEGIN(NORMAL, logger, m, "new PDU with txPower of ");
00539     m << requestedTxPower.get_dBm();
00540     m << " dBm, \n the current sum Tx power is " << this->getSumPower().get_dBm();
00541     m << " dBm, \n the available total Tx power is " << this->getMaxOutputPower().get_dBm() << "dBm";
00542     MESSAGE_END();
00543 
00544     Station* recipient = systemManager->getStation(_recipient);
00545 
00546     rise::BeamformingTransmissionObjectPtr bfto(new rise::TransmissionObjectBF(transmitter,
00547                                                                                recipient->receiver,
00548                                                                                this->getBFAntenna(),
00549                                                                                sdu,
00550                                                                                requestedTxPower,
00551                                                                                pattern,
00552                                                                                (unsigned long int)(1),
00553                                                                                numberOfSpatialStreams));
00554     MESSAGE_SINGLE(NORMAL, logger, "ofdmaphy::Station::startTransmissions(subBand="<<subBand<<",P="<<txPower<<",numSS="<<numberOfSpatialStreams<<") BF");
00555     this->startTransmitting(sdu, bfto, subBand);
00556 
00557     // Write Pattern to output file
00558     MESSAGE_BEGIN(NORMAL, logger, m, "Drawing radiation Pattern for transmission from ");
00559     m << this->getNode()->getName() << " to " << _recipient->getName();
00560     std::string fileName = std::string("patterns/")+this->getNode()->getName()+"_"+_recipient->getName()+".pattern";
00561     this->getBFAntenna()->drawRadiationPattern(fileName, pattern);
00562     MESSAGE_END();
00563 }
00564 
00565 bool
00566 Station::isReceiving() const
00567 {
00568     return receiver->isReceiving();
00569 }
00570 
00571 std::string
00572 Station::printActiveTransmissions() const
00573 {
00574     return receiver->printActiveTransmissions();
00575 }
00576 
00577 void
00578 Station::setRxTune(const wns::service::phy::ofdma::Tune& rxTune)
00579 {
00580     tuneRx = rxTune;
00581     receiver->tune(tuneRx.frequency,
00582                    tuneRx.bandwidth,
00583                    tuneRx.numberOfSubCarrier);
00584 }
00585 
00586 void
00587 Station::setTxTune(const wns::service::phy::ofdma::Tune& txTune)
00588 {
00589     tuneTx = txTune;
00590     transmitter->tune(tuneTx.frequency,
00591                       tuneTx.bandwidth,
00592                       tuneTx.numberOfSubCarrier);
00593 }
00594 
00595 void
00596 Station::setTxRxSwap(bool reverse)
00597 {
00598     if (tuneRx == tuneTx)
00599     {
00600         reverseState = reverse;
00601         return; // nothing to swap
00602     }
00603 
00604     if (reverse)
00605     {
00606         if (reverseState)
00607         {
00608             // do nothing
00609         }
00610         else
00611         {
00612             // reverse current setup
00613             wns::service::phy::ofdma::Tune oldRxTune = this->getRxTune();
00614 
00615             this->setRxTune( this->getTxTune() );
00616             this->setTxTune( oldRxTune );
00617         }
00618     }
00619     else
00620     {
00621         if (reverseState)
00622         {
00623             // revert back
00624             // reverse current setup
00625             wns::service::phy::ofdma::Tune oldRxTune = this->getRxTune();
00626 
00627             this->setRxTune( this->getTxTune() );
00628             this->setTxTune( oldRxTune );
00629         }
00630         else
00631         {
00632             // do nothing, stay reverse
00633         }
00634     }
00635 
00636     // remember the state
00637     reverseState = reverse;
00638 
00639     MESSAGE_BEGIN(NORMAL, logger, m, "ofdmaphy::setTxRxSwap(reverse="<< (reverse ? "true" : "false" ) << "): ");
00640     m << "fTx="<<tuneTx.frequency<<", fRx="<<tuneRx.frequency;
00641     MESSAGE_END();
00642 }
00643 
00644 void
00645 Station::setCurrentReceivePatterns(std::map<wns::node::Interface*, wns::service::phy::ofdma::PatternPtr> _receivePatterns)
00646 {
00647     // if the source station of the transmission  is not found
00648     // in _receivePatterns, the receiver will use instead of
00649     // the beamforming antenna the non-beamforming antenna for reception
00650 
00651     // @todo make known to the outside world whether we are capable of
00652     // beamforming or not
00653 
00654     // If someone tries to clear our pattern cache while we are not capable of
00655     // beamforming anyway, we just ignore it. All other functions where
00656     // beamforming would be actively required will raise an exception anyway in
00657     // this case
00658     if ( supportsBeamforming == false and _receivePatterns.empty())
00659         return;
00660 
00661     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00662     assure( beamformingAntenna , "No Beamforming Antenna present");
00663     receiver->setCurrentReceivePatterns(_receivePatterns);
00664 }
00665 
00666 void
00667 Station::insertReceivePattern(wns::node::Interface* _node, wns::service::phy::ofdma::PatternPtr _pattern)
00668 {
00669     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00670     assure( beamformingAntenna , "No Beamforming Antenna present");
00671     receiver->insertReceivePattern(_node, _pattern);
00672 }
00673 
00674 void
00675 Station::removeReceivePattern(wns::node::Interface* _node)
00676 {
00677     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00678     assure( beamformingAntenna , "No Beamforming Antenna present");
00679     receiver->removeReceivePattern(_node);
00680 }
00681 
00682 void
00683 Station::setTxPowerForStation(wns::node::Interface* stack, wns::Power _txPower)
00684 {
00685     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00686     assure( beamformingAntenna , "No Beamforming Antenna present");
00687     beamformingAntenna->setTxPowerForStation(systemManager->getStation(stack), _txPower);
00688 }
00689 
00690 void
00691 Station::setPowerReceivedForStation(wns::node::Interface* stack, wns::Power _rxPower)
00692 {
00693     assure( supportsBeamforming, "Beamforming not supported in current configuration" );
00694     assure( beamformingAntenna , "No Beamforming Antenna present");
00695     beamformingAntenna->setPowerReceivedForStation(systemManager->getStation(stack), _rxPower);
00696 }
00697 
00698 
00699 void
00700 Station::startReceiving(){
00701 // must be implemented since it is abstract
00702 }
00703 
00704 void
00705 Station::stopReceiving(){
00706 // must be implemented since it is abstract
00707 }
00708 
00709 void
00710 Station::enableReception()
00711 {
00712     isReceptionEnabledFlag = true;
00713 }
00714 
00715 void
00716 Station::disableReception()
00717 {
00718     isReceptionEnabledFlag = false;
00719 }
00720 
00721 bool
00722 Station::isReceptionEnabled() const
00723 {
00724     return isReceptionEnabledFlag;
00725 }
00726 
00727 wns::node::Interface*
00728 Station::getNode()
00729 {
00730     return component->getNode();
00731 }
00732 
00733 wns::Power
00734 Station::getSumPower() const
00735 {
00736     wns::Power sumPower = wns::Power().from_mW(0.0);
00737     for ( std::map<wns::osi::PDUPtr, rise::TransmissionObjectPtr>::const_iterator itr = activeTransmissions.begin();
00738           itr!= activeTransmissions.end();
00739           itr++)
00740     {
00741         sumPower += itr->second->getTxPower();
00742     }
00743     MESSAGE_SINGLE(NORMAL,logger,"Current Sum Power is: "<<sumPower);
00744     return sumPower;
00745 }
00746 
00747 wns::Power
00748 Station::admit(const wns::Power& requestedPower) const
00749 {
00750     wns::Power request = requestedPower;
00751     wns::Power currentPower = this->getSumPower();
00752     wns::Power maxPower = this->getMaxOutputPower();
00753 
00754 //  // Check per-subband limitations
00755 //  if (request > maxTxPowerPerSubband)
00756 //  {
00757 //      MESSAGE_SINGLE(NORMAL, logger, "Cut requested power of "<<request<<" to max Power per subband of "<<maxTxPowerPerSubband);
00758 //      // Cut to meet limit
00759 //      request = maxTxPowerPerSubband;
00760 //  }
00761 
00762     // Check overall limitations
00763     if (currentPower + request <= maxPower)
00764     {
00765         MESSAGE_SINGLE(NORMAL, logger, "Admitting transmission with txPower: "<<request);
00766         return request;
00767     }
00768 
00769     // Cut to meet limit
00770     wns::Power cutPower = maxPower-currentPower;
00771 
00772     MESSAGE_SINGLE(NORMAL, logger, "Cut requested power of "<<request<<" to "<<cutPower<<" due to Overall Power constraints");
00773     MESSAGE_SINGLE(NORMAL, logger, "Admitting transmission with txPower: "<<cutPower);
00774 
00775     assure(cutPower != wns::Power(), "You may not initiate a transmission with 0 mW");
00776     return cutPower;
00777 }
00778 
00779 

Generated on Sat May 26 03:32:16 2012 for openWNS by  doxygen 1.5.5