![]() |
User Manual, Developers Guide and API Documentation |
![]() |
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/timing/ResourceSchedulerUT.hpp> 00029 00030 #include <LTE/timing/RegistryProxy.hpp> 00031 #include <LTE/controlplane/flowmanagement/FlowManager.hpp> 00032 00033 #include <WNS/StaticFactory.hpp> 00034 00035 #define A2N(a) layer2->getStationManager()->getStationByMAC(a)->getName() 00036 00037 using namespace lte::timing; 00038 00039 STATIC_FACTORY_REGISTER_WITH_CREATOR(ResourceSchedulerUT, 00040 wns::ldk::FunctionalUnit, 00041 "lte.timing.ResourceScheduler.UT", 00042 wns::ldk::FUNConfigCreator); 00043 00044 ResourceSchedulerUT::ResourceSchedulerUT(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00045 ResourceScheduler(fun,config), 00046 wns::ldk::HasReceptor<>(), 00047 wns::ldk::HasConnector<>(), 00048 wns::ldk::HasDeliverer<>(), 00049 wns::Cloneable<ResourceSchedulerUT>(), 00050 symbolDuration(config.get<simTimeType>("symbolDuration")), 00051 myMasterUserID(NULL) 00052 { 00053 MESSAGE_SINGLE(NORMAL, logger, "RSUT: symbolDuration = " << symbolDuration); 00054 } 00055 00056 void 00057 ResourceSchedulerUT::onFUNCreated() 00058 { 00059 ResourceScheduler::onFUNCreated(); 00060 MESSAGE_SINGLE(NORMAL, logger, "ResourceSchedulerUT::onFUNCreated()"); 00061 lte::timing::RegistryProxy* registryInLte = dynamic_cast<lte::timing::RegistryProxy*>(colleagues.registry); 00062 registryInLte->setDL(false); 00063 // ^ registry must know it. Caution: this is set quite late, after all onFUNCreated() actions 00064 } 00065 00066 void 00067 //ResourceSchedulerUT::startCollection(int frameNr, wns::scheduler::MapInfoCollectionPtr ulMapInfo) { 00068 ResourceSchedulerUT::startCollection(int frameNr) { 00069 using namespace wns::scheduler; 00070 MESSAGE_BEGIN(NORMAL, logger, m, "Slave("<<(myMasterUserID?myMasterUserID->getName():"")<<") Scheduling for frame="<<frameNr<<": "); 00071 m << "Queue(cid:bits,pdus) = " << colleagues.queue->printAllQueues(); // show queue sizes: 00072 MESSAGE_END(); 00073 00074 // If we cannot send, then we do nothing. 00075 if (colleagues.registry->hasResourcesGranted()) 00076 { 00077 MESSAGE_SINGLE(NORMAL, logger, "Slave(hasResourcesGranted==true)"); 00078 ResourceScheduler::startCollection(frameNr, slotDuration); 00079 // TODO: do this in base class. Use schedulingMap->getResourceUsage() 00080 //float resourceUsage = colleagues.strategy->getResourceUsage(); 00081 //MESSAGE_SINGLE(NORMAL, logger, "Done scheduling. Used "<<100.0*resourceUsage<<"% of the available capacity."); 00082 //resourceUsageProbe->put(resourceUsage); 00083 ResourceScheduler::finishCollection(frameNr, wns::simulator::getEventScheduler()->getTime()); 00084 } 00085 else 00086 { 00087 MESSAGE_SINGLE(NORMAL, logger, "Slave(hasResourcesGranted==false)"); 00088 } 00089 /* 00090 wns::scheduler::MapInfoCollectionPtr ulMapInfo =friends.mapHandler->getTxResources(frameNr) 00091 assure(ulMapInfo != wns::scheduler::MapInfoCollectionPtr(),"ulMapInfo==NULL"); 00092 MESSAGE_BEGIN(NORMAL, logger, m, "Slave("<<(myMasterUserID?myMasterUserID->getName():"")<<") Scheduling for frame="<<frameNr<<": "); 00093 m << ulMapInfo->size() << " ULEntries for "; 00094 m << "Queue(cid:bits,pdus) = " << colleagues.queue->printAllQueues(); // show queue sizes: 00095 MESSAGE_END(); 00096 */ 00097 /* 00098 for (MapInfoCollection::iterator iter = ulMapInfo->begin(); iter != ulMapInfo->end(); ++iter) 00099 { 00100 MapInfoEntryPtr ulMapInfoEntry = (*iter); 00101 if (myMasterUserID!=NULL) 00102 ulMapInfoEntry->user = myMasterUserID; // "flip user": UTx->BSx 00103 if (colleagues.queue->getQueuedUsers().size()) { // queue has got some PDUs 00104 00105 // retrieve slotDuration 00106 simTimeType startTime = ulMapInfoEntry->start; // Is a member. Why? 00107 simTimeType slotDuration = ulMapInfoEntry->end - ulMapInfoEntry->start; 00108 00109 // for ScaleNet we need to have at least a full symbol duration as slotlength 00110 if (slotDuration < symbolDuration) 00111 { 00112 slotDuration = symbolDuration + 1e-7; 00113 ulMapInfoEntry->end = ulMapInfoEntry->start + slotDuration; 00114 } 00115 00116 MESSAGE_SINGLE(NORMAL, logger, "RSUT: startTime="<<startTime*1e6<<"us, slotDuration=" << slotDuration*1e5<<"us"); 00117 // create full freqChannelSet 00118 SubChannelRangeSet freqChannels; 00119 // this is only one subband: 00120 SubChannelRange myChannels = SubChannelRange::FromIncluding(ulMapInfoEntry->subBand).ToIncluding(ulMapInfoEntry->subBand); 00121 freqChannels.push_back(myChannels); 00122 00123 ResourceScheduler::startCollection(frameNr, slotDuration, freqChannels, ulMapInfoEntry); 00124 // TODO: ^ at this point it would be better to give the complete ulMapInfo instead of all the single ulMapInfoEntry's 00125 float resourceUsage = colleagues.strategy->getResourceUsage(); 00126 MESSAGE_SINGLE(NORMAL, logger, "Done scheduling. Used "<<100.0*resourceUsage<<"% of the available capacity."); 00127 resourceUsageProbe->put(resourceUsage); 00128 ResourceScheduler::finishCollection(frameNr, wns::simulator::getEventScheduler()->getTime()); 00129 // ulMapInfoEntry->start is already accounted for in callBack() 00130 //ResourceScheduler::finishCollection(frameNr, wns::simulator::getEventScheduler()->getTime() + ulMapInfoEntry->start); 00131 } 00132 } // forall mapInfo entries 00133 */ 00134 } // startCollection 00135 00136 // called by event ut::StartData::execute() and rstx->setExpectations(frameNr): fetches expectation from maphandler. 00137 /* obsolete 00138 void 00139 ResourceSchedulerUT::setExpectations(int frameNr) 00140 { 00141 lte::timing::ResourceScheduler::setExpectation(friends.mapHandler->getDLResources(frameNr)); 00142 } 00143 */ 00144 00145 void 00146 ResourceSchedulerUT::onDisassociated(wns::service::dll::UnicastAddress userAdr, wns::service::dll::UnicastAddress dstAdr) 00147 { 00148 // userAdr is always UT; dstAdr is always RAP (UT's next hop) 00149 if (layer2->getDLLAddress() == userAdr) // I am UT 00150 { 00151 assure(associationService->getAssociation() == dstAdr, "address mismatch when releasing association"); 00152 // Notification about Disassociation of UT from RAP (in the UT) 00153 wns::node::Interface* rap = layer2->getStationManager()->getStationByMAC(dstAdr)->getNode(); 00154 MESSAGE_SINGLE(NORMAL, logger, "onDisassociated("<<A2N(userAdr)<<","<<A2N(dstAdr)<<"): Removing Packets from " << A2N(userAdr) << " to " << A2N(dstAdr)); 00155 colleagues.queue->resetQueues(wns::scheduler::UserID(rap)); 00156 } 00157 else // I am RN (UT task) 00158 { 00159 // Notification about Disassociation of UT from RAP (in the RN) 00160 if (layer2->getDLLAddress() == dstAdr) 00161 { 00162 // If we have no association, we are not forwarding in this mode 00163 if (!associationService->hasAssociation()) 00164 return; 00165 00166 wns::service::dll::UnicastAddress myAssociation = associationService->getAssociation(); 00167 wns::node::Interface* hopDestination = layer2->getStationManager()->getStationByMAC(myAssociation)->getNode(); 00168 MESSAGE_SINGLE(NORMAL, logger, "onDisassociated("<<A2N(userAdr)<<","<<A2N(dstAdr)<<"): Removing Packets from " << A2N(userAdr) << " via " << A2N(dstAdr) << " to " << A2N(myAssociation)); 00169 this->deletePacketsToFrom(hopDestination, userAdr); 00170 } 00171 } 00172 } 00173 00174 void 00175 ResourceSchedulerUT::onAssociated(wns::service::dll::UnicastAddress userAdr, wns::service::dll::UnicastAddress dstAdr) 00176 { 00177 MESSAGE_SINGLE(NORMAL, logger, "onAssociated("<<A2N(userAdr)<<","<<A2N(dstAdr)<<")"); 00178 wns::service::dll::UnicastAddress myAssociation = associationService->getAssociation(); 00179 myMasterUserID = layer2->getStationManager()->getStationByMAC(myAssociation)->getNode(); 00180 } 00181 00182 wns::scheduler::QueueStatusContainer 00183 ResourceSchedulerUT::getQueueStatus() const 00184 { 00185 wns::scheduler::QueueStatusContainer result = colleagues.queue->getQueueStatus(); 00186 return result; 00187 } 00188 00189 void 00190 ResourceSchedulerUT::deletePacketsToFrom(wns::node::Interface* destination, 00191 wns::service::dll::UnicastAddress source) 00192 { 00193 wns::ldk::CommandReaderInterface* rlcReader = getFUN()->getCommandReader("rlc"); 00194 wns::scheduler::ConnectionVector conns = colleagues.registry->getConnectionsForUser(wns::scheduler::UserID(destination)); 00195 00196 MESSAGE_SINGLE(NORMAL, logger, "deletePacketsToFrom("<<destination->getName()<<","<<A2N(source)<<"): "<<conns.size()<<" conns"); 00197 00198 if (conns.size() == 0) 00199 { 00200 MESSAGE_SINGLE(NORMAL, logger, "No active queue for node " << destination->getName() << ", nothing had to be removed."); 00201 return; 00202 } 00203 00204 /* iterate over all cids */ 00205 for (wns::scheduler::ConnectionVector::const_iterator iter = conns.begin(); iter != conns.end(); ++iter) 00206 { 00207 wns::scheduler::ConnectionID cid = *iter; 00208 if (friends.flowManager->isControlPlaneFlowID(source, cid)) { 00209 continue; // don't delete. ControlPlane is always single/next-hop 00210 } else { // data plane flowID. Delete queue 00211 colleagues.queue->resetQueue(cid); 00212 } 00213 } // for all cids in connections 00214 } // deletePacketsToFrom() 00215 00216
1.5.5