User Manual, Developers Guide and API Documentation

BeaconEvaluator.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/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 }

Generated on Mon May 21 03:32:18 2012 for openWNS by  doxygen 1.5.5