1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the plugins of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39
40 #include <QObject>
41 #include <QList>
42 #include <QtDBus/QtDBus>
43 #include <QtDBus/QDBusConnection>
44 #include <QtDBus/QDBusError>
45 #include <QtDBus/QDBusInterface>
46 #include <QtDBus/QDBusMessage>
47 #include <QtDBus/QDBusReply>
48 #include <QtDBus/QDBusPendingCallWatcher>
49 #include <QtDBus/QDBusObjectPath>
50 #include <QtDBus/QDBusPendingCall>
51
52 #include "qconnmanservice_linux_p.h"
53
54 #ifndef QT_NO_DBUS
55
56 QT_BEGIN_NAMESPACE
57
operator <<(QDBusArgument & argument,const ConnmanMap & map)58 QDBusArgument &operator<<(QDBusArgument &argument, const ConnmanMap &map)
59 {
60 argument.beginStructure();
61 argument << map.objectPath << map.propertyMap;
62 argument.endStructure();
63 return argument;
64 }
65
operator >>(const QDBusArgument & argument,ConnmanMap & map)66 const QDBusArgument &operator>>(const QDBusArgument &argument, ConnmanMap &map)
67 {
68 argument.beginStructure();
69 argument >> map.objectPath >> map.propertyMap;
70 argument.endStructure();
71 return argument;
72 }
73
QConnmanManagerInterface(QObject * parent)74 QConnmanManagerInterface::QConnmanManagerInterface( QObject *parent)
75 : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
76 QLatin1String(CONNMAN_MANAGER_PATH),
77 CONNMAN_MANAGER_INTERFACE,
78 QDBusConnection::systemBus(), parent)
79 {
80 qDBusRegisterMetaType<ConnmanMap>();
81 qDBusRegisterMetaType<ConnmanMapList>();
82
83 QDBusPendingReply<QVariantMap> props_reply = asyncCall(QLatin1String("GetProperties"));
84 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(props_reply, this);
85
86 QObject::connect(watcher,SIGNAL(finished(QDBusPendingCallWatcher*)),
87 this, SLOT(propertiesReply(QDBusPendingCallWatcher*)));
88
89 QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
90 QLatin1String(CONNMAN_MANAGER_PATH),
91 QLatin1String(CONNMAN_SERVICE_INTERFACE),
92 QLatin1String("PropertyChanged"),
93 this,SLOT(changedProperty(QString,QDBusVariant)));
94
95
96 QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
97 QLatin1String(CONNMAN_MANAGER_PATH),
98 QLatin1String(CONNMAN_SERVICE_INTERFACE),
99 QLatin1String("TechnologyAdded"),
100 this,SLOT(technologyAdded(QDBusObjectPath,QVariantMap)));
101
102 QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
103 QLatin1String(CONNMAN_MANAGER_PATH),
104 QLatin1String(CONNMAN_SERVICE_INTERFACE),
105 QLatin1String("TechnologyRemoved"),
106 this,SLOT(technologyRemoved(QDBusObjectPath)));
107
108 QDBusPendingReply<ConnmanMapList> serv_reply = asyncCall(QLatin1String("GetServices"));
109 QDBusPendingCallWatcher *watcher2 = new QDBusPendingCallWatcher(serv_reply, this);
110
111 QObject::connect(watcher2,SIGNAL(finished(QDBusPendingCallWatcher*)),
112 this, SLOT(servicesReply(QDBusPendingCallWatcher*)));
113
114 }
115
~QConnmanManagerInterface()116 QConnmanManagerInterface::~QConnmanManagerInterface()
117 {
118 }
119
changedProperty(const QString & name,const QDBusVariant & value)120 void QConnmanManagerInterface::changedProperty(const QString &name, const QDBusVariant &value)
121 {
122 propertiesCacheMap[name] = value.variant();
123 }
124
propertiesReply(QDBusPendingCallWatcher * call)125 void QConnmanManagerInterface::propertiesReply(QDBusPendingCallWatcher *call)
126 {
127 QDBusPendingReply<QVariantMap> props_reply = *call;
128
129 if (props_reply.isError()) {
130 qDebug() << props_reply.error().message();
131 } else {
132 propertiesCacheMap = props_reply.value();
133 }
134 call->deleteLater();
135 }
136
servicesReply(QDBusPendingCallWatcher * call)137 void QConnmanManagerInterface::servicesReply(QDBusPendingCallWatcher *call)
138 {
139 QDBusPendingReply<ConnmanMapList> serv_reply = *call;
140
141 if (serv_reply.isError()) {
142 qDebug() << serv_reply.error().message();
143 } else {
144 servicesList.clear(); //connman list changes order
145 const ConnmanMapList connmanobjs = serv_reply.value();
146 for (const ConnmanMap &connmanobj : connmanobjs)
147 servicesList << connmanobj.objectPath.path();
148 Q_EMIT servicesReady(servicesList);
149 }
150 call->deleteLater();
151 }
152
connectNotify(const QMetaMethod & signal)153 void QConnmanManagerInterface::connectNotify(const QMetaMethod &signal)
154 {
155 static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::propertyChanged);
156 if (signal == propertyChangedSignal) {
157 if (!connection().connect(QLatin1String(CONNMAN_SERVICE),
158 QLatin1String(CONNMAN_MANAGER_PATH),
159 QLatin1String(CONNMAN_MANAGER_INTERFACE),
160 QLatin1String("PropertyChanged"),
161 this,SIGNAL(propertyChanged(QString,QDBusVariant)))) {
162 qWarning("PropertyChanged not connected");
163 }
164 }
165
166 static const QMetaMethod servicesChangedSignal = QMetaMethod::fromSignal(&QConnmanManagerInterface::servicesChanged);
167 if (signal == servicesChangedSignal) {
168 if (!connection().connect(QLatin1String(CONNMAN_SERVICE),
169 QLatin1String(CONNMAN_MANAGER_PATH),
170 QLatin1String(CONNMAN_MANAGER_INTERFACE),
171 QLatin1String("ServicesChanged"),
172 this,SLOT(onServicesChanged(ConnmanMapList,QList<QDBusObjectPath>)))) {
173 qWarning("servicesChanged not connected");
174 }
175 }
176 }
177
onServicesChanged(const ConnmanMapList & changed,const QList<QDBusObjectPath> & removed)178 void QConnmanManagerInterface::onServicesChanged(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed)
179 {
180 servicesList.clear(); //connman list changes order
181 for (const ConnmanMap &connmanobj : changed) {
182 const QString svcPath(connmanobj.objectPath.path());
183 servicesList << svcPath;
184 }
185
186 Q_EMIT servicesChanged(changed, removed);
187 }
188
getProperty(const QString & property)189 QVariant QConnmanManagerInterface::getProperty(const QString &property)
190 {
191 QVariant var;
192 var = propertiesCacheMap.value(property);
193 return var;
194 }
195
getProperties()196 QVariantMap QConnmanManagerInterface::getProperties()
197 {
198 if (propertiesCacheMap.isEmpty()) {
199 QDBusPendingReply<QVariantMap> reply = call(QLatin1String("GetProperties"));
200 reply.waitForFinished();
201 if (!reply.isError()) {
202 propertiesCacheMap = reply.value();
203 }
204 }
205 return propertiesCacheMap;
206 }
207
getState()208 QString QConnmanManagerInterface::getState()
209 {
210 return getProperty(QStringLiteral("State")).toString();
211 }
212
getOfflineMode()213 bool QConnmanManagerInterface::getOfflineMode()
214 {
215 QVariant var = getProperty(QStringLiteral("OfflineMode"));
216 return qdbus_cast<bool>(var);
217 }
218
getTechnologies()219 QStringList QConnmanManagerInterface::getTechnologies()
220 {
221 if (technologiesMap.isEmpty()) {
222 QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetTechnologies"));
223 reply.waitForFinished();
224 if (!reply.isError()) {
225 const ConnmanMapList maps = reply.value();
226 for (const ConnmanMap &map : maps) {
227 if (!technologiesMap.contains(map.objectPath.path())) {
228 technologyAdded(map.objectPath, map.propertyMap);
229 }
230 }
231 }
232 }
233 return technologiesMap.keys();
234 }
235
getServices()236 QStringList QConnmanManagerInterface::getServices()
237 {
238 if (servicesList.isEmpty()) {
239 QDBusPendingReply<ConnmanMapList> reply = call(QLatin1String("GetServices"));
240 reply.waitForFinished();
241 if (!reply.isError()) {
242 const ConnmanMapList maps = reply.value();
243 for (const ConnmanMap &map : maps)
244 servicesList << map.objectPath.path();
245 }
246 }
247 return servicesList;
248 }
249
requestScan(const QString & type)250 bool QConnmanManagerInterface::requestScan(const QString &type)
251 {
252 bool scanned = false;
253 if (technologiesMap.isEmpty())
254 getTechnologies();
255 Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) {
256 if (tech->type() == type) {
257 tech->scan();
258 scanned = true;
259 }
260 }
261 return scanned;
262 }
263
technologyAdded(const QDBusObjectPath & path,const QVariantMap &)264 void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, const QVariantMap &)
265 {
266 if (!technologiesList.contains(path.path())) {
267 technologiesList << path.path();
268 QConnmanTechnologyInterface *tech;
269 tech = new QConnmanTechnologyInterface(path.path(),this);
270 technologiesMap.insert(path.path(),tech);
271 connect(tech,SIGNAL(scanFinished(bool)),this,SIGNAL(scanFinished(bool)));
272 }
273 }
274
technologyRemoved(const QDBusObjectPath & path)275 void QConnmanManagerInterface::technologyRemoved(const QDBusObjectPath &path)
276 {
277 if (technologiesList.contains(path.path())) {
278 technologiesList.removeOne(path.path());
279 QConnmanTechnologyInterface * tech = technologiesMap.take(path.path());
280 delete tech;
281 }
282 }
283
QConnmanServiceInterface(const QString & dbusPathName,QObject * parent)284 QConnmanServiceInterface::QConnmanServiceInterface(const QString &dbusPathName,QObject *parent)
285 : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
286 dbusPathName,
287 CONNMAN_SERVICE_INTERFACE,
288 QDBusConnection::systemBus(), parent)
289 {
290 QDBusPendingReply<QVariantMap> props_reply = asyncCall(QLatin1String("GetProperties"));
291
292 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(props_reply, this);
293
294 QObject::connect(watcher,SIGNAL(finished(QDBusPendingCallWatcher*)),
295 this, SLOT(propertiesReply(QDBusPendingCallWatcher*)));
296
297 QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
298 path(),
299 QLatin1String(CONNMAN_SERVICE_INTERFACE),
300 QLatin1String("PropertyChanged"),
301 this,SLOT(changedProperty(QString,QDBusVariant)));
302 }
303
~QConnmanServiceInterface()304 QConnmanServiceInterface::~QConnmanServiceInterface()
305 {
306 }
307
getProperties()308 QVariantMap QConnmanServiceInterface::getProperties()
309 {
310 if (propertiesCacheMap.isEmpty()) {
311 QDBusPendingReply<QVariantMap> reply = call(QLatin1String("GetProperties"));
312 reply.waitForFinished();
313 if (!reply.isError()) {
314 propertiesCacheMap = reply.value();
315 Q_EMIT propertiesReady();
316 }
317 }
318 return propertiesCacheMap;
319 }
320
propertiesReply(QDBusPendingCallWatcher * call)321 void QConnmanServiceInterface::propertiesReply(QDBusPendingCallWatcher *call)
322 {
323 QDBusPendingReply<QVariantMap> props_reply = *call;
324 if (props_reply.isError()) {
325 qDebug() << props_reply.error().message();
326 return;
327 }
328 propertiesCacheMap = props_reply.value();
329 Q_EMIT propertiesReady();
330 }
331
connectNotify(const QMetaMethod & signal)332 void QConnmanServiceInterface::connectNotify(const QMetaMethod &signal)
333 {
334 static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanServiceInterface::propertyChanged);
335 if (signal == propertyChangedSignal) {
336 QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
337 path(),
338 QLatin1String(CONNMAN_SERVICE_INTERFACE),
339 QLatin1String("PropertyChanged"),
340 this,SIGNAL(propertyChanged(QString,QDBusVariant)));
341 }
342 }
343
changedProperty(const QString & name,const QDBusVariant & value)344 void QConnmanServiceInterface::changedProperty(const QString &name, const QDBusVariant &value)
345 {
346 propertiesCacheMap[name] = value.variant();
347 if (name == QLatin1String("State"))
348 Q_EMIT stateChanged(value.variant().toString());
349 }
350
getProperty(const QString & property)351 QVariant QConnmanServiceInterface::getProperty(const QString &property)
352 {
353 QVariant var;
354 QVariantMap map = getProperties();
355 var = map.value(property);
356 return var;
357 }
358
connect()359 void QConnmanServiceInterface::connect()
360 {
361 asyncCall(QLatin1String("Connect"));
362 }
363
disconnect()364 void QConnmanServiceInterface::disconnect()
365 {
366 asyncCall(QLatin1String("Disconnect"));
367 }
368
remove()369 void QConnmanServiceInterface::remove()
370 {
371 asyncCall(QLatin1String("Remove"));
372 }
373
374 // properties
state()375 QString QConnmanServiceInterface::state()
376 {
377 QVariant var = getProperty(QStringLiteral("State"));
378 return qdbus_cast<QString>(var);
379 }
380
lastError()381 QString QConnmanServiceInterface::lastError()
382 {
383 QVariant var = getProperty(QStringLiteral("Error"));
384 return qdbus_cast<QString>(var);
385 }
386
name()387 QString QConnmanServiceInterface::name()
388 {
389 QVariant var = getProperty(QStringLiteral("Name"));
390 return qdbus_cast<QString>(var);
391 }
392
type()393 QString QConnmanServiceInterface::type()
394 {
395 QVariant var = getProperty(QStringLiteral("Type"));
396 return qdbus_cast<QString>(var);
397 }
398
security()399 QString QConnmanServiceInterface::security()
400 {
401 QVariant var = getProperty(QStringLiteral("Security"));
402 return qdbus_cast<QString>(var);
403 }
404
favorite()405 bool QConnmanServiceInterface::favorite()
406 {
407 QVariant var = getProperty(QStringLiteral("Favorite"));
408 return qdbus_cast<bool>(var);
409 }
410
autoConnect()411 bool QConnmanServiceInterface::autoConnect()
412 {
413 QVariant var = getProperty(QStringLiteral("AutoConnect"));
414 return qdbus_cast<bool>(var);
415 }
416
roaming()417 bool QConnmanServiceInterface::roaming()
418 {
419 QVariant var = getProperty(QStringLiteral("Roaming"));
420 return qdbus_cast<bool>(var);
421 }
422
ethernet()423 QVariantMap QConnmanServiceInterface::ethernet()
424 {
425 QVariant var = getProperty(QStringLiteral("Ethernet"));
426 return qdbus_cast<QVariantMap >(var);
427 }
428
serviceInterface()429 QString QConnmanServiceInterface::serviceInterface()
430 {
431 QVariantMap map = ethernet();
432 return map.value(QStringLiteral("Interface")).toString();
433 }
434
isOfflineMode()435 bool QConnmanServiceInterface::isOfflineMode()
436 {
437 QVariant var = getProperty(QStringLiteral("OfflineMode"));
438 return qdbus_cast<bool>(var);
439 }
440
services()441 QStringList QConnmanServiceInterface::services()
442 {
443 QVariant var = getProperty(QStringLiteral("Services"));
444 return qdbus_cast<QStringList>(var);
445 }
446
447 //////////////////////////
QConnmanTechnologyInterface(const QString & dbusPathName,QObject * parent)448 QConnmanTechnologyInterface::QConnmanTechnologyInterface(const QString &dbusPathName,QObject *parent)
449 : QDBusAbstractInterface(QLatin1String(CONNMAN_SERVICE),
450 dbusPathName,
451 CONNMAN_TECHNOLOGY_INTERFACE,
452 QDBusConnection::systemBus(), parent)
453 {
454 }
455
~QConnmanTechnologyInterface()456 QConnmanTechnologyInterface::~QConnmanTechnologyInterface()
457 {
458 }
459
connectNotify(const QMetaMethod & signal)460 void QConnmanTechnologyInterface::connectNotify(const QMetaMethod &signal)
461 {
462 static const QMetaMethod propertyChangedSignal = QMetaMethod::fromSignal(&QConnmanTechnologyInterface::propertyChanged);
463 if (signal == propertyChangedSignal) {
464 QDBusConnection::systemBus().connect(QLatin1String(CONNMAN_SERVICE),
465 path(),
466 QLatin1String(CONNMAN_TECHNOLOGY_INTERFACE),
467 QLatin1String("PropertyChanged"),
468 this,SIGNAL(propertyChanged(QString,QDBusVariant)));
469 }
470 }
471
properties()472 QVariantMap QConnmanTechnologyInterface::properties()
473 {
474 if (propertiesMap.isEmpty()) {
475 QDBusPendingReply<QVariantMap> reply = call(QLatin1String("GetProperties"));
476 reply.waitForFinished();
477 propertiesMap = reply.value();
478 }
479 return propertiesMap;
480 }
481
getProperty(const QString & property)482 QVariant QConnmanTechnologyInterface::getProperty(const QString &property)
483 {
484 QVariant var;
485 QVariantMap map = properties();
486 var = map.value(property);
487 return var;
488 }
489
type()490 QString QConnmanTechnologyInterface::type()
491 {
492 QVariant var = getProperty(QStringLiteral("Type"));
493 return qdbus_cast<QString>(var);
494 }
495
scan()496 void QConnmanTechnologyInterface::scan()
497 {
498 QDBusPendingReply<> reply = asyncCall(QLatin1String("Scan"));
499 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
500 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
501 this, SLOT(scanReply(QDBusPendingCallWatcher*)));
502 }
503
scanReply(QDBusPendingCallWatcher * call)504 void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call)
505 {
506 QDBusPendingReply<> props_reply = *call;
507 if (props_reply.isError()) {
508 qDebug() << props_reply.error().message();
509 }
510 Q_EMIT scanFinished(props_reply.isError());
511 call->deleteLater();
512 }
513
514 QT_END_NAMESPACE
515
516 #endif // QT_NO_DBUS
517