*/
#include <QDebug>
-#include <glib-object.h>
-#include <dbus/dbus-glib-lowlevel.h>
+#include <QApplication>
+#include <QtCore/QTimerEvent>
+#include <QtCore/QVariant>
+#include <icd/dbus_api.h>
#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()
+bool ConnectionManager::connect()
{
- if(!instance_)
- {
- instance_ = new ConnectionManager;
- }
+ ready_ = false;
+ ignoreStateChanges_ = true;
+ unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
+ icd2interface_->call(ICD_DBUS_API_CONNECT_REQ, QVariant(flags));
+ waitSignal();
+ return connected_;
+}
- return *instance_;
+bool ConnectionManager::disconnect()
+{
+ if(!connected_)
+ {
+ return false;
+ }
+
+ ready_ = false;
+ ignoreStateChanges_ = false;
+ unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
+ icd2interface_->call(ICD_DBUS_API_DISCONNECT_REQ, QVariant(flags));
+ connected_ = false;
+ return true;
}
-bool ConnectionManager::connect()
+bool ConnectionManager::isConnected()
{
- return con_ic_connection_connect(connection_, CON_IC_CONNECT_FLAG_NONE);
+ ready_ = false;
+ ignoreStateChanges_ = false;
+ QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_STATE_REQ);
+
+ unsigned int numOfReplies = rep.arguments().value(0).value<unsigned int>();
+
+ if(numOfReplies == 0)
+ {
+ return false;
+ }
+
+ waitSignal();
+ return connected_;
}
-bool ConnectionManager::disconnect()
+void ConnectionManager::stateChange(const QDBusMessage& rep)
{
- return con_ic_connection_disconnect(connection_);
+ if(ignoreStateChanges_)
+ {
+ return;
+ }
+
+ unsigned int status = rep.arguments().value(7).value<unsigned int>();
+
+ switch(status)
+ {
+ case ICD_STATE_CONNECTING:
+ qDebug() << "Connecting";
+ break;
+ case ICD_STATE_CONNECTED:
+ connected_ = true;
+ ready_ = true;
+ qDebug() << "Connected";
+ break;
+ 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;
+ }
+
}
-bool ConnectionManager::isConnected()
+void ConnectionManager::connectionChange(const QDBusMessage& rep)
+{
+ unsigned int status = rep.arguments().value(6).value<unsigned int>();
+
+ 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()
{
- return connected_;
+ timeout_ = false;
+ timer_ = startTimer(TIMEOUT);
+
+ while(!ready_ && !timeout_)
+ {
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
+ }
+
+ killTimer(timer_);
+
+ return ready_ || !timeout_;
}
-void ConnectionManager::connectionHandler(ConIcConnection *connection,
- ConIcConnectionEvent *event,
- gpointer user_data)
+
+void ConnectionManager::timerEvent(QTimerEvent* event)
{
- Q_UNUSED(connection);
- Q_UNUSED(user_data);
-
- ConIcConnectionStatus status = con_ic_connection_event_get_status(event);
-
- switch(status)
- {
-
- case CON_IC_STATUS_CONNECTED:
- qDebug() << "Connected";
- instance_->emit connected();
- instance_->connected_ = true;
- break;
-
- case CON_IC_STATUS_DISCONNECTING:
- case CON_IC_STATUS_NETWORK_UP:
- break;
-
- 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;
- }
- break;
- }
+ Q_UNUSED(event);
+ killTimer(timer_);
+ timeout_ = true;
+ timer_ = 0;
+
+ qDebug() << "Connection request timed out";
}