![]() |
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/FlowHandlerBS.hpp> 00029 #include <LTE/controlplane/flowmanagement/FlowManager.hpp> 00030 #include <LTE/macg/MACg.hpp> 00031 #include <LTE/rlc/RLCCommand.hpp> 00032 #include <LTE/helper/Keys.hpp> 00033 00034 #include <WNS/StaticFactory.hpp> 00035 #include <WNS/ldk/tools/Synchronizer.hpp> 00036 #include <WNS/service/dll/FlowID.hpp> 00037 00038 #define A2N(a) (((a).getInteger()>0) ? layer2->getStationManager()->getStationByMAC(a)->getName() : "DLL<0") 00039 00040 using namespace lte::controlplane::flowmanagement::flowhandler; 00041 00042 STATIC_FACTORY_REGISTER_WITH_CREATOR(FlowHandlerBS, 00043 wns::ldk::FunctionalUnit, 00044 "lte.controlplane.flowmanagement.flowhandler.FlowHandlerBS", 00045 wns::ldk::FUNConfigCreator); 00046 00047 FlowHandlerBS::FlowHandlerBS(wns::ldk::fun::FUN* fun, const wns::pyconfig::View& config) : 00048 FlowHandler(fun, config), 00049 wns::Cloneable<FlowHandlerBS>(), 00050 fun(fun) 00051 { 00052 } 00053 00054 void 00055 FlowHandlerBS::onFUNCreated() 00056 { 00057 FlowHandler::onFUNCreated(); 00058 bsLayer2 = getFUN()->getLayer<dll::Layer2*>(); 00059 assure(bsLayer2==layer2,"obsolete?"); 00060 flowManagerBS = bsLayer2->getControlService<lte::controlplane::flowmanagement::FlowManagerBS>("FlowManagerBS"); 00061 assure(flowManagerBS == flowManager,"obsolete?"); 00062 00063 if (mode == modeBase) 00064 macg = fun->findFriend<lte::macg::MACg*>("macg"); 00065 else 00066 macg = fun->findFriend<lte::macg::MACg*>("macg"+separator+taskID); 00067 00068 lowerFlowGate = getFUN()->findFriend<wns::ldk::FlowGate*>(mode+separator+"lowerFlowGate"); 00069 assure(lowerFlowGate, "FlowHandlerHandler requires: "+mode+separator+"lowerFlowGate"); 00070 } 00071 00072 //confirms Flow_req and assigns new FlowID 00073 void 00074 FlowHandlerBS::flowConfirm(lte::helper::TransactionID _transactionId, 00075 wns::service::dll::FlowID _flowID, 00076 wns::service::dll::UnicastAddress _utAddress) 00077 { 00078 assure(TransactionIDToDestination.knows(_transactionId), "There is no such TransactionID"); 00079 createFlow_conf(_transactionId, TransactionIDToDestination.find(_transactionId), _flowID, _utAddress); 00080 } 00081 00082 void 00083 FlowHandlerBS::createFlow_conf(lte::helper::TransactionID _transactionId, 00084 wns::service::dll::UnicastAddress _destination, 00085 wns::service::dll::FlowID _flowID, 00086 wns::service::dll::UnicastAddress _utAddress) 00087 { 00088 // create closed Flow in gate 00089 lowerFlowGate->createFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(_flowID))); 00090 00092 wns::ldk::CompoundPtr FlowHandlerCompound = wns::ldk::CompoundPtr( 00093 new wns::ldk::Compound( 00094 getFUN()->createCommandPool())); 00095 00097 lte::macg::MACgCommand* macgCommand = macg->activateCommand(FlowHandlerCompound->getCommandPool()); 00098 macgCommand->peer.source = layer2->getDLLAddress(); 00099 macgCommand->peer.dest = _destination; 00100 00102 lte::rlc::RLCCommand* rlcCommand = dynamic_cast<lte::rlc::RLCCommand*>(rlcReader->activateCommand(FlowHandlerCompound->getCommandPool())); 00103 rlcCommand->peer.source = layer2->getDLLAddress(); 00104 //rlcCommand->peer.destination = ? 00105 // using _destinationAddress as peerAddress here is not fully correct 00106 // we must have the next hop address here to get the DCCH FlowID 00107 FlowManager::ControlPlaneFlowIDs controlPlaneFlowIDs = flowManager->getControlPlaneFlowIDs(_destination); 00108 rlcCommand->peer.flowID = controlPlaneFlowIDs[lte::helper::QoSClasses::DCCH()]; 00109 00111 FlowHandlerCommand* outgoingCommand = this->activateCommand(FlowHandlerCompound->getCommandPool()); 00112 outgoingCommand->peer.myCompoundType = CompoundType::flow_confirm(); 00113 outgoingCommand->peer.flowID = _flowID; 00114 outgoingCommand->peer.transactionId = _transactionId; 00115 outgoingCommand->peer.user = _utAddress; 00116 00117 if (getConnector()->hasAcceptor(FlowHandlerCompound)) 00118 { 00119 getConnector()->getAcceptor(FlowHandlerCompound)->sendData(FlowHandlerCompound); 00120 MESSAGE_SINGLE(NORMAL, logger, "Sending FlowConfirm for flowID="<< outgoingCommand->peer.flowID<<" to "<<A2N(_destination)); 00121 } 00122 else 00123 assure(false, "BS: Lower FU is not accepting scheduled FlowConfirm compound but is supposed to do so"); 00124 00125 //delete transactionID entry from container: 00126 TransactionIDToDestination.erase(_transactionId); 00127 } 00128 00129 void 00130 FlowHandlerBS::doOnData(const wns::ldk::CompoundPtr& compound) 00131 { 00132 lte::controlplane::flowmanagement::flowhandler::FlowHandlerCommand* incomingCommand = getCommand(compound->getCommandPool()); 00133 lte::macg::MACgCommand* macgCommand = macg->getCommand(compound->getCommandPool()); 00134 00135 if (incomingCommand->peer.myCompoundType == CompoundType::flow_req()) 00136 { 00137 MESSAGE_SINGLE(NORMAL, logger, "FlowRequest received from "<<A2N(incomingCommand->peer.user)<<" with TransactionID="<< incomingCommand->peer.transactionId); 00138 TransactionIDToDestination.insert(incomingCommand->peer.transactionId, macgCommand->peer.source); 00139 // call FlowManager 00140 flowManagerBS->forwardFlowRequest(incomingCommand->peer.transactionId, 00141 this, 00142 incomingCommand->peer.user, 00143 incomingCommand->peer.oldFlowID, 00144 incomingCommand->peer.qosClass); 00145 } 00146 00147 else if (incomingCommand->peer.myCompoundType == CompoundType::flow_rel()) 00148 { 00149 MESSAGE_SINGLE(NORMAL, logger, "FlowReleaseRequest received from "<<A2N(incomingCommand->peer.user)<<" for FlowID=" << incomingCommand->peer.flowID); 00150 00151 FlowIDInToDestIn.insert(incomingCommand->peer.flowID, macgCommand->peer.source); 00152 flowManagerBS->releaseFlow(incomingCommand->peer.flowID); 00153 createFlowReleaseAck(incomingCommand->peer.flowID); 00154 } 00155 00156 else if (incomingCommand->peer.myCompoundType == CompoundType::flow_ack()) 00157 { 00158 MESSAGE_SINGLE(NORMAL, logger, "FlowAck received from "<<A2N(incomingCommand->peer.user)<<" for FlowID=" << incomingCommand->peer.flowID); 00159 // open lower FlowGate: 00160 lowerFlowGate->openFlow(wns::ldk::ConstKeyPtr(new lte::helper::key::FlowID(incomingCommand->peer.flowID))); 00161 flowManagerBS->flowBuilt(incomingCommand->peer.flowID); 00162 } 00163 00164 else 00165 assure(false, "received FlowHandlerCompound with wrong type!"); 00166 00167 } 00168 00169 void 00170 FlowHandlerBS::createFlowReleaseAck(wns::service::dll::FlowID _flowID) 00171 { 00173 wns::ldk::CompoundPtr FlowHandlerCompound = 00174 wns::ldk::CompoundPtr(new wns::ldk::Compound(getFUN()->createCommandPool())); 00175 00176 wns::service::dll::UnicastAddress destinationAddress = FlowIDInToDestIn.find(_flowID); 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_rel_ack(); 00195 outgoingCommand->peer.flowID = _flowID; 00196 00197 if (getConnector()->hasAcceptor(FlowHandlerCompound)) 00198 { 00199 getConnector()->getAcceptor(FlowHandlerCompound)->sendData(FlowHandlerCompound); 00200 MESSAGE_SINGLE(NORMAL, logger, "Sending FlowReleaseAck " << outgoingCommand->peer.flowID); 00201 } 00202 else 00203 assure(false, "BS: Lower FU is not accepting scheduled FlowReleaseAck compound but is supposed to do so"); 00204 00205 FlowIDInToDestIn.erase(_flowID); 00206 }
1.5.5