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 2638 2008-06-01 23:42:53Z edmanm $
00014 ** \brief Singleton object for interacting with UPNP device
00015 */
00016 
00017 #include "upnpcontrol.h"
00018 
00019 #include <QMutex>
00020 #include <QMetaType>
00021 
00022 #ifdef Q_OS_WIN32
00023 #include <winsock2.h>
00024 #endif
00025 
00026 #include "upnpcontrolthread.h"
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   return _instance;
00037 }
00038 
00039 /** Constructor. Initializes and starts a thread in which all blocking UPnP
00040  * operations will be performed. */
00041 UPNPControl::UPNPControl()
00042 {
00043   _forwardedORPort = 0;
00044   _forwardedDirPort = 0;
00045   _error = UnknownError;
00046   _state = IdleState;
00047   
00048   qRegisterMetaType<UPNPControl::UPNPError>("UPNPControl::UPNPError");
00049   qRegisterMetaType<UPNPControl::UPNPState>("UPNPControl::UPNPState");
00050 
00051   _mutex = new QMutex();
00052   _controlThread = new UPNPControlThread(this);
00053   _controlThread->start();
00054 }
00055 
00056 /** Destructor. cleanup() should be called before the object is destroyed.
00057  * \sa cleanup()
00058  */
00059 UPNPControl::~UPNPControl()
00060 {
00061   delete _mutex;
00062   delete _controlThread;
00063 }
00064 
00065 /** Terminates the UPnP control thread and frees memory allocated to this
00066  * object's singleton instance. */
00067 void
00068 UPNPControl::cleanup()
00069 {
00070   _instance->_controlThread->stop();
00071   delete _instance;
00072   _instance = 0;
00073 }  
00074 
00075 /** Sets <b>desiredDirPort</b> and <b>desiredOrPort</b> to the currently
00076  * forwarded DirPort and ORPort values. */
00077 void
00078 UPNPControl::getDesiredState(quint16 *desiredDirPort, quint16 *desiredOrPort)
00079 {
00080   _mutex->lock();
00081   *desiredDirPort = _forwardedDirPort;
00082   *desiredOrPort = _forwardedORPort;
00083   _mutex->unlock();
00084 }
00085 
00086 /** Sets the desired DirPort and ORPort port mappings to <b>desiredDirPort</b>
00087  * and <b>desiredOrPort</b>, respectively. */
00088 void
00089 UPNPControl::setDesiredState(quint16 desiredDirPort, quint16 desiredOrPort)
00090 {
00091   _mutex->lock();
00092   _forwardedDirPort = desiredDirPort;
00093   _forwardedORPort = desiredOrPort;
00094   _mutex->unlock();
00095   
00096   _controlThread->wakeup();
00097 }
00098 
00099 /** Sets the most recent UPnP-related error to <b>error</b> and emits the
00100  * error() signal. */
00101 void
00102 UPNPControl::setError(UPNPError upnpError)
00103 {
00104   _mutex->lock();
00105   _error = upnpError;
00106   _mutex->unlock();
00107   
00108   emit error(upnpError);
00109 }
00110 
00111 /** Sets the current UPnP state to <b>state</b> and emits the stateChanged()
00112  * signal. */
00113 void
00114 UPNPControl::setState(UPNPState state)
00115 {
00116   _mutex->lock();
00117   _state = state;
00118   _mutex->unlock();
00119 
00120   emit stateChanged(state);
00121 }
00122 
00123 /** Returns the type of error that occurred last. */
00124 UPNPControl::UPNPError
00125 UPNPControl::error() const
00126 {
00127   QMutexLocker locker(_mutex);
00128   return _error;
00129 }
00130 
00131 /** Returns a QString describing the type of error that occurred last. */
00132 QString
00133 UPNPControl::errorString() const
00134 {
00135   UPNPError error = this->error();
00136 
00137   switch (error) {
00138     case Success:
00139       return tr("Success");
00140     case NoUPNPDevicesFound:
00141       return tr("No UPnP-enabled devices found");
00142     case NoValidIGDsFound:
00143       return tr("No valid UPnP-enabled Internet gateway devices found");
00144     case WSAStartupFailed:
00145       return tr("WSAStartup failed");
00146     case AddPortMappingFailed:
00147       return tr("Failed to add a port mapping");
00148     case GetPortMappingFailed:
00149       return tr("Failed to retrieve a port mapping");
00150     case DeletePortMappingFailed:
00151       return tr("Failed to remove a port mapping");
00152     default:
00153       return tr("Unknown error");
00154   }
00155 }
00156 
00157 /** Returns the number of milliseconds to wait for devices to respond
00158  * when attempting to discover UPnP-enabled IGDs. */
00159 int
00160 UPNPControl::discoverTimeout() const
00161 {
00162   return UPNPControlThread::UPNPCONTROL_DISCOVER_TIMEOUT;
00163 }
00164 

Generated on Wed Nov 26 21:04:20 2008 for Vidalia by  doxygen 1.5.7.1