diff options
Diffstat (limited to 'src/upnp/upnprouter.h')
-rw-r--r-- | src/upnp/upnprouter.h | 303 |
1 files changed, 303 insertions, 0 deletions
diff --git a/src/upnp/upnprouter.h b/src/upnp/upnprouter.h new file mode 100644 index 0000000..d717a49 --- /dev/null +++ b/src/upnp/upnprouter.h @@ -0,0 +1,303 @@ +/*************************************************************************** + * Copyright (C) 2005 by Joris Guisson * + * joris.guisson@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef KTUPNPROUTER_H +#define KTUPNPROUTER_H + +#include <qtimer.h> +#include <kio/job.h> +#include <qvaluelist.h> +#include "exitoperation.h" +#include <kurl.h> +#include <qstringlist.h> +#include <kstreamsocket.h> +#include "portlist.h" +#include "forwardportlist.h" + +using bt::Uint16; + +namespace bt +{ + + /** + * @author Joris Guisson <joris.guisson@gmail.com> + * + * Job to wait for a certain amount of time or until one or more ExitOperation's have + * finished. + */ + class WaitJob : public KIO::Job + { + Q_OBJECT + public: + WaitJob(Uint32 millis); + virtual ~WaitJob(); + + virtual void kill(bool quietly=true); + + /** + * Add an ExitOperation; + * @param op The operation + */ + void addExitOperation(kt::ExitOperation* op); + + + /** + * Execute a WaitJob + * @param job The Job + */ + static void execute(WaitJob* job); + + /// Are there any ExitOperation's we need to wait for + bool needToWait() const {return exit_ops.count() > 0;} + + private slots: + void timerDone(); + void operationFinished(kt::ExitOperation* op); + + private: + QTimer timer; + QValueList<kt::ExitOperation*> exit_ops; + }; + + void SynchronousWait(Uint32 millis); + + +} + +namespace bt +{ + class HTTPRequest; + class WaitJob; +} + +namespace net +{ + class ForwardPortList; +} +namespace KIO +{ + class Job; +} + +namespace kt +{ + + /** + * Structure describing a UPnP service found in an xml file. + */ + struct UPnPService + { + QString serviceid; + QString servicetype; + QString controlurl; + QString eventsuburl; + QString scpdurl; + + UPnPService(); + UPnPService(const UPnPService & s); + + /** + * Set a property of the service. + * @param name Name of the property (matches to variable names) + * @param value Value of the property + */ + void setProperty(const QString & name,const QString & value); + + /** + * Set all strings to empty. + */ + void clear(); + + /// Print the data of this service + void debugPrintData(); + + /** + * Assignment operator + * @param s The service to copy + * @return *this + */ + UPnPService & operator = (const UPnPService & s); + }; + + /** + * Struct to hold the description of a device + */ + struct UPnPDeviceDescription + { + QString friendlyName; + QString manufacturer; + QString modelDescription; + QString modelName; + QString modelNumber; + + /** + * Set a property of the description + * @param name Name of the property (matches to variable names) + * @param value Value of the property + */ + void setProperty(const QString & name,const QString & value); + }; + + /** + * @author Joris Guisson + * + * Class representing a UPnP enabled router. This class is also used to communicate + * with the router. + */ + class UPnPRouter : public QObject + { + Q_OBJECT + + public: + struct Forwarding + { + net::Port extport; + net::Port intport; + bt::HTTPRequest* pending_req; + UPnPService* service; + }; + + struct ForwardingRequest + { + net::Port extport; + net::Port intport; + bt::HTTPRequest* pending_req; + }; + + private: + QString server; + QString tmp_file; + KURL location; + UPnPDeviceDescription desc; + QValueList<UPnPService> services; + QValueList<Forwarding> fwds; + QValueList<ForwardingRequest> fwdreqs; + QValueList<bt::HTTPRequest*> active_reqs; + net::ForwardPortList* forwardedPortList; + + public: + /** + * Construct a router. + * @param server The name of the router + * @param location The location of it's xml description file + * @param verbose Print lots of debug info + */ + UPnPRouter(const QString & server,const KURL & location,bool verbose = false); + virtual ~UPnPRouter(); + + /// Get the name of the server + QString getServer() const {return server;} + + /// Get the location of it's xml description + KURL getLocation() const {return location;} + + /// Get the device description + UPnPDeviceDescription & getDescription() {return desc;} + + /// Get the device description (const version) + const UPnPDeviceDescription & getDescription() const {return desc;} + + /** + * Download the XML File of the router. + */ + void downloadXMLFile(); + + /** + * Add a service to the router. + * @param s The service + */ + void addService(const UPnPService & s); + +#if 0 + /** + * See if a port is forwarded + * @param port The Port + */ + void isPortForwarded(const net::Port & port); + + /** + * Get the external IP address. + */ + void getExternalIP(); +#endif + + /** + * Forward a local port + * @param port The local port to forward + */ + void forward(const net::Port & externalport, + const net::Port & internalport = net::Port::Port(), + bool force = false); + + /** + * Undo forwarding + * @param port The port + * @param waitjob When this is set the jobs needs to be added to the waitjob, + * so we can wait for their completeion at exit + */ + void undoForward(const net::Port & externalport,const net::Port & internalport, + bt::WaitJob* waitjob = 0); + + void debugPrintData(); + + QValueList<ForwardingRequest>::iterator beginReqMappings() {return fwdreqs.begin();} + QValueList<ForwardingRequest>::iterator endReqMappings() {return fwdreqs.end();} + QValueList<Forwarding>::iterator beginPortMappings() {return fwds.begin();} + QValueList<Forwarding>::iterator endPortMappings() {return fwds.end();} + net::ForwardPortList* forwardedPorts() {return forwardedPortList;} + private slots: + void onReplyOK(bt::HTTPRequest* r,const QString &,bool); + void onReplyError(bt::HTTPRequest* r,const QString &,bool); + void onError(bt::HTTPRequest* r,bool); + void downloadFinished(KIO::Job* j); + + + + signals: + /** + * Tell the GUI that it needs to be updated. + */ + void updateGUI(); + + /** + * Signal which indicates that the XML was downloaded successfully or not. + * @param r The router which emitted the signal + * @param success Wether or not it succeeded + */ + void xmlFileDownloaded(UPnPRouter* r,bool success); + + void replyOK(kt::UPnPRouter*,bt::HTTPRequest* ,const QString &,bool); + void replyError(kt::UPnPRouter*,bt::HTTPRequest* ,const QString &,bool); + + private: + QValueList<UPnPService>::iterator findPortForwardingService(); + + bt::HTTPRequest* sendSoapQuery(const QString & query,const QString & soapact,const QString & controlurl,bool fwd, bool at_exit = false ); + bool verbose; + + void forward(UPnPService* srv,const net::Port & externalport,const net::Port & internalport = net::Port::Port()); + void undoForward(UPnPService* srv,const net::Port & externalport,const net::Port & + internalport,bt::WaitJob* waitjob); + void httpRequestDone(bt::HTTPRequest* r,bool erase_fwd); + }; + +} + + +#endif |