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