From 24735dfd4819d95fdbd551c0ac571006a713f0f5 Mon Sep 17 00:00:00 2001 From: eshe Date: Sat, 29 May 2010 12:20:05 +0100 Subject: [PATCH] Better connection handling in daemon. --- Makefile | 2 +- src/common/connectionmanager.cpp | 207 +++++++++++++++++++++++++------------- src/common/connectionmanager.h | 31 +++--- src/daemon/Makefile | 8 +- src/daemon/calllistener.cpp | 73 ++++++++++---- src/daemon/calllistener.h | 3 + src/daemon/daemon.pro | 2 +- src/daemon/main.cpp | 1 + src/gui/Makefile | 8 +- src/gui/gui.pro | 2 +- 10 files changed, 221 insertions(+), 116 deletions(-) diff --git a/Makefile b/Makefile index e40eaf1..1b54f97 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: jenirok -# Generated by qmake (2.01a) (Qt 4.6.2) on: Fri May 28 20:43:16 2010 +# Generated by qmake (2.01a) (Qt 4.6.2) on: Sat May 29 12:19:01 2010 # Project: jenirok.pro # Template: subdirs # Command: /usr/bin/qmake -unix -o Makefile jenirok.pro diff --git a/src/common/connectionmanager.cpp b/src/common/connectionmanager.cpp index 174228e..14c0b0a 100644 --- a/src/common/connectionmanager.cpp +++ b/src/common/connectionmanager.cpp @@ -17,106 +17,177 @@ */ #include -#include -#include +#include +#include +#include +#include #include "connectionmanager.h" -ConnectionManager* ConnectionManager::instance_ = 0; -ConnectionManager::ConnectionManager(): connection_(0), connected_(false) +ConnectionManager::ConnectionManager(QObject* parent): QObject(parent), +ready_(false), connected_(false), timeout_(false), ignoreStateChanges_(false), +timer_(0) { - DBusError err; - DBusConnection* conn; - dbus_error_init(&err); - conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + QDBusConnection systemBus = QDBusConnection::systemBus(); - if(conn) - { - dbus_connection_setup_with_g_main(conn, NULL); - } - else - { - qDebug() << "Unable to connect to DBUS: " << err.message; - dbus_error_free(&err); - } + icd2interface_ = new QDBusInterface(ICD_DBUS_API_INTERFACE, + ICD_DBUS_API_PATH, ICD_DBUS_API_INTERFACE, + systemBus, this); - connection_ = con_ic_connection_new(); + systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, ICD_DBUS_API_STATE_SIG, + this, SLOT(stateChange(const QDBusMessage&))); - g_signal_connect(G_OBJECT(connection_), "connection-event", G_CALLBACK(connectionHandler), NULL); - - -} + systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH, + ICD_DBUS_API_INTERFACE, ICD_DBUS_API_CONNECT_SIG, + this, SLOT(connectionChange(const QDBusMessage&))); -ConnectionManager& ConnectionManager::instance() -{ - if(!instance_) - { - instance_ = new ConnectionManager; - } - return *instance_; } bool ConnectionManager::connect() { - return con_ic_connection_connect(connection_, CON_IC_CONNECT_FLAG_NONE); + ready_ = false; + ignoreStateChanges_ = true; + unsigned int flags = static_cast(ICD_CONNECTION_FLAG_USER_EVENT); + icd2interface_->call(ICD_DBUS_API_CONNECT_REQ, QVariant(flags)); + waitSignal(); + return connected_; } bool ConnectionManager::disconnect() { - return con_ic_connection_disconnect(connection_); + if(!connected_) + { + return false; + } + + ready_ = false; + ignoreStateChanges_ = false; + unsigned int flags = static_cast(ICD_CONNECTION_FLAG_USER_EVENT); + icd2interface_->call(ICD_DBUS_API_DISCONNECT_REQ, QVariant(flags)); + connected_ = false; + return true; } bool ConnectionManager::isConnected() { + ready_ = false; + ignoreStateChanges_ = false; + QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_STATE_REQ); + + unsigned int numOfReplies = rep.arguments().value(0).value(); + + if(numOfReplies == 0) + { + return false; + } + + waitSignal(); return connected_; } -void ConnectionManager::connectionHandler(ConIcConnection *connection, - ConIcConnectionEvent *event, - gpointer user_data) + +void ConnectionManager::stateChange(const QDBusMessage& rep) { - Q_UNUSED(connection); - Q_UNUSED(user_data); + if(ignoreStateChanges_) + { + return; + } - ConIcConnectionStatus status = con_ic_connection_event_get_status(event); + unsigned int status = rep.arguments().value(7).value(); switch(status) { - - case CON_IC_STATUS_CONNECTED: + case ICD_STATE_CONNECTING: + qDebug() << "Connecting"; + break; + case ICD_STATE_CONNECTED: + connected_ = true; + ready_ = true; qDebug() << "Connected"; - instance_->emit connected(); - instance_->connected_ = true; break; - - case CON_IC_STATUS_DISCONNECTING: - case CON_IC_STATUS_NETWORK_UP: + case ICD_STATE_DISCONNECTING: + qDebug() << "Disconnecting"; + break; + case ICD_STATE_DISCONNECTED: + connected_ = false; + ready_ = true; + qDebug() << "Disconnected"; + break; + case ICD_STATE_LIMITED_CONN_ENABLED: + connected_ = true; + ready_ = true; + qDebug() << "Limited connection enabled"; break; + case ICD_STATE_LIMITED_CONN_DISABLED: + connected_ = false; + ready_ = true; + qDebug() << "Limited connection disabled"; + break; + case ICD_STATE_SEARCH_START: + qDebug() << "Search start"; + break; + case ICD_STATE_SEARCH_STOP: + qDebug() << "Search stop"; + break; + case ICD_STATE_INTERNAL_ADDRESS_ACQUIRED: + qDebug() << "Internal address acquired"; + break; + default: + qDebug() << "Unknown connection status"; + break; + } + +} + +void ConnectionManager::connectionChange(const QDBusMessage& rep) +{ + unsigned int status = rep.arguments().value(6).value(); - case CON_IC_STATUS_DISCONNECTED: - ConIcConnectionError err = con_ic_connection_event_get_error(event); - switch(err) - { - case CON_IC_CONNECTION_ERROR_NONE: - case CON_IC_CONNECTION_ERROR_USER_CANCELED: - qDebug() << "Disconnected"; - instance_->emit disconnected(); - instance_->connected_ = false; - break; - - case CON_IC_CONNECTION_ERROR_INVALID_IAP: - qDebug() << "Invalid IAP"; - instance_->emit error("Invalid IAP"); - break; - - case CON_IC_CONNECTION_ERROR_CONNECTION_FAILED: - qDebug() << "Connection failed"; - instance_->emit error("Connection failed"); - break; - - default: - break; - } + switch(status) + { + case ICD_CONNECTION_SUCCESSFUL: + connected_ = true; + ready_ = true; + qDebug() << "Connection successful"; + break; + case ICD_CONNECTION_NOT_CONNECTED: + connected_ = false; + ready_ = true; + qDebug() << "Connection not connected"; + break; + case ICD_CONNECTION_DISCONNECTED: + connected_ = false; + ready_ = true; + qDebug() << "Connection disconnected"; break; + default: + qDebug() << "Unknown connection status"; + break; + } +} + +bool ConnectionManager::waitSignal() +{ + timeout_ = false; + timer_ = startTimer(TIMEOUT); + + while(!ready_ && !timeout_) + { + QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); } + + killTimer(timer_); + + return ready_ || !timeout_; +} + +void ConnectionManager::timerEvent(QTimerEvent* event) +{ + Q_UNUSED(event); + killTimer(timer_); + timeout_ = true; + timer_ = 0; + + qDebug() << "Connection request timed out"; } diff --git a/src/common/connectionmanager.h b/src/common/connectionmanager.h index ea44605..0c12a0d 100644 --- a/src/common/connectionmanager.h +++ b/src/common/connectionmanager.h @@ -20,35 +20,36 @@ #define CONNECTIONMANAGER_H #include -#include -#include -#include -#include +#include +#include +#include class ConnectionManager : public QObject { Q_OBJECT public: - static ConnectionManager& instance(); + ConnectionManager(QObject* parent = 0); bool connect(); bool disconnect(); bool isConnected(); + static unsigned int const TIMEOUT = 20000; -signals: - void connected(); - void disconnected(); - void error(QString const& error); +protected: + virtual void timerEvent(QTimerEvent* event); +private slots: + void stateChange(const QDBusMessage& rep); + void connectionChange(const QDBusMessage& rep); private: - ConnectionManager(); - static void connectionHandler(ConIcConnection *connection, - ConIcConnectionEvent *event, - gpointer user_data); - static ConnectionManager* instance_; - ConIcConnection* connection_; + bool waitSignal(); + bool ready_; bool connected_; + bool timeout_; + bool ignoreStateChanges_; + int timer_; + QDBusInterface *icd2interface_; }; #endif diff --git a/src/daemon/Makefile b/src/daemon/Makefile index 9382160..9c61e57 100644 --- a/src/daemon/Makefile +++ b/src/daemon/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: jenirokd -# Generated by qmake (2.01a) (Qt 4.6.2) on: Fri May 28 20:43:40 2010 +# Generated by qmake (2.01a) (Qt 4.6.2) on: Sat May 29 12:19:04 2010 # Project: daemon.pro # Template: app # Command: /usr/bin/qmake -unix -o Makefile daemon.pro @@ -11,12 +11,12 @@ CC = gcc CXX = g++ DEFINES = -DDATADIR=\"/usr/share\" -DPKGDATADIR=\"\" -DQT_NO_DEBUG -DQT_MAEMO5_LIB -DQT_SQL_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -CFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/conic -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) -CXXFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/conic -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) +CFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) +CXXFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) INCPATH = -I/targets/FREMANTLE_X86/usr/share/qt4/mkspecs/linux-g++ -I. -I/targets/FREMANTLE_X86/usr/include/QtCore -I/targets/FREMANTLE_X86/usr/include/QtNetwork -I/targets/FREMANTLE_X86/usr/include/QtGui -I/targets/FREMANTLE_X86/usr/include/QtSql -I/targets/FREMANTLE_X86/usr/include/QtMaemo5 -I/targets/FREMANTLE_X86/usr/include -I/targets/FREMANTLE_X86/usr/include/QtDBus -I../common -I. LINK = g++ LFLAGS = -Wl,-O1 -Wl,-rpath,/usr/lib -LIBS = $(SUBLIBS) -L/usr/lib -lebook-1.2 -ledataserver-1.2 -lxml2 -lgconf-2 -ldbus-glib-1 -lconic -ldbus-1 -lgobject-2.0 -lglib-2.0 -L/usr/lib -lQtMaemo5 -L/usr/X11R6/lib -lQtSql -lQtGui -lQtNetwork -lQtDBus -lQtXml -lQtCore -lpthread +LIBS = $(SUBLIBS) -L/usr/lib -lebook-1.2 -ledataserver-1.2 -lxml2 -lgconf-2 -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 -L/usr/lib -lQtMaemo5 -L/usr/X11R6/lib -lQtSql -lQtGui -lQtNetwork -lQtDBus -lQtXml -lQtCore -lpthread AR = ar cqs RANLIB = QMAKE = /usr/bin/qmake diff --git a/src/daemon/calllistener.cpp b/src/daemon/calllistener.cpp index 16ee0d5..1237b7c 100644 --- a/src/daemon/calllistener.cpp +++ b/src/daemon/calllistener.cpp @@ -37,7 +37,9 @@ namespace QDBusConnection CallListener::systemBus_ = QDBusConnection::systemBus(); -CallListener::CallListener(): eniro_(0), contactManager_(0), box_(0), label_(0), retries_(-1) +CallListener::CallListener(): eniro_(0), contactManager_(0), +connectionManager_(0), closeConnection_(false), box_(0), label_(0), +retries_(-1) { } @@ -63,6 +65,7 @@ void CallListener::begin() SLOT(callTerminate())); contactManager_ = new ContactManager; + connectionManager_ = new ConnectionManager; eniro_ = new Eniro(Eniro::stringToSite(Settings::instance()->get("site"))); @@ -100,6 +103,10 @@ void CallListener::end() this, SLOT(callTerminate())); + delete contactManager_; + contactManager_ = 0; + delete connectionManager_; + connectionManager_ = 0; delete eniro_; eniro_ = 0; delete box_; @@ -110,7 +117,7 @@ void CallListener::end() void CallListener::search(Eniro::SearchDetails const& details) { - qDebug() << "Search called"; + qDebug() << "Search called"; Eniro::Result result; @@ -126,6 +133,17 @@ void CallListener::search(Eniro::SearchDetails const& details) showResult(tr("Searching...")); retries_ = 0; currentSearch_ = details; + + if(!connectionManager_->isConnected()) + { + connectionManager_->connect(); + closeConnection_ = true; + } + else + { + closeConnection_ = false; + } + eniro_->search(details); } @@ -151,13 +169,13 @@ void CallListener::requestFinished(QVector const& results, if(retries_ < NUMBER_OF_RETRIES && retries_ >= 0) { - retries_++; - eniro_->search(currentSearch_); - return; + retries_++; + eniro_->search(currentSearch_); + return; } else { - message = tr("Search failed:") + " " + eniro_->errorString() + "."; + message = tr("Search failed:") + " " + eniro_->errorString() + "."; } } else if(results.size() == 0) @@ -174,10 +192,15 @@ void CallListener::requestFinished(QVector const& results, retries_ = -1; + if(closeConnection_) + { + connectionManager_->disconnect(); + closeConnection_ = false; + } + timedMessage_ = message; - // Show banner after small delay - showDelayedResult(message, BANNER_DELAY); + showResult(message); } @@ -217,7 +240,7 @@ void CallListener::incomingCall(QDBusObjectPath path, QString number) if(!contactManager_->numberExists(number)) { - qDebug() << "Number doesn't exist"; + qDebug() << "Number doesn't exist"; systemBus_.connect(CALL_SERVICE_NAME, path.path(), @@ -232,32 +255,38 @@ void CallListener::incomingCall(QDBusObjectPath path, QString number) } else { - qDebug() << "Number exists"; + qDebug() << "Number exists"; } } void CallListener::callTerminate() { - if(box_->isVisible()) - { - box_->hide(); - } + if(box_->isVisible()) + { + box_->hide(); + } + + if(closeConnection_) + { + connectionManager_->disconnect(); + closeConnection_ = false; + } } void CallListener::showDelayedResult(QString const& text, int delay) { - timedMessage_ = text; - QTimer::singleShot(delay, this, SLOT(showTimedMessage())); + timedMessage_ = text; + QTimer::singleShot(delay, this, SLOT(showTimedMessage())); } void CallListener::showTimedMessage() { - if(timedMessage_.size() == 0) - { - return; - } + if(timedMessage_.size() == 0) + { + return; + } - showResult(timedMessage_); + showResult(timedMessage_); - timedMessage_ = ""; + timedMessage_ = ""; } diff --git a/src/daemon/calllistener.h b/src/daemon/calllistener.h index a2f5e88..346b6f5 100644 --- a/src/daemon/calllistener.h +++ b/src/daemon/calllistener.h @@ -27,6 +27,7 @@ #include "informationbox.h" #include "eniro.h" #include "contactmanager.h" +#include "connectionmanager.h" class CallListener: public QObject { @@ -58,6 +59,8 @@ private: QString timedMessage_; Eniro* eniro_; ContactManager* contactManager_; + ConnectionManager* connectionManager_; + bool closeConnection_; InformationBox* box_; QLabel* label_; static QDBusConnection systemBus_; diff --git a/src/daemon/daemon.pro b/src/daemon/daemon.pro index 7262cef..c7fb9b2 100644 --- a/src/daemon/daemon.pro +++ b/src/daemon/daemon.pro @@ -8,7 +8,7 @@ TRANSLATIONS = ../common/translations/fi_FI.ts RESOURCES = ../common/translations.grc INCLUDEPATH += ../common CONFIG += link_pkgconfig -PKGCONFIG += libebook-1.2 glib-2.0 conic +PKGCONFIG += libebook-1.2 glib-2.0 unix { #VARIABLES diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index ef17c49..56b176d 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -24,6 +24,7 @@ #include #include "calllistener.h" #include "settings.h" +#include "connectionmanager.h" int main(int argc, char *argv[]) { diff --git a/src/gui/Makefile b/src/gui/Makefile index 261cd8c..5c68ad7 100644 --- a/src/gui/Makefile +++ b/src/gui/Makefile @@ -1,6 +1,6 @@ ############################################################################# # Makefile for building: jenirok -# Generated by qmake (2.01a) (Qt 4.6.2) on: Fri May 28 20:43:25 2010 +# Generated by qmake (2.01a) (Qt 4.6.2) on: Sat May 29 12:19:04 2010 # Project: gui.pro # Template: app # Command: /usr/bin/qmake -unix -o Makefile gui.pro @@ -11,12 +11,12 @@ CC = gcc CXX = g++ DEFINES = -DDATADIR=\"/usr/share\" -DPKGDATADIR=\"\" -DQT_NO_DEBUG -DQT_MAEMO5_LIB -DQT_SQL_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_SHARED -CFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/conic -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) -CXXFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/conic -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) +CFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) +CXXFLAGS = -pipe -O2 -I/usr/include/evolution-data-server-1.4 -I/usr/include/dbus-1.0 -I/usr/include/libxml2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/gconf/2 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -Wall -W -D_REENTRANT $(DEFINES) INCPATH = -I/targets/FREMANTLE_X86/usr/share/qt4/mkspecs/linux-g++ -I. -I/targets/FREMANTLE_X86/usr/include/QtCore -I/targets/FREMANTLE_X86/usr/include/QtNetwork -I/targets/FREMANTLE_X86/usr/include/QtGui -I/targets/FREMANTLE_X86/usr/include/QtSql -I/targets/FREMANTLE_X86/usr/include/QtMaemo5 -I/targets/FREMANTLE_X86/usr/include -I../common -I. LINK = g++ LFLAGS = -Wl,-O1 -Wl,-rpath,/usr/lib -LIBS = $(SUBLIBS) -L/usr/lib -lebook-1.2 -ledataserver-1.2 -lxml2 -lgconf-2 -ldbus-glib-1 -lconic -ldbus-1 -lgobject-2.0 -lglib-2.0 -lQtMaemo5 -L/usr/lib -L/usr/X11R6/lib -lQtSql -lQtGui -lQtNetwork -lQtDBus -lQtXml -lQtCore -lpthread +LIBS = $(SUBLIBS) -L/usr/lib -lebook-1.2 -ledataserver-1.2 -lxml2 -lgconf-2 -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 -lQtMaemo5 -L/usr/lib -L/usr/X11R6/lib -lQtSql -lQtGui -lQtNetwork -lQtDBus -lQtXml -lQtCore -lpthread AR = ar cqs RANLIB = QMAKE = /usr/bin/qmake diff --git a/src/gui/gui.pro b/src/gui/gui.pro index c0ea702..5ba8594 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -7,7 +7,7 @@ TRANSLATIONS = ../common/translations/fi_FI.ts RESOURCES = icons.grc ../common/translations.grc INCLUDEPATH += ../common CONFIG += link_pkgconfig -PKGCONFIG += libebook-1.2 glib-2.0 conic +PKGCONFIG += libebook-1.2 glib-2.0 unix { #VARIABLES -- 1.7.9.5