![]() |
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/management/BeaconEvaluator.hpp> 00030 #include <WIMEMAC/lowerMAC/Manager.hpp> 00031 #include "BeaconCommand.hpp" 00032 00033 using namespace wimemac::management; 00034 00035 BeaconEvaluator::BeaconEvaluator() 00036 { 00037 00038 DRPmapManager = new drp::DRPmap(256); 00039 hasPendingProbe = false; 00040 requestedProbes.drpAvailability = 0; 00041 FirstEval = true; 00042 } 00043 00044 void 00045 BeaconEvaluator::SetLogger(wns::logger::Logger _logger) 00046 { 00047 logger = _logger; 00048 DRPmapManager->SetLogger(logger); 00049 } 00050 00051 wimemac::convergence::PhyMode 00052 BeaconEvaluator::getPhyMode(wns::service::dll::UnicastAddress rx, int masNumber) 00053 { 00054 00055 if (DRPOutgoingConnections.knows(rx)) 00056 { 00057 DRPmanager = DRPOutgoingConnections.find(rx); 00058 return DRPmanager->getPhyMode(); 00059 } 00060 else 00061 { 00062 if(friends.manager->getPCAchannelAccess()) 00063 { 00064 return friends.manager->getDefaultPhyMode(); 00065 } 00066 else 00067 assure(false,"If only using DRP as channel access it shouldn't be asked for the PhyMode until a DRPManager exists"); 00068 } 00069 } 00070 00071 void 00072 BeaconEvaluator::BeaconExamination(wns::service::dll::UnicastAddress tx, wns::service::dll::UnicastAddress iam, BeaconCommand* BeaconCommand, 00073 wns::logger::Logger _logger) 00074 { 00075 ExamineBeaconPeriodOccupancy(tx,BeaconCommand); 00076 00077 logger =_logger; 00078 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Receive Beacon from device:" << tx); 00079 00080 // Fill rxAvailabilityBitamp 00081 if (BeaconCommand->peer.HasAvailabilityIE) 00082 { 00083 // If sender is already known update bitmap 00084 if (rxAvailabilityBitmap.knows(tx)) 00085 { 00086 rxAvailabilityBitmap.update(tx, BeaconCommand->peer.availabilityBitmap); 00087 } 00088 // Else insert new element 00089 else rxAvailabilityBitmap.insert(tx , BeaconCommand->peer.availabilityBitmap); 00090 } 00091 00092 // Evaluate Probes sent to me with the beacon 00093 if(BeaconCommand->HasProbeIE(iam)) 00094 { 00095 std::queue<BeaconCommand::ProbeElementID> probeElements = BeaconCommand->peer.probe.find(iam); 00096 while (probeElements.size() > 0) 00097 { 00098 // get first requested element ID 00099 BeaconCommand::ProbeElementID elementID = probeElements.front(); 00100 probeElements.pop(); 00101 00102 MESSAGE_SINGLE(NORMAL, logger, "Received Probe asking for IE : " << elementID); 00103 if (elementID == BeaconCommand::DRPAvailability) 00104 { 00105 // set counter to include IE in the next beacons, beginning next SF 00106 if (requestedProbes.drpAvailability > 0) 00107 { 00108 // The IE was already requested, reset the counter to max 00109 requestedProbes.drpAvailability = 3; // in the next x beacons the IE is included 00110 } 00111 // The IE was not included the in the last beacon. Set counter to -1 to signal that the IE shall be included in the next beacons beginning next SF 00112 else requestedProbes.drpAvailability = -1; 00113 } 00114 else assure(false, "The requested element ID : " << elementID << " is not known"); 00115 } 00116 00117 } // end probe evaluation 00118 00119 //if drp connection is always known, update the information if necessary, else create a new DRPManager and insert it into DRPConnections 00120 00121 if(BeaconCommand->peer.HasDRPIE) 00122 { int i = 1; 00123 while(BeaconCommand->GetDRPIESize()!=0) 00124 { 00125 MESSAGE_SINGLE(NORMAL, logger, "Evaluate DRPIE nr. " << i); 00126 i++; 00127 BeaconCommand::DRP DRPIECommand; 00128 DRPIECommand = BeaconCommand->GetDRPIE(); 00129 00130 if(DRPIECommand.address == iam) 00131 { 00132 if(!DRPIncomingConnections.knows(tx) && DRPIECommand.devicetype == BeaconCommand::Owner) 00133 { 00134 //peer.address as a unique identifier for a specific drp connection 00135 //This device doesn't know the drp connection, hence create a new drp manager for a new incoming 00136 //connection. Set the parameters according to incoming beacon command 00137 DRPIncomingConnections.insert(tx, new drp::DRPManager(tx, 00138 DRPIECommand.reservationtype,DRPIECommand.reasoncode, BeaconCommand::Target, 00139 DRPIECommand.DRPAlloc, queueInterface, logger, friends.manager, NumberOfBPSlots, friends.manager->getRateAdaptation(), friends.manager->getPatternPEROffset())); 00140 00141 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator has built a new drp connection manager for " 00142 << "transmission owner " << tx); 00143 } 00144 else if(DRPIncomingConnections.knows(tx) && DRPIECommand.devicetype == BeaconCommand::Owner) 00145 { 00146 DRPmanager = DRPIncomingConnections.find(tx); 00147 if(DRPIECommand.isAdditionalDRPIE == false) 00148 { 00149 // DRPIE is a standard DPRIE from the transmission owner 00150 if(DRPIECommand.reasoncode != BeaconCommand::Accept) 00151 { 00152 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Update Status " 00153 << DRPIECommand.status << " and Reason Code " << DRPIECommand.reasoncode); 00154 DRPmanager->SetReasonCode(DRPIECommand.reasoncode); 00155 00156 if(DRPIECommand.status == false) 00157 DRPmanager->SetStatus(DRPIECommand.status); 00158 00159 if(DRPIECommand.reasoncode == BeaconCommand::Modified) 00160 DRPmanager->SetPattern(DRPIECommand.DRPAlloc); 00161 } 00162 } 00163 else 00164 { 00165 // DRPIE is an additional DRPIE created for merging by the transmission owner 00166 if(DRPmanager->HasPendingDRPMerge()) 00167 { 00168 // DRP merge is already known -> update 00169 if(DRPIECommand.reasoncode != BeaconCommand::Accept) 00170 { 00171 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Update Status for merge DRPIE" 00172 << DRPIECommand.status); 00173 DRPmanager->SetMergeReasonCode(DRPIECommand.reasoncode); 00174 00175 if(DRPIECommand.status == false) 00176 DRPmanager->SetMergeStatus(DRPIECommand.status); 00177 00178 if(DRPIECommand.reasoncode == BeaconCommand::Modified) 00179 DRPmanager->SetMergePattern(DRPIECommand.DRPAlloc); 00180 } 00181 } 00182 else 00183 { 00184 // DRP merge is unknown -> inform DRP Manager about new reservation for merge 00185 DRPmanager->AddReservation(DRPIECommand.reasoncode, DRPIECommand.DRPAlloc); 00186 } 00187 } 00188 00189 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Owner address " << tx << " is already known"); 00190 } 00191 else if(DRPOutgoingConnections.knows(tx) && DRPIECommand.devicetype == BeaconCommand::Target) 00192 { 00193 DRPmanager = DRPOutgoingConnections.find(tx); 00194 00195 if(DRPIECommand.isAdditionalDRPIE == false) 00196 { 00197 // DRPIE is a standard DPRIE from the transmission target 00198 DRPmanager->SetReasonCode(DRPIECommand.reasoncode); 00199 DRPmanager->SetStatus(DRPIECommand.status); 00200 } 00201 else 00202 { 00203 // DRPIE is an additional DRPIE created for merging 00204 if(DRPmanager->HasPendingDRPMerge()) 00205 { 00206 // DRP merge is already known -> update 00207 DRPmanager->SetMergeReasonCode(DRPIECommand.reasoncode); 00208 DRPmanager->SetMergeStatus(DRPIECommand.status); 00209 00210 if(DRPIECommand.status == true) 00211 { 00212 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Merge DRPIE was accepted -> merging reservation patterns"); 00213 DRPmanager->MergePatterns(); 00214 } 00215 } 00216 else 00217 { 00218 assure(false, "False State: Got MergeDRPIE from target while owner has no MergeStatus"); 00219 } 00220 } 00221 00222 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Target address " << tx << " is already known"); 00223 } 00224 } 00225 00226 //Updating the maps if I'm the reservation target and the reservation is not acknowleged yet will cause a conflict 00227 //(the global maps mark the proposed slots as occupied during negotation) 00228 //If DRPIECommand.status is true, the reservation pattern is acknowleged, hence update the DRP Maps. 00229 00230 if(DRPIECommand.status == true) 00231 { 00232 MESSAGE_SINGLE(NORMAL, logger, "Updating my DRPMap; Received 'Accept' from address " << tx << " who accepts the connection with address " << DRPIECommand.address << "; DeviceType: " << DRPIECommand.devicetype); 00233 if(DRPIECommand.reservationtype == BeaconCommand::Hard) 00234 { 00235 UpdateGlobalHardDRPMap(DRPIECommand.DRPAlloc); 00236 } 00237 else if(DRPIECommand.reservationtype == BeaconCommand::Soft) 00238 { 00239 UpdateGlobalSoftDRPMap(DRPIECommand.DRPAlloc); 00240 } 00241 00242 if(DRPIECommand.address != iam) 00243 { 00244 MESSAGE_SINGLE(NORMAL, logger, "There is a valid connection now between address " << DRPIECommand.address << " (Owner) and address " << tx << " (Target)."); 00245 } 00246 } 00247 else 00248 { 00249 if(DRPIECommand.address != iam) 00250 { 00251 // Only respect the proposed pattern if it's not for me! Otherwise the negotiation will be conflicted 00252 MESSAGE_SINGLE(NORMAL, logger, "Received a DRPIE with pending negotiation for address " << DRPIECommand.address << " from address " << tx << ". The proposed reservation will be respected until final state is known"); 00253 00254 // Since only other DRP reservations need to respect the ongoing negotiation PCA is still usable -> Soft DRP Map 00255 UpdateGlobalSoftDRPMap(DRPIECommand.DRPAlloc); 00256 } 00257 } 00258 } 00259 } 00260 00261 } // end BeaconExamination 00262 00263 void 00264 BeaconEvaluator::CreateDRPMaps() 00265 { 00266 for(it = DRPOutgoingConnections.begin(); it != DRPOutgoingConnections.end() ;++it) 00267 { 00268 if((*it).second->GetDeviceType() == BeaconCommand::Owner) 00269 { 00270 Vector tmpGlobal(256,false); 00271 DRPmapManager->GetGlobalPattern(tmpGlobal); 00272 00273 //bool areMASsAvailable = DRPmapManager->IsSpaceInGlobalPattern(); 00274 bool areMASsAvailable = (*it).second->areMASsAvailable(tmpGlobal); 00275 00276 // create new drp maps for the upcoming BP 00277 if((*it).second->IsMapCreated() == false) 00278 { 00279 if(areMASsAvailable) 00280 { 00281 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: create a new reservation map for" 00282 << " the outgoing connection to target " << (*it).second->GetAddress()); 00283 (*it).second->FindNewPattern(tmpGlobal); 00284 // Update own Soft DRP Map in order to respect the just requested MASs in case further reservations need to be generated 00285 UpdateGlobalSoftDRPMap((*it).second->GetPattern()); 00286 } 00287 else MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: All MASs in the SF are already reserverd. Cannot create an initial pattern"); 00288 } 00289 00290 if((*it).second->IsMapCreated() == true) 00291 { 00292 // A change in phymode could have caused the need for more reserved MASs 00293 if((*it).second->NeedsAdditionalPattern()) 00294 { 00295 if(areMASsAvailable) 00296 { 00297 00298 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: create an additional reservation map for" 00299 << " the outgoing connection to target" << (*it).second->GetAddress()); 00300 (*it).second->CreateAdditionalPattern(tmpGlobal); 00301 // Update own Soft DRP Map in order to respect the just requested MASs in case further reservations need to be generated 00302 UpdateGlobalSoftDRPMap((*it).second->GetMergePattern()); 00303 } 00304 else MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: All MASs in the SF are already reserverd. Cannot create an additional pattern"); 00305 } 00306 } 00307 } 00308 } 00309 } 00310 00311 //BP has finished, update the upcoming drp reservations, set drp connection timers. This information is known by each DRPManager, hence notify each DRPManager to build DRPmaps 00312 int 00313 BeaconEvaluator::CollectDRPmaps(wns::simulator::Time BPDuration_) 00314 { 00315 // set Probe counters to assure requested IEs are put into the beacons beginning next SF 00316 if (requestedProbes.drpAvailability < 0) 00317 { 00318 // requestedProbes.drpAvailability < 0 means a Probe was received this BP -> answer through beacon in next SF 00319 requestedProbes.drpAvailability = 3; 00320 } 00321 00322 int reservedMASs = 0; 00323 tmpAllocatedMAS = Vector(256,false); 00324 00325 // update upcoming drp reservations 00326 for(it = DRPOutgoingConnections.begin(); it != DRPOutgoingConnections.end() ;++it) 00327 { 00328 if((*it).second->GetReasonCode() == BeaconCommand::Accept && (*it).second->GetStatus() == true) 00329 { 00330 Vector drpMap_ = (*it).second->GetPattern(); 00331 for(int i = 0; i < drpMap_.size(); i++) 00332 { 00333 if(drpMap_[i] == true) 00334 { 00335 assure(i < drpMap_.size(), "Vector boundary exeeded; loop error!"); 00336 reservedMASs +=1; 00337 tmpAllocatedMAS[i] = true; 00338 } 00339 } 00340 00341 (*it).second->StartRegisterReservation(BPDuration_); 00342 MESSAGE_SINGLE(NORMAL, logger, "StartRegister for target " << (*it).second->GetAddress()); 00343 } 00344 } 00345 00346 return reservedMASs; 00347 } 00348 00349 void 00350 BeaconEvaluator::EvaluateConnection() 00351 { 00352 for(it = DRPIncomingConnections.begin(); it != DRPIncomingConnections.end() ;++it) 00353 { 00354 // For all target managers check if there are new unestablished connections and evaluate pattern 00355 if((*it).second->GetStatus() == false) 00356 { 00357 if(DRPmapManager->PossiblePattern((*it).second->GetPattern())) 00358 { 00359 (*it).second->SetStatus(true); 00360 (*it).second->SetReasonCode(BeaconCommand::Accept); 00361 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: DRP reservation is possible," 00362 <<" setting status to true."); 00363 00364 } 00365 else 00366 { 00367 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: DRP reservation impossible," 00368 <<" set ReasonCode to conflict"); 00369 (*it).second->SetReasonCode(BeaconCommand::Conflict); 00370 requestedProbes.drpAvailability = 3; // Send complete DRP Availability IE with conflict response 00371 } 00372 } 00373 00374 // Check for merge patterns 00375 if((*it).second->HasPendingDRPMerge() && (*it).second->GetMergeStatus() == false) 00376 { 00377 if(DRPmapManager->PossiblePattern((*it).second->GetMergePattern())) 00378 { 00379 (*it).second->SetMergeStatus(true); 00380 (*it).second->SetMergeReasonCode(BeaconCommand::Accept); 00381 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: additional DRP reservation is possible," 00382 <<" setting status to true."); 00383 00384 } 00385 else 00386 { 00387 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: additional DRP reservation impossible," 00388 <<" set ReasonCode to conflict"); 00389 (*it).second->SetMergeReasonCode(BeaconCommand::Conflict); 00390 requestedProbes.drpAvailability = 3; // Send complete DRP Availability IE with conflict response 00391 } 00392 } 00393 00394 if((*it).second->GetReasonCode() == BeaconCommand::Accept && (*it).second->GetStatus() == true) 00395 { 00396 MESSAGE_SINGLE(NORMAL, logger, "Updating DRP-Map of this station with a new reservation as target with partner " << (*it).second->GetAddress()); 00397 if((*it).second->GetReservationType() == BeaconCommand::Hard) 00398 { 00399 UpdateGlobalHardDRPMap((*it).second->GetPattern()); 00400 } 00401 else if((*it).second->GetReservationType() == BeaconCommand::Soft) 00402 { 00403 UpdateGlobalSoftDRPMap((*it).second->GetPattern()); 00404 } 00405 } 00406 if((*it).second->HasPendingDRPMerge() && (*it).second->GetMergeReasonCode() == BeaconCommand::Accept && (*it).second->GetMergeStatus() == true) 00407 { 00408 MESSAGE_SINGLE(NORMAL, logger, "Updating DRP-Map of this station with an additional reservation as target with partner " << (*it).second->GetAddress()); 00409 if((*it).second->GetReservationType() == BeaconCommand::Hard) 00410 { 00411 UpdateGlobalHardDRPMap((*it).second->GetMergePattern()); 00412 } 00413 else if((*it).second->GetReservationType() == BeaconCommand::Soft) 00414 { 00415 UpdateGlobalSoftDRPMap((*it).second->GetMergePattern()); 00416 } 00417 } 00418 00419 } 00420 00421 for(it = DRPOutgoingConnections.begin(); it != DRPOutgoingConnections.end() ;++it) 00422 { 00423 // Evaluate conflicted reservations 00424 if((*it).second->GetReasonCode() == BeaconCommand::Conflict) 00425 { 00426 (*it).second->ResolveConflict(); 00427 } 00428 if((*it).second->GetMergeReasonCode() == BeaconCommand::Conflict) 00429 { 00430 (*it).second->ResolveMergeConflict(); 00431 } 00432 00433 } 00434 } 00435 00436 void 00437 BeaconEvaluator::setFriend(helper::IDRPQueueInterface* QueueInterface) 00438 { 00439 queueInterface = QueueInterface; 00440 } 00441 00442 void 00443 BeaconEvaluator::setManagerFriend(wimemac::lowerMAC::Manager* manager_) 00444 { 00445 friends.manager = manager_; 00446 } 00447 00448 void 00449 BeaconEvaluator::SetBPDuration(wns::simulator::Time duration) 00450 { 00451 BPDuration = duration; 00452 //Block the BP slots in the global drp map 00453 NumberOfBPSlots = ceil((int)(BPDuration*1E6) / 256); 00454 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Number of BP MASs set to : " << NumberOfBPSlots); 00455 00456 DRPmapManager->setBPSlots(NumberOfBPSlots); 00457 } 00458 00459 void 00460 BeaconEvaluator::evaluatePERforConnections() 00461 { 00462 00463 for(it = DRPOutgoingConnections.begin(); it != DRPOutgoingConnections.end() ;++it) 00464 { 00465 // Evaluate the PER of the connections the device owns 00466 if( friends.manager->adjustMCSdown((*it).second->GetAddress())) 00467 { 00468 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: A lower PhyMode will be used for address : " << (*it).second->GetAddress()); 00469 00470 wimemac::convergence::PhyMode newPhyMode_ = (*it).second->getPhyMode(); 00471 friends.manager->getPhyUser()->getPhyModeProvider()->mcsDown(newPhyMode_); 00472 00473 if (newPhyMode_ < (*it).second->getPhyMode()) 00474 (*it).second->UpdatePhyModeDown(newPhyMode_); 00475 else MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: The lowest PhyMode is already used. Proceed without changes"); 00476 } 00477 } 00478 } 00479 00480 00481 //For outgoing connection compounds are queued (see DRPScheduler, Queues). If the target device's mac address isn't known, 00482 // a new Queue will be created to store the outgoing device. CreateDRPManager will be invoked by DRPScheduler 00483 // to create a new drp manager for the new outgoing drp connection, this will cause a drp reservation negotation 00484 00485 void 00486 BeaconEvaluator::CreateDRPManager(wns::service::dll::UnicastAddress rx, int CompoundspSF, int BitspSF, int MaxCompoundSize, wimemac::convergence::PhyMode DefPhyMode) 00487 { 00488 if(DRPOutgoingConnections.knows(rx)) 00489 { 00490 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: That's not a new DRP Connection as owner" ); 00491 00492 } 00493 else 00494 { 00495 Vector emptyInitMap_(256,false); 00496 00497 MESSAGE_SINGLE(NORMAL, logger, "Create a new DRP Manager" ); 00498 00499 //create a new drp manager, set the parameters according to drp reservation negotation requirement 00500 //for own outgoing reservation DeviceType: Owner, ReservationStatus: 0, ReasonCode: Accept 00501 DRPOutgoingConnections.insert(rx, new drp::DRPManager(rx, BeaconCommand::Hard,BeaconCommand::Accept, BeaconCommand::Owner, emptyInitMap_, queueInterface, logger, friends.manager, NumberOfBPSlots, friends.manager->getRateAdaptation(), friends.manager->getPatternPEROffset(), DefPhyMode)); 00502 00503 DRPmanager = DRPOutgoingConnections.find(rx); 00504 00505 DRPmanager->SetTrafficChar(CompoundspSF,BitspSF,MaxCompoundSize, friends.manager->getReservationBlocks()); 00506 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: " 00507 <<"DRP reservation with DeviceType "<< DRPmanager->GetDeviceType()); 00508 00509 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator has built a new drp connection manager for an outgoing" 00510 << " DRP reservation, target is "<< rx); 00511 00512 } 00513 } 00514 00515 void 00516 BeaconEvaluator::UpdateDRPManager(wns::service::dll::UnicastAddress rx, int CompoundspSF, int BitspSF, int MaxCompoundSize) 00517 { 00518 assure(DRPOutgoingConnections.knows(rx), "Trying to update DRPManager for target " << rx << ", but target does not exist in DRPOutgoingConnections"); 00519 DRPmanager = DRPOutgoingConnections.find(rx); 00520 DRPmanager->UpdateTrafficChar(CompoundspSF,BitspSF,MaxCompoundSize); 00521 } 00522 00523 bool 00524 BeaconEvaluator::CreateBPOIE(BeaconCommand* BeaconCommand) 00525 { 00526 00527 ExamineBeaconPeriodOccupancy(friends.manager->getMACAddress(),BeaconCommand); 00528 BeaconCommand->peer.BPOIE.BPsize = BPoccupancy.size(); 00529 BeaconCommand->peer.BPOIE.IE = BPoccupancy; 00530 } 00531 00532 00533 //BeaconBuilder builts a new beacon compound and asked whether a DRPIE should be included. If there are already established connections a DRPIE must be included, for new connection it should be included to start negotiation 00534 bool 00535 BeaconEvaluator::CreateDRPIE(BeaconCommand* BeaconCommand) 00536 { 00537 bool HasCreated = false; 00538 00539 for(it = DRPOutgoingConnections.begin(); it != DRPOutgoingConnections.end() ;++it) 00540 { 00541 if( (*it).second->IsMapCreated() ) // Reservation partner shall also be informed about conflicts 00542 { 00543 BeaconCommand::DRP DRPIECommand; 00544 DRPIECommand.reservationtype = (*it).second->GetReservationType(); 00545 DRPIECommand.reasoncode = (*it).second->GetReasonCode(); 00546 DRPIECommand.devicetype = (*it).second->GetDeviceType(); 00547 DRPIECommand.address = (*it).second->GetAddress(); 00548 DRPIECommand.status = (*it).second->GetStatus(); 00549 DRPIECommand.DRPAlloc = (*it).second->GetPattern(); 00550 DRPIECommand.isAdditionalDRPIE = false; 00551 BeaconCommand->peer.HasDRPIE = true; 00552 00553 BeaconCommand->PutDRPIE(DRPIECommand); 00554 HasCreated = true; 00555 00556 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: build DRPIE as owner, reasoncode " << DRPIECommand.reasoncode <<" and " 00557 <<"Status " << DRPIECommand.status); 00558 00559 if ((*it).second->HasPendingDRPMerge() && (*it).second->GetMergeReasonCode() == BeaconCommand::Accept) 00560 { 00561 // There is an additional DRP Map pending for acceptance and merge 00562 BeaconCommand::DRP DRPIECommand; 00563 DRPIECommand.reservationtype = (*it).second->GetReservationType(); 00564 DRPIECommand.devicetype = (*it).second->GetDeviceType(); 00565 DRPIECommand.address = (*it).second->GetAddress(); 00566 00567 DRPIECommand.reasoncode = (*it).second->GetMergeReasonCode(); 00568 DRPIECommand.status = (*it).second->GetMergeStatus(); 00569 DRPIECommand.DRPAlloc = (*it).second->GetMergePattern(); 00570 00571 DRPIECommand.isAdditionalDRPIE = true; 00572 00573 BeaconCommand->PutDRPIE(DRPIECommand); 00574 00575 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: build additional DRPIE as owner for merge, reasoncode " << DRPIECommand.reasoncode <<" and" 00576 <<"Status " << DRPIECommand.status); 00577 00578 // Additional pattern was accepted -> merge with original one 00579 if (DRPIECommand.status == true) assure(false, "False State: Owner should have merged an additional pattern with activated status"); 00580 } 00581 } 00582 00583 if((*it).second->GetReasonCode() == BeaconCommand::Accept && (*it).second->GetStatus() == true) 00584 { 00585 MESSAGE_SINGLE(NORMAL, logger, "Updating DRP-Map of this station with an active reservation as owner with " << (*it).second->GetAddress() ); 00586 if((*it).second->GetReservationType() == BeaconCommand::Hard) 00587 { 00588 UpdateGlobalHardDRPMap((*it).second->GetPattern()); 00589 } 00590 else if((*it).second->GetReservationType() == BeaconCommand::Soft) 00591 { 00592 UpdateGlobalSoftDRPMap((*it).second->GetPattern()); 00593 } 00594 } 00595 } 00596 00597 for(it = DRPIncomingConnections.begin(); it != DRPIncomingConnections.end() ;++it) 00598 { 00599 if( (*it).second->IsMapCreated() ) // Reservation partner shall also be informed about conflicts 00600 { 00601 BeaconCommand::DRP DRPIECommand; 00602 DRPIECommand.reservationtype = (*it).second->GetReservationType(); 00603 DRPIECommand.reasoncode = (*it).second->GetReasonCode(); 00604 DRPIECommand.devicetype = (*it).second->GetDeviceType(); 00605 DRPIECommand.address = (*it).second->GetAddress(); 00606 DRPIECommand.status = (*it).second->GetStatus(); 00607 DRPIECommand.DRPAlloc = (*it).second->GetPattern(); 00608 DRPIECommand.isAdditionalDRPIE = false; 00609 BeaconCommand->peer.HasDRPIE = true; 00610 BeaconCommand->PutDRPIE(DRPIECommand); 00611 HasCreated = true; 00612 00613 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: build DRPIE as target, reasoncode " << DRPIECommand.reasoncode <<" and " 00614 <<"Status " << DRPIECommand.status); 00615 00616 if ((*it).second->HasPendingDRPMerge()) 00617 { 00618 // There is an additional DRP Map pending for acceptance and merge 00619 BeaconCommand::DRP DRPIECommand; 00620 DRPIECommand.reservationtype = (*it).second->GetReservationType(); 00621 DRPIECommand.devicetype = (*it).second->GetDeviceType(); 00622 DRPIECommand.address = (*it).second->GetAddress(); 00623 00624 DRPIECommand.reasoncode = (*it).second->GetMergeReasonCode(); 00625 DRPIECommand.status = (*it).second->GetMergeStatus(); 00626 DRPIECommand.DRPAlloc = (*it).second->GetMergePattern(); 00627 00628 DRPIECommand.isAdditionalDRPIE = true; 00629 00630 BeaconCommand->PutDRPIE(DRPIECommand); 00631 00632 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: build additional DRPIE as target for merge, reasoncode " << DRPIECommand.reasoncode <<" and" 00633 <<"Status " << DRPIECommand.status); 00634 00635 // Additional pattern was accepted -> merge with original one 00636 if (DRPIECommand.reasoncode == BeaconCommand::Accept && DRPIECommand.status == true) 00637 { 00638 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Accepting DRP merge pattern -> merging reservation patterns"); 00639 (*it).second->MergePatterns(); 00640 } 00641 } 00642 } 00643 00644 if((*it).second->GetReasonCode() == BeaconCommand::Accept && (*it).second->GetStatus() == true) 00645 { 00646 MESSAGE_SINGLE(NORMAL, logger, "Updating DRP-Map of this station with an active reservation as target with partner " << (*it).second->GetAddress()); 00647 if((*it).second->GetReservationType() == BeaconCommand::Hard) 00648 { 00649 UpdateGlobalHardDRPMap((*it).second->GetPattern()); 00650 } 00651 else if((*it).second->GetReservationType() == BeaconCommand::Soft) 00652 { 00653 UpdateGlobalSoftDRPMap((*it).second->GetPattern()); 00654 } 00655 } 00656 if ((*it).second->HasPendingDRPMerge() && (*it).second->GetMergeReasonCode() == BeaconCommand::Accept && (*it).second->GetMergeStatus() == true) 00657 { 00658 MESSAGE_SINGLE(NORMAL, logger, "Updating DRP-Map of this station with an additional active reservation as target with partner" << (*it).second->GetAddress()); 00659 if((*it).second->GetReservationType() == BeaconCommand::Hard) 00660 { 00661 UpdateGlobalHardDRPMap((*it).second->GetMergePattern()); 00662 } 00663 else if((*it).second->GetReservationType() == BeaconCommand::Soft) 00664 { 00665 UpdateGlobalSoftDRPMap((*it).second->GetMergePattern()); 00666 } 00667 } 00668 } 00669 00670 00671 if(!HasCreated) 00672 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: neither active nor pending connection, no stuff for a DRP InformationElement"); 00673 return HasCreated; 00674 } 00675 00676 bool 00677 BeaconEvaluator::CreateProbeIE(BeaconCommand* BeaconCommand) 00678 { 00679 if (hasPendingProbe) 00680 { 00681 // Put Probe into beacon 00682 BeaconCommand->peer.probe = pendingProbe; 00683 00684 // Reset internal Probe storage 00685 pendingProbe.clear(); 00686 hasPendingProbe = false; 00687 00688 return true; 00689 } 00690 else return false; 00691 } 00692 00693 void 00694 BeaconEvaluator::RequestIE(wns::service::dll::UnicastAddress rx, BeaconCommand::ProbeElementID elementID) 00695 { 00696 // Insert IE request into next beacon probe 00697 if (pendingProbe.knows(rx)) 00698 { 00699 // Push requested IE into existing Probe IE for that recipient 00700 pendingProbe.find(rx).push(elementID); 00701 } 00702 else 00703 { 00704 // Create a new Probe IE with the requested IE ID 00705 std::queue<BeaconCommand::ProbeElementID> probeElements; 00706 probeElements.push(elementID); 00707 pendingProbe.insert(rx, probeElements); 00708 hasPendingProbe = true; 00709 } 00710 } 00711 00712 void 00713 BeaconEvaluator::UpdateGlobalSoftDRPMap(Vector UpdateMap) 00714 { 00715 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Update Soft"); 00716 DRPmapManager->UpdateSoftDRPmap(UpdateMap, logger); 00717 } 00718 00719 00720 void 00721 BeaconEvaluator::UpdateGlobalHardDRPMap(Vector UpdateMap) 00722 { 00723 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Update Hard"); 00724 DRPmapManager->UpdateHardDRPmap(UpdateMap, logger); 00725 } 00726 00727 void 00728 BeaconEvaluator::UpdateGlobalDRPMap(Vector UpdateMap) 00729 { 00730 MESSAGE_SINGLE(NORMAL, logger, "BeaconEvaluator: Update Global"); 00731 DRPmapManager->UpdateHardDRPmap(UpdateMap, logger); 00732 DRPmapManager->UpdateSoftDRPmap(UpdateMap, logger); 00733 } 00734 00735 bool 00736 BeaconEvaluator::UpdateMapWithPeerAvailabilityMap(wns::service::dll::UnicastAddress rx , Vector& DRPMap) 00737 { 00738 if (rxAvailabilityBitmap.knows(rx)) 00739 { 00740 Vector availabilityMap_ = rxAvailabilityBitmap.find(rx); 00741 bool hasUpdated = false; 00742 for (int i = 0; i < availabilityMap_.size(); i++) 00743 { 00744 assure(i < availabilityMap_.size() && i < DRPMap.size(), "Vector boundary exeeded; loop error!"); 00745 if(availabilityMap_[i] == false) 00746 { 00747 // Return true only, if the availability map decreases the usable slots 00748 if(DRPMap[i] == false) hasUpdated = true; 00749 00750 DRPMap[i] = true; 00751 } 00752 } 00753 return hasUpdated; 00754 } 00755 else return false; 00756 } 00757 00758 Vector 00759 BeaconEvaluator::getAllocatedMASs() 00760 { 00761 return tmpAllocatedMAS; 00762 } 00763 00764 Vector 00765 BeaconEvaluator::getReservedMASs() 00766 { 00767 return DRPmapManager->GetGlobalHardDRPmap(); 00768 } 00769 00770 //TODO: the Beacon Period Slot Duration must be inserted instead of 85E-6 00771 //returns the beacon slot related to time of calling this function 00772 int 00773 BeaconEvaluator::getBeaconSlot() 00774 { 00775 BPStartTime = friends.manager-> getBPStartTime(); 00776 wns::simulator::Time timenow = wns::simulator::getEventScheduler()->getTime(); 00777 00778 MESSAGE_SINGLE(NORMAL, logger, "ExamineBeaconPeriodOccupancy, time now: " << timenow 00779 << " BP Start " << BPStartTime); 00780 00781 int BeaconSlot = floor((timenow-BPStartTime)/85E-6); 00782 return(BeaconSlot); 00783 00784 } 00785 00786 void 00787 BeaconEvaluator::ExamineBeaconPeriodOccupancy(wns::service::dll::UnicastAddress tx, BeaconCommand* BeaconCommand) 00788 { 00789 00790 int BeaconSlot = getBeaconSlot(); 00791 00792 wns::service::dll::UnicastAddress inValidAddress = wns::service::dll::UnicastAddress::UnicastAddress(); 00793 00794 for (int i = 0 ; i < BeaconCommand->peer.BPOIE.IE.size();i++) 00795 { 00796 MESSAGE_SINGLE(NORMAL, logger, "ExamineBeaconPeriodOccupancy, I've got a BPOIE from my neighbour " << tx <<", lets have a look: " 00797 << i << " Address: " << BeaconCommand->peer.BPOIE.IE[i]); 00798 } 00799 00800 //if the current Beacon Period Occupancy Vector is smaller than the Beacon Period Size announced in the received Beacon, the Vector will be increased to store the information 00801 if(BeaconCommand->peer.BPOIE.IE.size() > BPoccupancy.size()) 00802 { 00803 MESSAGE_SINGLE(NORMAL, logger, "Resize BPOIE size" << BeaconCommand->peer.BPOIE.IE.size() << " own Size " << BPoccupancy.size()); 00804 00805 //BPoccupancy.resize(BeaconCommand->peer.BPOIE.IE.size() - BPoccupancy.size(), inValidAddress); 00806 BPoccupancy.resize(BeaconCommand->peer.BPOIE.IE.size(), inValidAddress); 00807 } 00808 00809 if(BeaconSlot >= BPoccupancy.size()) 00810 { 00811 BPoccupancy.resize(BeaconSlot+1, inValidAddress); 00812 } 00813 00814 MESSAGE_SINGLE(NORMAL, logger, "ExamineBeaconPeriodOccupancy, received Beacon in Beacon Slot: " << BeaconSlot 00815 << "Beacon is originated from " << tx); 00816 00817 wns::service::dll::UnicastAddress address = BPoccupancy.at(BeaconSlot); 00818 if(!address.isValid()) 00819 { 00820 MESSAGE_SINGLE(NORMAL, logger, "ExamineBeaconPeriodOccupancy, invalid"); 00821 00822 assure(BeaconSlot <= BPoccupancy.size(), "Element is not part of BPoccupancy, limit is exceeded"); 00823 BPoccupancy[BeaconSlot] = tx; 00824 } 00825 00826 for(int i = 0 ; i < BPoccupancy.size(); i++) 00827 { 00828 MESSAGE_SINGLE(NORMAL, logger, "ExamineBeaconPeriodOccupancy, BPoccupancy is now as followed: " << i 00829 << " tx " << BPoccupancy[i]); 00830 } 00831 00832 //if the neighbour address is known, update the BPOIE or store the new element 00833 for(int i = 0; i < NeighboursBPoccupancy.size(); i++) 00834 { 00835 if(NeighboursBPoccupancy[i].source == tx) 00836 { 00837 MESSAGE_SINGLE(NORMAL, logger, "This neighbour is known, update the BPOIE"); 00838 NeighboursBPoccupancy[i].BPoccupancy = BeaconCommand->peer.BPOIE.IE; 00839 break; 00840 } 00841 else if(NeighboursBPoccupancy[i].source != tx && i == NeighboursBPoccupancy.size() - 1) 00842 { 00843 MESSAGE_SINGLE(NORMAL, logger, "This neighbour isn't known, insert it's BPOIE into the container"); 00844 InsertInNeighoursBPoccupancy(tx, BeaconCommand); 00845 } 00846 00847 } 00848 //if the container to store the BPOIEs of the neighbours is empty, insert the received BPOIE as the first element 00849 if(NeighboursBPoccupancy.size() == 0) 00850 { 00851 MESSAGE_SINGLE(NORMAL, logger, "This is the first received BPOIE, insert it into the container"); 00852 InsertInNeighoursBPoccupancy(tx, BeaconCommand); 00853 00854 } 00855 00856 } 00857 00858 void 00859 BeaconEvaluator::InsertInNeighoursBPoccupancy(wns::service::dll::UnicastAddress tx, BeaconCommand* BeaconCommand) 00860 { 00861 struct BPallocation BPallocation_; 00862 BPallocation_.source = tx; 00863 BPallocation_.BPoccupancy = BeaconCommand->peer.BPOIE.IE; 00864 NeighboursBPoccupancy.push_back(BPallocation_); 00865 00866 }
1.5.5