User Manual, Developers Guide and API Documentation

DRPScheduler.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiMeMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2011
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 5, 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 <WIMEMAC/drp/DRPScheduler.hpp>
00030 
00031 
00032 STATIC_FACTORY_REGISTER_WITH_CREATOR(
00033     wimemac::drp::DRPScheduler,
00034     wns::ldk::FunctionalUnit,
00035     "wimemac.drp.DRPScheduler",
00036     wns::ldk::FUNConfigCreator );
00037 
00038 using namespace wimemac::drp;
00039 
00040 DRPScheduler::DRPScheduler(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config_ ) :
00041         config(config_),
00042         wns::ldk::fu::Plain<DRPScheduler, DRPSchedulerCommand>(fun),
00043         managerName(config_.get<std::string>("managerName")),
00044         dcfName(config_.get<std::string>("dcfName")),
00045         txopName(config_.get<std::string>("txopName")),
00046         beaconBuilderName(config_.get<std::string>("beaconBuilderName")),
00047         maxPER(config_.get<double>("maxPER")),
00048         pcaPortionProbe(new wns::probe::bus::ContextCollector(wns::probe::bus::ContextProviderCollection(&fun->getLayer()->getContextProviderCollection()),"wimemac.drpscheduler.pcaPortion")),
00049         patternPEROffset(config_.get<double>("patternPEROffset")),
00050         isDroppingAfterRetr(config_.get<int>("isDroppingAfterRetr")),
00051         perMIBServiceName(config.get<std::string>("perMIBServiceName")),
00052         logger(config_.get("logger"))
00053 
00054 
00055 {   //create new queues to store the outgoing compounds
00056     DRPQueues = new helper::Queues(config, fun);
00057     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: QueueSize : " << (config_.get<long int>("queuesize")));
00058 
00059     //Don't start a drp outgoing connection yet
00060     AccessPermission = false;
00061     isPCAtransmissionActive = false;
00062     PCAcompoundsWereSent = false;
00063     //wnsscheduler = wns::simulator::getEventScheduler();
00064 
00065     friends.keyReader = fun->getProxy()->getCommandReader("upperConvergence");
00066 }
00067 
00068 DRPScheduler::~DRPScheduler()
00069 {
00070     for (SendBufferContainer::iterator it = SendBuffer.begin(); it != SendBuffer.end(); it++)
00071     {
00072         MESSAGE_SINGLE(NORMAL, logger, "Buffer for target " << it->second->GetTarget() << " had to retransmit numOfPackets : " << it->second->GetNumOfTotalRetransmissions() );
00073     }
00074 }
00075 
00076 int
00077 DRPScheduler::getNumOfRetransmissions(const wns::ldk::CompoundPtr& compound)
00078 {
00079     wns::service::dll::UnicastAddress target = friends.manager->getReceiverAddress(compound->getCommandPool());
00080     return PCABuffer[target]->GetNumOfRetransmissions(compound);
00081 }
00082 
00083 void
00084 DRPScheduler::doOnData( const wns::ldk::CompoundPtr& compound )
00085 {
00086     //for incoming compounds nothing should be done
00087     //     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Receive Compound");
00088 
00089     // Write pcaPortionProbe
00090     if(getCommand(compound->getCommandPool())->getTxType() == PCA)
00091         pcaPortionProbe->put(compound, 1);
00092     else if(getCommand(compound->getCommandPool())->getTxType() == DRP)
00093         pcaPortionProbe->put(compound, 0);
00094     else assure(false,"TxType is not properly set : " << getCommand(compound->getCommandPool())->getTxType());
00095     getDeliverer()->getAcceptor( compound )->onData( compound );
00096 }
00097 
00098 bool
00099 DRPScheduler::doIsAccepting( const wns::ldk::CompoundPtr& compound) const
00100 {
00101     //MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: doIsAccepting is called");
00102     return (DRPQueues->isAccepting(compound));
00103 
00104 }
00105 
00106 void
00107 DRPScheduler::doSendData( const wns::ldk::CompoundPtr& compound )
00108 {
00109     wns::service::dll::UnicastAddress iam
00110     = getFUN()->findFriend<dll::UpperConvergence*>("upperConvergence")->getMACAddress();
00111 
00112     wns::service::dll::UnicastAddress target
00113     = friends.manager->getReceiverAddress(compound->getCommandPool());
00114 
00115     //outgoing compounds should be stored in a queue
00116     DRPQueues->put(compound);
00117 
00118     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: New compound arrived for target " << target);
00119     //if a drp transmission has started, inform the intermediate buffer about the new incoming compound
00120     if((AccessPermission == true) && (AccessRx == target))
00121     {
00122         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: The target DRP buffer is active -> inform about the new arrival ");
00123         SendBuffer[AccessRx]->NewArrival();
00124     }
00125     else if((AccessPermission == true) && (AccessRx != target))
00126     {
00127         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: There is already a DRP buffer active for target " << AccessRx);
00128         return;
00129     }
00130 
00131     // only try any PCA action if it's enabled and no DRP transmission is currently active
00132     if(AccessPermission == false && friends.manager->getPCAchannelAccess())
00133     {
00134         if((isPCAtransmissionActive) && (ActivePCArx == target))
00135         {
00136             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: The target PCA buffer is active -> inform about the new arrival ");
00137             PCABuffer[ActivePCArx]->NewArrival();
00138         }
00139         else if((isPCAtransmissionActive) && (ActivePCArx != target))
00140         {
00141             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: There is already a PCA buffer active for target " << ActivePCArx);
00142         }
00143         else
00144         {
00145             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Try to start a new PCA transmission");
00146             startPCAtransmission();
00147         }
00148     }
00149 }
00150 
00151 wns::service::dll::UnicastAddress
00152 DRPScheduler::getCurrentTransmissionTarget()
00153 {
00154     // DRP Target
00155     if(AccessPermission == true) return AccessRx;
00156 
00157     // PCA Target
00158     if(friends.manager->getPCAchannelAccess() && isPCAtransmissionActive) return ActivePCArx;
00159 
00160     // else no Target
00161     return wns::service::dll::UnicastAddress();
00162 }
00163 
00164 void
00165 DRPScheduler::onFUNCreated()
00166 {
00167     friends.bb
00168     = getFUN()->findFriend<wimemac::management::BeaconBuilder*>(beaconBuilderName);
00169     friends.dcf
00170     = getFUN()->findFriend<wimemac::lowerMAC::timing::DCF*>(dcfName);
00171     friends.txop
00172     = getFUN()->findFriend<wimemac::lowerMAC::TXOP*>(txopName);
00173     friends.manager = getFUN()->findFriend<wimemac::lowerMAC::Manager*>(managerName);
00174 
00175     // signal packet success/errors to MIB
00176     perMIB = getFUN()->getLayer<dll::Layer2*>()->getManagementService<wimemac::management::PERInformationBase>(perMIBServiceName);
00177 }
00178 
00179 void
00180 DRPScheduler::doWakeup()
00181 {
00182 //     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Phy finished sending beacon!");
00183 }
00184 
00185 bool
00186 DRPScheduler::isBeacon(const wns::ldk::CommandPool* commandPool) const
00187 {
00188     return friends.bb->isBeacon(commandPool);
00189 }
00190 
00191 //TimeToTransmit is invoked by DRPManager. It's a signal to start a drp transmission. First an intermediate buffer is
00192 //created and the buffer starts buffering. If the intermediate buffer is ready, the compounds are sent.
00193 //AccessPermission is set to true in order to inform the buffer about new arrivals in outgoing direction
00194 void
00195 DRPScheduler::TimeToTransmit(wns::service::dll::UnicastAddress macaddress, wns::simulator::Time duration)
00196 {
00197     wns::service::dll::UnicastAddress iam
00198     = getFUN()->findFriend<dll::UpperConvergence*>("upperConvergence")->getMACAddress();
00199 
00200     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: TimeToTransmit is called for target " << macaddress
00201     <<" and I am " << iam
00202     <<". TXOP duration :" << duration);
00203 
00204     if(SendBuffer.find(macaddress) == SendBuffer.end())
00205     {
00206         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Create a new buffer for " << macaddress <<" and started buffering ");
00207         SendBuffer[macaddress] = new TempSendBuffer(DRPQueues,macaddress,this,logger);  
00208     }
00209     else
00210     {
00211 //        MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Buffer exists for " << macaddress <<" started buffering ");
00212 //        MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler begin TXOP number of compound in tempqueue: "<< SendBuffer[macaddress]->numCompounds());
00213 //        MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler begin TXOP number of compound in main queue: "<< DRPQueues->numCompoundsForMacAddress(macaddress));
00214     }
00215 
00216     AccessPermission = true;
00217     AccessRx = macaddress;
00218     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Set Timeout DRP");
00219     setTimeout(duration);
00220 
00221 //     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Timer exists " << hasTimeoutSet() );
00222 
00223     SendBuffer[macaddress]->SetTxopDuration(duration);
00224     if(SendBuffer[macaddress]->StartBuffering());
00225 
00226 }
00227 
00228 
00229 void
00230 DRPScheduler::SendCompounds(wns::service::dll::UnicastAddress macaddress)
00231 {
00232     assure(!((AccessPermission == true) && (isPCAtransmissionActive == true)),"Both DRP and PCA transmissions are active!");
00233     assure(((AccessPermission == true) or (isPCAtransmissionActive == true)),"SendCompounds called without neither DRP nor PCA transmission active");
00234 
00235     if(AccessPermission)
00236     {
00237         assure(macaddress == AccessRx, "SendCompounds() was called for target " << macaddress << ", but AccessRx is " << AccessRx);
00238 
00239         if(SendBuffer[macaddress]->IsBufferEmpty() == false)
00240         {
00241             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: start sending ");
00242             wns::ldk::CompoundPtr compound = SendBuffer[macaddress]->GetCompound();
00243 
00244             wns::ldk::CompoundPtr compound2send = compound->copy();
00245             DRPSchedulerCommand* drpsc = activateCommand(compound2send->getCommandPool());
00246             drpsc->peer.type = DRP;
00247             if(!getConnector()->hasAcceptor(compound2send))
00248             {
00249                 MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Error, can't send compound in a regular DRP reservation!");
00250             }
00251             else
00252             {
00253                 //MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler, send compound with DRP channel access");
00254                 SendBuffer[macaddress]->TransmitCompound(compound);
00255                 getConnector()->getAcceptor(compound2send)->sendData(compound2send);
00256             }
00257         }
00258         else
00259         {
00260             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler, Buffer is empty ");
00261         }
00262     }
00263     else if(isPCAtransmissionActive)
00264     {
00265         assure(macaddress == ActivePCArx, "SendCompounds() was called for target " << macaddress << ", but ActivePCArx is " << ActivePCArx);
00266 
00267         if(PCABuffer[macaddress]->IsBufferEmpty() == false)
00268         {
00269             wns::ldk::CompoundPtr compound = PCABuffer[macaddress]->GetCompound();
00270 
00271             wns::ldk::CompoundPtr compound2send = compound->copy();
00272             DRPSchedulerCommand* drpsc = activateCommand(compound2send->getCommandPool());
00273             drpsc->peer.type = PCA;
00274 
00275             if(!getConnector()->hasAcceptor(compound2send))
00276             {
00277                 MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Can't begin or send any more compounds in this PCA transmission!");
00278                 stopPCAtransmission();
00279             }
00280             else
00281             {
00282                 PCABuffer[macaddress]->TransmitCompound(compound);
00283                 getConnector()->getAcceptor(compound2send)->sendData(compound2send);
00284                 PCAcompoundsWereSent = true;
00285             }
00286         }
00287         else
00288         {
00289             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler, PCA Buffer is empty ");
00290         }
00291     }
00292 
00293  }
00294 
00295 wimemac::convergence::PhyMode
00296 DRPScheduler::getPhyMode(wns::service::dll::UnicastAddress rx, int masNumber)
00297 {
00298     return friends.bb->getPhyMode(rx, masNumber);
00299 }
00300 
00301 //An ACK arrives, send next 
00302 void
00303 DRPScheduler::Acknowledgment(wns::service::dll::UnicastAddress rx)
00304 {
00305     // Inform MIB about succesfull transmission
00306     if(AccessPermission)
00307     {
00308         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler, DRP compound is acknowledged, call ImmACK for target " << rx);
00309         // Only use compounds sent in a DRP transmission for PER evaluation
00310         perMIB->onSuccessfullTransmission(rx);
00311         SendBuffer[rx]->ImmAck();
00312     }
00313     else
00314     {
00315         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler, PCA compound is acknowledged, call ImmACK for target " << rx);
00316         // If AccessPermission is false then the ACK belongs to a PCA transmission
00317         PCABuffer[rx]->ImmAck();
00318     }
00319 
00320 }
00321 
00322 void
00323 DRPScheduler::failedAck(wns::service::dll::UnicastAddress rx)
00324 {
00325     // Inform MIB about unsuccesfull transmission
00326     if(AccessPermission)
00327     {
00328         // Only use compounds sent in a DRP transmission for PER evaluation
00329         perMIB->onFailedTransmission(rx);
00330     }
00331     
00332     if(isPCAtransmissionActive)
00333     {
00334         // Close TxOP in case a compound is not acknowledged!
00335         stopPCAtransmission();
00336         friends.txop->closeTXOP(false);
00337     }
00338 }
00339 
00340 bool
00341 DRPScheduler::adjustMCSdown(wns::service::dll::UnicastAddress rx)
00342 {
00343     if (perMIB->knowsPER(rx))
00344     {
00345         if (perMIB->getPER(rx) > friends.manager->getDesiredPER())
00346         {
00347             MESSAGE_SINGLE(NORMAL, logger, "PER Evaluation: The PER for address " << rx << " is ABOVE the threshold of " << friends.manager->getDesiredPER() << ". It is : " << perMIB->getPER(rx));
00348             perMIB->reset(rx);
00349             return true;
00350         }
00351         else
00352         {
00353             MESSAGE_SINGLE(NORMAL, logger, "PER Evaluation: The PER for address " << rx << " is below the threshold of " << friends.manager->getDesiredPER() << ". It is : " << perMIB->getPER(rx));
00354             return false;
00355         }
00356     }
00357     else
00358     {
00359         MESSAGE_SINGLE(NORMAL, logger, "PER Evaluation: There is no PER estimate yet for address : " << rx);
00360         return false;
00361     }
00362 }
00363 
00364 bool
00365 DRPScheduler::UpdateMapWithPeerAvailabilityMap(wns::service::dll::UnicastAddress rx , Vector& DRPMap)
00366 {
00367     return friends.bb->UpdateMapWithPeerAvailabilityMap(rx, DRPMap);
00368 }
00369 
00370 void
00371 DRPScheduler::RequestIE(wns::service::dll::UnicastAddress rx, wimemac::management::BeaconCommand::ProbeElementID elementID)
00372 {
00373     friends.bb->RequestIE(rx, elementID);
00374 }
00375 
00376 //DRP transmission time is over, stop sending and buffering
00377 void
00378 DRPScheduler::onTimeout()
00379 {
00380     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: On Timeout ");
00381     if(AccessPermission)
00382     {
00383         // DRP transmission is over
00384         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler, Time is over, stop DRP transmission to " << AccessRx);
00385         SendBuffer[AccessRx]->StopBuffering();
00386         AccessPermission = false;
00387         //DRPQueues->RemoveCompounds(AccessRx);
00388 
00389         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler number of compounds in tempqueue: "<< SendBuffer[AccessRx]->numCompounds());
00390         //  MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler number of compound in main queue: "<< DRPQueues->numCompoundsForMacAddress(AccessRx));
00391     }
00392     if(isPCAtransmissionActive)
00393     {
00394         // PCA transmission is over
00395         stopPCAtransmission();
00396     }
00397 }
00398 
00399 wns::simulator::Time
00400 DRPScheduler::getNextTransmissionDuration()
00401 {
00402     assure(PCABuffer.find(ActivePCArx) != PCABuffer.end(), "There is no TempBuffer for the current PCAReceiver" << ActivePCArx);
00403 
00404     Bit currentCompoundSize_ = PCABuffer[ActivePCArx]->getCurrentCompoundSize();
00405     Bit nextCompoundSize_ = PCABuffer[ActivePCArx]->getNextCompoundSize();
00406 
00407     wns::simulator::Time currentduration = friends.manager->getProtocolCalculator()->getDuration()->MSDU_PPDU(currentCompoundSize_,
00408         getPhyMode(ActivePCArx,friends.manager->getMASNumber(wns::simulator::getEventScheduler()->getTime())));
00409     wns::simulator::Time nextduration = friends.manager->getProtocolCalculator()->getDuration()->MSDU_PPDU(nextCompoundSize_,
00410         getPhyMode(ActivePCArx,friends.manager->getMASNumber(wns::simulator::getEventScheduler()->getTime())));
00411 
00412     // Check if the sending of the next compound does not interfere with a scheduled DRP reservation
00413     //      This Compound + SIFS + ACK + SIFS + Next Compound + SIFS + ACK + SIFS + Guard < NextDRPReservation
00414     if((nextCompoundSize_ > 0)
00415         && (wns::simulator::getEventScheduler()->getTime() + currentduration + 10E-6 + 13.125E-6 + 10E-6 + nextduration + 10E-6 + 13.125E-6 + 10E-6 < nextDRPReservationTime - 12E-6))
00416         return nextduration;
00417     else return 0;
00418 }
00419 
00420 wns::service::dll::UnicastAddress
00421 DRPScheduler::getNextReceiver() const
00422 {
00423     return DRPQueues->getNextPCAReceiver();
00424 }
00425 
00426 bool
00427 DRPScheduler::startPCAtransmission()
00428 {
00429     assure(AccessPermission == false, "A PCA transmission was started although a DRP transmission is already active");
00430   
00431     bool successfulStart = false;
00432 
00433     // Transmission already started
00434     if(hasTimeoutSet()) return false;
00435 
00436     wns::simulator::Time timeUntilNextDRPReservation = getTimeUntilNextDRPReservation();
00437 
00438     if(timeUntilNextDRPReservation > 0)
00439     {
00440         ActivePCArx = getNextReceiver();
00441         if(ActivePCArx != wns::service::dll::UnicastAddress())
00442         {
00443             isPCAtransmissionActive = true;
00444 
00445             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Beginning a PCA transmission for target " << ActivePCArx << " with maximum duration of " << timeUntilNextDRPReservation);
00446 
00447             if(PCABuffer.find(ActivePCArx) == PCABuffer.end())
00448             {
00449                 MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Create a new PCA buffer for " << ActivePCArx <<" and started buffering ");
00450                 PCABuffer[ActivePCArx] = new TempSendBuffer(DRPQueues,ActivePCArx,this,logger);
00451             }
00452 
00453             //Bit bits = DRPQueues->getHeadOfLinePDUbits(nextPCAReceiver);
00454             wns::simulator::Time txOPDuration = timeUntilNextDRPReservation;
00455 
00456             MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Set Timeout PCA | TxOpDuration " << txOPDuration);
00457             setTimeout(txOPDuration - 1E-9);
00458 
00459             PCABuffer[ActivePCArx]->SetTxopDuration(txOPDuration);
00460             if(PCABuffer[ActivePCArx]->StartBuffering())
00461                 successfulStart = true;
00462 
00463         }
00464         else MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: There are no compounds for any target!");
00465      }
00466      else MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: There is not enough time until the next DRP reservation starts!");
00467 
00468      return successfulStart;
00469 }
00470 
00471 wns::simulator::Time
00472 DRPScheduler::getTimeUntilNextDRPReservation()
00473 {
00474     wns::simulator::Time timeUntilNextDRPReservation;
00475     wns::simulator::Time bpStartTime = friends.manager->getBPStartTime();
00476     int nextDRPMAS = 256;
00477 
00478     int thisMAS = friends.manager->getMASNumber(wns::simulator::getEventScheduler()->getTime());
00479     for(int i = thisMAS; i < currentDRPMap.size(); i++)
00480     {
00481         if(currentDRPMap[i])
00482         {
00483             nextDRPMAS = i;
00484             break;
00485         }
00486     }
00487 
00488     // Calculate time until the next MAS occupied by a DRP reservation begins
00489     timeUntilNextDRPReservation = bpStartTime + nextDRPMAS*256E-6 - wns::simulator::getEventScheduler()->getTime();
00490 
00491     nextDRPReservationTime = wns::simulator::getEventScheduler()->getTime() + timeUntilNextDRPReservation;
00492 
00493     if(timeUntilNextDRPReservation < 30E-6) return 0;
00494     else if(timeUntilNextDRPReservation > 2*1024E-6) return 2*1024E-6;
00495     else return timeUntilNextDRPReservation;
00496 }
00497 
00498 void
00499 DRPScheduler::UpdateDRPMap(Vector DRPMap)
00500 {
00501     currentDRPMap = DRPMap;
00502     currentRegisterDRPMap = DRPMap;
00503 
00504     // TODO In Case of Soft-DRP this needs to be adjusted
00505 
00506     // ThisMAS is the first MAS after the BP
00507     int thisMAS = friends.manager->getMASNumber(wns::simulator::getEventScheduler()->getTime());
00508     RegisterDRPReservations(thisMAS);
00509 }
00510 
00511 void
00512 DRPScheduler::RegisterDRPReservations(int thisMAS)
00513 {
00514     int adjacent = 0;
00515     double MASduration = 256E-6;
00516     int i = thisMAS;
00517     wns::simulator::Time ReservationStart;
00518 
00519     while(i < currentRegisterDRPMap.size())
00520     {
00521 
00522         if(currentRegisterDRPMap[i] == true)
00523         {
00524             if(adjacent == 0)
00525             {
00526                 ReservationStart = (i - thisMAS) * MASduration;
00527             }
00528 
00529             currentRegisterDRPMap[i] = false;
00530             adjacent++;
00531         }
00532         else
00533         {
00534             if(adjacent != 0)
00535             {
00536                 break;
00537             }
00538         }
00539         i++;
00540     }
00541 
00542     if(adjacent != 0)
00543     {
00544         wns::simulator::Time duration = adjacent * MASduration - 1E-12;
00545         adjacent = 0;
00546 
00547         wns::simulator::getEventScheduler()->scheduleDelay(
00548             boost::bind(&DRPScheduler::onDRPStart, this),
00549             ReservationStart);
00550 
00551         wns::simulator::getEventScheduler()->scheduleDelay(
00552             boost::bind(&DRPScheduler::onDRPStop, this),
00553             ReservationStart + duration);
00554     }
00555 
00556     if(i < currentRegisterDRPMap.size())
00557         RegisterDRPReservations(thisMAS);
00558 
00559 }
00560 
00561 void
00562 DRPScheduler::onBPStart(wns::simulator::Time BPduration)
00563 {
00564     wns::simulator::Time nextBPStart = friends.manager->getBPStartTime() + 256*256E-6;
00565 
00566     wns::simulator::getEventScheduler()->schedule(
00567             boost::bind(&DRPScheduler::onDRPStart, this),
00568             nextBPStart);
00569 
00570     wns::simulator::getEventScheduler()->schedule(
00571             boost::bind(&DRPScheduler::onDRPStop, this),
00572             nextBPStart + BPduration - 1E-12);
00573 }
00574 
00575 void
00576 DRPScheduler::stopPCAtransmission()
00577 {
00578     if(!friends.manager->getPCAchannelAccess()) return;
00579 
00580     if(!isPCAtransmissionActive)
00581     {
00582         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: PCA transmission is already stopped");
00583         return;
00584     }
00585 
00586     //doWakeup();
00587     PCABuffer[ActivePCArx]->StopBuffering();
00588 
00589     if(hasTimeoutSet())
00590     {
00591         cancelTimeout();
00592     }
00593 
00594     if(PCAcompoundsWereSent)
00595     {
00596         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: StopPCATransmission after compounds were sent");
00597         DRPQueues->changePCAreceiver();
00598     }
00599     PCAcompoundsWereSent = false;
00600     isPCAtransmissionActive = false;
00601 
00602     if(DRPQueues->queueHasPDUs(ActivePCArx))
00603     {
00604         // Inform DCF about waiting transmissions
00605         MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Inform DCF about waiting transmissions with NumOfTransmissions : " << PCABuffer[ActivePCArx]->GetNumOfRetransmissions() +1);
00606         friends.dcf->waitingTransmissions(PCABuffer[ActivePCArx]->GetNumOfRetransmissions() +1);
00607     }
00608 
00609 }
00610 
00611 void
00612 DRPScheduler::txOPCloseIn(wns::simulator::Time duration)
00613 {
00614     MESSAGE_SINGLE(NORMAL, logger, "DRPScheduler: Close TxOP in " << duration - 1E-6);
00615     wns::simulator::getEventScheduler()->scheduleDelay(
00616             boost::bind(&DRPScheduler::stopPCAtransmission, this),
00617             duration - 1E-6);
00618 }
00619 
00620 void
00621 DRPScheduler::onDRPStart()
00622 {
00623     friends.dcf->onDRPStart();
00624 }
00625 
00626 void
00627 DRPScheduler::onDRPStop()
00628 {
00629     friends.dcf->onDRPStop();
00630 }

Generated on Wed May 23 03:32:11 2012 for openWNS by  doxygen 1.5.5