14c0b0a03b011907bebfa1682a5b7554e6f243e6
[jenirok] / src / common / connectionmanager.cpp
1 /*
2  * This file is part of Jenirok.
3  *
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.
8  *
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.
13  *
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/>.
16  *
17  */
18
19 #include <QDebug>
20 #include <QApplication>
21 #include <QtCore/QTimerEvent>
22 #include <QtCore/QVariant>
23 #include <icd/dbus_api.h>
24 #include "connectionmanager.h"
25
26
27 ConnectionManager::ConnectionManager(QObject* parent): QObject(parent),
28 ready_(false), connected_(false), timeout_(false), ignoreStateChanges_(false),
29 timer_(0)
30 {
31     QDBusConnection systemBus = QDBusConnection::systemBus();
32
33     icd2interface_ = new QDBusInterface(ICD_DBUS_API_INTERFACE,
34                                         ICD_DBUS_API_PATH, ICD_DBUS_API_INTERFACE,
35                                         systemBus, this);
36
37     systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
38                       ICD_DBUS_API_INTERFACE, ICD_DBUS_API_STATE_SIG,
39                       this, SLOT(stateChange(const QDBusMessage&)));
40
41     systemBus.connect(ICD_DBUS_API_INTERFACE, ICD_DBUS_API_PATH,
42                       ICD_DBUS_API_INTERFACE, ICD_DBUS_API_CONNECT_SIG,
43                       this, SLOT(connectionChange(const QDBusMessage&)));
44
45
46 }
47
48 bool ConnectionManager::connect()
49 {
50     ready_ = false;
51     ignoreStateChanges_ = true;
52     unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
53     icd2interface_->call(ICD_DBUS_API_CONNECT_REQ, QVariant(flags));
54     waitSignal();
55     return connected_;
56 }
57
58 bool ConnectionManager::disconnect()
59 {
60     if(!connected_)
61     {
62         return false;
63     }
64
65     ready_ = false;
66     ignoreStateChanges_ = false;
67     unsigned int flags = static_cast<unsigned int>(ICD_CONNECTION_FLAG_USER_EVENT);
68     icd2interface_->call(ICD_DBUS_API_DISCONNECT_REQ, QVariant(flags));
69     connected_ = false;
70     return true;
71 }
72
73 bool ConnectionManager::isConnected()
74 {
75     ready_ = false;
76     ignoreStateChanges_ = false;
77     QDBusMessage rep = icd2interface_->call(ICD_DBUS_API_STATE_REQ);
78
79     unsigned int numOfReplies = rep.arguments().value(0).value<unsigned int>();
80
81     if(numOfReplies == 0)
82     {
83         return false;
84     }
85
86     waitSignal();
87     return connected_;
88 }
89
90 void ConnectionManager::stateChange(const QDBusMessage& rep)
91 {
92     if(ignoreStateChanges_)
93     {
94         return;
95     }
96
97     unsigned int status = rep.arguments().value(7).value<unsigned int>();
98
99     switch(status)
100     {
101     case ICD_STATE_CONNECTING:
102         qDebug() << "Connecting";
103         break;
104     case ICD_STATE_CONNECTED:
105         connected_ = true;
106         ready_ = true;
107         qDebug() << "Connected";
108         break;
109     case ICD_STATE_DISCONNECTING:
110         qDebug() << "Disconnecting";
111         break;
112     case ICD_STATE_DISCONNECTED:
113         connected_ = false;
114         ready_ = true;
115         qDebug() << "Disconnected";
116         break;
117     case ICD_STATE_LIMITED_CONN_ENABLED:
118         connected_ = true;
119         ready_ = true;
120         qDebug() << "Limited connection enabled";
121         break;
122     case ICD_STATE_LIMITED_CONN_DISABLED:
123         connected_ = false;
124         ready_ = true;
125         qDebug() << "Limited connection disabled";
126         break;
127     case ICD_STATE_SEARCH_START:
128         qDebug() << "Search start";
129         break;
130     case ICD_STATE_SEARCH_STOP:
131         qDebug() << "Search stop";
132         break;
133     case ICD_STATE_INTERNAL_ADDRESS_ACQUIRED:
134         qDebug() << "Internal address acquired";
135         break;
136     default:
137         qDebug() << "Unknown connection status";
138         break;
139     }
140
141 }
142
143 void ConnectionManager::connectionChange(const QDBusMessage& rep)
144 {
145     unsigned int status = rep.arguments().value(6).value<unsigned int>();
146
147     switch(status)
148     {
149     case ICD_CONNECTION_SUCCESSFUL:
150         connected_ = true;
151         ready_ = true;
152         qDebug() << "Connection successful";
153         break;
154     case ICD_CONNECTION_NOT_CONNECTED:
155         connected_ = false;
156         ready_ = true;
157         qDebug() << "Connection not connected";
158         break;
159     case ICD_CONNECTION_DISCONNECTED:
160         connected_ = false;
161         ready_ = true;
162         qDebug() << "Connection disconnected";
163         break;
164     default:
165         qDebug() << "Unknown connection status";
166         break;
167     }
168 }
169
170 bool ConnectionManager::waitSignal()
171 {
172     timeout_ = false;
173     timer_ = startTimer(TIMEOUT);
174
175     while(!ready_ && !timeout_)
176     {
177         QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
178     }
179
180     killTimer(timer_);
181
182     return ready_ || !timeout_;
183 }
184
185 void ConnectionManager::timerEvent(QTimerEvent* event)
186 {
187     Q_UNUSED(event);
188     killTimer(timer_);
189     timeout_ = true;
190     timer_ = 0;
191
192     qDebug() << "Connection request timed out";
193 }