User Manual, Developers Guide and API Documentation

MapHandler.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-2007
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 <LTE/controlplane/MapHandler.hpp>
00029 
00030 #include <LTE/main/Layer2.hpp>
00031 #include <LTE/timing/TimingScheduler.hpp>
00032 #include <LTE/timing/ResourceScheduler.hpp>
00033 #include <LTE/macr/PhyUser.hpp>
00034 
00035 #include <DLL/StationManager.hpp>
00036 
00037 #include <WNS/ldk/fun/FUN.hpp>
00038 #include <WNS/service/phy/ofdma/Pattern.hpp>
00039 
00040 #include <fstream>
00041 
00042 using namespace lte;
00043 using namespace lte::controlplane;
00044 using namespace wns;
00045 using namespace wns::ldk;
00046 
00047 #define A2N(a) (((a).getInteger()>0) ? layer2->getStationManager()->getStationByMAC(a)->getName() : "DLL<0")
00048 
00049 STATIC_FACTORY_REGISTER_WITH_CREATOR(MapHandler, FunctionalUnit, "lte.controlplane.MapHandler", FUNConfigCreator);
00050 
00051 MapHandler::MapHandler(wns::ldk::fun::FUN* fun, const pyconfig::View& config) :
00052     CommandTypeSpecifier<MapCommand>(fun),
00053     HasReceptor<>(),
00054     HasConnector<>(),
00055     HasDeliverer<>(),
00056     Cloneable<MapHandler>(),
00057     helper::HasModeName(config),
00058     layer2(NULL),
00059     myUser(NULL),
00060     friends(),
00061     pduSize(config.get<uint32_t>("pduSize")),
00062     lowestSubChannel(config.get<uint32_t>("lowestMapChannel")),
00063     highestSubChannel(config.get<uint32_t>("highestMapChannel")),
00064     framesPerSuperFrame(config.get<int>("framesPerSuperFrame")),
00065     scheduledDLResources(framesPerSuperFrame),
00066     scheduledULResources(framesPerSuperFrame),
00067     phyModePtr(wns::service::phy::phymode::createPhyMode(config.getView("phyMode"))),
00068     txPower(config.get<wns::Power>("txPower")),
00069     writeMapOutput(config.get<bool>("writeMapOutput")),
00070     currentPhase(0),
00071     logger(config.get("logger"))
00072 {
00073     if (writeMapOutput) {
00074         mapOutputFileNameDL = config.get<std::string>("mapOutputFileNameDL");
00075         mapOutputFileNameUL = config.get<std::string>("mapOutputFileNameUL");
00076     } // else they are None
00077 }
00078 
00079 MapHandler::~MapHandler()
00080 {
00081     // better would be in a method onSimulationEnd()
00082     if (writeMapOutput) closeMapOutput();
00083     // cleanup:
00084     scheduledDLResources.clear();
00085     scheduledULResources.clear();
00086 }
00087 
00088 void
00089 MapHandler::onFUNCreated()
00090 {
00091     layer2 = getFUN()->getLayer<dll::ILayer2*>();
00092     myUser = dynamic_cast<lte::main::Layer2*>(getFUN()->getLayer())->getNode();
00093     friends.associationService = layer2->getControlService<dll::services::control::Association>("ASSOCIATION"+modeBase);
00094     friends.timer = layer2->getManagementService<lte::timing::TimingScheduler>(mode+separator+"Timer");
00095     friends.dlrs = getFUN()->findFriend<lte::timing::SchedulerIncoming*>(mode+separator+rsNameSuffix+"TX");
00096     friends.phyUser = getFUN()->findFriend<lte::macr::PhyUser*>(modeBase+separator+"phyUser");
00097     // obtain pointers to the schedulers that have prepared DL and UL Maps
00098     // (only needed in RAPs that perform master scheduling)
00099     try {
00100         friends.dlmip = getFUN()->findFriend<wns::scheduler::SchedulingMapProviderInterface*>(mode+separator+rsNameSuffix+"TX");
00101     } catch(...) {
00102         friends.dlmip = NULL;
00103     }
00104     try {
00105         friends.ulmip = getFUN()->findFriend<wns::scheduler::SchedulingMapProviderInterface*>(mode+separator+rsNameSuffix+"RX");
00106     } catch(...) {
00107         friends.ulmip = NULL;
00108     }
00109     // remember resource partitioning information service
00110     partInfo = layer2->getControlService<lte::timing::partitioning::PartitioningInfo>("PARTITIONINGINFO"+modeBase);
00111     initSuperFrameMap();
00112     if (writeMapOutput) prepareMapOutput();
00113 }
00114 
00115 bool
00116 MapHandler::doIsAccepting(const CompoundPtr& /* compound */) const
00117 {
00118     // will never be called since nobody is likely to downconnect on the MapHandler
00119     return false;
00120 } // isAccepting
00121 
00122 void
00123 MapHandler::doSendData(const CompoundPtr& /* compound */)
00124 {
00125     assure(false, "sendData of MapHandler");
00126 } // doSendData
00127 
00128 void
00129 MapHandler::saveDLMap(int frameNr, wns::scheduler::SchedulingMapPtr schedulingMap)
00130 {
00131     assure(frameNr < (int)scheduledDLResources.size(), "invalid frameNumber");
00132     scheduledDLResources[frameNr] = schedulingMap;
00133     MESSAGE_SINGLE(NORMAL, logger, "MapHandler::saveDLMap");
00134     MESSAGE_SINGLE(VERBOSE, logger, "MapHandler::saveDLMap schedulingMAP=" << scheduledDLResources[frameNr]->toString());
00135 }
00136 
00137 void
00138 MapHandler::saveULMap(int frameNr, wns::scheduler::SchedulingMapPtr schedulingMap)
00139 {
00140     assure(frameNr < (int)scheduledULResources.size(), "invalid frameNumber");
00141     scheduledULResources[frameNr] = schedulingMap;
00142     MESSAGE_SINGLE(NORMAL, logger, "MapHandler::saveULMap");
00143     MESSAGE_SINGLE(VERBOSE, logger, "MapHandler::saveULMap schedulingMAP=" << scheduledULResources[frameNr]->toString());
00144 }
00145 void
00146 MapHandler::resetResources(int frameNr)
00147 {
00148     assure(frameNr < (int)scheduledDLResources.size(), "invalid frameNumber");
00149     assure(frameNr < (int)scheduledULResources.size(), "invalid frameNumber");
00150     scheduledDLResources[frameNr] = wns::scheduler::SchedulingMapPtr();
00151     scheduledULResources[frameNr] = wns::scheduler::SchedulingMapPtr();
00152 
00153     int groupNumber = dynamic_cast<lte::timing::ResourceScheduler*>(friends.dlmip)->getPartitionGroup();
00154     int phaseNumber  = friends.timer->phaseNumberAtFrame(frameNr);
00155 }
00156 
00157 void
00158 MapHandler::initSuperFrameMap()
00159 {
00160     MESSAGE_SINGLE(NORMAL, logger,"initSuperFrameMap(frames 0.."<<framesPerSuperFrame-1<<")");
00161 
00162     int groupNumber = dynamic_cast<lte::timing::ResourceScheduler*>(friends.dlmip)->getPartitionGroup();
00163     assure(friends.timer, "MapHandler requires a friend with name: "+mode+separator+"Timer");
00164     friends.timer->initStationTaskPhases(); // needed before timer->phaseNumberAtFrame(i)
00165     for (int i=0; i<framesPerSuperFrame; i++)
00166     {
00167         int phaseNumber  = friends.timer->phaseNumberAtFrame(i);
00168         scheduledDLResources[i] = wns::scheduler::SchedulingMapPtr(); // empty map
00169         scheduledULResources[i] = wns::scheduler::SchedulingMapPtr(); // empty map
00170     }
00171 }
00172 
00173 // incoming MAP from RAP to RUT
00174 void
00175 MapHandler::doOnData(const CompoundPtr& compound)
00176 {
00178     assure (compound, "Invalid Map compound received!");
00179 
00180     MapCommand* myCommand = getCommand( compound->getCommandPool());
00181 
00183     wns::service::dll::UnicastAddress listeningTo;
00184 
00185     if (friends.associationService->hasAssociation())
00186         listeningTo = friends.associationService->getAssociation();
00187     wns::service::dll::UnicastAddress comingFrom = myCommand->magic.source;
00188 
00189     // this is for me...
00190     if (listeningTo == comingFrom && friends.timer->stationTaskAtOffset(0.0/*now*/) == timing::StationTasks::UT() )
00191     {
00192         MESSAGE_SINGLE(NORMAL, logger,"doOnData(): pdu from "<<A2N(comingFrom)<<" contains MAP");
00193         using namespace wns::scheduler;
00194 
00195         // get latest received UL+DL-MAP:
00196         SchedulingMapCollectionVector scheduledULResourceMAP = myCommand->peer.ulSchedulingMapVector;
00197         SchedulingMapCollectionVector scheduledDLResourceMAP = myCommand->peer.dlSchedulingMapVector;
00198 
00199         std::vector<int> dlFrameNumbers = myCommand->peer.dlFrameNumbers;
00200         std::vector<int> ulFrameNumbers = myCommand->peer.ulFrameNumbers;
00201 
00202         // check if at least one of the frames contains granted ul resources
00203         bool ulResourcesAvailable = false;
00204 
00205         // multi-frame maps (support half duplex FDD [sdr])
00206         for (size_t i=0; i<dlFrameNumbers.size(); i++)
00207         {
00208             int frameNumber = dlFrameNumbers[i];
00209             assure(scheduledDLResourceMAP[i]!=wns::scheduler::SchedulingMapPtr(),"empty DLMAP["<<i<<" = frame"<<frameNumber<<"]");
00210             MESSAGE_SINGLE(NORMAL, logger,"Received DL MAP for frameOffset="<<i
00211                            <<", DLsize="<<scheduledDLResourceMAP[i]->getResourceUsage()*100.0<<"%"
00212                            <<")");
00213             // At this point we could make a deep_copy ! (see below)
00214             scheduledDLResources[frameNumber] = scheduledDLResourceMAP[i];
00215             MESSAGE_SINGLE(NORMAL, logger,"DLMAP[frame="<<frameNumber<<"]="<<scheduledDLResources[frameNumber]->toString());
00216         } // for all DL frames in MAP
00217 
00218         for (size_t i=0; i<ulFrameNumbers.size(); i++)
00219         {
00220             int frameNumber = ulFrameNumbers[i];
00221             // UL+DL MAPs (ULMAP is important for UT.RS-TX but DLMAP is not needed anymore)
00222             assure(scheduledULResourceMAP[i]!=wns::scheduler::SchedulingMapPtr(),"empty ULMAP["<<i<<" = frame"<<frameNumber<<"]");
00223             MESSAGE_SINGLE(NORMAL, logger,"Received UL MAP for frameOffset="<<i
00224                            <<" (ULsize="<<scheduledULResourceMAP[i]->getResourceUsage()*100.0<<"%"
00225                            <<")");
00226             // At this point we could make a deep_copy ! (see below)
00227             scheduledULResources[frameNumber] = scheduledULResourceMAP[i];
00228             if (scheduledULResources[frameNumber]->hasResourcesForUser(wns::scheduler::UserID(myUser)))
00229             {
00230                 ulResourcesAvailable = true; // assume always true when a MAP comes
00231                 // At this point we should make a deep_copy !
00232             }
00233             MESSAGE_SINGLE(NORMAL, logger,"ULMAP[frame="<<frameNumber<<"]="<<scheduledULResources[frameNumber]->toString());
00234         } // for all UL frames in MAP
00235 
00236         // Inform all interested observers whether or not resources have been granted
00237         if (ulResourcesAvailable) {
00238             MESSAGE_SINGLE(NORMAL, logger, "doOnData(): ulResourcesAvailable => sendNotifies...");
00239         }
00240         // this calls resourcesGranted(bool) in RRHandler + CQIHandler:
00241         this->sendNotifies(&ResourceGrantNotificationInterface::resourcesGranted, ulResourcesAvailable);
00242         // if (ulResourcesAvailable==true): MapHandler says: "choosing cpDispatcher" instead of RACH
00243     } else {
00244         // received compound from a source (RAP) we are not associated with -> ignore it
00245         return;
00246     }
00247 } // doOnData
00248 
00249 // UT asks for allowed resources (old method?). timing/ut/Events.cpp
00250 wns::scheduler::SchedulingMapPtr
00251 MapHandler::getMasterMapForSlaveScheduling(int frameNr)
00252 {
00253     // This is a SmartPtr copy. We are in UT here.
00254     // It is still the original datastructure written by BS-RS-TX
00255     return scheduledULResources[frameNr];
00256 }
00257 // called for every frame by rap/Events.cpp: rap::StartMap::execute
00258 void
00259 MapHandler::setCurrentPhase()
00260 {
00261     //needed to reset resources at the and of a frame
00262     currentPhase = friends.timer->phaseNumberAtOffset(0.0/*relative to now*/);
00263 }
00264 
00265 void
00266 MapHandler::doWakeup()
00267 {
00268 }
00269 
00270 void
00271 MapHandler::calculateSizes(const CommandPool* commandPool, Bit& _commandPoolSize, Bit& _dataSize) const
00272 {
00273     getFUN()->getProxy()->calculateSizes(commandPool, _commandPoolSize, _dataSize, this);
00274     _dataSize += this->pduSize;
00275 }
00276 
00277 // start sending the (UL+DL) MAPs in DL towards user terminals
00278 void
00279 MapHandler::startMapTx(simTimeType duration, std::vector<int> dlFrameNumbers, std::vector<int> ulFrameNumbers)
00280 {
00281     MESSAGE_SINGLE(NORMAL, logger,"MapHandler::startMapTx(d="<<duration<<"s): sending maps for "<<ulFrameNumbers.size()<<" UL frames, "<< dlFrameNumbers.size()<<" DL frames ...");
00282     // when Map Tx starts, the phy has to be switched to RAP-like operation
00283     friends.phyUser->rapTuning();
00284 
00285     // prepare vectors with resource information
00286     SchedulingMapCollectionVector dlSchedulingMapVectorInMap;
00287     SchedulingMapCollectionVector ulSchedulingMapVectorInMap;
00288     for (size_t i=0; i<dlFrameNumbers.size(); i++)
00289     {
00290         int frameNumber = dlFrameNumbers[i];
00291         assure(frameNumber < (int)scheduledDLResources.size(), "invalid frameNumber="<<frameNumber);
00292         MESSAGE_SINGLE(NORMAL, logger,"MapHandler::startMapTx(): frameNumber["<<i<<"]="<<frameNumber
00293                        <<": map size: DL="<<scheduledDLResources[frameNumber]->getResourceUsage()*100.0);
00294         // Prepare sufficient copies of the map pdu for all subcarriers assigned to this station
00295         dlSchedulingMapVectorInMap.push_back(scheduledDLResources[frameNumber]);
00296     }
00297 
00298     for (size_t i=0; i<ulFrameNumbers.size(); i++)
00299     {
00300         int frameNumber = ulFrameNumbers[i];
00301         assure(frameNumber < (int)scheduledULResources.size(), "invalid frameNumber="<<frameNumber);
00302         MESSAGE_SINGLE(NORMAL, logger,"MapHandler::startMapTx(): frameNumber["<<i<<"]="<<frameNumber
00303                        <<"%, UL="<<scheduledULResources[frameNumber]->getResourceUsage()*100.0<<"%");
00304         // Prepare sufficient copies of the map pdu for all subcarriers assigned to this station
00305         ulSchedulingMapVectorInMap.push_back(scheduledULResources[frameNumber]);
00306     }
00307 
00308     MESSAGE_BEGIN(NORMAL, logger,m,"MapHandler::startMapTx(): dlSchedulingMapVectorInMap.size="<<dlSchedulingMapVectorInMap.size()<<", ulSchedulingMapVectorInMap.size="<<ulSchedulingMapVectorInMap.size()<<"\n");
00309     {
00310         for (size_t i=0; i<dlSchedulingMapVectorInMap.size(); i++)
00311         { // forall frames that are signaled in a map
00312             m<<"dlSchedulingMapVectorInMap[i="<<i<<"]="<<dlSchedulingMapVectorInMap[i]->getResourceUsage()*100.0<<"%\n";
00313         }
00314         for (size_t i=0; i<ulSchedulingMapVectorInMap.size(); i++)
00315         {
00316             m<<"ulSchedulingMapVectorInMap[i="<<i<<"]="<<ulSchedulingMapVectorInMap[i]->getResourceUsage()*100.0<<"%\n";
00317         }
00318         m<<"Map is broadcasted on SubChannels=" << lowestSubChannel << "..." << highestSubChannel;
00319     }
00320     MESSAGE_END();
00321     // put tempVectors into the commands and pass them to phy
00322     for (uint32_t subBand = lowestSubChannel; subBand <= highestSubChannel; ++subBand){
00323         CompoundPtr mapCompound = CompoundPtr(new Compound(getFUN()->createCommandPool()));
00324         MapCommand* myCommand = activateCommand(mapCompound->getCommandPool());
00325 
00326         myCommand->peer.dlSchedulingMapVector = dlSchedulingMapVectorInMap; // this is sent to the peer
00327         myCommand->peer.ulSchedulingMapVector = ulSchedulingMapVectorInMap; // this is sent to the peer
00328         myCommand->peer.dlFrameNumbers = dlFrameNumbers;
00329         myCommand->peer.ulFrameNumbers = ulFrameNumbers;
00330         myCommand->magic.source = layer2->getDLLAddress();
00331 
00332         // set PhyUser Command
00333         lte::macr::PhyCommand* phyCommand = dynamic_cast<lte::macr::PhyCommand*>(
00334             getFUN()->getProxy()->activateCommand( mapCompound->getCommandPool(), friends.phyUser ));
00335 
00336         simTimeType startTime = wns::simulator::getEventScheduler()->getTime(); // now
00337 
00338         phyCommand->local.beamforming = false;
00339         phyCommand->local.pattern = wns::service::phy::ofdma::PatternPtr(); // NULL Pointer
00340         phyCommand->local.start = startTime;
00341         phyCommand->local.stop = startTime + duration;
00342         phyCommand->local.subBand = subBand;
00343         phyCommand->local.modeRxTx = lte::macr::PhyCommand::Tx;
00344         phyCommand->local.phyModePtr = phyModePtr;
00345         phyCommand->magic.txp = txPower;
00346         phyCommand->magic.source = getFUN()->getLayer<dll::ILayer2*>()->getNode();
00347         phyCommand->magic.destination = NULL; // broadcast
00348         if (getConnector()->hasAcceptor(mapCompound)) {
00349             getConnector()->getAcceptor(mapCompound)->sendData(mapCompound);
00350             MESSAGE_SINGLE(NORMAL, logger, "startMapTx: prepared and sent new outgoing DL/UL MapInfo burst.");
00351         }
00352         else
00353             assure(false, "Lower FU is not accepting scheduled Map PDU but is supposed to do so");
00354     }
00355     // do this for DL and UL maps
00356     evaluateMaps();
00357 } // startMapTx()
00358 
00359 // prepare UT or RNUT to receive the MAPs from BS or RNBS
00360 void
00361 MapHandler::startMapRx()
00362 {
00363     // when Map Rx starts, the phy has to be switched to UT-like operation
00364     friends.phyUser->utTuning();
00365 }
00366 
00367 void
00368 MapHandler::prepareMapOutput()
00369 {
00370     if (!writeMapOutput) return; // nothing to do
00371     MESSAGE_SINGLE(NORMAL, logger, "prepareMapOutput(): opening output file "<<mapOutputFileNameDL<<" and "<<mapOutputFileNameUL);
00372     mapFileDL = new std::ofstream(mapOutputFileNameDL.c_str());
00373     mapFileUL = new std::ofstream(mapOutputFileNameUL.c_str());
00374     assure(mapFileDL!=NULL,"cannot write to mapFile "<<mapOutputFileNameDL);
00375     assure(mapFileUL!=NULL,"cannot write to mapFile "<<mapOutputFileNameUL);
00376     (*mapFileDL) << "% contents=\""<<logger.getLoggerName()<<" DL map\"\n";
00377     (*mapFileUL) << "% contents=\""<<logger.getLoggerName()<<" UL map\"\n";
00378 }
00379 
00380 // analyze MAPs to get performance values from it.
00381 // Probe output and file output for Matlab
00382 void
00383 MapHandler::evaluateMaps()
00384 {
00385     if (!writeMapOutput) return; // nothing to do
00386     MESSAGE_SINGLE(NORMAL, logger, "evaluateMaps(): writing to "<<mapOutputFileNameDL<<" and "<<mapOutputFileNameUL);
00387     assure(mapFileDL!=NULL,"cannot write to mapFile "<<mapOutputFileNameDL);
00388     assure(mapFileUL!=NULL,"cannot write to mapFile "<<mapOutputFileNameUL);
00389     // problem: we have 1..N maps here for DL/UL. They can overlap.
00390     // TODO: write table output to file for postprocessing with Matlab
00391     // TODO: write a probe "ResourceUsage" here, namely only for frame frameNumbers[0]
00392 }
00393 
00394 void
00395 MapHandler::closeMapOutput()
00396 {
00397     if (!writeMapOutput) return; // nothing to do
00398     MESSAGE_SINGLE(NORMAL, logger, "closeMapOutput(): closing "<<mapOutputFileNameDL<<" and "<<mapOutputFileNameUL);
00399     if (*mapFileDL) mapFileDL->close();
00400     if (*mapFileUL) mapFileUL->close();
00401 }
00402 

Generated on Fri May 25 03:32:04 2012 for openWNS by  doxygen 1.5.5