#include <QApplication>
#include <QtCore/QTimerEvent>
#include <QtCore/QVariant>
+#include <QtDBus/QDBusArgument>
#include <icd/dbus_api.h>
#include "connectionmanager.h"
ConnectionManager::ConnectionManager(QObject* parent): QObject(parent),
-ready_(false), connected_(false), timeout_(false), ignoreStateChanges_(false),
-timer_(0)
+blocking_(true), stateReady_(false), connectionReady_(false), scanReady_(false),
+connected_(false), timeout_(false), numberOfConnections_(0),
+scannedConnections_(0), timer_(0), connections_(false)
{
QDBusConnection systemBus = QDBusConnection::systemBus();
ICD_DBUS_API_INTERFACE, ICD_DBUS_API_CONNECT_SIG,
this, SLOT(connectionChange(const QDBusMessage&)));
+ systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
+ ICD_DBUS_API_INTERFACE, ICD_DBUS_API_SCAN_SIG,
+ this, SLOT(scanResult(const QDBusMessage&)));
}
systemBus.disconnect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
ICD_DBUS_API_INTERFACE, ICD_DBUS_API_CONNECT_SIG,
this, SLOT(connectionChange(const QDBusMessage&)));
+
+ systemBus.disconnect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
+ ICD_DBUS_API_INTERFACE, ICD_DBUS_API_SCAN_SIG,
+ this, SLOT(scanResult(const QDBusMessage&)));
+}
+
+void ConnectionManager::setBlocking(bool value)
+{
+ blocking_ = value;
}
bool ConnectionManager::connect()
{
- ready_ = false;
- ignoreStateChanges_ = true;
+ connectionReady_ = false;
unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
icd2interface_->call(ICD_DBUS_API_CONNECT_REQ, QVariant(flags));
- waitSignal();
- return connected_;
+
+ if(blocking_)
+ {
+ waitSignal(&connectionReady_);
+ return connected_;
+ }
+
+ return true;
}
-bool ConnectionManager::disconnect()
+bool ConnectionManager::connect(ConnectionManager::Connection const& connection)
{
- if(!connected_)
+ connectionReady_ = false;
+ QDBusArgument arg;
+ arg.beginStructure();
+ arg << connection.serviceType
+ << connection.serviceAttributes
+ << connection.serviceID
+ << connection.networkType
+ << connection.networkAttributes
+ << connection.networkID;
+ arg.endStructure();
+
+ unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
+ QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_CONNECT_REQ,
+ flags, arg.asVariant());
+
+ qDebug() << rep.errorName() << rep.errorMessage();
+
+ if(blocking_)
+ {
+ waitSignal(&connectionReady_);
+ return connected_;
+ }
+
+ return true;
+}
+
+bool ConnectionManager::disconnect(bool force)
+{
+ // Forced disconnect is not allowed if connection
+ // was not initialized by this class
+ if(!connected_ && force)
{
return false;
}
- ready_ = false;
- ignoreStateChanges_ = false;
- unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
+ connectionReady_ = false;
+ unsigned int flags;
+
+ if(force)
+ {
+ flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_UI_EVENT);
+ }
+ else
+ {
+ 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::isConnected()
{
- ready_ = false;
- ignoreStateChanges_ = false;
+ stateReady_ = false;
QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_STATE_REQ);
unsigned int numOfReplies = rep.arguments().value(0).value<unsigned int>();
if(numOfReplies == 0)
{
+ emit isConnectedReply(false);
return false;
}
- waitSignal();
- return connected_;
+ if(blocking_)
+ {
+ waitSignal(&stateReady_);
+ return connected_;
+ }
+
+ return true;
}
-void ConnectionManager::stateChange(const QDBusMessage& rep)
+bool ConnectionManager::scanConnections(QList<ConnectionManager::Connection>& connections)
{
- if(ignoreStateChanges_)
+ unsigned int flags = static_cast<unsigned int>(ICD_SCAN_REQUEST_ACTIVE);
+ scanReady_ = false;
+ scannedConnections_ = 0;
+ connections_ = &connections;
+ QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_SCAN_REQ, QVariant(flags));
+
+ numberOfConnections_ = rep.arguments().value(0).toList().size();
+
+ if(numberOfConnections_ == 0)
{
- return;
+ connections_ = 0;
+ return false;
}
+ if(blocking_)
+ {
+ bool ret = waitSignal(&scanReady_);
+ connections_ = 0;
+ return ret;
+ }
+
+ return true;
+}
+
+void ConnectionManager::stateChange(const QDBusMessage& rep)
+{
unsigned int status = rep.arguments().value(7).value<unsigned int>();
switch(status)
break;
case ICD_STATE_CONNECTED:
connected_ = true;
- ready_ = true;
+ stateReady_ = true;
break;
case ICD_STATE_DISCONNECTING:
break;
case ICD_STATE_DISCONNECTED:
connected_ = false;
- ready_ = true;
+ stateReady_ = true;
break;
case ICD_STATE_LIMITED_CONN_ENABLED:
connected_ = true;
- ready_ = true;
+ stateReady_ = true;
break;
case ICD_STATE_LIMITED_CONN_DISABLED:
connected_ = false;
- ready_ = true;
+ stateReady_ = true;
break;
case ICD_STATE_SEARCH_START:
break;
break;
}
+ if(stateReady_)
+ {
+ emit isConnectedReply(connected_);
+ }
+
}
void ConnectionManager::connectionChange(const QDBusMessage& rep)
{
case ICD_CONNECTION_SUCCESSFUL:
connected_ = true;
- ready_ = true;
+ connectionReady_ = true;
break;
case ICD_CONNECTION_NOT_CONNECTED:
connected_ = false;
- ready_ = true;
+ connectionReady_ = true;
break;
case ICD_CONNECTION_DISCONNECTED:
connected_ = false;
- ready_ = true;
+ connectionReady_ = true;
break;
default:
qDebug() << "Unknown connection status";
break;
}
+
+ if(connectionReady_)
+ {
+ emit connectReply(connected_);
+ }
+}
+
+void ConnectionManager::scanResult(const QDBusMessage& rep)
+{
+ if(!connections_)
+ {
+ return;
+ }
+
+ QList<QVariant> args = rep.arguments();
+
+ unsigned int status = args.value(0).value<unsigned int>();
+
+ if(status == ICD_SCAN_COMPLETE)
+ {
+ scannedConnections_++;
+ }
+
+ if(scannedConnections_ >= numberOfConnections_)
+ {
+ scanReady_ = true;
+ emit scanReady();
+ return;
+ }
+
+ if(status != ICD_SCAN_NEW)
+ {
+ return;
+ }
+
+ Connection connection;
+ connection.serviceType = args.value(2).toString();
+ connection.serviceAttributes = args.value(4).value<unsigned int>();
+ connection.serviceID = args.value(5).toString();
+ connection.networkName = args.value(8).toString();
+ connection.networkType = args.value(7).toString();
+ connection.networkAttributes = args.value(9).value<unsigned int>();
+ connection.networkID = args.value(10).toByteArray();
+
+ emit newConnection(connection);
+
+ connections_->push_back(connection);
}
-bool ConnectionManager::waitSignal()
+bool ConnectionManager::waitSignal(bool* ready)
{
timeout_ = false;
timer_ = startTimer(TIMEOUT);
- while(!ready_ && !timeout_)
+ while(!*ready && !timeout_)
{
QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
}
killTimer(timer_);
- return ready_ || !timeout_;
+ return *ready || !timeout_;
}
void ConnectionManager::timerEvent(QTimerEvent* event)