User Manual, Developers Guide and API Documentation

Service.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. 16, 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 <TCP/Service.hpp>
00029 #include <TCP/Connection.hpp>
00030 #include <TCP/UpperConvergence.hpp>
00031 #include <TCP/LowerConvergence.hpp>
00032 #include <TCP/ConnectionHandler.hpp>
00033 #include <TCP/HandshakeStrategyInterface.hpp>
00034 #include <TCP/FlowHandler.hpp>
00035 #include <TCP/FlowIDBuilder.hpp>
00036 
00037 #include <WNS/service/tl/PortPool.hpp>
00038 #include <WNS/service/tl/DataHandler.hpp>
00039 #include <WNS/service/tl/FlowID.hpp>
00040 
00041 #include <WNS/module/Base.hpp>
00042 #include <WNS/service/dll/FlowEstablishmentAndRelease.hpp>
00043 
00044 using namespace tcp;
00045 
00046 Service::Service(UpperConvergence* _upperConvergence,
00047          LowerConvergence* _lowerConvergence,
00048          wns::ldk::FlowSeparator* _flowSeparator,
00049          const wns::pyconfig::View& _pyco,
00050          tcp::FlowHandler* _tcpFlowHandler,
00051          wns::service::dll::FlowEstablishmentAndRelease* _fear,
00052          wns::ldk::ControlServiceRegistry* _csr) :
00053     wns::ldk::ControlService(_csr),
00054     removeDelay(2),
00055     ipService(NULL),
00056     dns(NULL),
00057     flowIDToConnectionHandler(),
00058     listeners(),
00059     portPool(_pyco.get<simTimeType>("portUnbindDelay")),
00060     logger(_pyco.get("logger")),
00061     pyco(_pyco),
00062     upperConvergence(_upperConvergence),
00063     lowerConvergence(_lowerConvergence),
00064     flowSeparator(_flowSeparator),
00065     flowEstablishmentAndRelease(_fear),
00066     tcpFlowHandler(_tcpFlowHandler)
00067 {
00068     upperConvergence->setTLService(this);
00069 }
00070 
00071 Service::~Service()
00072 {
00073 }
00074 
00075 void
00076 Service::listenOnPort(
00077     wns::service::tl::Port _port,
00078     wns::service::tl::ConnectionHandler* _ch)
00079 {
00080     assure(_port >= 0 && _port <= 65535, "Valid port number are: 0-65535 (is " << _port << ")");
00081     assure(_ch, "No valid ConnectionHandler provided (is NULL)");
00082     assure(portPool.isAvailable(_port), "Port already bound (is " << _port << ")");
00083 
00084     portPool.bind(_port);
00085     listeners.insert(_port, _ch);
00086 
00087     MESSAGE_SINGLE(NORMAL,  logger, "Listening on port " << _port << ": " << listeners.knows(_port));
00088 }
00089 
00090 void
00091 Service::stopListenOnPort(const wns::service::tl::Port _port)
00092 {
00093     assure(listeners.knows(_port), "Not currently listening on port.");
00094 
00095     MESSAGE_SINGLE(NORMAL, logger, "Stopping listenOnPort for port " << _port);
00096     listeners.erase(_port);
00097     portPool.unbind(_port);
00098 }
00099 
00100 void
00101 Service::openConnection(
00102     wns::service::tl::Port _dstPort,
00103     wns::service::nl::FQDN _source,
00104     wns::service::nl::FQDN _dstAddress,
00105     wns::service::qos::QoSClass _qosClass,
00106     wns::service::tl::ConnectionHandler* _ch)
00107 {
00108     assure(_dstPort >= 0 && _dstPort <= 65535, "Valid port numbers are: 0-65535 (is " << _dstPort << ")");
00109     assure(_ch, "No valid ConnectionHandler provided (is NULL)");
00110     assure(dns, "No DNS service is set");
00111 
00112     wns::service::tl::Port srcPort = portPool.suggestPort();
00113     portPool.bind(srcPort);
00114 
00115     wns::service::nl::Address source = dns->lookup(_source);
00116     wns::service::nl::Address destination = dns->lookup(_dstAddress);
00117     wns::service::tl::FlowID flowID(source, srcPort, destination, _dstPort);
00118 
00119     flowIDToConnectionHandler.insert(flowID, _ch);
00120 
00121     assure(!flowIDToConnections.knows(flowID), "Connection already created for flowID " << flowID);
00122     MESSAGE_SINGLE(NORMAL, logger, "TCP OpenConnection called for: " << flowID);
00123 
00124     if(flowEstablishmentAndRelease == NULL)
00125     {
00126         openConnectionContinue(flowID, 0);
00127     }
00128     else
00129     {
00130         MESSAGE_SINGLE(NORMAL, logger, "Triggering FlowEstablishment at Layer2 for FlowID: " <<flowID);
00131         flowEstablishmentAndRelease->establishFlow(flowID,_qosClass);
00132     }
00133 }
00134 
00135 void
00136 Service::openConnectionContinue(wns::service::tl::FlowID flowID, wns::service::dll::FlowID dllFlowID)
00137 {
00138     Connection* connection = new Connection(
00139         flowID, upperConvergence, this->pyco.get<wns::pyconfig::View>("connection"));
00140 
00141     lowerConvergence->mapFlowID(flowID, dllFlowID);
00142 
00143     assure(!flowIDToConnections.knows(flowID), "There is already a Connection for flowID "<< flowID);
00144     flowIDToConnections.insert(flowID, connection);
00145 
00146     MESSAGE_SINGLE(NORMAL, logger, "Opening connection for FlowID " << flowID);
00147     assure(!listeners.knows(flowID.srcPort), "Unable to open source port " << flowID  << " actively. Application is listening.");
00148     addFlowSeparatorInstance(flowID);
00149 
00150     // get handshake fu from instance of flow separator according to flowID
00151     wns::ldk::ConstKeyPtr key(new FlowIDKey(flowID));
00152     assure(flowSeparator->getInstance(key)!=NULL,"No flow created according to flowID " << flowID);
00153     HandshakeStrategyInterface* handshakeStrategy = getHandshakeStrategyFU(flowID);
00154 
00155     handshakeStrategy->registerStrategyHandler(this);
00156     handshakeStrategy->activeOpen(flowID);
00157 }
00158 
00159 void
00160 Service::dllFlowChanged(wns::service::tl::FlowID flowID, wns::service::dll::FlowID dllFlowID)
00161 {
00162        // delete old Flow, save new one
00163     lowerConvergence->unmapFlowID(flowID);
00164     lowerConvergence->mapFlowID(flowID, dllFlowID);
00165 }
00166 
00167 void
00168 Service::passiveOpenConnection(const wns::service::tl::FlowID& _flowID)
00169 {
00170     wns::service::tl::ConnectionHandler* ch = listeners.find(_flowID.srcPort);
00171 
00172     assure(!flowIDToConnectionHandler.knows(_flowID), "Connection Handler already registered for flowID " << _flowID);
00173     flowIDToConnectionHandler.insert(_flowID, ch);
00174 
00175     assure(!flowIDToConnections.knows(_flowID), "Connection already created for flowID " << _flowID);
00176     Connection* connection = new Connection(
00177         _flowID, upperConvergence, this->pyco.get<wns::pyconfig::View>("connection"));
00178 
00179     flowIDToConnections.insert(_flowID, connection);
00180 
00181     wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID));
00182     assure(flowSeparator->getInstance(key)!=NULL,"No flow created according to flowID " << _flowID);
00183     HandshakeStrategyInterface* handshakeStrategy = getHandshakeStrategyFU(_flowID);
00184     handshakeStrategy->registerStrategyHandler(this);
00185     handshakeStrategy->passiveOpen(_flowID);
00186 }
00187 
00188 void
00189 Service::addFlowSeparatorInstance(const wns::service::tl::FlowID& _flowID)
00190 {
00191     MESSAGE_SINGLE(VERBOSE, this->logger, "Asking FlowSeparator to create instance for flowID: " << _flowID);
00192     // The instance must not be available!
00193     wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID));
00194     assure(flowSeparator->getInstance(key) == NULL, "Instance of prototype flow separator already generated for flow id!");
00195     flowSeparator->addInstance(key);
00196 }
00197 
00198 HandshakeStrategyInterface*
00199 Service::getHandshakeStrategyFU(const wns::service::tl::FlowID& _flowID)
00200 {
00201     // get handshake fu from instance of flow separator according to flowID
00202     wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID));
00203     assure(flowSeparator->getInstance(key)!=NULL,
00204            "No instance of flow separator created for flowID " << _flowID);
00205     HandshakeStrategyInterface* hs = dynamic_cast<HandshakeStrategyInterface*>(
00206         dynamic_cast<wns::ldk::Group*>(
00207             flowSeparator->getInstance(key))->getSubFUN()->getFunctionalUnit(pyco.get<std::string>("handshakeStrategy")));
00208 
00209     return hs;
00210 }
00211 
00212 void
00213 Service::connectionEstablished(const wns::service::tl::FlowID& _flowID)
00214 {
00215     Connection* connection = flowIDToConnections.find(_flowID);
00216 
00217     flowIDToConnectionHandler.find(_flowID)->onConnectionEstablished(_flowID.dstAddress, connection);
00218     MESSAGE_SINGLE(NORMAL, logger, "Connection established for flow id " << _flowID);
00219 }
00220 
00221 void
00222 Service::closeConnection(wns::service::tl::Connection* _connection)
00223 {
00224     assure(_connection, "No valid Connection provided (is NULL)");
00225     assureType(_connection, tcp::Connection*);
00226 
00227     wns::service::tl::FlowID flowID = dynamic_cast<tcp::Connection*>(_connection)->getFlowID();
00228 
00229     HandshakeStrategyInterface* hs = getHandshakeStrategyFU(flowID);
00230     hs->closeConnection(flowID);
00231 }
00232 
00233 void
00234 Service::setDataTransmissionService(wns::service::nl::Service* _ipService)
00235 {
00236     assure(!ipService, "ipService already set!");
00237     assure(_ipService, "invalid ip service (NULL)");
00238 
00239     ipService = _ipService;
00240 
00241     MESSAGE_SINGLE(NORMAL, logger, "IP services registered.");
00242 }
00243 
00244 void
00245 Service::setTcpFlowHandlerService(tcp::FlowHandler* _flowHandler)
00246 {
00247     assure(_flowHandler, "invalid TcpFlowHandler service (NULL)!");
00248     tcpFlowHandler = _flowHandler;
00249     MESSAGE_SINGLE(NORMAL, logger, "TcpFlowHandler service registered.");
00250 }
00251 
00252 void
00253 Service::setDNSService(wns::service::nl::DNSService* _dns)
00254 {
00255     assure(!dns, "DNSService already set!");
00256     assure(_dns, "invalid DNS service (NULL)");
00257 
00258     dns = _dns;
00259 
00260     MESSAGE_SINGLE(NORMAL, logger, "DNS services registered.");
00261 }
00262 
00263 bool
00264 Service::isListening(wns::service::tl::Port _port)
00265 {
00266     return listeners.knows(_port);
00267 }
00268 
00269 wns::service::nl::Service*
00270 Service::getIPService()
00271 {
00272     return ipService;
00273 }
00274 
00275 Connection*
00276 Service::getConnection(const wns::service::tl::FlowID& _flowID)
00277 {
00284     if(!flowIDToConnections.knows(_flowID)){ // server: first compound arrived
00289         passiveOpenConnection(_flowID);
00290     }
00291 
00292     assure(flowIDToConnections.knows(_flowID), "No connection created for flowID " << _flowID);
00293     return flowIDToConnections.find(_flowID);
00294 }
00295 
00296 bool
00297 Service::isValidFlow(const wns::ldk::ConstKeyPtr& _key) const
00298 {
00299     ConstFlowIDKeyPtr key = wns::dynamicCast<const FlowIDKey>(_key);
00300     wns::service::tl::FlowID flowID = key->flowID_;
00301 
00302     MESSAGE_SINGLE(VERBOSE, logger, "isValidFlow(): flowID: " << flowID);
00303 
00304     if(listeners.knows(flowID.srcPort))
00305     { // server: incoming compound
00306         //const_cast<Service*>(this)->passiveOpenConnection(*flowID);
00307         return true;
00308     }
00309     else if(flowIDToConnections.knows(flowID))
00310     {
00311         // no connection open on client side
00312         return true;
00313     }
00314     else
00315     {
00316         return false;
00317     }
00318 }
00319 
00320 void
00321 Service::connectionClosed(const wns::service::tl::FlowID& _flowID)
00322 {
00323     assure(flowIDToConnections.knows(_flowID), "No connection created for flow id " << _flowID);
00324     Connection* _connection = flowIDToConnections.find(_flowID);
00325     assure(flowIDToConnectionHandler.knows(_flowID), "No connection handler registered for flow id " << _flowID);
00326     wns::service::tl::ConnectionHandler* ch = flowIDToConnectionHandler.find(_flowID);
00327 
00328     if(listeners.knows(_flowID.srcPort)){ // server
00329         ch->onConnectionClosed(_connection);
00330         flowIDToConnectionHandler.erase(_flowID);
00331         flowIDToConnections.erase(_flowID);
00332     }
00333     else { // client
00334         ch->onConnectionClosed(_connection);
00335         flowIDToConnectionHandler.erase(_flowID);
00336         flowIDToConnections.erase(_flowID);
00337         portPool.unbind(_flowID.srcPort);
00338     }
00339 
00340     wns::simulator::getEventScheduler()->scheduleNow(RemoveFlowSeparatorInstance(this, _flowID));
00341     // release the flow in layer 2
00342     lowerConvergence->unmapFlowID(_flowID);
00343 
00344     if(!(flowEstablishmentAndRelease == NULL))
00345     {
00346         MESSAGE_SINGLE(NORMAL, logger, "Deleting DLLFlow for TlFlowID: " <<_flowID);
00347         flowEstablishmentAndRelease->releaseFlow(_flowID);
00348     }
00349 
00350     // release flow in layer 2 only if there is a layer 2 at this peer
00351     delete _connection;
00352 }
00353 
00354 void
00355 Service::passiveClosed(const wns::service::tl::FlowID& _flowID)
00356 {
00357     assure(flowIDToConnections.knows(_flowID), "No connection created for flow id " << _flowID);
00358     Connection* _connection = flowIDToConnections.find(_flowID);
00359     assure(flowIDToConnectionHandler.knows(_flowID), "No connection handler registered for flow id " << _flowID);
00360     wns::service::tl::ConnectionHandler* ch = flowIDToConnectionHandler.find(_flowID);
00361 
00362     ch->onConnectionClosedByPeer(_connection);
00363     flowIDToConnectionHandler.erase(_flowID);
00364     flowIDToConnections.erase(_flowID);
00365 
00366     wns::simulator::getEventScheduler()->scheduleNow(RemoveFlowSeparatorInstance(this, _flowID));
00367     // the right place to release the flow in layer 2
00368     // release flow in layer 2 only if there is a layer 2 at this peer
00369     delete _connection;
00370 }
00371 void
00372 Service::deleteFlowSeparatorInstance(const wns::service::tl::FlowID& _flowID)
00373 {
00374     wns::ldk::ConstKeyPtr key(new FlowIDKey(_flowID));
00375     assure(flowSeparator->getInstance(key)!=NULL, "No instance with flowID " << _flowID);
00376     flowSeparator->removeInstance(key);
00377 }

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