![]() |
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/ResourceSchedulerBS.hpp> 00029 00030 #include <LTE/timing/RegistryProxy.hpp> 00031 #include <LTE/helper/QueueProxy.hpp> 00032 #include <LTE/controlplane/flowmanagement/FlowManager.hpp> 00033 00034 #include <DLL/StationManager.hpp> 00035 00036 #include <WNS/StaticFactory.hpp> 00037 00038 #define A2N(a) layer2->getStationManager()->getStationByMAC(a)->getName() 00039 00040 using namespace lte::timing; 00041 00042 STATIC_FACTORY_REGISTER_WITH_CREATOR(ResourceSchedulerBS, 00043 wns::ldk::FunctionalUnit, 00044 "lte.timing.ResourceScheduler.BS", 00045 wns::ldk::FUNConfigCreator); 00046 00047 ResourceSchedulerBS::ResourceSchedulerBS(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00048 ResourceScheduler(fun,config), 00049 wns::ldk::HasReceptor<>(), 00050 wns::ldk::HasConnector<>(), 00051 wns::ldk::HasDeliverer<>(), 00052 wns::Cloneable<ResourceSchedulerBS>() 00053 {} 00054 00055 ResourceSchedulerBS::~ResourceSchedulerBS() 00056 { 00057 MESSAGE_SINGLE(VERBOSE, logger, "ResourceSchedulerBS::~ResourceSchedulerBS()"); 00058 } 00059 00060 void 00061 ResourceSchedulerBS::onFUNCreated() 00062 { 00063 ResourceScheduler::onFUNCreated(); 00064 MESSAGE_SINGLE(NORMAL, logger, "ResourceSchedulerBS::onFUNCreated()"); 00065 lte::timing::RegistryProxy* registryInLte = dynamic_cast<lte::timing::RegistryProxy*>(colleagues.registry); 00066 registryInLte->setDL(!IamUplinkMaster); 00067 // ^ registry must know it. Caution: this is set quite late, after all onFUNCreated() actions 00068 } 00069 00070 void 00071 ResourceSchedulerBS::startCollection(int frameNr) { 00072 MESSAGE_BEGIN(NORMAL, logger, m, "Starting Master Scheduling("<<(IamUplinkMaster?"UL":"DL")<<") for frame="<<frameNr); 00073 if (!IamUplinkMaster) { // RS-TX 00074 assure(colleagues.queue!=NULL,"colleagues.queue==NULL"); 00075 m << ": Queue(cid:bits,pdus) = " << colleagues.queue->printAllQueues(); // show queue sizes: 00076 } else { // RS-RX 00077 assure(colleagues.queueProxy!=NULL,"colleagues.queueProxy==NULL"); 00078 m << ": Queue(cid:bits,pdus) = " << colleagues.queueProxy->printAllQueues(); // show queue sizes: 00079 } 00080 MESSAGE_END(); 00081 00082 ResourceScheduler::startCollection(frameNr, slotDuration); 00083 00084 lte::timing::RegistryProxy* registryInLte = dynamic_cast<lte::timing::RegistryProxy*>(colleagues.registry); 00085 registryInLte->setAllStations(); // TODO: still needed? 00086 } 00087 00088 void 00089 ResourceSchedulerBS::resetQueues(wns::scheduler::UserID user) 00090 { 00091 // Delete all PDUs from the queue 00092 assure(!colleagues.strategy->isTx(), "The scheduler queues should only be resetted for RX schedulers, exactly the fake PDUs."); 00093 colleagues.queue->resetQueues(user); 00094 } 00095 00096 void 00097 ResourceSchedulerBS::resetHARQScheduledPeerRetransmissions() 00098 { 00099 ResourceScheduler::resetHARQScheduledPeerRetransmissions(); 00100 } 00101 00102 void 00103 ResourceSchedulerBS::onDisassociated(wns::service::dll::UnicastAddress userAdr, wns::service::dll::UnicastAddress dstAdr) 00104 { 00105 // userAdr is always UT; dstAdr is always RAP (UT's next hop) 00106 if (layer2->getDLLAddress() == dstAdr) // user is directly connected to me (BS || RN-BS) 00107 { 00108 wns::node::Interface* user = layer2->getStationManager()->getStationByMAC(userAdr)->getNode(); 00109 colleagues.queue->resetQueues(wns::scheduler::UserID(user)); 00110 MESSAGE_SINGLE(NORMAL, logger, "onDisassociated("<<A2N(userAdr)<<","<<A2N(dstAdr)<<"): Removed Packets from " << A2N(dstAdr) << " to " << A2N(userAdr)); 00111 } 00112 else // multihop case: I am BS; user is connected via RN to me 00113 { 00114 // disassociation of userAdr from dstAdr 00115 // (in RAP that has dstAdr in its set of associated stations) 00116 assure(associationService->hasAssociated(dstAdr), "Disassociation notification on unknown route."); 00117 wns::node::Interface* viaRelay = layer2->getStationManager()->getStationByMAC(dstAdr)->getNode(); 00118 MESSAGE_SINGLE(NORMAL, logger, "onDisassociated("<<A2N(userAdr)<<","<<A2N(dstAdr)<<"): Removing Packets from " << A2N(layer2->getDLLAddress()) << " via " << A2N(dstAdr) << " to " << A2N(userAdr)); 00119 this->deletePacketsToVia(userAdr, viaRelay); 00120 } 00121 // disassociation of userAdr from dstAdr (in RAP that has dstAdr) 00122 if (scorer.hasRoute(userAdr)) 00123 scorer.deleteRoute(userAdr); 00124 } 00125 00126 void 00127 ResourceSchedulerBS::onAssociated(wns::service::dll::UnicastAddress userAdr, wns::service::dll::UnicastAddress dstAdr) 00128 { 00129 if (layer2->getDLLAddress() == dstAdr) 00130 { 00131 scorer.setRoute(userAdr, userAdr); 00132 MESSAGE_SINGLE(NORMAL, logger, "onAssociated: setting route to address " << A2N(userAdr)); 00133 } 00134 00135 else if (!(layer2->getDLLAddress() == userAdr)) 00136 { 00137 assure(associationService->hasAssociated(dstAdr), "onAssociated: trying to set route to a RN which not associated!"); 00138 scorer.setRoute(userAdr, dstAdr); 00139 MESSAGE_SINGLE(NORMAL, logger, "onAssociated: setting route to address " << A2N(userAdr) << " via address " << A2N(dstAdr)); 00140 } 00141 } 00142 00143 // called during disassociation: 00144 void 00145 ResourceSchedulerBS::deletePacketsToVia(wns::service::dll::UnicastAddress destination, 00146 wns::node::Interface* via) 00147 { 00148 wns::ldk::CommandReaderInterface* rlcReader = getFUN()->getCommandReader("rlc"); 00149 wns::scheduler::ConnectionVector conns = colleagues.registry->getConnectionsForUser(wns::scheduler::UserID(via)); 00150 wns::service::dll::UnicastAddress RNAddress = layer2->getStationManager()->getStationByNode(via)->getDLLAddress(); 00151 00152 MESSAGE_SINGLE(NORMAL, logger, "deletePacketsToVia("<<A2N(destination)<<","<<via->getName()<<"): "<<conns.size()<<" connections"); 00153 00154 if (conns.size() == 0) 00155 { 00156 MESSAGE_SINGLE(NORMAL, logger, "No active queue for node " << via->getName() << ", nothing had to be removed."); 00157 return; 00158 } 00159 00160 /* iterate over all cids */ 00161 for (wns::scheduler::ConnectionVector::const_iterator iter = conns.begin(); iter != conns.end(); ++iter) 00162 { 00163 wns::scheduler::ConnectionID cid = *iter; 00164 if (friends.flowManager->isControlPlaneFlowID(RNAddress,cid)) { 00165 continue; // don't delete. ControlPlane is always single/next-hop 00166 } else { // data plane flowID. Delete queue 00167 colleagues.queue->resetQueue(cid); 00168 } 00169 } // for all cids in connections 00170 } // deletePacketsToVia()
1.5.5