1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "qnmwifiengine_unix_p.h" |
|
43 #include "qnetworkconfiguration_p.h" |
|
44 #include <qnetworkconfiguration.h> |
|
45 |
|
46 #include <QtCore/qstringlist.h> |
|
47 #include <QScopedPointer> |
|
48 |
|
49 #include <QtNetwork/qnetworkinterface.h> |
|
50 #include <qnetworkmanagerservice_p.h> |
|
51 |
|
52 #include <QNetworkInterface> |
|
53 |
|
54 QTM_BEGIN_NAMESPACE |
|
55 Q_GLOBAL_STATIC(QNmWifiEngine, nmWifiEngine) |
|
56 typedef QList<QList<uint> > QNmSettingsAddressMap; |
|
57 QTM_END_NAMESPACE |
|
58 |
|
59 Q_DECLARE_METATYPE(QTM_PREPEND_NAMESPACE(QNmSettingsAddressMap)) |
|
60 |
|
61 QTM_BEGIN_NAMESPACE |
|
62 |
|
63 QNmWifiEngine::QNmWifiEngine(QObject *parent) |
|
64 : QNetworkSessionEngine(parent) |
|
65 { |
|
66 iface = new QNetworkManagerInterface(this); |
|
67 if(!iface->isValid()) { |
|
68 return; |
|
69 } |
|
70 iface->setConnections(); |
|
71 connect(iface,SIGNAL(deviceAdded(QDBusObjectPath)), |
|
72 this,SLOT(addDevice(QDBusObjectPath))); |
|
73 // connect(iface,SIGNAL(deviceRemoved(QDBusObjectPath)), |
|
74 // this,SLOT(removeDevice(QDBusObjectPath))); |
|
75 connect(iface, SIGNAL(activationFinished(QDBusPendingCallWatcher*)), |
|
76 this, SLOT(slotActivationFinished(QDBusPendingCallWatcher*))); |
|
77 |
|
78 foreach (const QDBusObjectPath &path, iface->getDevices()) |
|
79 addDevice(path); |
|
80 |
|
81 QStringList connectionServices; |
|
82 connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS; |
|
83 connectionServices << NM_DBUS_SERVICE_USER_SETTINGS; |
|
84 QNetworkManagerSettings *settingsiface; |
|
85 foreach (const QString &service, connectionServices) { |
|
86 settingsiface = new QNetworkManagerSettings(service, this); |
|
87 settingsiface->setConnections(); |
|
88 connect(settingsiface,SIGNAL(newConnection(QDBusObjectPath)), |
|
89 this,(SLOT(newConnection(QDBusObjectPath)))); |
|
90 } |
|
91 |
|
92 updated = false; |
|
93 } |
|
94 |
|
95 QNmWifiEngine::~QNmWifiEngine() |
|
96 { |
|
97 } |
|
98 |
|
99 QString QNmWifiEngine::getNameForConfiguration(QNetworkManagerInterfaceDevice *devIface) |
|
100 { |
|
101 QString newname; |
|
102 if (devIface->state() == NM_DEVICE_STATE_ACTIVATED) { |
|
103 QString path = devIface->ip4config().path(); |
|
104 QNetworkManagerIp4Config * ipIface; |
|
105 ipIface = new QNetworkManagerIp4Config(path); |
|
106 newname = ipIface->domains().join(" "); |
|
107 delete ipIface; |
|
108 } |
|
109 //fallback to interface name |
|
110 if(newname.isEmpty()) |
|
111 newname = devIface->networkInterface().name(); |
|
112 return newname; |
|
113 } |
|
114 |
|
115 |
|
116 QList<QNetworkConfigurationPrivate *> QNmWifiEngine::getConfigurations(bool *ok) |
|
117 { |
|
118 if (ok) |
|
119 *ok = false; |
|
120 |
|
121 if(!updated) { |
|
122 foundConfigurations.clear(); |
|
123 if(knownSsids.isEmpty()) |
|
124 updateKnownSsids(); |
|
125 |
|
126 scanForAccessPoints(); |
|
127 updateActiveConnectionsPaths(); |
|
128 knownConnections(); |
|
129 |
|
130 accessPointConnections(); |
|
131 |
|
132 updated = true; |
|
133 } |
|
134 return foundConfigurations; |
|
135 } |
|
136 |
|
137 void QNmWifiEngine::knownConnections() |
|
138 { |
|
139 QStringList connectionServices; |
|
140 connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS; |
|
141 connectionServices << NM_DBUS_SERVICE_USER_SETTINGS; |
|
142 |
|
143 QString connPath; |
|
144 |
|
145 QScopedPointer<QNetworkManagerSettings> settingsiface; |
|
146 foreach (const QString &service, connectionServices) { |
|
147 QString ident; |
|
148 settingsiface.reset(new QNetworkManagerSettings(service)); |
|
149 |
|
150 QNetworkManagerSettingsConnection *sysIface; |
|
151 foreach (const QDBusObjectPath &path, settingsiface->listConnections()) { |
|
152 ident = path.path(); |
|
153 bool addIt = false; |
|
154 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
155 sysIface = new QNetworkManagerSettingsConnection(service, path.path(), this); |
|
156 sysIface->setConnections(); |
|
157 connect(sysIface, SIGNAL(removed(QString)), |
|
158 this,SLOT(settingsConnectionRemoved(QString))); |
|
159 |
|
160 cpPriv->name = sysIface->getId(); |
|
161 cpPriv->isValid = true; |
|
162 cpPriv->id = sysIface->getUuid(); |
|
163 cpPriv->internet = true; |
|
164 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
|
165 cpPriv->state = getStateForId(cpPriv->id); |
|
166 |
|
167 cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; |
|
168 |
|
169 |
|
170 if(sysIface->getType() == DEVICE_TYPE_802_3_ETHERNET) { |
|
171 QString mac = sysIface->getMacAddress(); |
|
172 if(!mac.length() > 2) { |
|
173 QString devPath; |
|
174 devPath = deviceConnectionPath(mac); |
|
175 |
|
176 QNetworkManagerInterfaceDevice devIface(devPath); |
|
177 cpPriv->serviceInterface = devIface.networkInterface(); |
|
178 QScopedPointer<QNetworkManagerInterfaceDeviceWired> devWiredIface; |
|
179 devWiredIface.reset(new QNetworkManagerInterfaceDeviceWired(devIface.connectionInterface()->path())); |
|
180 cpPriv->internet = devWiredIface->carrier(); |
|
181 |
|
182 // use this mac addy |
|
183 } else { |
|
184 cpPriv->serviceInterface = getBestInterface( DEVICE_TYPE_802_3_ETHERNET, cpPriv->id); |
|
185 } |
|
186 |
|
187 cpPriv->internet = true; |
|
188 |
|
189 addIt = true; |
|
190 } else if(sysIface->getType() == DEVICE_TYPE_802_11_WIRELESS) { |
|
191 QString mac = sysIface->getMacAddress();; |
|
192 if(!mac.length() > 2) { |
|
193 QString devPath; |
|
194 devPath = deviceConnectionPath(mac); |
|
195 |
|
196 QNetworkManagerInterfaceDevice devIface(devPath); |
|
197 cpPriv->serviceInterface = devIface.networkInterface(); |
|
198 // use this mac addy |
|
199 } else { |
|
200 cpPriv->serviceInterface = getBestInterface( DEVICE_TYPE_802_11_WIRELESS, cpPriv->id); |
|
201 } |
|
202 addIt = true; |
|
203 // get the wifi interface state first.. do we need this? |
|
204 // QString activeAPPath = devWirelessIface->activeAccessPoint().path(); |
|
205 } |
|
206 if(addIt) { |
|
207 foundConfigurations.append(cpPriv); |
|
208 configurationInterface[cpPriv->id] = cpPriv->serviceInterface.name(); |
|
209 cpPriv->bearer = bearerName(cpPriv->id); |
|
210 } |
|
211 } |
|
212 } |
|
213 } |
|
214 |
|
215 void QNmWifiEngine::accessPointConnections() |
|
216 { |
|
217 QScopedPointer<QNetworkManagerInterfaceDevice> devIface; |
|
218 foreach (const QDBusObjectPath &path, iface->getDevices()) { |
|
219 devIface.reset(new QNetworkManagerInterfaceDevice(path.path())); |
|
220 if(devIface->deviceType() == DEVICE_TYPE_802_11_WIRELESS) { |
|
221 const QList<QString> apList = availableAccessPoints.uniqueKeys(); |
|
222 |
|
223 QList<QString>::const_iterator i; |
|
224 for (i = apList.constBegin(); i != apList.constEnd(); ++i) { |
|
225 QNetworkConfigurationPrivate* cpPriv; |
|
226 cpPriv = addAccessPoint( devIface->connectionInterface()->path(), availableAccessPoints[*i]); |
|
227 if(cpPriv->isValid) { |
|
228 foundConfigurations.append(cpPriv); |
|
229 configurationInterface[cpPriv->id] = cpPriv->serviceInterface.name(); |
|
230 cpPriv->bearer = bearerName(cpPriv->id); |
|
231 } |
|
232 } |
|
233 } |
|
234 } |
|
235 } |
|
236 |
|
237 QString QNmWifiEngine::getInterfaceFromId(const QString &id) |
|
238 { |
|
239 return configurationInterface.value(id); |
|
240 } |
|
241 |
|
242 bool QNmWifiEngine::hasIdentifier(const QString &id) |
|
243 { |
|
244 if (configurationInterface.contains(id)) |
|
245 return true; |
|
246 |
|
247 return false; |
|
248 } |
|
249 |
|
250 QString QNmWifiEngine::bearerName(const QString &id) |
|
251 { |
|
252 QString interface = getInterfaceFromId(id); |
|
253 QScopedPointer<QNetworkManagerInterfaceDevice> devIface; |
|
254 foreach (const QDBusObjectPath &path, iface->getDevices()) { |
|
255 devIface.reset(new QNetworkManagerInterfaceDevice(path.path())); |
|
256 |
|
257 if(interface == devIface->networkInterface().name()) { |
|
258 |
|
259 switch(devIface->deviceType()) { |
|
260 case DEVICE_TYPE_802_3_ETHERNET: |
|
261 return QLatin1String("Ethernet"); |
|
262 break; |
|
263 case DEVICE_TYPE_802_11_WIRELESS: |
|
264 return QLatin1String("WLAN"); |
|
265 break; |
|
266 case DEVICE_TYPE_GSM: |
|
267 return QLatin1String("2G"); |
|
268 break; |
|
269 case DEVICE_TYPE_CDMA: |
|
270 return QLatin1String("CDMA2000"); |
|
271 break; |
|
272 default: |
|
273 break; |
|
274 } |
|
275 } |
|
276 } |
|
277 return QLatin1String("Unknown"); |
|
278 } |
|
279 |
|
280 void QNmWifiEngine::connectToId(const QString &id) |
|
281 { |
|
282 activatingConnectionPath = id; |
|
283 QStringList connectionSettings = getConnectionPathForId(id); |
|
284 if(connectionSettings.isEmpty()) { |
|
285 emit connectionError(id, OperationNotSupported); |
|
286 return; |
|
287 } |
|
288 |
|
289 QDBusObjectPath connectionPath(connectionSettings.at(1)); |
|
290 QString interface = getInterfaceFromId(id); |
|
291 |
|
292 interface = QNetworkInterface::interfaceFromName(interface).hardwareAddress().toLower(); |
|
293 QString devPath; |
|
294 devPath = deviceConnectionPath(interface); |
|
295 QDBusObjectPath devicePath(devPath); |
|
296 |
|
297 iface->activateConnection( |
|
298 connectionSettings.at(0), |
|
299 connectionPath, |
|
300 devicePath, |
|
301 connectionPath); |
|
302 } |
|
303 |
|
304 void QNmWifiEngine::disconnectFromId(const QString &id) |
|
305 { |
|
306 QString activeConnectionPath = getActiveConnectionPath(id); |
|
307 |
|
308 if (!activeConnectionPath.isEmpty()) { |
|
309 QScopedPointer<QNetworkManagerConnectionActive> activeCon; |
|
310 activeCon.reset(new QNetworkManagerConnectionActive(activeConnectionPath)); |
|
311 QScopedPointer<QNetworkManagerSettingsConnection> settingsCon; |
|
312 settingsCon.reset(new QNetworkManagerSettingsConnection(activeCon->serviceName(), activeCon->connection().path())); |
|
313 |
|
314 if(settingsCon->getType() == DEVICE_TYPE_802_3_ETHERNET) { //use depreciated value for now |
|
315 emit connectionError(id, OperationNotSupported); |
|
316 } else { |
|
317 QDBusObjectPath dbpath(activeConnectionPath); |
|
318 iface->deactivateConnection(dbpath); |
|
319 activatingConnectionPath = ""; |
|
320 } |
|
321 } |
|
322 } |
|
323 |
|
324 void QNmWifiEngine::requestUpdate() |
|
325 { |
|
326 updated = false; |
|
327 knownSsids.clear(); |
|
328 availableAccessPoints.clear(); |
|
329 emitConfigurationsChanged(); |
|
330 } |
|
331 |
|
332 QNmWifiEngine *QNmWifiEngine::instance() |
|
333 { |
|
334 QDBusConnection dbusConnection = QDBusConnection::systemBus(); |
|
335 if (dbusConnection.isConnected()) { |
|
336 QDBusConnectionInterface *dbiface = dbusConnection.interface(); |
|
337 QDBusReply<bool> reply = dbiface->isServiceRegistered("org.freedesktop.NetworkManager"); |
|
338 if (reply.isValid() && reply.value()) |
|
339 return nmWifiEngine(); |
|
340 } |
|
341 |
|
342 return 0; |
|
343 } |
|
344 |
|
345 void QNmWifiEngine::updateKnownSsids() |
|
346 { |
|
347 QStringList connectionServices; |
|
348 connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS; |
|
349 connectionServices << NM_DBUS_SERVICE_USER_SETTINGS; |
|
350 |
|
351 QScopedPointer<QNetworkManagerSettings> settingsiface; |
|
352 foreach (const QString &service, connectionServices) { |
|
353 settingsiface.reset(new QNetworkManagerSettings(service)); |
|
354 foreach (const QDBusObjectPath &path, settingsiface->listConnections()) { |
|
355 QNetworkManagerSettingsConnection sysIface(service, path.path()); |
|
356 knownSsids << sysIface.getSsid(); |
|
357 } |
|
358 } |
|
359 } |
|
360 |
|
361 void QNmWifiEngine::updateActiveConnectionsPaths() |
|
362 { //need to know which connection paths are currently active/connected |
|
363 QScopedPointer<QNetworkManagerInterface> dbIface; |
|
364 activeConnectionPaths.clear(); |
|
365 dbIface.reset(new QNetworkManagerInterface); |
|
366 foreach (const QDBusObjectPath &conpath, dbIface->activeConnections()) |
|
367 activeConnectionPaths << conpath.path(); |
|
368 } |
|
369 |
|
370 QNetworkConfigurationPrivate * QNmWifiEngine::addAccessPoint( const QString &iPath, QDBusObjectPath path) |
|
371 { |
|
372 |
|
373 QScopedPointer<QNetworkManagerInterfaceDevice> devIface(new QNetworkManagerInterfaceDevice(iPath)); |
|
374 QScopedPointer<QNetworkManagerInterfaceDeviceWireless> devWirelessIface(new QNetworkManagerInterfaceDeviceWireless(iPath)); |
|
375 |
|
376 QString activeAPPath = devWirelessIface->activeAccessPoint().path(); |
|
377 |
|
378 QScopedPointer<QNetworkManagerInterfaceAccessPoint> accessPointIface(new QNetworkManagerInterfaceAccessPoint(path.path())); |
|
379 |
|
380 QString ident = accessPointIface->connectionInterface()->path(); |
|
381 quint32 nmState = devIface->state(); |
|
382 |
|
383 QString ssid = accessPointIface->ssid(); |
|
384 QString hwAddy = accessPointIface->hwAddress(); |
|
385 QString sInterface = devIface->networkInterface().name(); |
|
386 |
|
387 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
388 bool addIt = true; |
|
389 |
|
390 if(addIt) { |
|
391 |
|
392 cpPriv->name = ssid; |
|
393 cpPriv->isValid = true; |
|
394 cpPriv->id = ident; |
|
395 cpPriv->internet = true; |
|
396 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
|
397 cpPriv->serviceInterface = devIface->networkInterface(); |
|
398 |
|
399 cpPriv->state = getAPState(nmState, knownSsids.contains(cpPriv->name)); |
|
400 |
|
401 if(activeAPPath == accessPointIface->connectionInterface()->path()) { |
|
402 cpPriv->state = ( cpPriv->state | QNetworkConfiguration::Active); |
|
403 } |
|
404 if(accessPointIface->flags() == NM_802_11_AP_FLAGS_PRIVACY) |
|
405 cpPriv->purpose = QNetworkConfiguration::PrivatePurpose; |
|
406 else |
|
407 cpPriv->purpose = QNetworkConfiguration::PublicPurpose; |
|
408 return cpPriv; |
|
409 } else { |
|
410 cpPriv->isValid = false; |
|
411 } |
|
412 return cpPriv; |
|
413 } |
|
414 |
|
415 |
|
416 QNetworkConfiguration::StateFlags QNmWifiEngine::getAPState(qint32 nmState, bool isKnown) |
|
417 { |
|
418 QNetworkConfiguration::StateFlags state = QNetworkConfiguration::Undefined; |
|
419 // this is the state of the wifi device interface |
|
420 if(isKnown) |
|
421 state = ( QNetworkConfiguration::Defined); |
|
422 |
|
423 switch(nmState) { //device interface state, not AP state |
|
424 case NM_DEVICE_STATE_UNKNOWN: |
|
425 case NM_DEVICE_STATE_UNMANAGED: |
|
426 case NM_DEVICE_STATE_UNAVAILABLE: |
|
427 state = (QNetworkConfiguration::Undefined); |
|
428 break; |
|
429 case NM_DEVICE_STATE_DISCONNECTED: |
|
430 { |
|
431 if(isKnown) |
|
432 state = ( state | QNetworkConfiguration::Discovered); |
|
433 } |
|
434 break; |
|
435 case NM_DEVICE_STATE_PREPARE: |
|
436 case NM_DEVICE_STATE_CONFIG: |
|
437 case NM_DEVICE_STATE_NEED_AUTH: |
|
438 case NM_DEVICE_STATE_IP_CONFIG: |
|
439 if(isKnown) |
|
440 state = ( state | QNetworkConfiguration::Discovered); |
|
441 break; |
|
442 case NM_DEVICE_STATE_ACTIVATED: |
|
443 { |
|
444 if(isKnown) |
|
445 state = ( state | QNetworkConfiguration::Discovered); |
|
446 } |
|
447 break; |
|
448 }; |
|
449 return state; |
|
450 } |
|
451 |
|
452 QString QNmWifiEngine::getActiveConnectionPath(const QString &id) |
|
453 { |
|
454 QStringList connectionSettings = getConnectionPathForId(id); |
|
455 QNetworkManagerInterface ifaceD; |
|
456 QScopedPointer<QNetworkManagerConnectionActive> conDetailsD; |
|
457 foreach (const QDBusObjectPath &path, ifaceD.activeConnections()) { |
|
458 conDetailsD.reset(new QNetworkManagerConnectionActive( path.path())); |
|
459 if(conDetailsD->connection().path() == connectionSettings.at(1) |
|
460 && conDetailsD->serviceName() == connectionSettings.at(0)) |
|
461 return path.path(); |
|
462 } |
|
463 return QString(); |
|
464 } |
|
465 |
|
466 QNetworkConfiguration::StateFlags QNmWifiEngine::getStateFlag(quint32 nmstate) |
|
467 { |
|
468 QNetworkConfiguration::StateFlags flag; |
|
469 switch (nmstate) { |
|
470 case NM_DEVICE_STATE_UNKNOWN: |
|
471 case NM_DEVICE_STATE_FAILED: |
|
472 case NM_DEVICE_STATE_UNMANAGED: |
|
473 flag = (QNetworkConfiguration::Undefined); |
|
474 break; |
|
475 case NM_DEVICE_STATE_PREPARE: |
|
476 case NM_DEVICE_STATE_CONFIG: |
|
477 case NM_DEVICE_STATE_NEED_AUTH: |
|
478 case NM_DEVICE_STATE_IP_CONFIG: |
|
479 case NM_DEVICE_STATE_UNAVAILABLE: |
|
480 flag = (QNetworkConfiguration::Defined); |
|
481 break; |
|
482 case NM_DEVICE_STATE_DISCONNECTED: |
|
483 flag = ( flag | QNetworkConfiguration::Discovered ); |
|
484 break; |
|
485 case NM_DEVICE_STATE_ACTIVATED: |
|
486 { |
|
487 flag = ( flag | QNetworkConfiguration::Discovered |
|
488 | QNetworkConfiguration::Active ); |
|
489 } |
|
490 break; |
|
491 default: |
|
492 flag = ( QNetworkConfiguration::Defined); |
|
493 break; |
|
494 }; |
|
495 return flag; |
|
496 } |
|
497 |
|
498 void QNmWifiEngine::updateDeviceInterfaceState(const QString &/*path*/, quint32 nmState) |
|
499 { |
|
500 if(nmState == NM_DEVICE_STATE_ACTIVATED |
|
501 || nmState == NM_DEVICE_STATE_DISCONNECTED |
|
502 || nmState == NM_DEVICE_STATE_UNAVAILABLE |
|
503 || nmState == NM_DEVICE_STATE_FAILED) { |
|
504 |
|
505 QNetworkConfiguration::StateFlags state = (QNetworkConfiguration::Defined); |
|
506 switch (nmState) { |
|
507 case NM_DEVICE_STATE_UNKNOWN: |
|
508 case NM_DEVICE_STATE_FAILED: |
|
509 state = (QNetworkConfiguration::Undefined); |
|
510 emit connectionError(activatingConnectionPath, ConnectError); |
|
511 requestUpdate(); |
|
512 break; |
|
513 case NM_DEVICE_STATE_UNAVAILABLE: |
|
514 state = (QNetworkConfiguration::Defined); |
|
515 requestUpdate(); |
|
516 break; |
|
517 case NM_DEVICE_STATE_DISCONNECTED: |
|
518 state = ( state | QNetworkConfiguration::Discovered ); |
|
519 requestUpdate(); |
|
520 break; |
|
521 case NM_DEVICE_STATE_ACTIVATED: |
|
522 { |
|
523 state = ( state | QNetworkConfiguration::Discovered |
|
524 | QNetworkConfiguration::Active ); |
|
525 requestUpdate(); |
|
526 } |
|
527 break; |
|
528 default: |
|
529 state = ( QNetworkConfiguration::Defined); |
|
530 break; |
|
531 }; |
|
532 } |
|
533 } |
|
534 |
|
535 void QNmWifiEngine::addDevice(QDBusObjectPath path) |
|
536 { |
|
537 QNetworkManagerInterfaceDevice *devIface = new QNetworkManagerInterfaceDevice(path.path(), this); |
|
538 devIface->setConnections(); |
|
539 connect(devIface,SIGNAL(stateChanged(const QString &, quint32)), |
|
540 this, SLOT(updateDeviceInterfaceState(const QString&, quint32))); |
|
541 |
|
542 if(!devicePaths.contains(path.path())) |
|
543 devicePaths << path.path(); |
|
544 |
|
545 switch(devIface->deviceType()) { |
|
546 case DEVICE_TYPE_802_3_ETHERNET: |
|
547 { |
|
548 QNetworkManagerInterfaceDeviceWired * devWiredIface; |
|
549 devWiredIface = new QNetworkManagerInterfaceDeviceWired(devIface->connectionInterface()->path(), this); |
|
550 devWiredIface->setConnections(); |
|
551 connect(devWiredIface, SIGNAL(propertiesChanged(const QString &,QMap<QString,QVariant>)), |
|
552 this,SLOT(cmpPropertiesChanged( const QString &, QMap<QString,QVariant>))); |
|
553 requestUpdate(); |
|
554 } |
|
555 break; |
|
556 case DEVICE_TYPE_802_11_WIRELESS: |
|
557 { |
|
558 QNetworkManagerInterfaceDeviceWireless *devWirelessIface; |
|
559 devWirelessIface = new QNetworkManagerInterfaceDeviceWireless(devIface->connectionInterface()->path(), this); |
|
560 devWirelessIface->setConnections(); |
|
561 |
|
562 connect(devWirelessIface, SIGNAL(propertiesChanged(const QString &,QMap<QString,QVariant>)), |
|
563 this,SLOT(cmpPropertiesChanged( const QString &, QMap<QString,QVariant>))); |
|
564 |
|
565 connect(devWirelessIface, SIGNAL(accessPointAdded(const QString &,QDBusObjectPath)), |
|
566 this,SLOT(accessPointAdded(const QString &,QDBusObjectPath))); |
|
567 |
|
568 connect(devWirelessIface, SIGNAL(accessPointRemoved(const QString &,QDBusObjectPath)), |
|
569 this,SLOT(accessPointRemoved(const QString &,QDBusObjectPath))); |
|
570 requestUpdate(); |
|
571 |
|
572 } |
|
573 break; |
|
574 default: |
|
575 break; |
|
576 }; |
|
577 } |
|
578 |
|
579 void QNmWifiEngine::cmpPropertiesChanged(const QString &path, QMap<QString,QVariant> map) |
|
580 { |
|
581 QMapIterator<QString, QVariant> i(map); |
|
582 while (i.hasNext()) { |
|
583 i.next(); |
|
584 if( i.key() == "State") { //only applies to device interfaces |
|
585 updateDeviceInterfaceState(path, i.value().toUInt()); |
|
586 } |
|
587 if( i.key() == "ActiveAccessPoint") { |
|
588 } |
|
589 if( i.key() == "Carrier") { //someone got plugged in |
|
590 } |
|
591 } |
|
592 } |
|
593 |
|
594 void QNmWifiEngine::accessPointRemoved( const QString &aPath, QDBusObjectPath /*oPath*/) |
|
595 { |
|
596 if(aPath.contains("devices")) { |
|
597 requestUpdate(); |
|
598 } |
|
599 } |
|
600 |
|
601 void QNmWifiEngine::accessPointAdded( const QString &/*aPath*/, QDBusObjectPath /*oPath*/) |
|
602 { |
|
603 requestUpdate(); |
|
604 } |
|
605 |
|
606 QNetworkConfiguration::StateFlags QNmWifiEngine::getStateForId(const QString &id) |
|
607 { |
|
608 bool isAvailable = false; |
|
609 QStringList conPath = getConnectionPathForId(id); |
|
610 QString aconpath = getActiveConnectionPath(id); |
|
611 |
|
612 if(!aconpath.isEmpty()) { |
|
613 //active connection |
|
614 QNetworkManagerConnectionActive aConn(aconpath); |
|
615 |
|
616 QScopedPointer<QNetworkManagerInterfaceDevice> ifaceDevice; |
|
617 QScopedPointer<QNetworkManagerInterfaceDeviceWired> devWiredIface; |
|
618 foreach (const QDBusObjectPath &dev, aConn.devices()) { |
|
619 ifaceDevice.reset(new QNetworkManagerInterfaceDevice(dev.path())); |
|
620 |
|
621 if(ifaceDevice->deviceType() == DEVICE_TYPE_802_3_ETHERNET) { |
|
622 |
|
623 if(isAddressOfConnection(id, ifaceDevice->ip4Address())) { |
|
624 // this is it! |
|
625 return getStateFlag(ifaceDevice->state()); |
|
626 } else { |
|
627 continue; |
|
628 } |
|
629 |
|
630 if(ifaceDevice->state() == NM_DEVICE_STATE_UNAVAILABLE || |
|
631 ifaceDevice->state() == NM_DEVICE_STATE_DISCONNECTED) { |
|
632 isAvailable = true; |
|
633 |
|
634 devWiredIface.reset(new QNetworkManagerInterfaceDeviceWired(ifaceDevice->connectionInterface()->path())); |
|
635 if(!devWiredIface->carrier()) |
|
636 return QNetworkConfiguration::Defined; |
|
637 } |
|
638 } else if(ifaceDevice->deviceType() == DEVICE_TYPE_802_11_WIRELESS) { |
|
639 |
|
640 } |
|
641 |
|
642 return getStateFlag(ifaceDevice->state()); |
|
643 } |
|
644 } else { |
|
645 // not active |
|
646 QScopedPointer<QNetworkManagerSettingsConnection> sysIface; |
|
647 sysIface.reset(new QNetworkManagerSettingsConnection(conPath.at(0),conPath.at(1))); |
|
648 if(sysIface->isValid()) { |
|
649 if(sysIface->getType() == DEVICE_TYPE_802_11_WIRELESS) { |
|
650 QString ssid = sysIface->getSsid(); |
|
651 bool ok = false; |
|
652 |
|
653 if(knownSsids.contains(ssid, Qt::CaseSensitive)) { |
|
654 foreach (const QString &onessid, knownSsids) { |
|
655 if(onessid == ssid && availableAccessPoints.contains(ssid)) { |
|
656 ok = true; |
|
657 break; |
|
658 } |
|
659 } |
|
660 } |
|
661 if(ok) |
|
662 return getStateFlag(NM_DEVICE_STATE_DISCONNECTED); |
|
663 else |
|
664 return getStateFlag(NM_DEVICE_STATE_UNAVAILABLE); |
|
665 } |
|
666 } |
|
667 } |
|
668 |
|
669 return QNetworkConfiguration::Defined; //not active, but we know this connection |
|
670 } |
|
671 |
|
672 bool QNmWifiEngine::isAddressOfConnection(const QString &id, quint32 ipaddress) |
|
673 { |
|
674 QStringList conPath = getConnectionPathForId(id); |
|
675 QString aConPath = getActiveConnectionPath(id); |
|
676 if(aConPath.isEmpty()) { |
|
677 // not active |
|
678 return false; |
|
679 } |
|
680 |
|
681 QScopedPointer<QNetworkManagerConnectionActive> aConn; |
|
682 aConn.reset(new QNetworkManagerConnectionActive(aConPath)); |
|
683 QScopedPointer<QNetworkManagerInterfaceDevice> ifaceDevice; |
|
684 foreach (const QDBusObjectPath &device, aConn->devices()) { |
|
685 ifaceDevice.reset(new QNetworkManagerInterfaceDevice(device.path())); |
|
686 if(ifaceDevice->ip4Address() == ipaddress) { |
|
687 return true; |
|
688 } |
|
689 } |
|
690 return false; |
|
691 } |
|
692 |
|
693 QNetworkInterface QNmWifiEngine::getBestInterface( quint32 type, const QString &id) |
|
694 { |
|
695 // check active connections first. |
|
696 QStringList conIdPath = getConnectionPathForId(id); |
|
697 |
|
698 QNetworkInterface interface; |
|
699 QScopedPointer<QNetworkManagerConnectionActive> aConn; |
|
700 |
|
701 foreach (const QString &conpath, activeConnectionPaths) { |
|
702 aConn.reset(new QNetworkManagerConnectionActive(conpath)); |
|
703 if(aConn->connection().path() == conIdPath.at(1) |
|
704 && aConn->serviceName() == conIdPath.at(0)) { |
|
705 |
|
706 QList <QDBusObjectPath> devs = aConn->devices(); |
|
707 QNetworkManagerInterfaceDevice ifaceDevice(devs[0].path()); //just take the first one |
|
708 return ifaceDevice.networkInterface(); |
|
709 } |
|
710 } |
|
711 |
|
712 //try guessing |
|
713 QScopedPointer<QNetworkManagerInterfaceDevice> devIface; |
|
714 foreach (const QDBusObjectPath &path, iface->getDevices()) { |
|
715 devIface.reset(new QNetworkManagerInterfaceDevice(path.path())); |
|
716 if(devIface->deviceType() == type ) { |
|
717 if(devIface->state() == NM_DEVICE_STATE_DISCONNECTED) { |
|
718 return devIface->networkInterface(); |
|
719 } |
|
720 } |
|
721 } |
|
722 return QNetworkInterface(); |
|
723 } |
|
724 |
|
725 quint64 QNmWifiEngine::receivedDataForId(const QString &id) const |
|
726 { |
|
727 if(configurationInterface.count() > 1) |
|
728 return 0; |
|
729 quint64 result = 0; |
|
730 |
|
731 QString devFile; |
|
732 devFile = configurationInterface.value(id); |
|
733 QFile rx("/sys/class/net/"+devFile+"/statistics/rx_bytes"); |
|
734 if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) { |
|
735 QTextStream in(&rx); |
|
736 in >> result; |
|
737 rx.close(); |
|
738 } |
|
739 return result; |
|
740 } |
|
741 |
|
742 quint64 QNmWifiEngine::sentDataForId(const QString &id) const |
|
743 { |
|
744 if(configurationInterface.count() > 1) |
|
745 return 0; |
|
746 quint64 result = 0; |
|
747 QString devFile; |
|
748 devFile = configurationInterface.value(id); |
|
749 |
|
750 QFile tx("/sys/class/net/"+devFile+"/statistics/tx_bytes"); |
|
751 if(tx.exists() && tx.open(QIODevice::ReadOnly | QIODevice::Text)) { |
|
752 QTextStream in(&tx); |
|
753 in >> result; |
|
754 tx.close(); |
|
755 } |
|
756 return result; |
|
757 } |
|
758 |
|
759 void QNmWifiEngine::newConnection(QDBusObjectPath /*path*/) |
|
760 { |
|
761 requestUpdate(); |
|
762 } |
|
763 |
|
764 void QNmWifiEngine::settingsConnectionRemoved(const QString &/*path*/) |
|
765 { |
|
766 requestUpdate(); |
|
767 } |
|
768 |
|
769 void QNmWifiEngine::slotActivationFinished(QDBusPendingCallWatcher *openCall) |
|
770 { |
|
771 QDBusPendingReply<QDBusObjectPath> reply = *openCall; |
|
772 if (reply.isError()) { |
|
773 qWarning() <<"Error" << reply.error().name() << reply.error().message() |
|
774 <<activatingConnectionPath; |
|
775 emit connectionError(activatingConnectionPath, ConnectError); |
|
776 } |
|
777 } |
|
778 |
|
779 void QNmWifiEngine::scanForAccessPoints() |
|
780 { |
|
781 availableAccessPoints.clear(); |
|
782 |
|
783 QScopedPointer<QNetworkManagerInterfaceDevice> devIface; |
|
784 QScopedPointer<QNetworkManagerInterfaceDeviceWireless> devWirelessIface; |
|
785 QScopedPointer<QNetworkManagerInterfaceAccessPoint> accessPointIface; |
|
786 foreach (const QDBusObjectPath &path, iface->getDevices()) { |
|
787 devIface.reset(new QNetworkManagerInterfaceDevice(path.path())); |
|
788 |
|
789 if(devIface->deviceType() == DEVICE_TYPE_802_11_WIRELESS) { |
|
790 |
|
791 devWirelessIface.reset(new QNetworkManagerInterfaceDeviceWireless(devIface->connectionInterface()->path())); |
|
792 ////////////// AccessPoints |
|
793 |
|
794 foreach (const QDBusObjectPath &path, devWirelessIface->getAccessPoints()) { |
|
795 accessPointIface.reset(new QNetworkManagerInterfaceAccessPoint(path.path())); |
|
796 const QString ssid = accessPointIface->ssid(); |
|
797 availableAccessPoints.insert(ssid, path); |
|
798 } |
|
799 } |
|
800 } |
|
801 } |
|
802 |
|
803 QString QNmWifiEngine::deviceConnectionPath(const QString &mac) |
|
804 { |
|
805 QString newMac = mac.toLower(); |
|
806 newMac.replace(QLatin1Char(':'), QLatin1Char('_')); |
|
807 //device object path might not contain just mac address |
|
808 //might contain extra numbers on the end. thanks HAL |
|
809 foreach (const QString &device, devicePaths) { |
|
810 if(device.contains(newMac)) { |
|
811 newMac = device; |
|
812 break; |
|
813 } |
|
814 } |
|
815 return newMac; |
|
816 } |
|
817 |
|
818 QStringList QNmWifiEngine::getConnectionPathForId(const QString &uuid) |
|
819 { |
|
820 QStringList connectionServices; |
|
821 connectionServices << NM_DBUS_SERVICE_SYSTEM_SETTINGS; |
|
822 connectionServices << NM_DBUS_SERVICE_USER_SETTINGS; |
|
823 QScopedPointer<QNetworkManagerSettings> settingsiface; |
|
824 foreach (const QString &service, connectionServices) { |
|
825 settingsiface.reset(new QNetworkManagerSettings(service)); |
|
826 QScopedPointer<QNetworkManagerSettingsConnection> sysIface; |
|
827 foreach (const QDBusObjectPath &path, settingsiface->listConnections()) { |
|
828 sysIface.reset(new QNetworkManagerSettingsConnection(service, path.path())); |
|
829 if(sysIface->getUuid() == uuid) |
|
830 return QStringList() << service << sysIface->connectionInterface()->path(); |
|
831 } |
|
832 } |
|
833 return QStringList(); |
|
834 } |
|
835 |
|
836 #include "moc_qnmwifiengine_unix_p.cpp" |
|
837 |
|
838 QTM_END_NAMESPACE |
|
839 |
|