Vidalia 0.2.10
|
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