User Manual, Developers Guide and API Documentation

RTSCTSwithFLA.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiFiMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2007
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 16, D-52074 Aachen, Germany
00009  * phone: ++49-241-80-27910,
00010  * fax: ++49-241-80-22242
00011  * email: info@openwns.org
00012  * www: http://www.openwns.org
00013  * _____________________________________________________________________________
00014  *
00015  * openWNS is free software; you can redistribute it and/or modify it under the
00016  * terms of the GNU Lesser General Public License version 2 as published by the
00017  * Free Software Foundation;
00018  *
00019  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00020  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00021  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00022  * details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026  *
00027  ******************************************************************************/
00028 
00029 #include <WIFIMAC/draftn/RTSCTSwithFLA.hpp>
00030 #include <WIFIMAC/convergence/PhyMode.hpp>
00031 #include <DLL/Layer2.hpp>
00032 #include <WNS/probe/bus/utils.hpp>
00033 
00034 using namespace wifimac::draftn;
00035 
00036 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00037     wifimac::draftn::RTSCTSwithFLA,
00038     wns::ldk::FunctionalUnit,
00039     "wifimac.draftn.RTSCTSwithFLA",
00040     wns::ldk::FUNConfigCreator);
00041 
00042 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00043     wifimac::draftn::RTSCTSwithFLA,
00044     wns::ldk::probe::Probe,
00045     "wifimac.draftn.RTSCTSwithFLA",
00046     wns::ldk::FUNConfigCreator);
00047 
00048 
00049 RTSCTSwithFLA::RTSCTSwithFLA(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_) :
00050     wns::ldk::fu::Plain<RTSCTSwithFLA, RTSCTSwithFLACommand>(fun),
00051 
00052     phyUserName(config_.get<std::string>("phyUserName")),
00053     managerName(config_.get<std::string>("managerName")),
00054     protocolCalculatorName(config_.get<std::string>("protocolCalculatorName")),
00055     arqName(config_.get<std::string>("arqName")),
00056     navName(config_.get<std::string>("navName")),
00057     rxsName(config_.get<std::string>("rxStartName")),
00058     txStartEndName(config_.get<std::string>("txStartEndName")),
00059     sinrMIBServiceName(config_.get<std::string>("sinrMIBServiceName")),
00060     raName(config_.get<std::string>("raName")),
00061 
00062     sifsDuration(config_.get<wns::simulator::Time>("myConfig.sifsDuration")),
00063     maximumACKDuration(config_.get<wns::simulator::Time>("myConfig.maximumACKDuration")),
00064     maximumCTSDuration(config_.get<wns::simulator::Time>("myConfig.maximumCTSDuration")),
00065     preambleProcessingDelay(config_.get<wns::simulator::Time>("myConfig.preambleProcessingDelay")),
00066     ctsTimeout(config_.get<wns::simulator::Time>("myConfig.ctsTimeout")),
00067     rtsctsPhyMode(config_.getView("myConfig.rtsctsPhyMode")),
00068     rtsBits(config_.get<Bit>("myConfig.rtsBits")),
00069     ctsBits(config_.get<Bit>("myConfig.ctsBits")),
00070     rtsctsThreshold(config_.get<Bit>("myConfig.rtsctsThreshold")),
00071     rtsctsOnTxopData(config_.get<bool>("myConfig.rtsctsOnTxopData")),
00072 
00073     estimatedValidity(100e-6),//config_.get<wns::simulator::Time>("myConfig.estimatedValidity")),
00074     nav(false),
00075     navSetter(),
00076     logger(config_.get("logger")),
00077 
00078     pendingRTS(),
00079     pendingCTS(),
00080     pendingMPDU(),
00081 
00082     state(idle)
00083 {
00084     MESSAGE_SINGLE(NORMAL, this->logger, "created, threshold: " << rtsctsThreshold << "b");
00085     sinrMIB = NULL;
00086     protocolCalculator = NULL;
00087     friends.phyUser = NULL;
00088     friends.manager = NULL;
00089     friends.arq = NULL;
00090     friends.ra = NULL;
00091 
00092     this->ctsPrepared = 0;
00093     this->lastTimeout = 0;
00094 
00095     // read the local IDs from the config
00096     wns::probe::bus::ContextProviderCollection localContext(&fun->getLayer()->getContextProviderCollection());
00097     for (int ii = 0; ii<config_.len("localIDs.keys()"); ++ii)
00098     {
00099         std::string key = config_.get<std::string>("localIDs.keys()",ii);
00100         unsigned long int value  = config_.get<unsigned long int>("localIDs.values()",ii);
00101         localContext.addProvider(wns::probe::bus::contextprovider::Constant(key, value));
00102         MESSAGE_SINGLE(VERBOSE, logger, "Using Local IDName '"<<key<<"' with value: "<<value);
00103     }
00104     rtsSuccessProbe = wns::probe::bus::collector(localContext, config_, "rtsSuccessProbeName");
00105 }
00106 
00107 
00108 RTSCTSwithFLA::~RTSCTSwithFLA()
00109 {
00110 }
00111 
00112 void RTSCTSwithFLA::onFUNCreated()
00113 {
00114     MESSAGE_SINGLE(NORMAL, this->logger, "onFUNCreated() started");
00115 
00116     friends.phyUser = getFUN()->findFriend<wifimac::convergence::PhyUser*>(phyUserName);
00117     friends.manager = getFUN()->findFriend<wifimac::lowerMAC::Manager*>(managerName);
00118     friends.arq = getFUN()->findFriend<wifimac::lowerMAC::ITransmissionCounter*>(arqName);
00119     friends.ra = getFUN()->findFriend<wifimac::lowerMAC::RateAdaptation*>(raName);
00120 
00121     // Observe NAV
00122     this->wns::Observer<INetworkAllocationVector>::startObserving
00123         (getFUN()->findFriend<wifimac::convergence::NAVNotification*>(navName));
00124 
00125     // Observe rxStartEnd
00126     this->wns::Observer<wifimac::convergence::IRxStartEnd>::startObserving
00127         (getFUN()->findFriend<wifimac::convergence::RxStartEndNotification*>(rxsName));
00128 
00129     // Observe txStartEnd
00130     this->wns::Observer<wifimac::convergence::ITxStartEnd>::startObserving
00131         (getFUN()->findFriend<wifimac::convergence::TxStartEndNotification*>(txStartEndName));
00132 
00133     protocolCalculator = getFUN()->getLayer<dll::ILayer2*>()->getManagementService<wifimac::management::ProtocolCalculator>(protocolCalculatorName);
00134     sinrMIB = getFUN()->getLayer<dll::Layer2*>()->getManagementService<wifimac::draftn::SINRwithMIMOInformationBase>(sinrMIBServiceName);
00135 }
00136 
00137 void
00138 RTSCTSwithFLA::processIncoming(const wns::ldk::CompoundPtr& compound)
00139 {
00140     if(getFUN()->getProxy()->commandIsActivated(compound->getCommandPool(), this))
00141     {
00142         if(getCommand(compound->getCommandPool())->peer.isRTS)
00143         {
00144             if(getCommand(compound->getCommandPool())->peer.isFLARequest)
00145             {
00146                 wns::Ratio sinr = friends.phyUser->getCommand
00147                     (compound->getCommandPool())->getCIRwithoutMIMO();
00148                 sinrMIB->putMeasurement
00149                     (friends.manager->getTransmitterAddress(compound->getCommandPool()), sinr, estimatedValidity);
00150                 MESSAGE_SINGLE(NORMAL, this->logger, "Request from " <<  friends.manager->getTransmitterAddress(compound->getCommandPool()) << ", measured SINR " << sinr);
00151             }
00152 
00153             if(nav)
00154             {
00155                 if(friends.manager->getTransmitterAddress(compound->getCommandPool()) == navSetter)
00156                 {
00157                     MESSAGE_BEGIN(NORMAL, this->logger, m, "Incoming RTS from ");
00158                     m << friends.manager->getTransmitterAddress(compound->getCommandPool());
00159                     m << ", nav busy from " << navSetter;
00160                     m << " -> reply with CTS";
00161                     MESSAGE_END();
00162 
00163                     assure(this->pendingCTS == wns::ldk::CompoundPtr(),
00164                            "Old pending CTS not transmitted");
00165                     this->pendingCTS = this->prepareCTS(compound);
00166                 }
00167                 else
00168                 {
00169                     MESSAGE_BEGIN(NORMAL, this->logger, m, "Incoming RTS from ");
00170                     m << friends.manager->getTransmitterAddress(compound->getCommandPool());
00171                     m << ", nav busy from " << navSetter;
00172                     m << " -> Drop";
00173                     MESSAGE_END();
00174                 }
00175             } // nav
00176             else
00177             {
00178                 MESSAGE_SINGLE(NORMAL, this->logger, "Incoming RTS, nav idle -> reply with CTS");
00179 
00180                 assure(this->pendingCTS == wns::ldk::CompoundPtr(),
00181                        "Old pending CTS not transmitted");
00182                 this->pendingCTS = this->prepareCTS(compound);
00183             } // not nav
00184         } // is RTS
00185         else
00186         {
00187             if(getCommand(compound->getCommandPool())->peer.isFLAResponse)
00188             {
00189                 MESSAGE_BEGIN(NORMAL, this->logger, m, "Reply from ");
00190                 m << friends.manager->getTransmitterAddress(compound->getCommandPool());
00191                 m << ", with SINR ";
00192                 m << getCommand(compound->getCommandPool())->peer.cqi;
00193                 MESSAGE_END();
00194 
00195                 // put peer SINR measurement
00196                 sinrMIB->putPeerSINR(friends.manager->getTransmitterAddress(compound->getCommandPool()),
00197                                      getCommand(compound->getCommandPool())->peer.cqi,
00198                                      estimatedValidity);
00199 
00200                 // put peer mimo factors measurement
00201                 for(std::vector< std::vector<wns::Ratio> >::iterator it = getCommand(compound->getCommandPool())->peer.mimoFactors.begin();
00202                     it != getCommand(compound->getCommandPool())->peer.mimoFactors.end();
00203                     ++it)
00204                 {
00205                     sinrMIB->putPeerFactor(friends.manager->getTransmitterAddress(compound->getCommandPool()),
00206                                            *it);
00207 #ifndef WNS_NO_LOGGING
00208                     MESSAGE_BEGIN(NORMAL, logger, m, "Contains peer factors");
00209                     for(std::vector<wns::Ratio>::iterator itFactors = it->begin();
00210                         itFactors != it->end();
00211                         ++itFactors)
00212                     {
00213                         m << " " << *itFactors;
00214                     }
00215                     MESSAGE_END();
00216 #endif
00217                 }
00218 
00219                 wifimac::convergence::PhyMode pm = friends.ra->getPhyMode(friends.manager->getTransmitterAddress(compound->getCommandPool()),1);
00220                 friends.manager->setPhyMode(this->pendingMPDU->getCommandPool(), pm);
00221             }
00222 
00223             // received CTS on transmitted RTS --> successfully reserved the channel
00224             // for data
00225             assure(this->pendingMPDU, "Received CTS, but no pending MPDU");
00226             if(state == idle)
00227             {
00228                 MESSAGE_BEGIN(NORMAL, this->logger, m, "received CTS although state is idle, now: ");
00229                 m << wns::simulator::getEventScheduler()->getTime();
00230                 m << ", last timeout: " << this->lastTimeout << "\n";
00231                 if(state == transmitRTS)
00232                     m << "state is transmitRTS\n";
00233                 if(state == waitForCTS)
00234                     m << "state is waitForCTS\n";
00235                 if(state == receiveCTS)
00236                     m << "state is receiveCTS\n";
00237                 MESSAGE_END();
00238             }
00239             assure(state == receptionFinished or state == receiveCTS,
00240                    "received CTS although state is idle, now: " << wns::simulator::getEventScheduler()->getTime() << ", last timeout: " << this->lastTimeout);
00241 
00242             if(friends.manager->getTransmitterAddress(compound->getCommandPool())
00243                != friends.manager->getReceiverAddress(this->pendingMPDU->getCommandPool()))
00244             {
00245                 MESSAGE_SINGLE(NORMAL, this->logger,
00246                                "Incoming CTS does not match the receiver's address on the pending MPDU -> do nothing");
00247             }
00248             else
00249             {
00250                 assure(this->pendingMPDU, "Received CTS, but no pending MPDU");
00251                 MESSAGE_SINGLE(NORMAL, this->logger,
00252                                "Incoming awaited CTS -> send data");
00253                 rtsSuccessProbe->put(this->pendingMPDU, 1);
00254                 state = idle;
00255                 if(this->hasTimeoutSet())
00256                 {
00257                     this->cancelTimeout();
00258                 }
00259             }
00260         } // is not RTS
00261     } // is activated
00262     else
00263     {
00264         // deliver frame
00265         MESSAGE_SINGLE(NORMAL, this->logger, "Received frame -> deliver");
00266         getDeliverer()->getAcceptor(compound)->onData(compound);
00267     } // no RTSCTS command
00268 }
00269 
00270 void
00271 RTSCTSwithFLA::processOutgoing(const wns::ldk::CompoundPtr& compound)
00272 {
00273     assure(this->pendingMPDU == wns::ldk::CompoundPtr(),
00274            "Cannot have two MPDUs");
00275     assure(this->pendingRTS == wns::ldk::CompoundPtr(),
00276            "Cannot have two RTSs");
00277 
00278     this->pendingMPDU = compound;
00279 
00280     switch(friends.manager->getFrameType(compound->getCommandPool()))
00281     {
00282     case DATA_TXOP:
00283         if(not this->rtsctsOnTxopData)
00284         {
00285             break;
00286         }
00287         // fall through to DATA if RTS/CTS during TXOP is activ
00288     case DATA:
00289         if(compound->getLengthInBits() < this->rtsctsThreshold)
00290         {
00291             MESSAGE_SINGLE(NORMAL, this->logger,
00292                            "Outgoing DATA with size " << compound->getLengthInBits() << ", below threshold");
00293         }
00294         else
00295         {
00296             MESSAGE_SINGLE(NORMAL, this->logger,
00297                            "Outgoing DATA with size " << compound->getLengthInBits() << "-> Save and send RTS");
00298             this->pendingRTS = this->prepareRTS(this->pendingMPDU);
00299 
00300             // RTS/CTS initializes mini-TXOP for compound, it can be send
00301             // directly after SIFS
00302             friends.manager->setFrameType(this->pendingMPDU->getCommandPool(), DATA_TXOP);
00303         }
00304         break;
00305     default:
00306         throw wns::Exception("Unknown frame type");
00307         break;
00308     }
00309 }
00310 
00311 const wns::ldk::CompoundPtr
00312 RTSCTSwithFLA::hasSomethingToSend() const
00313 {
00314 
00315     if(this->pendingCTS)
00316     {
00317         return(this->pendingCTS);
00318     }
00319     if(this->pendingRTS)
00320     {
00321         return(this->pendingRTS);
00322     }
00323     if(state == idle)
00324     {
00325         return(this->pendingMPDU);
00326     }
00327     return wns::ldk::CompoundPtr();
00328 
00329 }
00330 
00331 wns::ldk::CompoundPtr
00332 RTSCTSwithFLA::getSomethingToSend()
00333 {
00334     assure(this->hasSomethingToSend(), "Called getSomethingToSend without pending compound");
00335 
00336     wns::ldk::CompoundPtr it;
00337     if(this->pendingCTS)
00338     {
00339         it = this->pendingCTS;
00340         assure(this->ctsPrepared == wns::simulator::getEventScheduler()->getTime(),
00341                "ctsPrepared is " << this->ctsPrepared << ", but time is " <<  wns::simulator::getEventScheduler()->getTime());
00342         this->pendingCTS = wns::ldk::CompoundPtr();
00343         MESSAGE_SINGLE(NORMAL, this->logger, "Sending CTS frame to "<< friends.manager->getReceiverAddress(it->getCommandPool()));
00344         return(it);
00345     }
00346     if(this->pendingRTS)
00347     {
00348         it = this->pendingRTS;
00349         this->pendingRTS = wns::ldk::CompoundPtr();
00350         state = transmitRTS;
00351         MESSAGE_SINGLE(NORMAL, this->logger, "Send RTS frame to "<< friends.manager->getReceiverAddress(it->getCommandPool()));
00352         return(it);
00353     }
00354 
00355     it = this->pendingMPDU;
00356     this->pendingMPDU = wns::ldk::CompoundPtr();
00357     MESSAGE_SINGLE(NORMAL, this->logger, "Send MPDU to "<< friends.manager->getReceiverAddress(it->getCommandPool()));
00358     return(it);
00359 }
00360 
00361 bool
00362 RTSCTSwithFLA::hasCapacity() const
00363 {
00364     return(this->pendingMPDU == wns::ldk::CompoundPtr());
00365 }
00366 
00367 void
00368 RTSCTSwithFLA::onTxStart(const wns::ldk::CompoundPtr& /*compound*/)
00369 {
00370 
00371 }
00372 
00373 void
00374 RTSCTSwithFLA::onTxEnd(const wns::ldk::CompoundPtr& compound)
00375 {
00376     if(this->pendingMPDU and
00377        (getFUN()->getProxy()->commandIsActivated(compound->getCommandPool(), this)) and
00378        (getCommand(compound->getCommandPool())->peer.isRTS) and
00379        (state == transmitRTS))
00380     {
00381         state = waitForCTS;
00382         setNewTimeout(ctsTimeout);
00383         MESSAGE_BEGIN(NORMAL, logger, m, "RTS to ");
00384         m << friends.manager->getReceiverAddress(compound->getCommandPool());
00385         m << " is sent, waiting for CTS for ";
00386         m << ctsTimeout;
00387         MESSAGE_END();
00388     }
00389 }
00390 
00391 void
00392 RTSCTSwithFLA::onRxStart(wns::simulator::Time /*expRxTime*/)
00393 {
00394     if(state == waitForCTS)
00395     {
00396         assure(this->hasTimeoutSet(), "state waitForCTS but no timeout set?");
00397         assure(this->pendingMPDU, "state waitForCTS but no pendingMPDU?");
00398         //cancelTimeout();
00399         MESSAGE_SINGLE(NORMAL, logger,
00400                        "got rxStartIndication, cancel timeout");
00401         state = receiveCTS;
00402     }
00403 }
00404 
00405 void
00406 RTSCTSwithFLA::onRxEnd()
00407 {
00408     if(state == receiveCTS)
00409     {
00410         assure(this->pendingMPDU, "state receiveCTS but no pendingMPDU?");
00411         MESSAGE_SINGLE(NORMAL, logger,
00412                        "onRxEnd and waiting for CTS -> set short timeout");
00413         state = receptionFinished;
00414 
00415         // wait some time for the delivery
00416         setNewTimeout(10e-9);
00417     }
00418 }
00419 
00420 void
00421 RTSCTSwithFLA::onRxError()
00422 {
00423     if(state == receiveCTS)
00424     {
00425         assure(this->pendingMPDU, "state waitForCTS/receiveCTS but no pendingMPDU?");
00426         MESSAGE_SINGLE(NORMAL, logger,
00427                        "onRxError and waiting for CTS -> failure!");
00428         state = waitForCTS;
00429 
00430         if(not hasTimeoutSet())
00431         {
00432             // waiting period is over
00433             this->onTimeout();
00434         }
00435     }
00436 }
00437 
00438 void RTSCTSwithFLA::onNAVBusy(const wns::service::dll::UnicastAddress setter)
00439 {
00440     nav = true;
00441     navSetter = setter;
00442     MESSAGE_SINGLE(VERBOSE, logger, "onNAVBusy from " << navSetter);
00443 }
00444 
00445 void RTSCTSwithFLA::onNAVIdle()
00446 {
00447     nav = false;
00448     MESSAGE_SINGLE(VERBOSE, logger, "onNAVIdle");
00449 }
00450 
00451 void
00452 RTSCTSwithFLA::onTimeout()
00453 {
00454     if(state == receiveCTS)
00455     {
00456         MESSAGE_SINGLE(NORMAL, this->logger, "Started reception during wait for CTS -> wait for delivery");
00457         return;
00458     }
00459     assure(state != idle, "onTimeout although state is idle");
00460 
00461     // reception of cts has failed --> frame has failed
00462     MESSAGE_SINGLE(NORMAL, this->logger, "No CTS received -> transmission has failed");
00463 
00464     rtsSuccessProbe->put(this->pendingMPDU, 0);
00465 
00466     // re-convert MPDU type from DATA_TXOP to DATA
00467     friends.manager->setFrameType(this->pendingMPDU->getCommandPool(), DATA);
00468     friends.arq->onTransmissionHasFailed(this->pendingMPDU);
00469 
00470     this->pendingMPDU = wns::ldk::CompoundPtr();
00471     state = idle;
00472 
00473     this->lastTimeout = wns::simulator::getEventScheduler()->getTime();
00474 
00475     this->tryToSend();
00476 }
00477 
00478 wns::ldk::CompoundPtr
00479 RTSCTSwithFLA::prepareRTS(const wns::ldk::CompoundPtr& mpdu)
00480 {
00481     // Calculate duration of the mpdu for NAV setting
00482 
00483     wns::simulator::Time duration =
00484         protocolCalculator->getDuration()->MPDU_PPDU(mpdu->getLengthInBits(),
00485                                                      friends.manager->getPhyMode(mpdu->getCommandPool()));
00486     wns::service::dll::UnicastAddress receiver = friends.manager->getReceiverAddress(mpdu->getCommandPool());
00487 
00488     wns::simulator::Time nav = sifsDuration
00489         + maximumCTSDuration
00490         + sifsDuration;
00491 
00492     wns::ldk::CompoundPtr rts =
00493         friends.manager->createCompound(friends.manager->getTransmitterAddress(mpdu->getCommandPool()),   // tx address
00494                                         receiver,                                                         // rx address
00495                                         friends.manager->getFrameType(mpdu->getCommandPool()),            // frame type
00496                                         nav,               // NAV
00497                                         ctsTimeout);  // requires direct reply after timeout
00498 
00499     wns::ldk::CommandPool* rtsCP = rts->getCommandPool();
00500     friends.manager->setPhyMode(rtsCP, rtsctsPhyMode);
00501     RTSCTSwithFLACommand* rtsctsC = this->activateCommand(rtsCP);
00502     rtsctsC->peer.isRTS = true;
00503 
00504     /* set the transmission counter to the same value as the mpdu */
00505     friends.arq->copyTransmissionCounter(mpdu, rts);
00506 
00507     MESSAGE_BEGIN(NORMAL, this->logger, m, "Prepare RTS frame + FLA request");
00508     m << " to " << friends.manager->getReceiverAddress(rtsCP);
00509     m << " with NAV " << nav;
00510     MESSAGE_END();
00511 
00512     rtsctsC->peer.isFLARequest = true;
00513     rtsctsC->peer.isFLAResponse = false;
00514     rtsctsC->magic.frameSize = mpdu->getLengthInBits();
00515 
00516     return(rts);
00517 }
00518 
00519 wns::ldk::CompoundPtr
00520 RTSCTSwithFLA::prepareCTS(const wns::ldk::CompoundPtr& rts)
00521 {
00522     wns::ldk::CommandPool* rtsCP = rts->getCommandPool();
00523     wns::service::dll::UnicastAddress peer = friends.manager->getTransmitterAddress(rtsCP);
00524 
00525     // Simulate the RA process at the transmitter: First, put the measured SINR
00526     // as the (faked) peer SINR
00527     sinrMIB->putFakePeerSINR(peer, sinrMIB->getMeasuredSINR(peer));
00528     sinrMIB->putFakePeerMIMOFactors(peer, sinrMIB->getAllMeasuredFactors(peer));
00529 
00530     // then, the RA uses the (faked) peer SINR to compute the phyMode
00531     wifimac::convergence::PhyMode pm = friends.ra->getPhyMode(peer, 1);
00532 
00533     // finaly, this allows for computing the correct NAV
00534     wns::simulator::Time nav = sifsDuration
00535         + protocolCalculator->getDuration()->MPDU_PPDU(
00536             getCommand(rts->getCommandPool())->magic.frameSize, pm)
00537         + sifsDuration
00538         + maximumACKDuration;
00539 
00540     wns::ldk::CompoundPtr cts = friends.manager->createCompound(friends.manager->getReceiverAddress(rtsCP),
00541                                                                 peer,
00542                                                                 ACK,
00543                                                                 nav,
00544                                                                 sifsDuration + preambleProcessingDelay);
00545     friends.manager->setPhyMode(cts->getCommandPool(), rtsctsPhyMode);
00546     RTSCTSwithFLACommand* rtsctsC = this->activateCommand(cts->getCommandPool());
00547     rtsctsC->peer.isRTS = false;
00548 
00549     MESSAGE_BEGIN(NORMAL, this->logger, m, "Prepare CTS frame");
00550     m << " to " << friends.manager->getTransmitterAddress(rtsCP);
00551     m << " with NAV " << nav;
00552     MESSAGE_END();
00553 
00554     this->ctsPrepared = wns::simulator::getEventScheduler()->getTime();
00555 
00556     // Add measurements as reply
00557     if(sinrMIB->knowsMeasuredSINR(peer))
00558     {
00559         rtsctsC->peer.isFLARequest = false;
00560         rtsctsC->peer.isFLAResponse = true;
00561         rtsctsC->peer.cqi = sinrMIB->getMeasuredSINR(peer);
00562 
00563         for(unsigned int numSS = 1; numSS <= friends.manager->getNumAntennas(); ++numSS)
00564         {
00565             if(sinrMIB->knowsMeasuredFactor(peer, numSS))
00566             {
00567                 rtsctsC->peer.mimoFactors.push_back(sinrMIB->getMeasuredFactor(peer, numSS));
00568             }
00569         }
00570 
00571 #ifndef WNS_NO_LOGGING
00572         MESSAGE_BEGIN(NORMAL, this->logger, m, "Outgoing CTS/FLA response to " << peer);
00573         m << ", piggyback measured SINR " << rtsctsC->peer.cqi;
00574         m << ", pF:";
00575         for(unsigned int numSS = 1; numSS <= friends.manager->getNumAntennas(); ++numSS)
00576         {
00577             m << "(";
00578             if(sinrMIB->knowsMeasuredFactor(peer, numSS))
00579             {
00580                 std::vector<wns::Ratio> pF = sinrMIB->getMeasuredFactor(peer, numSS);
00581                 for(std::vector<wns::Ratio>::iterator it = pF.begin();
00582                     it != pF.end();
00583                     ++it)
00584                 {
00585                     m << " " << *it;
00586                 }
00587             }
00588             m << ")";
00589         }
00590         MESSAGE_END();
00591 #endif
00592     }
00593     else
00594     {
00595         MESSAGE_SINGLE(NORMAL, this->logger, "FLA response to: " << peer << ", but SINR is not known!");
00596     }
00597     return(cts);
00598 }
00599 
00600 void
00601 RTSCTSwithFLA::calculateSizes(const wns::ldk::CommandPool* commandPool, Bit& commandPoolSize, Bit& dataSize) const
00602 {
00603     if(getFUN()->getProxy()->commandIsActivated(commandPool, this))
00604     {
00605         if(getCommand(commandPool)->peer.isRTS)
00606         {
00607             commandPoolSize = this->rtsBits;
00608             dataSize = 0;
00609             MESSAGE_SINGLE(VERBOSE, this->logger, "Calculate size for RTS: " << rtsBits);
00610         }
00611         else
00612         {
00613             commandPoolSize = this->ctsBits;
00614             dataSize = 0;
00615             MESSAGE_SINGLE(VERBOSE, this->logger, "Calculate size for CTS: " << ctsBits);
00616         }
00617     }
00618     else
00619     {
00620         getFUN()->getProxy()->calculateSizes(commandPool, commandPoolSize, dataSize, this);
00621     }
00622 }
00623 

Generated on Fri May 25 03:32:09 2012 for openWNS by  doxygen 1.5.5