Vidalia
0.2.17
|
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.torproject.org/projects/vidalia.html. No part of Vidalia, 00007 ** including this file, may be copied, modified, propagated, or distributed 00008 ** except according to the terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file UPNPControl.cpp 00013 ** \brief Singleton object for interacting with UPNP device 00014 */ 00015 00016 #include "UPNPControl.h" 00017 #include "UPNPControlThread.h" 00018 00019 #include <QMutex> 00020 #include <QMetaType> 00021 00022 #ifdef Q_OS_WIN32 00023 #include <winsock2.h> 00024 #endif 00025 00026 00027 /** UPNPControl singleton instance. */ 00028 UPNPControl* UPNPControl::_instance = 0; 00029 00030 /** Returns a pointer to this object's singleton instance. */ 00031 UPNPControl* UPNPControl::instance() 00032 { 00033 if (0 == _instance) { 00034 _instance = new UPNPControl(); 00035 _instance->_controlThread->start(); 00036 } 00037 return _instance; 00038 } 00039 00040 /** Constructor. Initializes and starts a thread in which all blocking UPnP 00041 * operations will be performed. */ 00042 UPNPControl::UPNPControl() 00043 { 00044 _forwardedORPort = 0; 00045 _forwardedDirPort = 0; 00046 _error = UnknownError; 00047 _state = IdleState; 00048 00049 qRegisterMetaType<UPNPControl::UPNPError>("UPNPControl::UPNPError"); 00050 qRegisterMetaType<UPNPControl::UPNPState>("UPNPControl::UPNPState"); 00051 00052 _mutex = new QMutex(); 00053 _controlThread = new UPNPControlThread(this); 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