User Manual, Developers Guide and API Documentation

HARQRetransmission.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2009
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/scheduler/strategy/staticpriority/HARQRetransmission.hpp>
00029 #include <WNS/scheduler/SchedulerTypes.hpp>
00030 
00031 #include <vector>
00032 #include <map>
00033 #include <algorithm>
00034 #include <iostream>
00035 
00036 using namespace std;
00037 using namespace wns::scheduler;
00038 using namespace wns::scheduler::strategy;
00039 using namespace wns::scheduler::strategy::staticpriority;
00040 
00041 STATIC_FACTORY_REGISTER_WITH_CREATOR(HARQRetransmission,
00042                                      SubStrategyInterface,
00043                                      "HARQRetransmission",
00044                                      wns::PyConfigViewCreator);
00045 
00046 
00047 HARQRetransmission::HARQRetransmission(const wns::pyconfig::View& config)
00048     : SubStrategy(config)
00049 {
00050     blockSize=INT_MAX; // ExhaustiveRoundRobin=RoundRobin with infinite blockSize
00051     MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission(): constructed");
00052 }
00053 
00054 HARQRetransmission::~HARQRetransmission()
00055 {
00056 }
00057 
00058 void
00059 HARQRetransmission::initialize()
00060 {
00061     // make state
00062     lastScheduledConnection = 0;
00063     //colleagues.harq->initialize(); // TODO!
00064     MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission(): initialized");
00065 }
00066 
00067 wns::scheduler::ConnectionID
00068 HARQRetransmission::getValidCurrentConnection(const ConnectionSet &currentConnections, ConnectionID cid) const
00069 {
00070     MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission::getValidCurrentConnection");
00071     // uses state var currentConnections
00072     wns::scheduler::ConnectionSet::iterator iter =
00073         currentConnections.upper_bound(cid);
00074     if ( iter != currentConnections.end() ) { // exists
00075         return *iter;
00076     } else { // continue with next higher cid
00077         return *currentConnections.begin();
00078     }
00079     //MESSAGE_SINGLE(NORMAL, logger, "getValidCurrentConnection("<<cid<<") = ");
00080 }
00081 
00082 wns::scheduler::ConnectionID
00083 HARQRetransmission::getNextConnection(const ConnectionSet &currentConnections, ConnectionID cid) const
00084 {
00085     MESSAGE_SINGLE(NORMAL, logger, "HARQRetransmission::getNextConnection");
00086     // uses state var currentConnections
00087     wns::scheduler::ConnectionSet::iterator iter =
00088         currentConnections.upper_bound(cid);
00089     if ( iter != currentConnections.end() ) { // found
00090         if ( *iter == cid ) { // go on
00091             iter++;
00092         } else {
00093             return *iter;
00094         }
00095     }
00096     if ( iter != currentConnections.end() ) { // exists
00097         return *iter;
00098     } else { // continue with next higher cid
00099         return *currentConnections.begin();
00100     }
00101     //MESSAGE_SINGLE(NORMAL, logger, "getNextConnection("<<cid<<") = ");
00102 }
00103 
00104 std::vector<int>
00105 HARQRetransmission::getUsableSubChannelsIDs(wns::scheduler::UserID user, const wns::scheduler::SchedulingMapPtr& schedulingMap)
00106 {
00107     std::vector<int> result;
00108 
00109     for (wns::scheduler::SubChannelVector::const_iterator iterSubChannel = schedulingMap->subChannels.begin();
00110          iterSubChannel != schedulingMap->subChannels.end();
00111          ++iterSubChannel
00112         )
00113     {
00114         const SchedulingSubChannel& subChannel = *iterSubChannel;
00115         int subChannelIndex = subChannel.subChannelIndex;
00116 
00117         // Is it blocked?
00118         if (!subChannel.subChannelIsUsable) continue;
00119 
00120         for ( SchedulingTimeSlotPtrVector::const_iterator iterTimeSlot = subChannel.temporalResources.begin();
00121               iterTimeSlot != subChannel.temporalResources.end(); ++iterTimeSlot)
00122         {
00123             const SchedulingTimeSlotPtr timeSlotPtr = *iterTimeSlot;
00124             int timeSlotIndex = timeSlotPtr->timeSlotIndex;
00125             if ( ((!timeSlotPtr->getUserID().isValid()) ||
00126                   timeSlotPtr->getUserID() == user) &&
00127                  timeSlotPtr->countScheduledCompounds()==0)
00128             { // free space found. Pack it into.
00129                 result.push_back(subChannel.subChannelIndex);
00130             }
00131         }
00132     }
00133     return result;
00134 }
00135 
00136 wns::scheduler::MapInfoCollectionPtr
00137 HARQRetransmission::doStartSubScheduling(SchedulerStatePtr schedulerState,
00138                                          wns::scheduler::SchedulingMapPtr schedulingMap)
00139 {
00140     ConnectionSet &currentConnections = schedulerState->currentState->activeConnections;
00141     assure(currentConnections.empty(), "HARQ retransmission cannot have active connections. This should not have happened.");
00142 
00143     // harq colleague may be NULL, e.g. Uplink Master Scheduler does not have HARQ
00144     if(colleagues.harq == NULL)
00145     {
00146         MapInfoCollectionPtr mapInfoCollection = MapInfoCollectionPtr(new wns::scheduler::MapInfoCollection);
00147         MESSAGE_SINGLE(NORMAL, logger, "colleagues.harq==NULL is illegal. Please choose another strategy than HARQRetransmission");
00148         return mapInfoCollection;
00149     }
00150 
00151     assure(colleagues.harq!=NULL,"colleagues.harq==NULL is illegal. Please choose another strategy than HARQRetransmission");
00152 
00156     wns::scheduler::UserSet usersWithRetransmissions = colleagues.harq->getUsersWithRetransmissions();
00157 
00158     for (wns::scheduler::UserSet::iterator it = usersWithRetransmissions.begin();
00159      it != usersWithRetransmissions.end();
00160      ++it)
00161       {
00162     int processID = colleagues.harq->getProcessesWithRetransmissions(*it).front();
00163 
00164     int numberOfRetransmissions = colleagues.harq->getNumberOfRetransmissions(*it, processID);
00165 
00166     MESSAGE_SINGLE(NORMAL, logger, "doStartSubScheduling: "<<numberOfRetransmissions<<" HARQ retransmission(s) waiting for user=" << it->getName() << " ,processID=" << processID);
00167 
00168     wns::scheduler::SchedulingTimeSlotPtr resourceBlock = colleagues.harq->peekNextRetransmission(*it, processID);
00169     assure(resourceBlock != NULL, "resourceBlock == NULL although numberOfRetransmissions="<<numberOfRetransmissions);
00170 
00171     std::vector<int> subchannels = getUsableSubChannelsIDs(resourceBlock->getUserID(), schedulingMap);
00172 
00173     if (numberOfRetransmissions > subchannels.size())
00174     {
00175       MESSAGE_BEGIN(NORMAL, logger, m, "Not enough room for ");
00176       m << numberOfRetransmissions;
00177       m << " retransmissions for user " << it->getName();
00178       m << " (pid=" << processID << ") skipping this user";
00179       MESSAGE_END();
00180       continue;
00181     }
00182 
00183 
00184     while(resourceBlock != NULL)
00185       {
00186         subchannels = getUsableSubChannelsIDs(resourceBlock->getUserID(), schedulingMap);
00187 
00188         size_t numAvailable = subchannels.size();
00189 
00190         if (numAvailable > 0)
00191           {
00192         double random = randomDist();
00193         int sc = subchannels[int(random*numAvailable)];
00194 
00195         for ( SchedulingTimeSlotPtrVector::iterator iterTimeSlot = schedulingMap->subChannels[sc].temporalResources.begin();
00196               iterTimeSlot != schedulingMap->subChannels[sc].temporalResources.end(); ++iterTimeSlot)
00197           {
00198             SchedulingTimeSlotPtr timeSlotPtr = *iterTimeSlot;
00199             int timeSlotIndex = timeSlotPtr->timeSlotIndex;
00200             
00201             if ( ((!timeSlotPtr->getUserID().isValid()) ||
00202               timeSlotPtr->getUserID() == resourceBlock->getUserID()) &&
00203              timeSlotPtr->countScheduledCompounds()==0)
00204               { // free space found. Pack it into.
00205             // We found room for the retransmission, now remove it from
00206             // the pending retransmissions
00207             resourceBlock = colleagues.harq->getNextRetransmission(*it, processID);
00208             MESSAGE_BEGIN(NORMAL, logger, m, "Retransmitting");
00209             m << " HARQ block ("<<resourceBlock->getUserID().getName()<<",processID=" << resourceBlock->harq.processID;
00210             m << ",Retry="<<resourceBlock->harq.retryCounter<<")";
00211             m << " inside subchannel.timeslot=" <<sc<<"."<<timeSlotIndex;
00212             m << " (ex "<<resourceBlock->subChannelIndex<<"."<<resourceBlock->timeSlotIndex<<")";
00213             MESSAGE_END();
00214             assure(resourceBlock->subChannelIndex==resourceBlock->physicalResources[0].getSubChannelIndex(),
00215                    "mismatch of subChannelIndex: "<<resourceBlock->subChannelIndex<<"!="<<resourceBlock->physicalResources[0].getSubChannelIndex());
00216             assure(resourceBlock->timeSlotIndex==resourceBlock->physicalResources[0].getTimeSlotIndex(),
00217                    "mismatch of timeSlotIndex: "<<resourceBlock->timeSlotIndex<<"!="<<resourceBlock->physicalResources[0].getTimeSlotIndex());
00218             assure (resourceBlock != wns::scheduler::SchedulingTimeSlotPtr(),"resourceBlock==NULL");
00219 
00220             if (resourceBlock->harq.ackCallback.empty())
00221               {
00222                 std::cout << "Trying to transmit resource block with empty ack callback in ResourceScheduler::finishCollection" << std::endl;
00223                 exit(1);
00224               }
00225 
00226             if (resourceBlock->harq.nackCallback.empty())
00227               {
00228                 std::cout << "Trying to transmit resource block with empty nack callback in ResourceScheduler::finishCollection" << std::endl;
00229                 exit(1);
00230               }
00231 
00232             schedulingMap->subChannels[sc].temporalResources[timeSlotIndex] = resourceBlock; // copy Smartptr over
00233             // at this point timeSlotPtr is no longer valid for use! Only resourceBlock
00234             resourceBlock->subChannelIndex = sc;
00235             resourceBlock->timeSlotIndex = timeSlotIndex;
00236             assure(resourceBlock->physicalResources.size()==resourceBlock->numSpatialLayers,
00237                    "mismatch in spatial domain: "<<resourceBlock->physicalResources.size()<<"!="<<resourceBlock->numSpatialLayers);
00238             // foreach PRB... fix subChannelIndex
00239             for ( PhysicalResourceBlockVector::iterator iterPRB = resourceBlock->physicalResources.begin();
00240                   iterPRB != resourceBlock->physicalResources.end(); ++iterPRB)
00241               {
00242                 int spatialIndex = iterPRB->getSpatialLayerIndex();
00243                 MESSAGE_SINGLE(NORMAL, logger, sc<<"."<<timeSlotIndex<<".PRB["<<spatialIndex<<"]: Adjusting subChannelIndex from "<<iterPRB->getSubChannelIndex()<<" to "<<sc);
00244                 iterPRB->setSubChannelIndex(sc);
00245                 iterPRB->setTimeSlotIndex(timeSlotIndex);
00246               }
00247             resourceBlock = colleagues.harq->peekNextRetransmission(*it, processID);
00248             break;
00249               }
00250           }
00251           }
00252         else
00253           {
00254         // Due to the BCH fix see above we drop the remaining retransmissions here.
00255         while(resourceBlock != NULL)
00256           {
00257             resourceBlock = colleagues.harq->getNextRetransmission(*it, processID);
00258           }
00259           }
00260       } // while resource block to send
00261       } // for
00262 
00263     MapInfoCollectionPtr mapInfoCollection = MapInfoCollectionPtr(new wns::scheduler::MapInfoCollection);
00264 
00265     return mapInfoCollection;
00266 } // doStartSubScheduling
00267 

Generated on Thu May 24 03:31:51 2012 for openWNS by  doxygen 1.5.5