2 * This file is part of Jenirok.
4 * Jenirok is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Jenirok is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Jenirok. If not, see <http://www.gnu.org/licenses/>.
20 #include <QApplication>
21 #include <QtCore/QTimerEvent>
22 #include <QtCore/QVariant>
23 #include <QtDBus/QDBusArgument>
24 #include <icd/dbus_api.h>
25 #include "connectionmanager.h"
28 ConnectionManager::ConnectionManager(QObject* parent): QObject(parent),
29 blocking_(true), stateReady_(false), connectionReady_(false), scanReady_(false),
30 connected_(false), timeout_(false), numberOfConnections_(0),
31 scannedConnections_(0), timer_(0), connections_(false)
33 QDBusConnection systemBus = QDBusConnection::systemBus();
35 icd2interface_ = new QDBusInterface(ICD_DBUS_API_INTERFACE,
36 ICD_DBUS_API_PATH, ICD_DBUS_API_INTERFACE,
39 systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
40 ICD_DBUS_API_INTERFACE, ICD_DBUS_API_STATE_SIG,
41 this, SLOT(stateChange(const QDBusMessage&)));
43 systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
44 ICD_DBUS_API_INTERFACE, ICD_DBUS_API_CONNECT_SIG,
45 this, SLOT(connectionChange(const QDBusMessage&)));
47 systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
48 ICD_DBUS_API_INTERFACE, ICD_DBUS_API_SCAN_SIG,
49 this, SLOT(scanResult(const QDBusMessage&)));
53 ConnectionManager::~ConnectionManager()
55 QDBusConnection systemBus = QDBusConnection::systemBus();
57 systemBus.disconnect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
58 ICD_DBUS_API_INTERFACE, ICD_DBUS_API_STATE_SIG,
59 this, SLOT(stateChange(const QDBusMessage&)));
61 systemBus.disconnect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
62 ICD_DBUS_API_INTERFACE, ICD_DBUS_API_CONNECT_SIG,
63 this, SLOT(connectionChange(const QDBusMessage&)));
65 systemBus.disconnect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
66 ICD_DBUS_API_INTERFACE, ICD_DBUS_API_SCAN_SIG,
67 this, SLOT(scanResult(const QDBusMessage&)));
70 void ConnectionManager::setBlocking(bool value)
75 bool ConnectionManager::connect()
77 connectionReady_ = false;
78 unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
79 icd2interface_->call(ICD_DBUS_API_CONNECT_REQ, QVariant(flags));
83 waitSignal(&connectionReady_);
90 bool ConnectionManager::connect(ConnectionManager::Connection const& connection)
92 connectionReady_ = false;
95 arg << connection.serviceType
96 << connection.serviceAttributes
97 << connection.serviceID
98 << connection.networkType
99 << connection.networkAttributes
100 << connection.networkID;
103 unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
104 QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_CONNECT_REQ,
105 flags, arg.asVariant());
107 qDebug() << rep.errorName() << rep.errorMessage();
111 waitSignal(&connectionReady_);
118 bool ConnectionManager::disconnect(bool force)
120 // Forced disconnect is not allowed if connection
121 // was not initialized by this class
122 if(!connected_ && force)
127 connectionReady_ = false;
132 flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_UI_EVENT);
136 flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
139 icd2interface_->call(ICD_DBUS_API_DISCONNECT_REQ, QVariant(flags));
144 bool ConnectionManager::isConnected()
147 QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_STATE_REQ);
149 unsigned int numOfReplies = rep.arguments().value(0).value<unsigned int>();
151 if(numOfReplies == 0)
153 emit isConnectedReply(false);
159 waitSignal(&stateReady_);
166 bool ConnectionManager::scanConnections(QList<ConnectionManager::Connection>& connections)
168 unsigned int flags = static_cast<unsigned int>(ICD_SCAN_REQUEST_ACTIVE);
170 scannedConnections_ = 0;
171 connections_ = &connections;
172 QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_SCAN_REQ, QVariant(flags));
174 numberOfConnections_ = rep.arguments().value(0).toList().size();
176 if(numberOfConnections_ == 0)
184 bool ret = waitSignal(&scanReady_);
192 void ConnectionManager::stateChange(const QDBusMessage& rep)
194 unsigned int status = rep.arguments().value(7).value<unsigned int>();
198 case ICD_STATE_CONNECTING:
200 case ICD_STATE_CONNECTED:
204 case ICD_STATE_DISCONNECTING:
206 case ICD_STATE_DISCONNECTED:
210 case ICD_STATE_LIMITED_CONN_ENABLED:
214 case ICD_STATE_LIMITED_CONN_DISABLED:
218 case ICD_STATE_SEARCH_START:
220 case ICD_STATE_SEARCH_STOP:
222 case ICD_STATE_INTERNAL_ADDRESS_ACQUIRED:
225 qDebug() << "Unknown connection status";
231 emit isConnectedReply(connected_);
236 void ConnectionManager::connectionChange(const QDBusMessage& rep)
238 unsigned int status = rep.arguments().value(6).value<unsigned int>();
242 case ICD_CONNECTION_SUCCESSFUL:
244 connectionReady_ = true;
246 case ICD_CONNECTION_NOT_CONNECTED:
248 connectionReady_ = true;
250 case ICD_CONNECTION_DISCONNECTED:
252 connectionReady_ = true;
255 qDebug() << "Unknown connection status";
261 emit connectReply(connected_);
265 void ConnectionManager::scanResult(const QDBusMessage& rep)
272 QList<QVariant> args = rep.arguments();
274 unsigned int status = args.value(0).value<unsigned int>();
276 if(status == ICD_SCAN_COMPLETE)
278 scannedConnections_++;
281 if(scannedConnections_ >= numberOfConnections_)
288 if(status != ICD_SCAN_NEW)
293 Connection connection;
294 connection.serviceType = args.value(2).toString();
295 connection.serviceAttributes = args.value(4).value<unsigned int>();
296 connection.serviceID = args.value(5).toString();
297 connection.networkName = args.value(8).toString();
298 connection.networkType = args.value(7).toString();
299 connection.networkAttributes = args.value(9).value<unsigned int>();
300 connection.networkID = args.value(10).toByteArray();
302 emit newConnection(connection);
304 connections_->push_back(connection);
307 bool ConnectionManager::waitSignal(bool* ready)
310 timer_ = startTimer(TIMEOUT);
312 while(!*ready && !timeout_)
314 QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
319 return *ready || !timeout_;
322 void ConnectionManager::timerEvent(QTimerEvent* event)
329 qDebug() << "Connection request timed out";