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