User Manual, Developers Guide and API Documentation

DRPPatternCreator.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  * WiMeMac                                                                    *
00003  * This file is part of openWNS (open Wireless Network Simulator)
00004  * _____________________________________________________________________________
00005  *
00006  * Copyright (C) 2004-2011
00007  * Chair of Communication Networks (ComNets)
00008  * Kopernikusstr. 5, D-52074 Aachen, Germany
00009  * phone: ++49-241-80-27910,
00010  * fax: ++49-241-80-22242
00011  * email: info@openwns.org
00012  * www: http://www.openwns.org
00013  * _____________________________________________________________________________
00014  *
00015  * openWNS is free software; you can redistribute it and/or modify it under the
00016  * terms of the GNU Lesser General Public License version 2 as published by the
00017  * Free Software Foundation;
00018  *
00019  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00020  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00021  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00022  * details.
00023  *
00024  * You should have received a copy of the GNU Lesser General Public License
00025  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00026  *
00027  ******************************************************************************/
00028 
00029 #include <WIMEMAC/drp/DRPPatternCreator.hpp>
00030 #include <WIMEMAC/lowerMAC/Manager.hpp>
00031 #include <math.h>
00032 
00033 using namespace wimemac::drp;
00034 
00035 DRPPatternCreator::DRPPatternCreator(wns::logger::Logger logger_, double patternPEROffset_, wns::service::dll::UnicastAddress TargetAddress_):
00036     SlotpSF(256),
00037     GlobalDRPMap(256, false),
00038     SlotDuration(256E-6),
00039     GuardDuration(12E-6),
00040     SIFSduration(10E-6),
00041     PreambPlusHeadDuration(11.25E-6),
00042     ACKduration(13.125E-6),
00043     patternPEROffset(patternPEROffset_),
00044     TargetAddress(TargetAddress_),
00045     logger(logger_)
00046 {
00047 }
00048 
00049 void 
00050 DRPPatternCreator::SetReservationGap(int SlotAmount)
00051 {
00052     ReservationGap = SlotAmount;
00053 }
00054 
00055 void
00056 DRPPatternCreator::SetNumberOfBPSlots(int numberOfBPSlots_)
00057 {
00058     NumberOfBPSlots = numberOfBPSlots_;
00059 }
00060 
00061 void
00062 DRPPatternCreator::SetPhyMode(wimemac::convergence::PhyMode phyMode_)
00063 {
00064     phyMode = phyMode_;
00065 }
00066 
00067 int
00068 DRPPatternCreator::CalcMissingPackets(Vector& allocMap_)
00069 {
00070     int i = 0;
00071     int last = allocMap_.size();
00072     int tmpAdj = 0;
00073     int PosPacketpSF = 0;
00074 
00075     while(i < last)
00076     {
00077         assure(i<allocMap_.size(), "Vector boundary exeeded; loop error!");
00078         while(i < last && allocMap_[i] == false)
00079             i++;
00080 
00081         if (i >= last) break;
00082         assure(i<allocMap_.size(), "Vector boundary exeeded; loop error!");
00083         while(i < last && allocMap_[i] == true)
00084         {
00085             ++tmpAdj;
00086             ++i;
00087         }
00088         if(tmpAdj > 0)
00089         {
00090             wns::simulator::Time TXOP = 0;
00091             TXOP = tmpAdj * SlotDuration - GuardDuration;
00092 
00093             double FTDuration_ = friends.manager->getProtocolCalculator()->getDuration()->MSDU_PPDU((Bit)MaxPacketSize, phyMode) + 2*SIFSduration + ACKduration;
00094 
00095             PosPacketpSF += floor(TXOP/FTDuration_);
00096             tmpAdj = 0;
00097         }
00098 
00099     }
00100 
00101     int missingPackets = (PosPacketpSF < PacketpSF) ? PacketpSF - PosPacketpSF : 0;
00102     return missingPackets;
00103 }
00104 
00105 wimemac::convergence::PhyMode
00106 DRPPatternCreator::getPhyMode()
00107 {
00108     return phyMode;
00109 }
00110 
00111 void
00112 DRPPatternCreator::SetTrafficChar(int PacketpFrame, int BitpFrame, int MaxCompoundSize, int reservationBlocks)
00113 {
00114     MaxPacketSize = MaxCompoundSize;
00115     PacketpSF = ceil( PacketpFrame * (1 + patternPEROffset) ); // Add traffic bandwidth according to max allowed PER
00116     DataDuration = friends.manager->getProtocolCalculator()->getDuration()->MSDU_PPDU((Bit)MaxPacketSize, phyMode);
00117     FTDuration = DataDuration + 2*SIFSduration + ACKduration;
00118     DivideSFintoAreas = reservationBlocks;
00119     ReservationGap = (SlotpSF - NumberOfBPSlots) / DivideSFintoAreas;
00120     mAdjSlot = ceil( (double) FTDuration / (double) SlotDuration);
00121     PacketpArea = ceil( (double) PacketpSF / (double) DivideSFintoAreas);
00122     AdjSlot = ceil( ((double)PacketpArea * (double)FTDuration) / (double)SlotDuration);
00123 
00124     if (AdjSlot > ReservationGap)
00125     {
00126         MESSAGE_SINGLE(NORMAL, logger, "SetTrafficChar : Too much traffic! Using phymode " << phyMode.getDataRate() << " the transmission would need " << AdjSlot * SlotpSF / ReservationGap << " MASs. Trying to use the maximum of " << SlotpSF << " - " <<  NumberOfBPSlots << " Beacon slots");
00127         AdjSlot = SlotpSF - NumberOfBPSlots;
00128         ReservationGap = SlotpSF - NumberOfBPSlots;
00129         PacketpArea = PacketpSF;
00130     }
00131 
00132     MESSAGE_SINGLE(NORMAL, logger, "SetTrafficChar : ReservationGap: " << ReservationGap << " | PacketpArea: " << PacketpArea << " | AdjSlot: " << AdjSlot << " | FTDuration is set to " << FTDuration);
00133 
00134 }
00135 
00136 void
00137 DRPPatternCreator::UpdateTrafficChar(int CompoundspSF, int BitspSF, int MaxCompoundSize)
00138 {
00139     MaxPacketSize = MaxCompoundSize;
00140     PacketpSF = ceil( CompoundspSF * (1 + patternPEROffset) ); // Add traffic bandwidth according to max allowed PER
00141     PacketpArea = ceil( (double) PacketpSF / (double) DivideSFintoAreas);
00142     
00143     UpdateTrafficChar();
00144 }
00145 
00146 void
00147 DRPPatternCreator::UpdateTrafficChar()
00148 {
00149     // Update TrafficChar according to changes of phymode
00150     DataDuration = friends.manager->getProtocolCalculator()->getDuration()->MSDU_PPDU((Bit)MaxPacketSize, phyMode);
00151     FTDuration = DataDuration + 2*SIFSduration + ACKduration;
00152     mAdjSlot = ceil( (double) FTDuration / (double) SlotDuration);
00153     AdjSlot = ceil( ((double)PacketpArea * (double)FTDuration) / (double)SlotDuration);
00154 
00155     if (AdjSlot > ReservationGap)
00156     {
00157         MESSAGE_SINGLE(NORMAL, logger, "UpdateTrafficChar : Too much traffic! Using phymode " << phyMode.getDataRate() << " the transmission would need " << AdjSlot * SlotpSF / ReservationGap << " MASs. Trying to use the maximum of " << SlotpSF << " - " <<  NumberOfBPSlots << " Beacon slots");
00158         AdjSlot = SlotpSF - NumberOfBPSlots;
00159         ReservationGap = SlotpSF - NumberOfBPSlots;
00160         PacketpArea = PacketpSF;
00161     }
00162 
00163     MESSAGE_SINGLE(NORMAL, logger, "UpdateTrafficChar : ReservationGap: " << ReservationGap << " | PacketpArea: " << PacketpArea << " | AdjSlot: " << AdjSlot << " | FTDuration is set to " << FTDuration);
00164 }
00165 
00166 
00167 bool DRPPatternCreator::GetPattern(Vector& ProposedPattern, Vector& ConstraintDRPMap, bool useInperfectPatterns)
00168 {
00169 
00170     if(friends.manager->getRandomUse())
00171     {
00172         Vector tmpDRPAllocMap(256, false);
00173         return CreateRandomPattern(ProposedPattern, tmpDRPAllocMap, ConstraintDRPMap, useInperfectPatterns);
00174     }
00175     else
00176     {
00177 
00178         copy(ConstraintDRPMap.begin(), ConstraintDRPMap.end(), GlobalDRPMap.begin());
00179 
00180         Vector tmpProposedPattern(256,false);
00181         InitVector(tmpProposedPattern);
00182         int PosArea;
00183         CalcMaxPropMap(tmpProposedPattern);
00184 
00185         for(int i = 0; i < 256; i++)
00186         {
00187             assure(i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00188             if(maxPosPattern.maxProposedPattern[i] == true)
00189                     MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Maximum proper pattern occupies slot nr: " << i );
00190         }
00191 
00192         if(maxPosPattern.conflict != 0)
00193         {
00194             ClearConflictArea();
00195 
00196             for(int i = 0; i < 256; i++)
00197             {
00198                 assure(i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00199                 if(maxPosPattern.maxProposedPattern[i] == true)
00200                     MESSAGE_SINGLE(NORMAL, logger, "InitPattern: After conflicts are removed pattern occupies slot nr: " << i );
00201             }
00202 
00203             int first = NumberOfBPSlots;
00204             int last = NumberOfBPSlots + ReservationGap;
00205             int nr = 1;
00206             while(last <= maxPosPattern.maxProposedPattern.size())
00207             {
00208 
00209                 if(FindEmptyArea(maxPosPattern.maxProposedPattern, first, last))
00210                 {
00211                     MESSAGE_SINGLE(NORMAL, logger, "InitPattern: this area is empty " << nr << " of " << DivideSFintoAreas);
00212                     if(!AllocAreaOutside(first,last, AdjSlot))
00213                     {
00214                         int block = ceil(double(AdjSlot)/double(mAdjSlot));
00215 
00216                         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Blocks of size " << mAdjSlot << " needed : " << block);
00217                         while(block != 0)
00218                         {
00219                             if(AllocAreaOutside(first,last, mAdjSlot))
00220                                 block--;
00221                             else break;
00222                         }
00223                     }
00224 
00225                     for(int i = first; i < last; i++)
00226                     {
00227                         assure(i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00228                         if(maxPosPattern.maxProposedPattern[i] == true)
00229                             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: SplitArea: " << i );
00230                     }
00231 
00232                 }
00233                 else
00234                 {
00235                     MESSAGE_SINGLE(NORMAL, logger, "InitPattern: this area is not empty " << nr << " of " << DivideSFintoAreas);
00236                 }
00237                 first = last;
00238                 last += ReservationGap;
00239                 if(last >= maxPosPattern.maxProposedPattern.size())
00240                     last =  maxPosPattern.maxProposedPattern.size() - 1;
00241                 if(last <= first)
00242                     break;
00243                 nr++;
00244             }
00245 
00246         }
00247 
00248         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: With this pattern  " << CalcPacketpArea(0, 256)  <<" compounds could be transported ");
00249 
00250         bool returnValue;
00251         // Evaluation of return value using only one single stream
00252         if (EvaluateReservation())
00253         {
00254             for(int i = 0; i< 256;i++)
00255             {
00256                 assure(i<ProposedPattern.size() && i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00257                 ProposedPattern[i] = maxPosPattern.maxProposedPattern[i];
00258             }
00259             returnValue = true;
00260         }
00261         else
00262         {
00263             if(useInperfectPatterns)
00264             {
00265                 for(int i = 0; i< 256;i++)
00266                 {
00267                     assure(i<ProposedPattern.size() && i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00268                     ProposedPattern[i] = maxPosPattern.maxProposedPattern[i];
00269                 }
00270             }
00271 
00272             returnValue = false;
00273         }
00274         for(int i = 0; i < ProposedPattern.size(); i++)
00275         {
00276             if(ProposedPattern[i] == true)
00277                 MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Pattern after evaluation slot nr: " << i );
00278         }
00279         return returnValue;
00280     }
00281 }
00282 
00283 bool
00284 DRPPatternCreator::AddPattern(Vector& ProposedPattern, Vector& DRPAllocMap, Vector& ConstraintDRPMap, bool useInperfectPatterns)
00285 {
00286 
00287     if(friends.manager->getRandomUse())
00288     {
00289         return CreateRandomPattern(ProposedPattern, DRPAllocMap, ConstraintDRPMap, useInperfectPatterns);
00290     }
00291     else
00292     {
00293     // Initialise pattern with already reserved slots of this station
00294     Vector tmpProposedPattern = DRPAllocMap;
00295     copy(ConstraintDRPMap.begin(), ConstraintDRPMap.end(), GlobalDRPMap.begin());
00296 
00297     // Since this pattern is already used there are no conflicts
00298     maxPosPattern.conflict = 0;
00299     maxPosPattern.SetVector(tmpProposedPattern);
00300 
00301     MESSAGE_SINGLE(NORMAL, logger, "AddPattern: With this pattern  " << CalcPacketpArea(0, 256)  <<" compounds could be transported ");
00302 
00303     // Evaluate complete reservation
00304     bool returnValue;
00305     if (EvaluateReservation())
00306     {
00307         // Reservation evaluation returned perfect -> use proposed pattern
00308         for(int i = 0; i < 256; i++)
00309         {
00310             assure(i<maxPosPattern.maxProposedPattern.size() && i< DRPAllocMap.size() && i<ProposedPattern.size(), "Vector boundary exeeded; loop error!");
00311             if (maxPosPattern.maxProposedPattern[i] == true && DRPAllocMap[i] == false)
00312                 ProposedPattern[i] = true;
00313             else ProposedPattern[i] = false;
00314         }
00315 
00316         returnValue = true;
00317     }
00318     else
00319     {
00320         if(useInperfectPatterns)
00321         {
00322             // Reservation evaluation returned NOT perfect, but inperfect patterns should also be used
00323             for(int i = 0; i < 256; i++)
00324             {
00325                 assure(i<maxPosPattern.maxProposedPattern.size() && i< DRPAllocMap.size() && i<ProposedPattern.size(), "Vector boundary exeeded; loop error!");
00326                 if (maxPosPattern.maxProposedPattern[i] == true && DRPAllocMap[i] == false)
00327                     ProposedPattern[i] = true;
00328                 else ProposedPattern[i] = false;
00329             }
00330         }
00331 
00332         returnValue = false;
00333     }
00334 
00335     MESSAGE_SINGLE(NORMAL, logger, "AddPattern: Additional pattern is determined:");
00336     for(int i = 0; i < ProposedPattern.size(); i++)
00337     {
00338         if(ProposedPattern[i] == true)
00339             MESSAGE_SINGLE(NORMAL, logger, "AddPattern: Additional pattern slot nr " << i );
00340     }
00341 
00342     return returnValue;
00343     }
00344 }
00345 
00346 bool
00347 DRPPatternCreator::CreateRandomPattern(Vector& ProposedPattern, Vector& DRPAllocMap, Vector& ConstraintDRPMap, bool useInperfectPatterns)
00348 {
00349     copy(ConstraintDRPMap.begin(), ConstraintDRPMap.end(), GlobalDRPMap.begin());
00350     Vector tmpProposedPattern(256,false);
00351 
00352     // Prevent allocated slots from being used that may not yet be in the constraintdrpmap
00353     for(int i = 0; i < 256; i++)
00354     {
00355         if(DRPAllocMap[i] == true) GlobalDRPMap[i] = true;
00356     }
00357     // Fill List with all free areas of size mAdjSlots
00358     std::vector<int> emptyAreas_;
00359     int i = 0;
00360     while (i < GlobalDRPMap.size())
00361     {
00362         while (GlobalDRPMap[i] == true && i < GlobalDRPMap.size()) i++;
00363         int tmpAdjSlots = 0;
00364         int firstSlot_ = i;
00365         while (GlobalDRPMap[i] == false && i < GlobalDRPMap.size())
00366         {
00367             i++;
00368             tmpAdjSlots++;
00369             if (tmpAdjSlots == 2) break;
00370         }
00371         if (tmpAdjSlots >= 2)
00372         {
00373             emptyAreas_.push_back(firstSlot_);
00374         }
00375     }
00376     int MissingReservation = CalcMissingPackets(DRPAllocMap);
00377 
00378     while (MissingReservation > 0 && emptyAreas_.size() > 0 )
00379     {
00380         int areaNumber_ = rand() % emptyAreas_.size();
00381         int i = emptyAreas_[areaNumber_];
00382         int GapSize_ = 0;
00383         while(GlobalDRPMap[i] == false && tmpProposedPattern[i] == false)
00384         {
00385             GapSize_++;
00386             i++;
00387             if(i >= tmpProposedPattern.size()) //if the end of the map is reached
00388                 break;
00389             if(GapSize_ >= 2)   //if the number of MASs fits mAdjSlots
00390                 break;
00391         }
00392         if(GapSize_ >= 2)
00393         {
00394             MESSAGE_SINGLE(NORMAL, logger, "CreateRandomPattern : Reserved slots " << i - GapSize_ << " to slot " << i-1);
00395             // Fill pattern with new allocated slots
00396             for(int j=i-GapSize_; j<i; j++)
00397             {
00398                 tmpProposedPattern[j] = true;
00399             }
00400             // Delete allocated area from list
00401             emptyAreas_.erase(emptyAreas_.begin() + areaNumber_);
00402             // Missing now
00403             int packetsInThisGap = floor((GapSize_ * SlotDuration - GuardDuration) / FTDuration);
00404             MissingReservation -= packetsInThisGap;
00405         }
00406     }
00407 
00408 
00409     if (emptyAreas_.size() == 0) MESSAGE_SINGLE(NORMAL, logger, "CreateRandomPattern : No more Areas with mAdjSlot size available");
00410 
00411     if((MissingReservation <= 0) || useInperfectPatterns)
00412     {
00413         for (int i = 0; i < tmpProposedPattern.size(); i++)
00414         {
00415             if(tmpProposedPattern[i] == true) ProposedPattern[i] = true;
00416         }
00417     }
00418 
00419     if(MissingReservation > 0) return false;
00420     else return true;
00421 }
00422 
00423 int
00424 DRPPatternCreator::GapFilling(int MissingReservation)
00425 {
00426     MESSAGE_SINGLE(NORMAL, logger, "Start GapFilling");
00427     for(int i=0; i<maxPosPattern.maxProposedPattern.size(); i++)
00428     {
00429         if(MissingReservation > 0)
00430         {
00431             if(GlobalDRPMap[i] == false && maxPosPattern.maxProposedPattern[i] == false)
00432             {
00433                 int GapSize = 0;
00434                 int packetsInThisGap = 0;
00435                 while(GlobalDRPMap[i] == false && maxPosPattern.maxProposedPattern[i] == false)
00436                 {
00437                     GapSize++;
00438                     i++;
00439                     if(i >= maxPosPattern.maxProposedPattern.size()) //if the end of the map is reached
00440                         break;
00441                     packetsInThisGap = floor((GapSize * SlotDuration - GuardDuration) / FTDuration);
00442                     if(packetsInThisGap >= MissingReservation)   //if the number of neccessary packets is reached
00443                         break;
00444                 }
00445                 if(GapSize >= mAdjSlot)
00446                 {
00447                     MESSAGE_SINGLE(NORMAL, logger, "GapFilling : Found a gap.");
00448                     if(GapSize == 1)
00449                     {
00450                         MESSAGE_SINGLE(NORMAL, logger, "GapFilling : New reserved slot: " << i - GapSize);
00451                     }
00452                     else
00453                         MESSAGE_SINGLE(NORMAL, logger, "GapFilling : Reserved slot " << i - GapSize << " to slot " << i-1);
00454 
00455                     for(int j=i-GapSize; j<i; j++)
00456                     {
00457                         maxPosPattern.maxProposedPattern[j] = true;
00458                     }
00459                     MissingReservation -= packetsInThisGap;
00460                 }
00461             }
00462         }
00463     }
00464     return MissingReservation;
00465 }
00466 
00467 void
00468 DRPPatternCreator::InitVector(Vector& InitMap)
00469 {
00470     int tmpAdjSlot = AdjSlot;
00471     int SlotNumber = NumberOfBPSlots;
00472     int it = NumberOfBPSlots;
00473 
00474     if (AdjSlot == 0) return;
00475 
00476     MESSAGE_SINGLE(NORMAL, logger, "InitVector :  AdjSlot : " << AdjSlot << " |  Size : " << InitMap.size());
00477     while(it <= InitMap.size() - AdjSlot)
00478     {
00479 
00480         while((SlotNumber - NumberOfBPSlots) % ReservationGap != 0 && it <= InitMap.size())
00481         {
00482             ++it;
00483             ++SlotNumber;
00484         }
00485 
00486         tmpAdjSlot = AdjSlot;
00487         if(it <= InitMap.size() - AdjSlot)
00488         {
00489             while(tmpAdjSlot > 0)
00490             {
00491                 InitMap[it] = true;
00492                 --tmpAdjSlot;
00493                 it++;
00494                 SlotNumber++;
00495             }
00496 
00497         }
00498 
00499     }
00500 
00501 }
00502 
00503 bool
00504 DRPPatternCreator::IsPatternValid(Vector& ProposedMap) const
00505 {
00506     for(int i = 0; i < ProposedMap.size(); i++)
00507     {
00508         assure(i<GlobalDRPMap.size(), "Vector boundary exeeded; loop error!");
00509         if(ProposedMap[i] && GlobalDRPMap[i] == true)
00510             return false;
00511     }
00512     return true;
00513 }
00514 
00515 int
00516 DRPPatternCreator::CalcNumArea(Vector& ProposedMap)
00517 {
00518     int Conflict = 0;
00519     for(int i = 0; i < 256; i++)
00520     {
00521         while(ProposedMap[i] == false && i < ProposedMap.size())
00522             i++;
00523         if(ProposedMap[i] && GlobalDRPMap[i] == true && i < GlobalDRPMap.size())
00524         {
00525             Conflict++;
00526             while(ProposedMap[i] == true && i < ProposedMap.size())
00527                 i++;
00528         }
00529     }
00530     return Conflict;
00531 }
00532 
00533 void
00534 DRPPatternCreator::CalcMaxPropMap(Vector& tmpProposedPattern)
00535 {
00536     int conflict;
00537     conflict = CalcNumArea(tmpProposedPattern);
00538     maxPosPattern.conflict = conflict;
00539     maxPosPattern.SetVector(tmpProposedPattern);
00540 
00541     int RotationShifts = 0;
00542     while(!IsPatternValid(tmpProposedPattern) && RotationShifts < ReservationGap)
00543     {
00544         conflict = CalcNumArea(tmpProposedPattern);
00545         if(conflict < maxPosPattern.conflict)
00546         {
00547             maxPosPattern.conflict = conflict;
00548             maxPosPattern.SetVector(tmpProposedPattern);
00549         }
00550         rotate(tmpProposedPattern.begin(), tmpProposedPattern.end()-1, tmpProposedPattern.end());
00551         RotationShifts++;
00552     }
00553     conflict = CalcNumArea(tmpProposedPattern);
00554     if(conflict == 0)
00555         maxPosPattern.SetVector(tmpProposedPattern);
00556     maxPosPattern.conflict = conflict;
00557 
00558 }
00559 
00560 bool
00561 DRPPatternCreator::PatternHasFreeSlots(Vector pattern)
00562 {
00563     bool hasFreeSlots = false;
00564 
00565     for(int i = NumberOfBPSlots; i < pattern.size(); i++)
00566     {
00567         if(pattern[i] == false)
00568         {
00569             hasFreeSlots = true;
00570             break;
00571         }
00572     }
00573     return hasFreeSlots;
00574 }
00575 
00576 bool
00577 DRPPatternCreator::FindEmptyArea(Vector& tmpProposedPattern, int first, int last)
00578 {
00579     int i = first;
00580     int tmpAdj = AdjSlot;
00581     while(i < tmpProposedPattern.size() && i < last)
00582     {
00583         if(tmpProposedPattern[i] == true)
00584             tmpAdj--;
00585 
00586         i++;
00587     }
00588 
00589     if(tmpAdj == 0)
00590         return false;
00591 
00592     return true;
00593 }
00594 
00595 bool
00596 DRPPatternCreator::ClearConflictArea()
00597 {
00598     int i = 0;
00599     while(i < maxPosPattern.maxProposedPattern.size())
00600     {
00601         assure(i<GlobalDRPMap.size(), "Vector boundary exeeded; loop error!");
00602         if(maxPosPattern.maxProposedPattern[i] == true && GlobalDRPMap[i] == true)
00603         {
00604             int FirstConflict = i;
00605             while(i < maxPosPattern.maxProposedPattern.size() && maxPosPattern.maxProposedPattern[i] == true)
00606             {
00607                 maxPosPattern.maxProposedPattern[i] = false;
00608                 i++;
00609             }
00610             if(FirstConflict > 0)
00611             {
00612                 i = FirstConflict - 1;
00613                 while(i >= 0 && maxPosPattern.maxProposedPattern[i] == true)
00614                 {
00615                     assure(i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00616                     maxPosPattern.maxProposedPattern[i] = false;
00617                     i--;
00618                 }
00619             }
00620 
00621         }
00622         i++;
00623     }
00624 }
00625 
00626 
00627 bool
00628 DRPPatternCreator::AllocAreaOutside(int first, int last, int CalcAdjSlot)
00629 {
00630     assure(first<maxPosPattern.maxProposedPattern.size() && last<=maxPosPattern.maxProposedPattern.size() && CalcAdjSlot > 0, "AllocAreaOutside: invalid input parameters.");
00631     if(IsSpaceLeft(first, last, CalcAdjSlot))
00632     {
00633         int i = first;
00634         int firstfree;
00635         int tmpAdj = CalcAdjSlot;
00636         assure(i<GlobalDRPMap.size() && i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00637         while(i < last && (GlobalDRPMap[i] == true || maxPosPattern.maxProposedPattern[i] == true))
00638             i++;
00639         firstfree = i;
00640         while(i < last && GlobalDRPMap[i] == false && maxPosPattern.maxProposedPattern[i] == false)
00641         {
00642             --tmpAdj;
00643             ++i;
00644         }
00645         if(tmpAdj <= 0)
00646         {
00647             tmpAdj = CalcAdjSlot;
00648             i = firstfree;
00649             while(tmpAdj > 0)
00650             {
00651                 assure(i<maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00652                 maxPosPattern.maxProposedPattern[i] = true;
00653                 ++i;
00654                 --tmpAdj ;
00655             }
00656         }
00657         else
00658         {
00659             if(i < maxPosPattern.maxProposedPattern.size())
00660                 return(AllocAreaOutside(i, last,CalcAdjSlot));
00661             else
00662                 return false;
00663         }
00664         return true;
00665     }
00666     else
00667     {
00668         return false;
00669     }
00670 }
00671 
00672 
00673 bool
00674 DRPPatternCreator::IsSpaceLeft(int first, int last, int CalcAdjSlot) const
00675 {
00676     int i = first;
00677     int space = 0;
00678 
00679     assure(last<=GlobalDRPMap.size(), "Vector boundary exeeded; loop error!");
00680         while(i < last && (GlobalDRPMap[i] == true || maxPosPattern.maxProposedPattern[i] == true))
00681             i++;
00682 
00683         assure(i <= last && last <= GlobalDRPMap.size(), "Vector boundary exeeded; loop error!");
00684         while(i < last && (GlobalDRPMap[i] == false && maxPosPattern.maxProposedPattern[i] == false))
00685         {
00686             ++space;
00687             ++i;
00688         }
00689         if(space >= CalcAdjSlot)
00690         {
00691             return true;
00692         }
00693 
00694         if(i == last)
00695             return false;
00696         return(IsSpaceLeft(i, last,CalcAdjSlot));
00697 
00698 }
00699 
00700 
00701 
00702 bool
00703 DRPPatternCreator::EvaluateReservation()
00704 {
00705     MESSAGE_SINGLE(NORMAL, logger, "InitPattern: evaluate reservation ");
00706 
00707     int ExpectedPackets = PacketpSF;
00708     int first = 0;
00709     int last = maxPosPattern.maxProposedPattern.size();
00710     int MissingReservation = (CalcPacketpArea(first,last) < ExpectedPackets) ? ExpectedPackets - CalcPacketpArea(first,last) : 0;
00711     if(MissingReservation != 0)
00712     {
00713         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: evaluate the reservation: not perfect -> search for more slots");
00714 
00715         // Count number of reserved MASs
00716         int numberOfReservedSlots_ = 0;
00717         for(int i = 0; i< maxPosPattern.maxProposedPattern.size();i++)
00718             if(maxPosPattern.maxProposedPattern[i] == true) numberOfReservedSlots_++;
00719 
00720         if (numberOfReservedSlots_ == SlotpSF - NumberOfBPSlots)
00721         {
00722             // If the whole SF is reserved, don't continue since there are no more slots
00723             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: All MASs slots are used. The missing " << MissingReservation << " packets definitely cannot be send");
00724             return true;
00725         }
00726 
00727         BestEfficency(MissingReservation);
00728 
00729     }
00730     first = 0;
00731     last = maxPosPattern.maxProposedPattern.size();
00732     MissingReservation = (CalcPacketpArea(first,last) < ExpectedPackets) ? ExpectedPackets - CalcPacketpArea(first,last) : 0;
00733 
00734     if(MissingReservation > 0)
00735     {
00736         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: evaluate the reservation: not perfect -> Gapfilling");
00737         MissingReservation = GapFilling(MissingReservation);
00738     }
00739     if(MissingReservation > 0)
00740     {
00741         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: evaluate the reservation: not perfect -> returning anyway");
00742         return false;
00743     }
00744     else
00745     {
00746         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: evaluate the reservation: perfect");
00747         return true;
00748     }
00749 }
00750 
00751 
00752 void
00753 DRPPatternCreator::BestEfficency(int MissingReservation)
00754 {
00755     int i = 0;
00756     int tmpAdj = 0;
00757     int packet = 0;
00758     int first;
00759     int NextFirst = 0;
00760     int last;
00761     int FreeBefore = 0;
00762     int FreeAfter = 0;
00763     Vector CopyProposedPattern(256,false);
00764     int StoreMissingReservation = 0;
00765     int area = 0;
00766 
00767 
00768     while(MissingReservation >= 0)
00769     {
00770         i = 0;
00771         tmpAdj = 0;
00772         packet = 0;
00773         first = 0;
00774         NextFirst = 0;
00775         last = 0;
00776         FreeBefore = 0;
00777         FreeAfter = 0;
00778 
00779         copy(maxPosPattern.maxProposedPattern.begin(), maxPosPattern.maxProposedPattern.end(), CopyProposedPattern.begin());
00780 
00781         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: best efficiency, missing Reservations: " << MissingReservation);
00782         if(StoreMissingReservation == MissingReservation)
00783         {
00784             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: best efficiency, there were no new slots found in the last search. Exiting search");
00785             break;
00786         }
00787 
00788         StoreMissingReservation = MissingReservation;
00789 
00790 
00791         while(i < SlotpSF)
00792         {
00793             while(i < SlotpSF && maxPosPattern.maxProposedPattern[i] == false)
00794                 i++;
00795 
00796             first = i;
00797             //data-slots are summarized to areas. Each area has [ReservationGap] slots
00798             area = floor((double)(i - NumberOfBPSlots)/ double (ReservationGap));
00799 
00800             while(i < SlotpSF && maxPosPattern.maxProposedPattern[i] == true)
00801                 i++;
00802 
00803             last = i;
00804             //first: beginning of a reservation block; last: slot after the end of a reservation block
00805             NextFirst = i;
00806 
00807             while(NextFirst < SlotpSF && maxPosPattern.maxProposedPattern[NextFirst] == false)
00808                 NextFirst++;
00809 
00810             //NextFirst: Beginning of the next reservation block. i will be set to NextFirst at the end of this cycle
00811 
00812             packet = CalcPacketpArea(first,last);
00813             wns::simulator::Time TrainDuration = packet * FTDuration;
00814             wns::simulator::Time iFragmentDuration = (last - first)*SlotDuration - GuardDuration - TrainDuration;
00815             if (iFragmentDuration < 0) iFragmentDuration = 0;
00816             double AddSlot = ceil ((FTDuration - iFragmentDuration) / SlotDuration);
00817 
00818             int tmpFirst = (first - AddSlot >= 0) ? first - AddSlot : 0;
00819             int tmpLast = (last + AddSlot) <= SlotpSF ? last + AddSlot : SlotpSF ;
00820 
00821             //tmpFirst and tmpLast: Appends [AddSlot] Slots to the examined reservation block
00822 
00823             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: best efficiency, free space between: " << tmpFirst <<" " << tmpLast);
00824             //IsSpaceLeft checks, if there are [AddSlot] free connected slots between tmpFirst and tmpLast
00825             if(!IsSpaceLeft(tmpFirst, tmpLast, AddSlot))
00826             {
00827                 tmpFirst = first > 0 ? first - 1 : 0;
00828                 tmpLast = first;
00829                 int neighbour = 1;
00830                 while(tmpFirst >= 0 && neighbour <= AddSlot && IsSpaceLeft(tmpFirst, tmpLast, neighbour) )
00831                 {
00832                     tmpFirst--;
00833                     tmpAdj++;
00834                     ++neighbour;
00835                 }
00836                 FreeBefore = tmpAdj;
00837                 tmpAdj = 0;
00838                 tmpFirst = last;
00839                 tmpLast = last < 256 ? last + 1 : 256;
00840                 neighbour = 1;
00841                 while(tmpLast < SlotpSF && neighbour <= AddSlot && IsSpaceLeft(tmpFirst, tmpLast, neighbour) )
00842                 {
00843                     tmpLast++;
00844                     tmpAdj++;
00845                     ++neighbour;
00846                 }
00847                 FreeAfter = tmpAdj;
00848                 tmpAdj = 0;
00849 
00850                 if(FreeAfter + FreeBefore >= AddSlot)
00851                 {
00852                     if(FreeAfter == AddSlot)
00853                         FreeBefore = 0;
00854                     if(FreeBefore == AddSlot)
00855                         FreeAfter = 0;
00856                     packet = floor((last+AddSlot - first)*SlotDuration / FTDuration);
00857                     TrainDuration = packet * FTDuration;
00858                     iFragmentDuration = (last + AddSlot - first)*SlotDuration - GuardDuration - TrainDuration;
00859 
00860                     if(maxEfficiency.iFragmentDuration > iFragmentDuration || maxEfficiency.AddSlot == 0)
00861                     {
00862                         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: I'm splitting fragmentation before : " << maxEfficiency.iFragmentDuration << " and now : " << iFragmentDuration << " in area " << area);
00863 
00864                         maxEfficiency.AddSlot = AddSlot;
00865                         maxEfficiency.area = area;
00866 
00867                         tmpLast = first;
00868                         tmpFirst = first - FreeBefore;
00869                         if(!AllocAreaOutside(tmpFirst, tmpLast, FreeBefore))
00870                             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Reservation error");
00871 
00872                         packet = floor((last+AddSlot - first)*SlotDuration / FTDuration);
00873                         TrainDuration = packet * FTDuration;
00874                         iFragmentDuration = (last + AddSlot - first)*SlotDuration - GuardDuration - TrainDuration;
00875 
00876                         maxEfficiency.iFragmentDuration = iFragmentDuration;
00877                         maxEfficiency.AdditionalPackets = packet - floor((last - first)*SlotDuration / FTDuration);
00878                         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: set fragmentation: "<< iFragmentDuration);
00879 
00880                         tmpFirst = last;
00881                         tmpLast = last + FreeAfter;
00882                         if(!AllocAreaOutside(tmpFirst, tmpLast, FreeAfter))
00883                             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Reservation error");
00884 
00885                         copy(maxPosPattern.maxProposedPattern.begin(), maxPosPattern.maxProposedPattern.end(),
00886                             maxEfficiency.maxProposedPattern.begin());
00887                         copy(CopyProposedPattern.begin(), CopyProposedPattern.end(),
00888                             maxPosPattern.maxProposedPattern.begin());
00889 
00890                     }
00891                 }
00892             }
00893             else
00894             {
00895 
00896                 packet = floor((last+AddSlot - first)*SlotDuration / FTDuration);
00897                 TrainDuration = packet * FTDuration;
00898                 iFragmentDuration = (last + AddSlot - first)*SlotDuration - GuardDuration - TrainDuration;
00899                 MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Calculate fragment, without split; addslot : " << AddSlot << " packets now: "<< packet 
00900                 << " train duration: " << TrainDuration << " Fragment duration: "
00901                 << iFragmentDuration);
00902 
00903                 if(maxEfficiency.iFragmentDuration < iFragmentDuration || maxEfficiency.AddSlot == 0)
00904                 {
00905                     MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Fragmentation before : " << maxEfficiency.iFragmentDuration << " and now : " << iFragmentDuration);
00906                     maxEfficiency.AddSlot = AddSlot;
00907 
00908                     if(!AllocAreaOutside(tmpFirst, tmpLast, AddSlot))
00909                         MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Reservation error");
00910                     if(last + AddSlot > maxPosPattern.maxProposedPattern.size())
00911                         packet = CalcPacketpArea(first - AddSlot,last);
00912                     else
00913                         packet = CalcPacketpArea(first - AddSlot,last + AddSlot); // Slots could have been added before or after the existing slots
00914                     TrainDuration = packet * FTDuration;
00915                     iFragmentDuration = (last + AddSlot - first)*SlotDuration - GuardDuration - TrainDuration;
00916                     maxEfficiency.AdditionalPackets = packet - CalcPacketpArea(first, last);
00917                     maxEfficiency.iFragmentDuration = iFragmentDuration;
00918                     maxEfficiency.area = area;
00919                     copy(maxPosPattern.maxProposedPattern.begin(), maxPosPattern.maxProposedPattern.end(),
00920                         maxEfficiency.maxProposedPattern.begin());
00921                     copy(CopyProposedPattern.begin(), CopyProposedPattern.end(),
00922                         maxPosPattern.maxProposedPattern.begin());
00923                 }
00924             }
00925 
00926             i = NextFirst;
00927             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: best efficiency, next is: " << NextFirst);
00928         }
00929         if(maxEfficiency.AddSlot > 0)
00930         {
00931             copy(maxEfficiency.maxProposedPattern.begin(), maxEfficiency.maxProposedPattern.end(),
00932                 maxPosPattern.maxProposedPattern.begin());
00933 
00934             maxEfficiency.Clear();
00935             MissingReservation -= maxEfficiency.AdditionalPackets;
00936             if (MissingReservation < 0) MissingReservation = 0;
00937             MESSAGE_SINGLE(NORMAL, logger, "InitPattern: Missing: " << MissingReservation);
00938         }
00939     }
00940 
00941 
00942 }
00943 
00944 int
00945 DRPPatternCreator::CalcPacketpArea(int first, int last)
00946 {
00947     int i = first;
00948     int tmpAdj = 0;
00949     int PacketpArea = 0;
00950 
00951     assure(last<=maxPosPattern.maxProposedPattern.size(), "Vector boundary exeeded; loop error!");
00952     while(i < last)
00953     {
00954         while(i < last && maxPosPattern.maxProposedPattern[i] == false)
00955         {
00956             i++;
00957         }
00958 
00959         if (i >= last) break;
00960         while(i < last && maxPosPattern.maxProposedPattern[i] == true)
00961         {
00962             ++tmpAdj;
00963             ++i;
00964         }
00965         if(tmpAdj > 0)
00966         {
00967             wns::simulator::Time TXOP = 0;
00968             TXOP = tmpAdj * SlotDuration - GuardDuration;
00969 
00970             double FTDuration_ = friends.manager->getProtocolCalculator()->getDuration()->MSDU_PPDU((Bit)MaxPacketSize, phyMode) + 2*SIFSduration + ACKduration;
00971 
00972             PacketpArea += floor(TXOP/FTDuration_);
00973             tmpAdj = 0;
00974         }
00975 
00976     }
00977     return PacketpArea;
00978 
00979 }

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