![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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 }
1.5.5