UPNPControl.cpp

Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If 
00004 **  you did not receive the LICENSE file with this file, you may obtain it
00005 **  from the Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to
00008 **  the terms described in the LICENSE file.
00009 */
00010 
00011 /* 
00012 ** \file UPNPControl.cpp
00013 ** \version $Id: UPNPControl.cpp 3803 2009-05-31 00:12:09Z edmanm $
00014 ** \brief Singleton object for interacting with UPNP device
00015 */
00016 
00017 #include "UPNPControl.h"
00018 #include "UPNPControlThread.h"
00019 
00020 #include <QMutex>
00021 #include <QMetaType>
00022 
00023 #ifdef Q_OS_WIN32
00024 #include <winsock2.h>
00025 #endif
00026 
00027 
00028 /** UPNPControl singleton instance. */
00029 UPNPControl* UPNPControl::_instance = 0;
00030 
00031 /** Returns a pointer to this object's singleton instance. */
00032 UPNPControl* UPNPControl::instance()
00033 {
00034   if (0 == _instance) {
00035     _instance = new UPNPControl();
00036     _instance->_controlThread->start();
00037   }
00038   return _instance;
00039 }
00040 
00041 /** Constructor. Initializes and starts a thread in which all blocking UPnP
00042  * operations will be performed. */
00043 UPNPControl::UPNPControl()
00044 {
00045   _forwardedORPort = 0;
00046   _forwardedDirPort = 0;
00047   _error = UnknownError;
00048   _state = IdleState;
00049   
00050   qRegisterMetaType<UPNPControl::UPNPError>("UPNPControl::UPNPError");
00051   qRegisterMetaType<UPNPControl::UPNPState>("UPNPControl::UPNPState");
00052 
00053   _mutex = new QMutex();
00054   _controlThread = new UPNPControlThread(this);
00055 }
00056 
00057 /** Destructor. cleanup() should be called before the object is destroyed.
00058  * \sa cleanup()
00059  */
00060 UPNPControl::~UPNPControl()
00061 {
00062   delete _mutex;
00063   delete _controlThread;
00064 }
00065 
00066 /** Terminates the UPnP control thread and frees memory allocated to this
00067  * object's singleton instance. */
00068 void
00069 UPNPControl::cleanup()
00070 {
00071   _instance->_controlThread->stop();
00072   delete _instance;
00073   _instance = 0;
00074 }  
00075 
00076 /** Sets <b>desiredDirPort</b> and <b>desiredOrPort</b> to the currently
00077  * forwarded DirPort and ORPort values. */
00078 void
00079 UPNPControl::getDesiredState(quint16 *desiredDirPort, quint16 *desiredOrPort)
00080 {
00081   _mutex->lock();
00082   *desiredDirPort = _forwardedDirPort;
00083   *desiredOrPort = _forwardedORPort;
00084   _mutex->unlock();
00085 }
00086 
00087 /** Sets the desired DirPort and ORPort port mappings to <b>desiredDirPort</b>
00088  * and <b>desiredOrPort</b>, respectively. */
00089 void
00090 UPNPControl::setDesiredState(quint16 desiredDirPort, quint16 desiredOrPort)
00091 {
00092   _mutex->lock();
00093   _forwardedDirPort = desiredDirPort;
00094   _forwardedORPort = desiredOrPort;
00095   _mutex->unlock();
00096   
00097   _controlThread->wakeup();
00098 }
00099 
00100 /** Sets the most recent UPnP-related error to <b>error</b> and emits the
00101  * error() signal. */
00102 void
00103 UPNPControl::setError(UPNPError upnpError)
00104 {
00105   _mutex->lock();
00106   _error = upnpError;
00107   _mutex->unlock();
00108   
00109   emit error(upnpError);
00110 }
00111 
00112 /** Sets the current UPnP state to <b>state</b> and emits the stateChanged()
00113  * signal. */
00114 void
00115 UPNPControl::setState(UPNPState state)
00116 {
00117   _mutex->lock();
00118   _state = state;
00119   _mutex->unlock();
00120 
00121   emit stateChanged(state);
00122 }
00123 
00124 /** Returns the type of error that occurred last. */
00125 UPNPControl::UPNPError
00126 UPNPControl::error() const
00127 {
00128   QMutexLocker locker(_mutex);
00129   return _error;
00130 }
00131 
00132 /** Returns a QString describing the type of error that occurred last. */
00133 QString
00134 UPNPControl::errorString() const
00135 {
00136   UPNPError error = this->error();
00137 
00138   switch (error) {
00139     case Success:
00140       return tr("Success");
00141     case NoUPNPDevicesFound:
00142       return tr("No UPnP-enabled devices found");
00143     case NoValidIGDsFound:
00144       return tr("No valid UPnP-enabled Internet gateway devices found");
00145     case WSAStartupFailed:
00146       return tr("WSAStartup failed");
00147     case AddPortMappingFailed:
00148       return tr("Failed to add a port mapping");
00149     case GetPortMappingFailed:
00150       return tr("Failed to retrieve a port mapping");
00151     case DeletePortMappingFailed:
00152       return tr("Failed to remove a port mapping");
00153     default:
00154       return tr("Unknown error");
00155   }
00156 }
00157 
00158 /** Returns the number of milliseconds to wait for devices to respond
00159  * when attempting to discover UPnP-enabled IGDs. */
00160 int
00161 UPNPControl::discoverTimeout() const
00162 {
00163   return UPNPControlThread::UPNPCONTROL_DISCOVER_TIMEOUT;
00164 }
00165 
Generated on Mon Aug 30 23:09:51 2010 for Vidalia by  doxygen 1.6.3