1 /* This file is part of the KDE project
2 Copyright (C) 2007 Will Stephenson <wstephenson@kde.org>
3 Copyright (C) 2008 Pino Toscano <pino@kde.org>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
9 This library 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 GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 #include "NetworkManager-networkmanager.h"
23 #include <NetworkManager/NetworkManager.h>
25 #include <QtDBus/QDBusConnection>
26 #include <QtDBus/QDBusConnectionInterface>
27 #include <QtDBus/QDBusInterface>
28 #include <QtDBus/QDBusMetaType>
29 #include <QtDBus/QDBusReply>
33 #include "NetworkManager-wirednetwork.h"
34 #include "NetworkManager-wirelessnetwork.h"
36 class NMNetworkManagerPrivate
39 NMNetworkManagerPrivate();
41 void fillNetworkInterfacesList();
43 QDBusInterface manager
;
44 QHash
<QString
, NMNetworkInterface
*> interfaces
;
47 bool wirelessHardwareEnabled
;
50 NMNetworkManagerPrivate::NMNetworkManagerPrivate()
51 : manager(NM_DBUS_SERVICE
, NM_DBUS_PATH
, NM_DBUS_INTERFACE
, QDBusConnection::systemBus())
52 , cachedState(NM_STATE_UNKNOWN
)
53 , wirelessEnabled(false)
54 , wirelessHardwareEnabled(false)
59 NMNetworkManager::NMNetworkManager(QObject
* parent
, const QVariantList
& /*args */)
60 : NetworkManager(parent
), d(new NMNetworkManagerPrivate
)
62 #define connectNMToThis(signal, slot) \
63 d->manager.connection().connect(NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, \
64 signal, this, SLOT(slot));
65 connectNMToThis(NM_DBUS_SIGNAL_STATE_CHANGE
, stateChanged(uint
));
66 connectNMToThis("DeviceAdded", receivedDeviceAdded(QDBusObjectPath
));
67 connectNMToThis("DeviceRemoved", receivedDeviceRemoved(QDBusObjectPath
));
68 connectNMToThis("DeviceStrengthChanged", deviceStrengthChanged(QDBusObjectPath
,int));
69 connectNMToThis("WirelessNetworkStrengthChanged", networkStrengthChanged(QDBusObjectPath
,QDBusObjectPath
,int));
70 connectNMToThis("WirelessNetworkAppeared", wirelessNetworkAppeared(QDBusObjectPath
,QDBusObjectPath
));
71 connectNMToThis("WirelessNetworkDisappeared", wirelessNetworkDisappeared(QDBusObjectPath
,QDBusObjectPath
));
72 connectNMToThis("DeviceActivationStage", deviceActivationStageChanged(QDBusObjectPath
,uint
));
74 connectNMToThis("DeviceCarrierOn", carrierOn(QDBusObjectPath
));
75 connectNMToThis("DeviceCarrierOff", carrierOff(QDBusObjectPath
));
76 connectNMToThis("DeviceNowActive", nowActive(QDBusObjectPath
));
77 connectNMToThis("DeviceNoLongerActive", noLongerActive(QDBusObjectPath
));
78 connectNMToThis("DeviceActivating", activating(QDBusObjectPath
));
79 //TODO: find a way to connect to the wireless variant of this, incl essid
80 connectNMToThis("DeviceActivationFailed", activationFailed(QDBusObjectPath
));
81 connectNMToThis("WirelessEnabled", wirelessEnabled(bool, bool));
83 connect(QDBusConnection::systemBus().interface(), SIGNAL(serviceOwnerChanged(QString
, QString
, QString
)),
84 this, SLOT(nameOwnerChanged(QString
,QString
,QString
)));
86 qDBusRegisterMetaType
<QList
<QDBusObjectPath
> >();
88 d
->fillNetworkInterfacesList();
90 const QDBusMessage wirelessEnabledReply
= d
->manager
.call("getWirelessEnabled");
91 if (wirelessEnabledReply
.type() == QDBusMessage::ReplyMessage
)
93 const QList
<QVariant
> args
= wirelessEnabledReply
.arguments();
94 if (args
.size() > 0) d
->wirelessEnabled
= args
[0].toBool();
95 if (args
.size() > 1) d
->wirelessHardwareEnabled
= args
[1].toBool();
99 NMNetworkManager::~NMNetworkManager()
104 Solid::Networking::Status
NMNetworkManager::status() const
106 if (NM_STATE_UNKNOWN
== d
->cachedState
)
108 QDBusReply
< uint
> state
= d
->manager
.call("state");
111 kDebug(1441) << " got state: " << state
.value();
112 d
->cachedState
= static_cast<NMState
>(state
.value());
115 switch ( d
->cachedState
) {
116 case NM_STATE_CONNECTING
:
117 return Solid::Networking::Connecting
;
119 case NM_STATE_CONNECTED
:
120 return Solid::Networking::Connected
;
122 case NM_STATE_DISCONNECTED
:
123 return Solid::Networking::Unconnected
;
126 case NM_STATE_UNKNOWN
:
127 case NM_STATE_ASLEEP
:
128 return Solid::Networking::Unknown
;
133 QStringList
NMNetworkManager::networkInterfaces() const
136 return d
->interfaces
.keys();
139 void NMNetworkManagerPrivate::fillNetworkInterfacesList()
141 // wtf does this work when not called on org.freedesktop.NetworkManager.Devices?
142 QDBusReply
< QList
<QDBusObjectPath
> > deviceList
= manager
.call("getDevices");
143 if (deviceList
.isValid())
145 kDebug(1441) << "Got device list";
146 QList
<QDBusObjectPath
> devices
= deviceList
.value();
147 foreach (const QDBusObjectPath
& op
, devices
)
149 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= interfaces
.find(op
.path());
150 if (it
== interfaces
.end())
152 interfaces
.insert(op
.path(), 0);
153 kDebug(1441) << " adding:" << op
.path();
158 kDebug(1441) << "Error getting device list: " << deviceList
.error().name() << ": " << deviceList
.error().message();
161 QObject
* NMNetworkManager::createNetworkInterface(const QString
& uni
)
164 NMNetworkInterface
* netInterface
= 0;
165 QHash
<QString
, NMNetworkInterface
*>::Iterator it
= d
->interfaces
.find(uni
);
166 if (it
== d
->interfaces
.end())
168 kDebug(1441) << "unknown interface:" << uni
;
173 netInterface
= it
.value();
177 QDBusInterface
iface(NM_DBUS_SERVICE
,
179 NM_DBUS_INTERFACE_DEVICES
,
180 QDBusConnection::systemBus());
181 QDBusReply
<int> reply
= iface
.call("getType");
182 if (!reply
.isValid())
184 kDebug(1441) << "Invalid reply, most probably the specified device does not exists.";
187 const int type
= reply
.value();
190 case DEVICE_TYPE_802_3_ETHERNET
:
191 netInterface
= new NMWiredNetwork(uni
);
193 case DEVICE_TYPE_802_11_WIRELESS
:
194 netInterface
= new NMWirelessNetwork(uni
);
196 case DEVICE_TYPE_UNKNOWN
:
203 netInterface
->setManagerInterface(&d
->manager
);
204 it
.value() = netInterface
;
210 bool NMNetworkManager::isNetworkingEnabled() const
213 if (NM_STATE_UNKNOWN
== d
->cachedState
)
215 QDBusReply
< uint
> state
= d
->manager
.call("state");
218 kDebug(1441) << " got state: " << state
.value();
219 d
->cachedState
= static_cast<NMState
>(state
.value());
222 return NM_STATE_CONNECTING
== d
->cachedState
|| NM_STATE_CONNECTED
== d
->cachedState
|| NM_STATE_DISCONNECTED
== d
->cachedState
;
225 bool NMNetworkManager::isWirelessEnabled() const
228 return d
->wirelessEnabled
;
231 bool NMNetworkManager::isWirelessHardwareEnabled() const
234 return d
->wirelessHardwareEnabled
;
237 QStringList
NMNetworkManager::activeConnections() const
240 QStringList activeConnections
;
241 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.constBegin(), itEnd
= d
->interfaces
.constEnd();
242 for ( ; it
!= itEnd
; ++it
)
244 NMNetworkInterface
* interface
= it
.value();
245 if (interface
&& interface
->isActive())
247 activeConnections
<< it
.key();
250 return activeConnections
;
253 void NMNetworkManager::activateConnection(const QString
& interfaceUni
, const QString
& connectionUni
, const QVariantMap
& connectionParameters
)
255 kDebug(1441) << interfaceUni
<< connectionUni
<< connectionParameters
;
256 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(interfaceUni
);
257 if (it
!= d
->interfaces
.end())
259 NMNetworkInterface
* interface
= it
.value();
261 interface
= qobject_cast
<NMNetworkInterface
*>(createNetworkInterface(interfaceUni
));
264 bool activated
= interface
->activateConnection(connectionUni
, connectionParameters
);
270 void NMNetworkManager::deactivateConnection(const QString
& activeConnection
)
272 kDebug(1441) << activeConnection
;
273 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(activeConnection
);
274 if (it
!= d
->interfaces
.end() && it
.value())
276 NMNetworkInterface
* interface
= it
.value();
277 bool deactivated
= interface
->deactivateConnection();
278 Q_UNUSED(deactivated
)
282 void NMNetworkManager::setNetworkingEnabled(bool enabled
)
284 kDebug(1441) << enabled
;
285 d
->manager
.call(enabled
? "wake" : "sleep"); //TODO Find out the semantics of the optional bool argument to 'sleep'
288 void NMNetworkManager::setWirelessEnabled(bool enabled
)
290 kDebug(1441) << enabled
;
291 d
->manager
.call("setWirelessEnabled", enabled
);
294 void NMNetworkManager::stateChanged(uint state
)
296 d
->cachedState
= static_cast<NMState
>(state
);
297 switch ( d
->cachedState
) {
298 case NM_STATE_CONNECTING
:
299 kDebug(1441) << "Connecting";
300 emit
statusChanged( Solid::Networking::Connecting
);
302 case NM_STATE_CONNECTED
:
303 kDebug(1441) << "CONNECTED";
304 emit
statusChanged( Solid::Networking::Connected
);
306 case NM_STATE_ASLEEP
:
307 case NM_STATE_DISCONNECTED
:
308 kDebug(1441) << "Unconnected";
309 emit
statusChanged( Solid::Networking::Unconnected
);
312 case NM_STATE_UNKNOWN
:
313 kDebug(1441) << "Unknown";
314 emit
statusChanged( Solid::Networking::Unknown
);
319 void NMNetworkManager::receivedDeviceAdded(const QDBusObjectPath
& objpath
)
321 kDebug(1441) << objpath
.path();
322 const QString path
= objpath
.path();
323 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(path
);
324 if (it
== d
->interfaces
.end())
326 d
->interfaces
.insert(path
, 0);
327 emit
networkInterfaceAdded(path
);
331 void NMNetworkManager::receivedDeviceRemoved(const QDBusObjectPath
& objpath
)
333 kDebug(1441) << objpath
.path();
334 const QString path
= objpath
.path();
335 QHash
<QString
, NMNetworkInterface
*>::Iterator it
= d
->interfaces
.find(path
);
336 if (it
!= d
->interfaces
.end())
338 NMNetworkInterface
* iface
= it
.value();
339 d
->interfaces
.erase(it
);
340 emit
networkInterfaceRemoved(path
);
345 void NMNetworkManager::deviceStrengthChanged(const QDBusObjectPath
& devPath
, int strength
)
347 kDebug(1441) << devPath
.path() << strength
;
350 void NMNetworkManager::networkStrengthChanged(const QDBusObjectPath
& devPath
, const QDBusObjectPath
& netPath
, int strength
)
352 kDebug(1441) << devPath
.path() << "," << netPath
.path() << "," << strength
;
353 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
354 if (it
!= d
->interfaces
.end() && it
.value())
356 NMNetworkInterface
* interface
= it
.value();
357 NMWirelessNetwork
* wifiNet
= qobject_cast
<NMWirelessNetwork
*>(interface
);
359 wifiNet
->setSignalStrength(netPath
, strength
);
363 void NMNetworkManager::wirelessNetworkAppeared(const QDBusObjectPath
& devPath
, const QDBusObjectPath
& netPath
)
365 kDebug(1441) << devPath
.path() << "," << netPath
.path();
366 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
367 if (it
!= d
->interfaces
.end() && it
.value())
369 NMNetworkInterface
* interface
= it
.value();
370 interface
->addNetwork(netPath
);
374 void NMNetworkManager::wirelessNetworkDisappeared(const QDBusObjectPath
& devPath
, const QDBusObjectPath
& netPath
)
376 kDebug(1441) << devPath
.path() << "," << netPath
.path();
377 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
378 if (it
!= d
->interfaces
.end() && it
.value())
380 NMNetworkInterface
* interface
= it
.value();
381 interface
->removeNetwork(netPath
);
385 void NMNetworkManager::deviceActivationStageChanged(const QDBusObjectPath
& devPath
, uint stage
)
387 kDebug(1441) << devPath
.path() << "("<< stage
<< ")";
388 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
389 if (it
!= d
->interfaces
.end() && it
.value())
391 NMNetworkInterface
* interface
= it
.value();
392 interface
->setActivationStage(stage
);
396 void NMNetworkManager::carrierOn(const QDBusObjectPath
& devPath
)
398 kDebug(1441) << devPath
.path();
399 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
400 if (it
!= d
->interfaces
.end() && it
.value())
402 NMNetworkInterface
* interface
= it
.value();
403 NMWiredNetwork
* wiredNet
= qobject_cast
<NMWiredNetwork
*>(interface
);
405 wiredNet
->setCarrier(true);
409 void NMNetworkManager::carrierOff(const QDBusObjectPath
& devPath
)
411 kDebug(1441) << devPath
.path();
412 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
413 if (it
!= d
->interfaces
.end() && it
.value())
415 NMNetworkInterface
* interface
= it
.value();
416 NMWiredNetwork
* wiredNet
= qobject_cast
<NMWiredNetwork
*>(interface
);
418 wiredNet
->setCarrier(false);
422 void NMNetworkManager::nowActive(const QDBusObjectPath
& devPath
)
424 kDebug(1441) << devPath
.path();
425 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
426 if (it
!= d
->interfaces
.end() && it
.value())
428 NMNetworkInterface
* interface
= it
.value();
429 interface
->setActive(true);
433 void NMNetworkManager::noLongerActive(const QDBusObjectPath
& devPath
)
435 kDebug(1441) << devPath
.path();
436 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
437 if (it
!= d
->interfaces
.end() && it
.value())
439 NMNetworkInterface
* interface
= it
.value();
440 interface
->setActive(false);
444 void NMNetworkManager::activating(const QDBusObjectPath
& devPath
)
446 kDebug(1441) << devPath
.path();
447 // We don't do anything with this signal as it is duplicated by connectionStateChanged
450 void NMNetworkManager::activationFailed(const QDBusObjectPath
& devPath
)
452 kDebug(1441) << devPath
.path();
453 QHash
<QString
, NMNetworkInterface
*>::ConstIterator it
= d
->interfaces
.find(devPath
.path());
454 if (it
!= d
->interfaces
.end() && it
.value())
456 NMNetworkInterface
* interface
= it
.value();
457 interface
->setActivationStage(NM_ACT_STAGE_FAILED
);
461 void NMNetworkManager::wirelessEnabled(bool wirelessEnabled
, bool wirelessHardwareEnabled
)
463 kDebug(1441) << wirelessEnabled
<< wirelessHardwareEnabled
;
464 if (wirelessEnabled
!= d
->wirelessEnabled
)
466 d
->wirelessEnabled
= wirelessEnabled
;
467 emit
wirelessEnabledChanged(d
->wirelessEnabled
);
469 if (wirelessHardwareEnabled
!= d
->wirelessHardwareEnabled
)
471 d
->wirelessHardwareEnabled
= wirelessHardwareEnabled
;
472 emit
wirelessHardwareEnabledChanged(d
->wirelessHardwareEnabled
);
476 void NMNetworkManager::nameOwnerChanged(const QString
& name
, const QString
& oldOwner
, const QString
& newOwner
)
478 if (name
== QLatin1String(NM_DBUS_SERVICE
))
480 kDebug(1441) << "name: " << name
<< ", old owner: " << oldOwner
<< ", new owner: " << newOwner
;
481 if ( oldOwner
.isEmpty() && !newOwner
.isEmpty() ) {
482 // NetworkManager started, but we are already listening to StateChanged so we should get
483 // its status that way
486 if ( !oldOwner
.isEmpty() && newOwner
.isEmpty() ) {
487 // NetworkManager stopped, set status Unknown for safety
488 stateChanged(NM_STATE_UNKNOWN
);
493 #include "NetworkManager-networkmanager.moc"