X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fcommon%2Fconnectionmanager.cpp;h=dfee7d6d7f67cf9abf5be57d72d8cc9ff578f9c9;hb=b7a9e838eaf1539637b2bf46a1907d7aa604bcd9;hp=07f277e7291fcce8a7d285c2e054849cc30cb698;hpb=ee9cbde6d8233ae35e57771468588e6a198ec246;p=jenirok diff --git a/src/common/connectionmanager.cpp b/src/common/connectionmanager.cpp index 07f277e..dfee7d6 100644 --- a/src/common/connectionmanager.cpp +++ b/src/common/connectionmanager.cpp @@ -16,17 +16,22 @@ * */ -#include -#include +#include #include #include +#include +#include +#include +#include #include #include "connectionmanager.h" +bool ConnectionManager::connected_ = false; ConnectionManager::ConnectionManager(QObject* parent): QObject(parent), -ready_(false), connected_(false), timeout_(false), ignoreStateChanges_(false), -timer_(0) +blocking_(true), stateReady_(false), connectionReady_(false), scanReady_(false), +timeout_(false), numberOfConnections_(0), +scannedConnections_(0), timer_(0), error_(NO_ERROR), connections_(0) { QDBusConnection systemBus = QDBusConnection::systemBus(); @@ -42,6 +47,9 @@ timer_(0) 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&))); } @@ -56,28 +64,181 @@ ConnectionManager::~ConnectionManager() 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(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::connect(ConnectionManager::Connection const& connection) +{ + return connect(connection.id); } -bool ConnectionManager::disconnect() +bool ConnectionManager::connect(QString const& id) { - if(!connected_) + QDBusMessage msg = QDBusMessage::createMethodCall("com.nokia.icd", + "/com/nokia/icd", + "com.nokia.icd", + "connect"); + QList arguments; + + arguments.append(QVariant(id)); + + unsigned int val = 0; + + arguments.append(QVariant(val)); + + msg.setArguments(arguments); + + QDBusMessage rep = QDBusConnection::systemBus().call(msg); + + if(rep.type() == QDBusMessage::ErrorMessage) { + if(rep.errorName() == "com.nokia.icd.error.invalid_iap") + { + error_ = INVALID_IAP; + } + else + { + error_ = UNKNOWN_ERROR; + } + + connected_ = false; + return false; } - ready_ = false; - ignoreStateChanges_ = false; - unsigned int flags = static_cast(ICD_CONNECTION_FLAG_USER_EVENT); + connected_ = true; + + return true; +} + +bool ConnectionManager::getBestConnection(Connection& connection, ConnectionType type) +{ + bool blockingValue = blocking_; + + blocking_ = true; + + QList connections; + + if(!scanConnections(connections)) + { + qDebug() << "Unable to scan connections"; + return false; + } + + blocking_ = blockingValue; + + if(connections.size() == 0) + { + error_ = NO_AVAILABLE_CONNECTIONS; + return false; + } + + int biggestWlan = -1; + int biggestGprs = -1; + int bestWlan = -1; + int bestGprs = -1; + + for(int i = 0; i < connections.size(); i++) + { + switch(connections.at(i).type) + { + case WLAN: + if(type != GPRS && connections.at(i).strength > biggestWlan) + { + biggestWlan = connections.at(i).strength; + bestWlan = i; + } + break; + + case GPRS: + if(type != WLAN && connections.at(i).strength > biggestGprs) + { + biggestGprs = connections.at(i).strength; + bestGprs = i; + } + break; + + default: + qDebug() << "Unknown connection type"; + } + } + + if(bestWlan >= 0) + { + connection = connections.at(bestWlan); + return true; + } + else if(bestGprs >= 0) + { + connection = connections.at(bestGprs); + return true; + } + else + { + error_ = NO_AVAILABLE_CONNECTIONS; + return false; + } + +} + +bool ConnectionManager::disconnect(bool force) +{ + if(force) + { + // Do not allow forced disconnection if connection was not started + // by this class. + if(!connected_) + { + return false; + } + + QDBusMessage msg = QDBusMessage::createSignal("/com/nokia/icd_ui", + "com.nokia.icd_ui", + "disconnect"); + + QList arguments; + bool val = true; + arguments.append(QVariant(val)); + msg.setArguments(arguments); + + bool ret = QDBusConnection::systemBus().send(msg); + + if(ret) + { + connected_ = false; + } + + return ret; + } + + connectionReady_ = false; + unsigned int flags; + + flags = static_cast(ICD_CONNECTION_FLAG_USER_EVENT); + icd2interface_->call(ICD_DBUS_API_DISCONNECT_REQ, QVariant(flags)); connected_ = false; return true; @@ -85,28 +246,78 @@ bool ConnectionManager::disconnect() 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(); 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& connections, + ConnectionManager::ConnectionType type) { - if(ignoreStateChanges_) + unsigned int flags = static_cast(ICD_SCAN_REQUEST_ACTIVE_SAVED); + scanReady_ = false; + scannedConnections_ = 0; + connections_ = &connections; + + QStringList networks; + + switch(type) { - return; + case WLAN: + networks << "WLAN_INFRA" << "WLAN_ADHOC"; + break; + case GPRS: + networks << "GPRS"; + break; + default: + break; + } + + QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_SCAN_REQ, + QVariant(flags), + QVariant(networks)); + + numberOfConnections_ = rep.arguments().value(0).toList().size(); + + if(numberOfConnections_ == 0) + { + connections_ = 0; + qDebug() << "No connections"; + return false; + } + + if(blocking_) + { + bool ret = waitSignal(&scanReady_); + connections_ = 0; + return ret; } + return true; +} + +ConnectionManager::Error ConnectionManager::error() const +{ + return error_; +} + +void ConnectionManager::stateChange(const QDBusMessage& rep) +{ unsigned int status = rep.arguments().value(7).value(); switch(status) @@ -115,21 +326,21 @@ void ConnectionManager::stateChange(const QDBusMessage& rep) 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; @@ -142,6 +353,11 @@ void ConnectionManager::stateChange(const QDBusMessage& rep) break; } + if(stateReady_) + { + emit isConnectedReply(connected_); + } + } void ConnectionManager::connectionChange(const QDBusMessage& rep) @@ -152,35 +368,95 @@ 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 args = rep.arguments(); + + unsigned int status = args.value(0).value(); + + if(status == ICD_SCAN_COMPLETE) + { + scannedConnections_++; + } + + if(scannedConnections_ >= numberOfConnections_) + { + scanReady_ = true; + connections_ = 0; + emit scanReady(); + return; + } + + if(status != ICD_SCAN_NEW) + { + return; + } + + Connection connection; + connection.id = QString(args.value(10).toByteArray()); + connection.name = args.value(8).toString(); + connection.strength = args.value(11).toInt(); + + QString type = args.value(7).toString(); + + if(type == "GPRS") + { + connection.type = GPRS; + } + else if(type == "WLAN_INFRA" || type == "WLAN_ADHOC") + { + connection.type = WLAN; + } + else + { + qDebug() << "Unknown connection type: " << type; + return; + } + + 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)