![]() |
User Manual, Developers Guide and API Documentation |
![]() |
00001 /****************************************************************************** 00002 * WiMeMac * 00003 * This file is part of openWNS (open Wireless Network Simulator) 00004 * _____________________________________________________________________________ 00005 * 00006 * Copyright (C) 2004-2011 00007 * Chair of Communication Networks (ComNets) 00008 * Kopernikusstr. 5, D-52074 Aachen, Germany 00009 * phone: ++49-241-80-27910, 00010 * fax: ++49-241-80-22242 00011 * email: info@openwns.org 00012 * www: http://www.openwns.org 00013 * _____________________________________________________________________________ 00014 * 00015 * openWNS is free software; you can redistribute it and/or modify it under the 00016 * terms of the GNU Lesser General Public License version 2 as published by the 00017 * Free Software Foundation; 00018 * 00019 * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY 00020 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00021 * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00022 * details. 00023 * 00024 * You should have received a copy of the GNU Lesser General Public License 00025 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00026 * 00027 ******************************************************************************/ 00028 00029 #include <WIMEMAC/drp/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 }
1.5.5