![]() |
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/controlplane/flowmanagement/flowhandler/FlowHandlerUT.hpp> 00029 #include <LTE/macg/MACg.hpp> 00030 #include <LTE/rlc/RLCCommand.hpp> 00031 #include <LTE/helper/Keys.hpp> 00032 #include <LTE/controlplane/flowmanagement/FlowManager.hpp> 00033 00034 #include <WNS/StaticFactory.hpp> 00035 #include <DLL/Layer2.hpp> 00036 00037 #define A2N(a) (((a).getInteger()>0) ? layer2->getStationManager()->getStationByMAC(a)->getName() : "DLL<0") 00038 00039 using namespace lte::controlplane::flowmanagement::flowhandler; 00040 00041 STATIC_FACTORY_REGISTER_WITH_CREATOR(lte::controlplane::flowmanagement::flowhandler::FlowHandlerUT, 00042 wns::ldk::FunctionalUnit, 00043 "lte.controlplane.flowmanagement.flowhandler.FlowHandlerUT", 00044 wns::ldk::FUNConfigCreator); 00045 00046 FlowHandlerUT::FlowHandlerUT(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00047 FlowHandler(fun, config), 00048 wns::Cloneable<FlowHandlerUT>(), 00049 timeout(config.get<double>("timeout")), 00050 commandname(config.get<std::string>("commandname")), 00051 fun(fun) 00052 { 00053 } 00054 00055 void 00056 FlowHandlerUT::onFUNCreated() 00057 { 00058 FlowHandler::onFUNCreated(); 00059 utLayer2 = fun->getLayer<dll::Layer2*>(); 00060 assure(utLayer2==layer2,"obsolete?"); 00061 flowManagerUT = utLayer2->getControlService<lte::controlplane::flowmanagement::FlowManagerUT>("FlowManagerUT"); 00062 assure(flowManagerUT == flowManager,"obsolete?"); 00063 00064 if (mode == modeBase) 00065 macg = fun->findFriend<lte::macg::MACg*>("macg"); 00066 else 00067 fun->findFriend<lte::macg::MACg*>("macg"+separator+taskID); 00068 00069 lowerFlowGate = getFUN()->findFriend<wns::ldk::FlowGate*>(mode+separator+"lowerFlowGate"); 00070 assure(lowerFlowGate, "FlowHandlerHandler required: "+mode+separator+"lowerFlowGate"); 00071 } 00072 00073 void 00074 FlowHandlerUT::createFlow(wns::service::dll::FlowID flowID) 00075 { 00076 lowerFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(flowID))); 00077 lowerFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(flowID))); 00078 } 00079 00080 void 00081 FlowHandlerUT::doOnData(const wns::ldk::CompoundPtr& compound) 00082 { 00083 lte::macg::MACgCommand* macgCommand = macg->getCommand(compound->getCommandPool()); 00084 00085 lte::controlplane::flowmanagement::flowhandler::FlowHandlerCommand* incomingCommand = getCommand(compound->getCommandPool()); 00086 if (incomingCommand->peer.myCompoundType == CompoundType::flow_confirm()) 00087 { 00088 MESSAGE_SINGLE(NORMAL, logger, "FlowConfirm received for TransactionID="<< incomingCommand->peer.transactionId<<" with FlowID="<< incomingCommand->peer.flowID); 00089 00090 //return ACK! 00091 createFlow_ack(incomingCommand->peer.flowID, macgCommand->peer.source); 00092 00093 // inform FlowManager 00094 flowManagerUT->flowBuilt(incomingCommand->peer.transactionId, incomingCommand->peer.flowID); 00095 00096 // create open Flow in gates 00097 createFlow(incomingCommand->peer.flowID); 00098 00099 // delete if an old flowID: 00100 if(FlowIDOutToDestOut.knows(incomingCommand->peer.flowID)) 00101 FlowIDOutToDestOut.erase(incomingCommand->peer.flowID); 00102 00103 FlowIDOutToDestOut.insert(incomingCommand->peer.flowID, macgCommand->peer.source); 00104 00105 } 00106 else if (incomingCommand->peer.myCompoundType == CompoundType::flow_rel_ack()) 00107 { 00108 MESSAGE_SINGLE(NORMAL, logger, "FlowReleaseAck received for FlowID=" << incomingCommand->peer.flowID); 00109 flowReleased(incomingCommand->peer.flowID); 00110 } 00111 00112 else //unknown CompoundType 00113 { 00114 MESSAGE_SINGLE(NORMAL, logger, "Unknown compound received. Type: " << incomingCommand->peer.myCompoundType); 00115 assure(false, "Received FlowHandler Compound with wrong type!"); 00116 } 00117 } 00118 00119 void 00120 FlowHandlerUT::onTimeout() 00121 { 00122 00123 MESSAGE_SINGLE(NORMAL, logger, "FlowRequest TimeOut reached"); 00124 } 00125 00126 void 00127 FlowHandlerUT::flowReq(lte::helper::TransactionID _transactionId, wns::service::dll::UnicastAddress _destinationAddress, wns::service::dll::FlowID oldFlowID, wns::service::qos::QoSClass qosClass) 00128 { 00129 createFlow_req(_transactionId, _destinationAddress, oldFlowID, qosClass); 00130 } 00131 00132 void 00133 FlowHandlerUT::createFlow_req(lte::helper::TransactionID _transactionId, wns::service::dll::UnicastAddress _destinationAddress, wns::service::dll::FlowID oldFlowID, wns::service::qos::QoSClass qosClass) const 00134 { 00136 wns::ldk::CompoundPtr FlowHandlerCompound = 00137 wns::ldk::CompoundPtr(new wns::ldk::Compound(getFUN()->createCommandPool())); 00138 00140 lte::macg::MACgCommand* macgCommand = macg->activateCommand(FlowHandlerCompound->getCommandPool()); 00141 macgCommand->peer.source = layer2->getDLLAddress(); 00142 macgCommand->peer.dest = _destinationAddress; 00143 00145 lte::rlc::RLCCommand* rlcCommand = dynamic_cast<lte::rlc::RLCCommand*>(rlcReader->activateCommand(FlowHandlerCompound->getCommandPool())); 00146 rlcCommand->peer.source = layer2->getDLLAddress(); 00147 //rlcCommand->peer.destination = ? 00148 // using _destinationAddress as peerAddress here is not fully correct 00149 // we must have the next hop address here to get the ControlPlaneFlowID 00150 FlowManager::ControlPlaneFlowIDs controlPlaneFlowIDs = flowManager->getControlPlaneFlowIDs(_destinationAddress); 00151 rlcCommand->peer.flowID = controlPlaneFlowIDs[lte::helper::QoSClasses::DCCH()]; 00152 00154 FlowHandlerCommand* outgoingCommand = this->activateCommand(FlowHandlerCompound->getCommandPool()); 00155 outgoingCommand->peer.myCompoundType = CompoundType::flow_req(); 00156 outgoingCommand->peer.transactionId = _transactionId; 00157 outgoingCommand->peer.user = layer2->getDLLAddress(); 00158 outgoingCommand->peer.oldFlowID = oldFlowID; 00159 outgoingCommand->peer.qosClass = qosClass; 00160 00161 if (getConnector()->hasAcceptor(FlowHandlerCompound)) 00162 { 00163 getConnector()->getAcceptor(FlowHandlerCompound)->sendData(FlowHandlerCompound); 00164 00165 MESSAGE_SINGLE(NORMAL, logger, "Sending FlowRequest with TransactionID="<<outgoingCommand->peer.transactionId<<" to "<<A2N(_destinationAddress)); 00166 } 00167 else 00168 assure(false, "UT: Lower FU is not accepting scheduled FlowRequest compound but is supposed to do so"); 00169 } 00170 00171 void 00172 FlowHandlerUT::createFlow_ack(wns::service::dll::FlowID _flowID, wns::service::dll::UnicastAddress _destinationAddress) const 00173 { 00175 wns::ldk::CompoundPtr FlowHandlerCompound = 00176 wns::ldk::CompoundPtr(new wns::ldk::Compound(getFUN()->createCommandPool())); 00177 00179 lte::macg::MACgCommand* macgCommand = macg->activateCommand(FlowHandlerCompound->getCommandPool()); 00180 macgCommand->peer.source = layer2->getDLLAddress(); 00181 macgCommand->peer.dest = _destinationAddress; 00182 00184 lte::rlc::RLCCommand* rlcCommand = dynamic_cast<lte::rlc::RLCCommand*>(rlcReader->activateCommand(FlowHandlerCompound->getCommandPool())); 00185 rlcCommand->peer.source = layer2->getDLLAddress(); 00186 //rlcCommand->peer.destination = ? 00187 // using _destinationAddress as peerAddress here is not fully correct 00188 // we must have the next hop address here to get the ControlPlaneFlowID 00189 FlowManager::ControlPlaneFlowIDs controlPlaneFlowIDs = flowManager->getControlPlaneFlowIDs(_destinationAddress); 00190 rlcCommand->peer.flowID = controlPlaneFlowIDs[lte::helper::QoSClasses::DCCH()]; 00191 00193 FlowHandlerCommand* outgoingCommand = this->activateCommand(FlowHandlerCompound->getCommandPool()); 00194 outgoingCommand->peer.myCompoundType = CompoundType::flow_ack(); 00195 outgoingCommand->peer.flowID = _flowID; 00196 outgoingCommand->peer.user = layer2->getDLLAddress(); 00197 00198 if (getConnector()->hasAcceptor(FlowHandlerCompound)) 00199 { 00200 getConnector()->getAcceptor(FlowHandlerCompound)->sendData(FlowHandlerCompound); 00201 00202 MESSAGE_SINGLE(NORMAL, logger, "Sending FlowAck for FlowID=" << outgoingCommand->peer.flowID); 00203 } 00204 else 00205 assure(false, "UT: Lower FU is not accepting scheduled FlowAck compound but is supposed to do so"); 00206 } 00207 00208 void 00209 FlowHandlerUT::createFlowReleaseReq(wns::service::dll::FlowID _flowID) 00210 { 00212 wns::ldk::CompoundPtr FlowHandlerCompound = 00213 wns::ldk::CompoundPtr(new wns::ldk::Compound(getFUN()->createCommandPool())); 00214 00215 wns::service::dll::UnicastAddress destinationAddress = FlowIDOutToDestOut.find(_flowID); 00216 00218 lte::macg::MACgCommand* macgCommand = macg->activateCommand(FlowHandlerCompound->getCommandPool()); 00219 macgCommand->peer.source = layer2->getDLLAddress(); 00220 macgCommand->peer.dest = destinationAddress; 00221 00223 lte::rlc::RLCCommand* rlcCommand = dynamic_cast<lte::rlc::RLCCommand*>(rlcReader->activateCommand(FlowHandlerCompound->getCommandPool())); 00224 rlcCommand->peer.source = layer2->getDLLAddress(); 00225 //rlcCommand->peer.destination = ? 00226 // using _destinationAddress as peerAddress here is not fully correct 00227 // we must have the next hop address here to get the ControlPlaneFlowID 00228 FlowManager::ControlPlaneFlowIDs controlPlaneFlowIDs = flowManager->getControlPlaneFlowIDs(destinationAddress); 00229 rlcCommand->peer.flowID = controlPlaneFlowIDs[lte::helper::QoSClasses::DCCH()]; 00230 00232 FlowHandlerCommand* outgoingCommand = this->activateCommand(FlowHandlerCompound->getCommandPool()); 00233 outgoingCommand->peer.myCompoundType = CompoundType::flow_rel(); 00234 outgoingCommand->peer.flowID = _flowID; 00235 outgoingCommand->peer.user = layer2->getDLLAddress(); 00236 00237 if (getConnector()->hasAcceptor(FlowHandlerCompound)) 00238 { 00239 getConnector()->getAcceptor(FlowHandlerCompound)->sendData(FlowHandlerCompound); 00240 00241 MESSAGE_SINGLE(NORMAL, logger, "Sending FlowReleaseRequest for FlowID=" << outgoingCommand->peer.flowID); 00242 } 00243 else 00244 assure(false, "UT: Lower FU is not accepting scheduled FlowRelease_Request compound but is supposed to do so"); 00245 } 00246 00247 void 00248 FlowHandlerUT::releaseFlow(wns::service::dll::FlowID flowID) 00249 { 00250 //send FlowReleaseRequest to next RAP 00251 createFlowReleaseReq(flowID); 00252 } 00253 00254 void 00255 FlowHandlerUT::flowReleased(wns::service::dll::FlowID flowID) 00256 { 00257 //destroyFlow(flowID); 00258 // Flow released -> inform FlowManager 00259 flowManagerUT->flowReleased(flowID); 00260 }
1.5.5