diff --git a/TODO b/TODO
index e31720a73..a46b84940 100644
--- a/TODO
+++ b/TODO
@@ -43,4 +43,5 @@
- Use tooltips to explain options
- Exit confirmation only if there are active downloads (display number of downloads) - SMARTER
- Make use of QNetworkInterface (could be useful ?)
-- Display more info in log (PeX, UPnP, DHT w/ ports...)
\ No newline at end of file
+- Display more info in log (PeX, UPnP, DHT w/ ports...)
+- Possibility to disable the trayicon
\ No newline at end of file
diff --git a/src/GUI.cpp b/src/GUI.cpp
index 8e7716af6..5fde3e21f 100644
--- a/src/GUI.cpp
+++ b/src/GUI.cpp
@@ -405,7 +405,7 @@ void GUI::updateDlList(bool force){
// No need to update if qBittorrent DL list is hidden
return;
}
- qDebug("Updating download list");
+// qDebug("Updating download list");
LCD_UpSpeed->display(tmp); // UP LCD
LCD_DownSpeed->display(tmp2); // DL LCD
// browse handles
@@ -485,7 +485,7 @@ void GUI::updateDlList(bool force){
continue;
}
}
- qDebug("Updated Download list");
+// qDebug("Updated Download list");
}
void GUI::sortDownloadListFloat(int index, Qt::SortOrder sortOrder){
@@ -1195,7 +1195,7 @@ void GUI::trackerAuthenticationRequired(torrent_handle& h){
// Check connection status and display right icon
void GUI::checkConnectionStatus(){
- qDebug("Checking connection status");
+// qDebug("Checking connection status");
char tmp[MAX_CHAR_TMP];
session_status sessionStatus = BTSession.getSessionStatus();
// Update ratio info
@@ -1232,7 +1232,7 @@ void GUI::checkConnectionStatus(){
connecStatusLblIcon->setToolTip(""+tr("Connection status:")+"
"+tr("Offline")+"
"+tr("No peers found...")+"");
}
}
- qDebug("Connection status updated");
+// qDebug("Connection status updated");
}
/*****************************************************
diff --git a/src/UPnP.cpp b/src/UPnP.cpp
index 3a9126d90..a0abba8b5 100644
--- a/src/UPnP.cpp
+++ b/src/UPnP.cpp
@@ -87,11 +87,8 @@ m_LibraryHandle(dlopen(libname, RTLD_LAZY))
std::ostringstream msg;
if (!m_LibraryHandle) {
qDebug("error(CDynamicLibHandle): Unable to dlopen the lib. Check PATH and LD_LIBRARY_PATH.");
- //AddLogLineM(true, logUPnP, msg);
-// throw CUPnPException(msg);
} else {
qDebug("Successfully opened the lib.");
- //AddLogLineM(false, logUPnP, msg);
}
}
@@ -104,11 +101,10 @@ CDynamicLibHandle::~CDynamicLibHandle()
msg << "error(CDynamicLibHandle): Error closing " <<
m_libname << ": " << dlerror() <<
".";
-// AddLogLineM(true, logUPnP, msg);
fprintf(stderr, "%s\n", msg.str().c_str());
} else {
msg << "Successfully closed " << m_libname << ".";
-// AddLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
}
@@ -291,14 +287,14 @@ std::string CUPnPLib::processUPnPErrorMessage(
errorString <<
"'.";
}
-// AddLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
} else {
msg << "Error: " <<
messsage <<
": UPnP SDK error: " <<
GetUPnPErrorMessage(errorCode) <<
" (" << errorCode << ").";
-// AddLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
return msg.str();
@@ -326,7 +322,7 @@ void CUPnPLib::ProcessActionResponse(
msg << "\n Empty response for action '" <<
actionName << "'.";
}
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -510,7 +506,7 @@ m_relatedStateVariable(upnpLib.Element_GetChildValueByTag(argument, "relatedStat
"\n direction: " << m_direction <<
"\n retval: " << m_retval <<
"\n relatedStateVariable: " << m_relatedStateVariable;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -527,7 +523,7 @@ m_name(upnpLib.Element_GetChildValueByTag(action, "name"))
std::ostringstream msg;
msg << "\n Action:" <<
"\n name: " << m_name;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -543,7 +539,7 @@ m_allowedValue(upnpLib.Element_GetTextValue(allowedValue))
std::ostringstream msg;
msg << "\n AllowedValue:" <<
"\n allowedValue: " << m_allowedValue;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -566,7 +562,7 @@ m_sendEvents (upnpLib.Element_GetAttributeByTag (stateVariable, "sendEvents"))
"\n dataType: " << m_dataType <<
"\n defaultValue: " << m_defaultValue <<
"\n sendEvents: " << m_sendEvents;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -629,7 +625,7 @@ m_SCPD(NULL)
msg << "Error generating scpdURL from " <<
"|" << URLBase << "|" <<
m_SCPDURL << "|.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
} else {
m_absSCPDURL = scpdURL;
}
@@ -644,7 +640,7 @@ m_SCPD(NULL)
msg << "Error generating controlURL from " <<
"|" << URLBase << "|" <<
m_controlURL << "|.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
} else {
m_absControlURL = controlURL;
}
@@ -659,7 +655,7 @@ m_SCPD(NULL)
msg << "Error generating eventURL from " <<
"|" << URLBase << "|" <<
m_eventSubURL << "|.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
} else {
m_absEventSubURL = eventURL;
}
@@ -673,7 +669,7 @@ m_SCPD(NULL)
"\n absControlURL: " << m_absControlURL <<
"\n eventSubURL: " << m_eventSubURL <<
"\n absEventSubURL: " << m_absEventSubURL;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
if ( m_serviceType == upnpLib.UPNP_SERVICE_WAN_IP_CONNECTION ||
m_serviceType == upnpLib.UPNP_SERVICE_WAN_PPP_CONNECTION) {
@@ -685,7 +681,7 @@ m_SCPD(NULL)
msg.str("");
msg << "WAN Service Detected: '" <<
m_serviceType << "'.";
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
// Subscribe
upnpLib.m_ctrlPoint.Subscribe(*this);
#if 0
@@ -694,14 +690,14 @@ m_SCPD(NULL)
msg << "WAN service detected again: '" <<
m_serviceType <<
"'. Will only use the first instance.";
- AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
#endif
} else {
msg.str("");
msg << "Uninteresting service detected: '" <<
m_serviceType << "'. Ignoring.";
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
}
@@ -723,7 +719,7 @@ bool CUPnPService::Execute(
if (itAction == m_SCPD->GetActionList().end()) {
msg << "Invalid action name '" << ActionName <<
"' for service '" << GetServiceType() << "'.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
msgAction << ActionName << "(";
@@ -737,7 +733,7 @@ bool CUPnPService::Execute(
msg << "Invalid argument name '" << ArgValue[i].GetArgument() <<
"' for action '" << action.GetName() <<
"' for service '" << GetServiceType() << "'.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
const CUPnPArgument &argument = *(itArg->second);
@@ -747,7 +743,7 @@ bool CUPnPService::Execute(
ArgValue[i].GetArgument() <<
"' for action '" << action.GetName() <<
"' for service '" << GetServiceType() << "'.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
const std::string relatedStateVariableName =
@@ -762,7 +758,7 @@ bool CUPnPService::Execute(
"' for argument '" << argument.GetName() <<
"' for action '" << action.GetName() <<
"' for service '" << GetServiceType() << "'.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
const CUPnPStateVariable &stateVariable = *(itSVT->second);
@@ -774,7 +770,7 @@ bool CUPnPService::Execute(
"' for argument '" << argument.GetName() <<
"' for action '" << action.GetName() <<
"' for service '" << GetServiceType() << "'.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
}
@@ -790,7 +786,7 @@ bool CUPnPService::Execute(
"'";
}
msgAction << ")";
-// AddDebugLogLineM(false, logUPnP, msgAction);
+ qDebug("UPnP: %s", msgAction.str().c_str());
// Everything is ok, make the action
IXML_Document *ActionDoc = NULL;
if (ArgValue.size()) {
@@ -814,7 +810,7 @@ bool CUPnPService::Execute(
0, NULL);
if (!ActionDoc) {
msg << "Error: m_UpnpMakeAction returned NULL.";
-// AddLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
}
@@ -880,7 +876,7 @@ const std::string CUPnPService::GetStateVariable(
"='" <<
StVarVal <<
"'.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return stdEmptyString;
}
@@ -919,7 +915,7 @@ m_presentationURL (upnpLib.Element_GetChildValueByTag(device, "presentationURL"
msg << "Error generating presentationURL from " <<
"|" << URLBase << "|" <<
m_presentationURL << "|.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
} else {
m_presentationURL = presURL;
}
@@ -938,7 +934,7 @@ m_presentationURL (upnpLib.Element_GetChildValueByTag(device, "presentationURL"
"\n UDN: " << m_UDN <<
"\n UPC: " << m_UPC <<
"\n presentationURL: " << m_presentationURL;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -964,7 +960,7 @@ m_expires(expires)
"\n Fixed URLBase: " << FixedURLBase <<
"\n location: " << m_location <<
"\n expires: " << m_expires;
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -1000,7 +996,7 @@ m_UPnPPort(udpPort)
ipAddress = m_upnpLib.m_UpnpGetServerIpAddress();
msg << "bound to " << ipAddress << ":" <<
port << ".";
-// AddLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
msg.str("");
ret = m_upnpLib.m_UpnpRegisterClient(
static_cast(&CUPnPControlPoint::Callback),
@@ -1045,7 +1041,7 @@ m_UPnPPort(udpPort)
error:
m_upnpLib.m_UpnpFinish();
msg << ret << ": " << m_upnpLib.GetUPnPErrorMessage(ret) << ".";
-// throw CUPnPException(msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
@@ -1071,7 +1067,7 @@ bool CUPnPControlPoint::AddPortMappings(
msg << "UPnP Error: "
"CUPnPControlPoint::AddPortMapping: "
"Wan Service not detected.";
-// AddLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
@@ -1133,7 +1129,7 @@ bool CUPnPControlPoint::AddPortMappings(
msg << "CUPnPControlPoint::DeletePortMappings: "
"m_ActivePortMappingsMap.size() == " <<
m_ActivePortMappingsMap.size();
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
// Not very good, must find a better test
PortMappingNumberOfEntries.str(
@@ -1207,7 +1203,7 @@ bool CUPnPControlPoint::DeletePortMappings(
msg << "UPnP Error: "
"CUPnPControlPoint::DeletePortMapping: "
"Wan Service not detected.";
-// AddLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
return false;
}
@@ -1236,7 +1232,7 @@ bool CUPnPControlPoint::DeletePortMappings(
"CUPnPControlPoint::DeletePortMapping: "
"Mapping was not found in the active "
"mapping map.";
-// AddLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
// Delete the port mapping
@@ -1249,7 +1245,7 @@ bool CUPnPControlPoint::DeletePortMappings(
msg << "CUPnPControlPoint::DeletePortMappings: "
"m_ActivePortMappingsMap.size() == " <<
m_ActivePortMappingsMap.size();
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
// Not very good, must find a better test
PortMappingNumberOfEntries.str(
@@ -1314,7 +1310,7 @@ upnpDiscovery:
int ret;
if (d_event->ErrCode != UPNP_E_SUCCESS) {
msg << upnpCP->m_upnpLib.GetUPnPErrorMessage(d_event->ErrCode) << ".";
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
// Get the XML tree device description in doc
ret = upnpCP->m_upnpLib.m_UpnpDownloadXmlDoc(d_event->Location, &doc);
@@ -1322,7 +1318,7 @@ upnpDiscovery:
msg << "Error retrieving device description from " <<
d_event->Location << ": " <<
upnpCP->m_upnpLib.GetUPnPErrorMessage(ret) << ".";
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
if (doc) {
// Get the root node
@@ -1365,7 +1361,7 @@ upnpDiscovery:
//fprintf(stderr, "Callback: UPNP_DISCOVERY_SEARCH_TIMEOUT\n");
// Search timeout
msg << "UPNP_DISCOVERY_SEARCH_TIMEOUT.";
-// AddDebugLogLineM(false, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
// Unlock the search timeout mutex
upnpCP->m_WaitForSearchTimeout.unlock();
@@ -1380,7 +1376,7 @@ upnpDiscovery:
msg << "error(UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE): " <<
upnpCP->m_upnpLib.GetUPnPErrorMessage(dab_event->ErrCode) <<
".";
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
std::string devType = dab_event->DeviceType;
// Check for an InternetGatewayDevice and removes it from the list
@@ -1540,7 +1536,7 @@ eventSubscriptionRequest:
EventType);
msg << "error(UPnP::Callback): Event not handled:'" <<
EventType << "'.";
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
fprintf(stderr, "%s\n", msg.str().c_str());
// Better not throw in the callback. Who would catch it?
//throw CUPnPException(msg);
@@ -1581,7 +1577,7 @@ void CUPnPControlPoint::OnEventReceived(
} else {
msg << "\n Empty property list.";
}
-// AddDebugLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
// Freeing that doc segfaults. Probably should not be freed.
//m_upnpLib.m_ixmlDocument_free(ChangedVariablesDoc);
}
@@ -1646,7 +1642,7 @@ void CUPnPControlPoint::Subscribe(CUPnPService &service)
msg << "Successfully subscribed to service " <<
service.GetServiceType() << ", absEventSubURL: " <<
service.GetAbsEventSubURL() << ".";
-// AddLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
IXML_Document *scpdDoc = NULL;
errcode = m_upnpLib.m_UpnpDownloadXmlDoc(
@@ -1662,7 +1658,7 @@ void CUPnPControlPoint::Subscribe(CUPnPService &service)
msg.str("");
msg << "Error getting SCPD Document from " <<
service.GetAbsSCPDURL() << ".";
-// AddLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
} else {
msg << "Error subscribing to service " <<
@@ -1676,8 +1672,7 @@ void CUPnPControlPoint::Subscribe(CUPnPService &service)
// Error processing
error:
- return;
-// AddLogLineM(true, logUPnP, msg);
+ qDebug("UPnP: %s", msg.str().c_str());
}
diff --git a/src/bittorrent.h b/src/bittorrent.h
index 19b93e3ba..eae9e7331 100644
--- a/src/bittorrent.h
+++ b/src/bittorrent.h
@@ -37,6 +37,7 @@
#include
#include "deleteThread.h"
+#include "upnp.h"
class QTimer;
class QString;
diff --git a/src/src.pro b/src/src.pro
index a942ca7a3..79aac610b 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -28,6 +28,7 @@ contains(DEBUG_MODE, 0){
QMAKE_CXXFLAGS_RELEASE += -fwrapv
QMAKE_CXXFLAGS_DEBUG += -fwrapv
#LIBS += -lcurl
+LIBS += -lupnp
#CONFIG += link_pkgconfig
#PKGCONFIG += libtorrent
QT += network
@@ -129,8 +130,8 @@ SOURCES += GUI.cpp \
searchEngine.cpp
!contains(DEFINES, NO_UPNP){
message(UPnP Enabled)
- HEADERS += UPnP.h
- SOURCES += UPnP.cpp
+ HEADERS += UPnP.h upnp.h
+ SOURCES += UPnP.cpp upnp.cpp
}else{
message(UPnP Disabled)
}
diff --git a/src/upnp.cpp b/src/upnp.cpp
new file mode 100644
index 000000000..3a3d71ba4
--- /dev/null
+++ b/src/upnp.cpp
@@ -0,0 +1,57 @@
+#include "upnp.h"
+
+int callBackCPRegister( Upnp_EventType EventType, void* Event, void* Cookie ){
+ switch(EventType){
+ case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
+ case UPNP_DISCOVERY_SEARCH_RESULT:
+ {
+ struct Upnp_Discovery *d_event = (struct Upnp_Discovery*) Event;
+ IXML_Document *DescDoc=NULL;
+ int ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc);
+ if(ret != UPNP_E_SUCCESS){
+ // silently ignore?
+ }else{
+ ((UPnPHandler*)Cookie)->addUPnPDevice(d_event);
+// TvCtrlPointAddDevice(DescDoc, d_event->Location, d_event->Expires);
+ }
+ if(DescDoc) ixmlDocument_free(DescDoc);
+// TvCtrlPointPrintList();
+ break;
+ }
+ case UPNP_DISCOVERY_SEARCH_TIMEOUT:
+ qDebug("UPnP devices discovery timed out...");
+ break;
+ case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
+ {
+ struct Upnp_Discovery *d_event = (struct Upnp_Discovery*) Event;
+ ((UPnPHandler*)Cookie)->removeUPnPDevice(QString(d_event->DeviceId));
+// TvCtrlPointPrintList();
+ break;
+ }
+ default:
+ qDebug("Debug: UPnP Unhandled event");
+ }
+ return 0;
+}
+
+void UPnPHandler::run(){
+ // Initialize the SDK
+ int ret = UpnpInit(NULL, 0);
+ if(ret != UPNP_E_SUCCESS){
+ qDebug("Fatal error: UPnP initialization failed");
+ UpnpFinish();
+ return;
+ }
+ qDebug("UPnP successfully initialized");
+ qDebug("UPnP bind on IP %s:%d", UpnpGetServerIpAddress(), UpnpGetServerPort());
+ // Register the UPnP control point
+ ret = UpnpRegisterClient(callBackCPRegister, this, &UPnPClientHandle);
+ if(ret != UPNP_E_SUCCESS){
+ qDebug("Fatal error: UPnP control point registration failed");
+ UpnpFinish();
+ return;
+ }
+ qDebug("UPnP control point successfully registered");
+ // Look for UPnP enabled routers (devices)
+ ret = UpnpSearchAsync(UPnPClientHandle, WAIT_TIMEOUT, "upnp:rootdevice", this);
+}
\ No newline at end of file
diff --git a/src/upnp.h b/src/upnp.h
new file mode 100644
index 000000000..8e6859e35
--- /dev/null
+++ b/src/upnp.h
@@ -0,0 +1,57 @@
+/*
+ * Bittorrent Client using Qt4 and libtorrent.
+ * Copyright (C) 2006 Christophe Dumez
+ *
+ * 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.
+ *
+ * Contact : chris@qbittorrent.org
+ */
+#ifndef __QBT_UPNP__
+#define __QBT_UPNP__
+
+#include
+#include
+
+#include
+
+#define WAIT_TIMEOUT 5
+
+// Control point registration callback
+
+class UPnPHandler : public QThread {
+ Q_OBJECT
+
+ private:
+ UpnpClient_Handle UPnPClientHandle;
+ QHash UPnPDevices;
+
+ public:
+ UPnPHandler(){}
+ ~UPnPHandler(){}
+
+ public slots:
+ void addUPnPDevice(struct Upnp_Discovery* device){
+
+ }
+
+ void removeUPnPDevice(QString device_id){
+
+ }
+
+ private:
+ void run();
+};
+
+#endif