1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 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 plugins of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
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 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at qt-info@nokia.com.
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "qicdengine.h"
|
---|
43 | #include "qnetworksession_impl.h"
|
---|
44 |
|
---|
45 | #include <wlancond.h>
|
---|
46 | #include <wlan-utils.h>
|
---|
47 | #include <iapconf.h>
|
---|
48 | #include <iapmonitor.h>
|
---|
49 |
|
---|
50 | #ifndef QT_NO_BEARERMANAGEMENT
|
---|
51 |
|
---|
52 | QT_BEGIN_NAMESPACE
|
---|
53 |
|
---|
54 | IcdNetworkConfigurationPrivate::IcdNetworkConfigurationPrivate()
|
---|
55 | : service_attrs(0), network_attrs(0)
|
---|
56 | {
|
---|
57 | }
|
---|
58 |
|
---|
59 | IcdNetworkConfigurationPrivate::~IcdNetworkConfigurationPrivate()
|
---|
60 | {
|
---|
61 | }
|
---|
62 |
|
---|
63 | QString IcdNetworkConfigurationPrivate::bearerTypeName() const
|
---|
64 | {
|
---|
65 | QMutexLocker locker(&mutex);
|
---|
66 |
|
---|
67 | return iap_type;
|
---|
68 | }
|
---|
69 |
|
---|
70 | /******************************************************************************/
|
---|
71 | /** IapAddTimer specific */
|
---|
72 | /******************************************************************************/
|
---|
73 |
|
---|
74 | /* The IapAddTimer is a helper class that makes sure we update
|
---|
75 | * the configuration only after all db additions to certain
|
---|
76 | * iap are finished (after a certain timeout)
|
---|
77 | */
|
---|
78 | class _IapAddTimer : public QObject
|
---|
79 | {
|
---|
80 | Q_OBJECT
|
---|
81 |
|
---|
82 | public:
|
---|
83 | _IapAddTimer() {}
|
---|
84 | ~_IapAddTimer()
|
---|
85 | {
|
---|
86 | if (timer.isActive()) {
|
---|
87 | QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
---|
88 | timer.stop();
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | void add(QString& iap_id, QIcdEngine *d);
|
---|
93 |
|
---|
94 | QString iap_id;
|
---|
95 | QTimer timer;
|
---|
96 | QIcdEngine *d;
|
---|
97 |
|
---|
98 | public Q_SLOTS:
|
---|
99 | void timeout();
|
---|
100 | };
|
---|
101 |
|
---|
102 |
|
---|
103 | void _IapAddTimer::add(QString& id, QIcdEngine *d_ptr)
|
---|
104 | {
|
---|
105 | iap_id = id;
|
---|
106 | d = d_ptr;
|
---|
107 |
|
---|
108 | if (timer.isActive()) {
|
---|
109 | QObject::disconnect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
---|
110 | timer.stop();
|
---|
111 | }
|
---|
112 | timer.setSingleShot(true);
|
---|
113 | QObject::connect(&timer, SIGNAL(timeout()), this, SLOT(timeout()));
|
---|
114 | timer.start(1500);
|
---|
115 | }
|
---|
116 |
|
---|
117 |
|
---|
118 | void _IapAddTimer::timeout()
|
---|
119 | {
|
---|
120 | d->addConfiguration(iap_id);
|
---|
121 | }
|
---|
122 |
|
---|
123 |
|
---|
124 | class IapAddTimer {
|
---|
125 | QHash<QString, _IapAddTimer* > timers;
|
---|
126 |
|
---|
127 | public:
|
---|
128 | IapAddTimer() {}
|
---|
129 | ~IapAddTimer() {}
|
---|
130 |
|
---|
131 | void add(QString& iap_id, QIcdEngine *d);
|
---|
132 | void del(QString& iap_id);
|
---|
133 | void removeAll();
|
---|
134 | };
|
---|
135 |
|
---|
136 |
|
---|
137 | void IapAddTimer::removeAll()
|
---|
138 | {
|
---|
139 | QHashIterator<QString, _IapAddTimer* > i(timers);
|
---|
140 | while (i.hasNext()) {
|
---|
141 | i.next();
|
---|
142 | _IapAddTimer *t = i.value();
|
---|
143 | delete t;
|
---|
144 | }
|
---|
145 | timers.clear();
|
---|
146 | }
|
---|
147 |
|
---|
148 |
|
---|
149 | void IapAddTimer::add(QString& iap_id, QIcdEngine *d)
|
---|
150 | {
|
---|
151 | if (timers.contains(iap_id)) {
|
---|
152 | _IapAddTimer *iap = timers.value(iap_id);
|
---|
153 | iap->add(iap_id, d);
|
---|
154 | } else {
|
---|
155 | _IapAddTimer *iap = new _IapAddTimer;
|
---|
156 | iap->add(iap_id, d);
|
---|
157 | timers.insert(iap_id, iap);
|
---|
158 | }
|
---|
159 | }
|
---|
160 |
|
---|
161 | void IapAddTimer::del(QString& iap_id)
|
---|
162 | {
|
---|
163 | if (timers.contains(iap_id)) {
|
---|
164 | _IapAddTimer *iap = timers.take(iap_id);
|
---|
165 | delete iap;
|
---|
166 | }
|
---|
167 | }
|
---|
168 |
|
---|
169 | /******************************************************************************/
|
---|
170 | /** IAPMonitor specific */
|
---|
171 | /******************************************************************************/
|
---|
172 |
|
---|
173 | class IapMonitor : public Maemo::IAPMonitor
|
---|
174 | {
|
---|
175 | public:
|
---|
176 | IapMonitor() : first_call(true) { }
|
---|
177 |
|
---|
178 | void setup(QIcdEngine *d);
|
---|
179 | void cleanup();
|
---|
180 |
|
---|
181 | protected:
|
---|
182 | void iapAdded(const QString &iapId);
|
---|
183 | void iapRemoved(const QString &iapId);
|
---|
184 |
|
---|
185 | private:
|
---|
186 | bool first_call;
|
---|
187 |
|
---|
188 | QIcdEngine *d;
|
---|
189 | IapAddTimer timers;
|
---|
190 | };
|
---|
191 |
|
---|
192 | void IapMonitor::setup(QIcdEngine *d_ptr)
|
---|
193 | {
|
---|
194 | if (first_call) {
|
---|
195 | d = d_ptr;
|
---|
196 | first_call = false;
|
---|
197 | }
|
---|
198 | }
|
---|
199 |
|
---|
200 |
|
---|
201 | void IapMonitor::cleanup()
|
---|
202 | {
|
---|
203 | if (!first_call) {
|
---|
204 | timers.removeAll();
|
---|
205 | first_call = true;
|
---|
206 | }
|
---|
207 | }
|
---|
208 |
|
---|
209 |
|
---|
210 | void IapMonitor::iapAdded(const QString &iap_id)
|
---|
211 | {
|
---|
212 | /* We cannot know when the IAP is fully added to db, so a timer is
|
---|
213 | * installed instead. When the timer expires we hope that IAP is added ok.
|
---|
214 | */
|
---|
215 | QString id = iap_id;
|
---|
216 | timers.add(id, d);
|
---|
217 | }
|
---|
218 |
|
---|
219 |
|
---|
220 | void IapMonitor::iapRemoved(const QString &iap_id)
|
---|
221 | {
|
---|
222 | QString id = iap_id;
|
---|
223 | d->deleteConfiguration(id);
|
---|
224 | }
|
---|
225 |
|
---|
226 |
|
---|
227 | /******************************************************************************/
|
---|
228 | /** QIcdEngine implementation */
|
---|
229 | /******************************************************************************/
|
---|
230 |
|
---|
231 | QIcdEngine::QIcdEngine(QObject *parent)
|
---|
232 | : QBearerEngine(parent), iapMonitor(0), m_dbusInterface(0), m_icdServiceWatcher(0),
|
---|
233 | firstUpdate(true), m_scanGoingOn(false)
|
---|
234 | {
|
---|
235 | }
|
---|
236 |
|
---|
237 | QIcdEngine::~QIcdEngine()
|
---|
238 | {
|
---|
239 | cleanup();
|
---|
240 | delete iapMonitor;
|
---|
241 | }
|
---|
242 |
|
---|
243 | QNetworkConfigurationManager::Capabilities QIcdEngine::capabilities() const
|
---|
244 | {
|
---|
245 | return QNetworkConfigurationManager::CanStartAndStopInterfaces |
|
---|
246 | QNetworkConfigurationManager::DataStatistics |
|
---|
247 | QNetworkConfigurationManager::ForcedRoaming |
|
---|
248 | QNetworkConfigurationManager::NetworkSessionRequired;
|
---|
249 | }
|
---|
250 |
|
---|
251 | bool QIcdEngine::ensureDBusConnection()
|
---|
252 | {
|
---|
253 | if (m_dbusInterface)
|
---|
254 | return true;
|
---|
255 |
|
---|
256 | // Setup DBus Interface for ICD
|
---|
257 | m_dbusInterface = new QDBusInterface(ICD_DBUS_API_INTERFACE,
|
---|
258 | ICD_DBUS_API_PATH,
|
---|
259 | ICD_DBUS_API_INTERFACE,
|
---|
260 | QDBusConnection::systemBus(),
|
---|
261 | this);
|
---|
262 |
|
---|
263 | if (!m_dbusInterface->isValid()) {
|
---|
264 | delete m_dbusInterface;
|
---|
265 | m_dbusInterface = 0;
|
---|
266 |
|
---|
267 | if (!m_icdServiceWatcher) {
|
---|
268 | m_icdServiceWatcher = new QDBusServiceWatcher(ICD_DBUS_API_INTERFACE,
|
---|
269 | QDBusConnection::systemBus(),
|
---|
270 | QDBusServiceWatcher::WatchForOwnerChange,
|
---|
271 | this);
|
---|
272 |
|
---|
273 | connect(m_icdServiceWatcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)),
|
---|
274 | this, SLOT(icdServiceOwnerChanged(QString,QString,QString)));
|
---|
275 | }
|
---|
276 |
|
---|
277 | return false;
|
---|
278 | }
|
---|
279 |
|
---|
280 | connect(&m_scanTimer, SIGNAL(timeout()), this, SLOT(finishAsyncConfigurationUpdate()));
|
---|
281 | m_scanTimer.setSingleShot(true);
|
---|
282 |
|
---|
283 | /* Turn on IAP state monitoring */
|
---|
284 | startListeningStateSignalsForAllConnections();
|
---|
285 |
|
---|
286 | /* Turn on IAP add/remove monitoring */
|
---|
287 | iapMonitor = new IapMonitor;
|
---|
288 | iapMonitor->setup(this);
|
---|
289 |
|
---|
290 | /* We create a default configuration which is a pseudo config */
|
---|
291 | QNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate;
|
---|
292 | cpPriv->name = "UserChoice";
|
---|
293 | cpPriv->state = QNetworkConfiguration::Discovered;
|
---|
294 | cpPriv->isValid = true;
|
---|
295 | cpPriv->id = OSSO_IAP_ANY;
|
---|
296 | cpPriv->type = QNetworkConfiguration::UserChoice;
|
---|
297 | cpPriv->purpose = QNetworkConfiguration::UnknownPurpose;
|
---|
298 | cpPriv->roamingSupported = false;
|
---|
299 |
|
---|
300 | QNetworkConfigurationPrivatePointer ptr(cpPriv);
|
---|
301 | userChoiceConfigurations.insert(cpPriv->id, ptr);
|
---|
302 |
|
---|
303 | doRequestUpdate();
|
---|
304 |
|
---|
305 | getIcdInitialState();
|
---|
306 |
|
---|
307 | return true;
|
---|
308 | }
|
---|
309 |
|
---|
310 | void QIcdEngine::initialize()
|
---|
311 | {
|
---|
312 | QMutexLocker locker(&mutex);
|
---|
313 |
|
---|
314 | if (!ensureDBusConnection()) {
|
---|
315 | locker.unlock();
|
---|
316 | emit updateCompleted();
|
---|
317 | locker.relock();
|
---|
318 | }
|
---|
319 | }
|
---|
320 |
|
---|
321 | static inline QString network_attrs_to_security(uint network_attrs)
|
---|
322 | {
|
---|
323 | uint cap = 0;
|
---|
324 | nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */
|
---|
325 | if (cap & WLANCOND_OPEN)
|
---|
326 | return "NONE";
|
---|
327 | else if (cap & WLANCOND_WEP)
|
---|
328 | return "WEP";
|
---|
329 | else if (cap & WLANCOND_WPA_PSK)
|
---|
330 | return "WPA_PSK";
|
---|
331 | else if (cap & WLANCOND_WPA_EAP)
|
---|
332 | return "WPA_EAP";
|
---|
333 | return "";
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | struct SSIDInfo {
|
---|
338 | QString iap_id;
|
---|
339 | QString wlan_security;
|
---|
340 | };
|
---|
341 |
|
---|
342 |
|
---|
343 | void QIcdEngine::deleteConfiguration(const QString &iap_id)
|
---|
344 | {
|
---|
345 | QMutexLocker locker(&mutex);
|
---|
346 |
|
---|
347 | /* Called when IAPs are deleted in db, in this case we do not scan
|
---|
348 | * or read all the IAPs from db because it might take too much power
|
---|
349 | * (multiple applications would need to scan and read all IAPs from db)
|
---|
350 | */
|
---|
351 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(iap_id);
|
---|
352 | if (ptr) {
|
---|
353 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
354 | qDebug() << "IAP" << iap_id << "was removed from storage.";
|
---|
355 | #endif
|
---|
356 |
|
---|
357 | locker.unlock();
|
---|
358 | emit configurationRemoved(ptr);
|
---|
359 | } else {
|
---|
360 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
361 | qDebug("IAP: %s, already missing from the known list", iap_id.toAscii().data());
|
---|
362 | #endif
|
---|
363 | }
|
---|
364 | }
|
---|
365 |
|
---|
366 |
|
---|
367 | static quint32 getNetworkAttrs(bool is_iap_id,
|
---|
368 | const QString &iap_id,
|
---|
369 | const QString &iap_type,
|
---|
370 | QString security_method)
|
---|
371 | {
|
---|
372 | guint network_attr = 0;
|
---|
373 | dbus_uint32_t cap = 0;
|
---|
374 |
|
---|
375 | if (iap_type == "WLAN_INFRA")
|
---|
376 | cap |= WLANCOND_INFRA;
|
---|
377 | else if (iap_type == "WLAN_ADHOC")
|
---|
378 | cap |= WLANCOND_ADHOC;
|
---|
379 |
|
---|
380 | if (security_method.isEmpty() && (cap & (WLANCOND_INFRA | WLANCOND_ADHOC))) {
|
---|
381 | Maemo::IAPConf saved_ap(iap_id);
|
---|
382 | security_method = saved_ap.value("wlan_security").toString();
|
---|
383 | }
|
---|
384 |
|
---|
385 | if (!security_method.isEmpty()) {
|
---|
386 | if (security_method == "WEP")
|
---|
387 | cap |= WLANCOND_WEP;
|
---|
388 | else if (security_method == "WPA_PSK")
|
---|
389 | cap |= WLANCOND_WPA_PSK;
|
---|
390 | else if (security_method == "WPA_EAP")
|
---|
391 | cap |= WLANCOND_WPA_EAP;
|
---|
392 | else if (security_method == "NONE")
|
---|
393 | cap |= WLANCOND_OPEN;
|
---|
394 |
|
---|
395 | if (cap & (WLANCOND_WPA_PSK | WLANCOND_WPA_EAP)) {
|
---|
396 | Maemo::IAPConf saved_iap(iap_id);
|
---|
397 | bool wpa2_only = saved_iap.value("EAP_wpa2_only_mode").toBool();
|
---|
398 | if (wpa2_only) {
|
---|
399 | cap |= WLANCOND_WPA2;
|
---|
400 | }
|
---|
401 | }
|
---|
402 | }
|
---|
403 |
|
---|
404 | cap2nwattr(cap, &network_attr);
|
---|
405 | if (is_iap_id)
|
---|
406 | network_attr |= ICD_NW_ATTR_IAPNAME;
|
---|
407 |
|
---|
408 | return quint32(network_attr);
|
---|
409 | }
|
---|
410 |
|
---|
411 |
|
---|
412 | void QIcdEngine::addConfiguration(QString& iap_id)
|
---|
413 | {
|
---|
414 | // Note: When new IAP is created, this function gets called multiple times
|
---|
415 | // in a row.
|
---|
416 | // For example: Empty type & name for WLAN was stored into newly
|
---|
417 | // created IAP data in gconf when this function gets
|
---|
418 | // called for the first time.
|
---|
419 | // WLAN type & name are updated into IAP data in gconf
|
---|
420 | // as soon as WLAN connection is up and running.
|
---|
421 | // => And this function gets called again.
|
---|
422 |
|
---|
423 | QMutexLocker locker(&mutex);
|
---|
424 |
|
---|
425 | if (!accessPointConfigurations.contains(iap_id)) {
|
---|
426 | Maemo::IAPConf saved_iap(iap_id);
|
---|
427 | QString iap_type = saved_iap.value("type").toString();
|
---|
428 | QString iap_name = saved_iap.value("name").toString();
|
---|
429 | QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray();
|
---|
430 | if (!iap_type.isEmpty() && !iap_name.isEmpty()) {
|
---|
431 | // Check if new IAP is actually Undefined WLAN configuration
|
---|
432 | // Note: SSID is used as an iap id for Undefined WLAN configurations
|
---|
433 | // => configuration must be searched using SSID
|
---|
434 | if (!ssid.isEmpty() && accessPointConfigurations.contains(ssid)) {
|
---|
435 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(ssid);
|
---|
436 | if (ptr) {
|
---|
437 | ptr->mutex.lock();
|
---|
438 | ptr->id = iap_id;
|
---|
439 | toIcdConfig(ptr)->iap_type = iap_type;
|
---|
440 | ptr->bearerType = bearerTypeFromIapType(iap_type);
|
---|
441 | toIcdConfig(ptr)->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString());
|
---|
442 | toIcdConfig(ptr)->network_id = ssid;
|
---|
443 | toIcdConfig(ptr)->service_id = saved_iap.value("service_id").toString();
|
---|
444 | toIcdConfig(ptr)->service_type = saved_iap.value("service_type").toString();
|
---|
445 | if (m_onlineIapId == iap_id) {
|
---|
446 | ptr->state = QNetworkConfiguration::Active;
|
---|
447 | } else {
|
---|
448 | ptr->state = QNetworkConfiguration::Defined;
|
---|
449 | }
|
---|
450 | ptr->mutex.unlock();
|
---|
451 | accessPointConfigurations.insert(iap_id, ptr);
|
---|
452 |
|
---|
453 | locker.unlock();
|
---|
454 | emit configurationChanged(ptr);
|
---|
455 | locker.relock();
|
---|
456 | }
|
---|
457 | } else {
|
---|
458 | IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate;
|
---|
459 | cpPriv->name = saved_iap.value("name").toString();
|
---|
460 | if (cpPriv->name.isEmpty())
|
---|
461 | cpPriv->name = iap_id;
|
---|
462 | cpPriv->isValid = true;
|
---|
463 | cpPriv->id = iap_id;
|
---|
464 | cpPriv->iap_type = iap_type;
|
---|
465 | cpPriv->bearerType = bearerTypeFromIapType(iap_type);
|
---|
466 | cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString());
|
---|
467 | cpPriv->service_id = saved_iap.value("service_id").toString();
|
---|
468 | cpPriv->service_type = saved_iap.value("service_type").toString();
|
---|
469 | if (iap_type.startsWith(QLatin1String("WLAN"))) {
|
---|
470 | QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray();
|
---|
471 | if (ssid.isEmpty()) {
|
---|
472 | qWarning() << "Cannot get ssid for" << iap_id;
|
---|
473 | }
|
---|
474 | cpPriv->network_id = ssid;
|
---|
475 | }
|
---|
476 | cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
|
---|
477 | if (m_onlineIapId == iap_id) {
|
---|
478 | cpPriv->state = QNetworkConfiguration::Active;
|
---|
479 | } else {
|
---|
480 | cpPriv->state = QNetworkConfiguration::Defined;
|
---|
481 | }
|
---|
482 |
|
---|
483 | QNetworkConfigurationPrivatePointer ptr(cpPriv);
|
---|
484 | accessPointConfigurations.insert(iap_id, ptr);
|
---|
485 |
|
---|
486 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
487 | qDebug("IAP: %s, name: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data());
|
---|
488 | #endif
|
---|
489 | locker.unlock();
|
---|
490 | emit configurationAdded(ptr);
|
---|
491 | locker.relock();
|
---|
492 | }
|
---|
493 | } else {
|
---|
494 | qWarning("IAP %s does not have \"type\" or \"name\" fields defined, skipping this IAP.", iap_id.toAscii().data());
|
---|
495 | }
|
---|
496 | } else {
|
---|
497 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
498 | qDebug() << "IAP" << iap_id << "already in db.";
|
---|
499 | #endif
|
---|
500 |
|
---|
501 | /* Check if the data in db changed and update configuration accordingly
|
---|
502 | */
|
---|
503 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iap_id);
|
---|
504 | if (ptr) {
|
---|
505 | Maemo::IAPConf changed_iap(iap_id);
|
---|
506 | QString iap_type = changed_iap.value("type").toString();
|
---|
507 | bool update_needed = false; /* if IAP type or ssid changed, we need to change the state */
|
---|
508 |
|
---|
509 | QMutexLocker configLocker(&ptr->mutex);
|
---|
510 |
|
---|
511 | toIcdConfig(ptr)->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString());
|
---|
512 | toIcdConfig(ptr)->service_id = changed_iap.value("service_id").toString();
|
---|
513 | toIcdConfig(ptr)->service_type = changed_iap.value("service_type").toString();
|
---|
514 |
|
---|
515 | if (!iap_type.isEmpty()) {
|
---|
516 | ptr->name = changed_iap.value("name").toString();
|
---|
517 | if (ptr->name.isEmpty())
|
---|
518 | ptr->name = iap_id;
|
---|
519 | ptr->isValid = true;
|
---|
520 | if (toIcdConfig(ptr)->iap_type != iap_type) {
|
---|
521 | toIcdConfig(ptr)->iap_type = iap_type;
|
---|
522 | ptr->bearerType = bearerTypeFromIapType(iap_type);
|
---|
523 | update_needed = true;
|
---|
524 | }
|
---|
525 | if (iap_type.startsWith(QLatin1String("WLAN"))) {
|
---|
526 | QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray();
|
---|
527 | if (ssid.isEmpty()) {
|
---|
528 | qWarning() << "Cannot get ssid for" << iap_id;
|
---|
529 | }
|
---|
530 | if (toIcdConfig(ptr)->network_id != ssid) {
|
---|
531 | toIcdConfig(ptr)->network_id = ssid;
|
---|
532 | update_needed = true;
|
---|
533 | }
|
---|
534 | }
|
---|
535 | }
|
---|
536 |
|
---|
537 | if (update_needed) {
|
---|
538 | ptr->type = QNetworkConfiguration::InternetAccessPoint;
|
---|
539 | if (m_onlineIapId == iap_id) {
|
---|
540 | if (ptr->state < QNetworkConfiguration::Active) {
|
---|
541 | ptr->state = QNetworkConfiguration::Active;
|
---|
542 |
|
---|
543 | configLocker.unlock();
|
---|
544 | locker.unlock();
|
---|
545 | emit configurationChanged(ptr);
|
---|
546 | locker.relock();
|
---|
547 | }
|
---|
548 | } else if (ptr->state < QNetworkConfiguration::Defined) {
|
---|
549 | ptr->state = QNetworkConfiguration::Defined;
|
---|
550 |
|
---|
551 | configLocker.unlock();
|
---|
552 | locker.unlock();
|
---|
553 | emit configurationChanged(ptr);
|
---|
554 | locker.relock();
|
---|
555 | }
|
---|
556 | }
|
---|
557 | } else {
|
---|
558 | qWarning("Cannot find IAP %s from current configuration although it should be there.", iap_id.toAscii().data());
|
---|
559 | }
|
---|
560 | }
|
---|
561 | }
|
---|
562 |
|
---|
563 | void QIcdEngine::doRequestUpdate(QList<Maemo::IcdScanResult> scanned)
|
---|
564 | {
|
---|
565 | /* Contains all known iap_ids from storage */
|
---|
566 | QList<QString> knownConfigs = accessPointConfigurations.keys();
|
---|
567 |
|
---|
568 | /* Contains all known WLAN network ids (like ssid) from storage */
|
---|
569 | QMultiHash<QByteArray, SSIDInfo* > notDiscoveredWLANConfigs;
|
---|
570 |
|
---|
571 | QList<QString> all_iaps;
|
---|
572 | Maemo::IAPConf::getAll(all_iaps);
|
---|
573 |
|
---|
574 | foreach (const QString &iap_id, all_iaps) {
|
---|
575 | QByteArray ssid;
|
---|
576 |
|
---|
577 | Maemo::IAPConf saved_ap(iap_id);
|
---|
578 | bool is_temporary = saved_ap.value("temporary").toBool();
|
---|
579 | if (is_temporary) {
|
---|
580 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
581 | qDebug() << "IAP" << iap_id << "is temporary, skipping it.";
|
---|
582 | #endif
|
---|
583 | continue;
|
---|
584 | }
|
---|
585 |
|
---|
586 | QString iap_type = saved_ap.value("type").toString();
|
---|
587 | if (iap_type.startsWith(QLatin1String("WLAN"))) {
|
---|
588 | ssid = saved_ap.value("wlan_ssid").toByteArray();
|
---|
589 | if (ssid.isEmpty())
|
---|
590 | continue;
|
---|
591 |
|
---|
592 | QString security_method = saved_ap.value("wlan_security").toString();
|
---|
593 | SSIDInfo *info = new SSIDInfo;
|
---|
594 | info->iap_id = iap_id;
|
---|
595 | info->wlan_security = security_method;
|
---|
596 | notDiscoveredWLANConfigs.insert(ssid, info);
|
---|
597 | } else if (iap_type.isEmpty()) {
|
---|
598 | continue;
|
---|
599 | } else {
|
---|
600 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
601 | qDebug() << "IAP" << iap_id << "network type is" << iap_type;
|
---|
602 | #endif
|
---|
603 | ssid.clear();
|
---|
604 | }
|
---|
605 |
|
---|
606 | if (!accessPointConfigurations.contains(iap_id)) {
|
---|
607 | IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate;
|
---|
608 |
|
---|
609 | cpPriv->name = saved_ap.value("name").toString();
|
---|
610 | if (cpPriv->name.isEmpty()) {
|
---|
611 | if (!ssid.isEmpty() && ssid.size() > 0)
|
---|
612 | cpPriv->name = ssid.data();
|
---|
613 | else
|
---|
614 | cpPriv->name = iap_id;
|
---|
615 | }
|
---|
616 | cpPriv->isValid = true;
|
---|
617 | cpPriv->id = iap_id;
|
---|
618 | cpPriv->network_id = ssid;
|
---|
619 | cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString());
|
---|
620 | cpPriv->iap_type = iap_type;
|
---|
621 | cpPriv->bearerType = bearerTypeFromIapType(iap_type);
|
---|
622 | cpPriv->service_id = saved_ap.value("service_id").toString();
|
---|
623 | cpPriv->service_type = saved_ap.value("service_type").toString();
|
---|
624 | cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
|
---|
625 | cpPriv->state = QNetworkConfiguration::Defined;
|
---|
626 |
|
---|
627 | QNetworkConfigurationPrivatePointer ptr(cpPriv);
|
---|
628 | accessPointConfigurations.insert(iap_id, ptr);
|
---|
629 |
|
---|
630 | mutex.unlock();
|
---|
631 | emit configurationAdded(ptr);
|
---|
632 | mutex.lock();
|
---|
633 |
|
---|
634 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
635 | qDebug("IAP: %s, name: %s, ssid: %s, added to known list",
|
---|
636 | iap_id.toAscii().data(), ptr->name.toAscii().data(),
|
---|
637 | !ssid.isEmpty() ? ssid.data() : "-");
|
---|
638 | #endif
|
---|
639 | } else {
|
---|
640 | knownConfigs.removeOne(iap_id);
|
---|
641 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
642 | qDebug("IAP: %s, ssid: %s, already exists in the known list",
|
---|
643 | iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-");
|
---|
644 | #endif
|
---|
645 | }
|
---|
646 | }
|
---|
647 |
|
---|
648 | /* This is skipped in the first update as scanned size is zero */
|
---|
649 | if (!scanned.isEmpty()) {
|
---|
650 | for (int i=0; i<scanned.size(); ++i) {
|
---|
651 | const Maemo::IcdScanResult ap = scanned.at(i);
|
---|
652 |
|
---|
653 | if (ap.scan.network_attrs & ICD_NW_ATTR_IAPNAME) {
|
---|
654 | /* The network_id is IAP id, so the IAP is a known one */
|
---|
655 | QString iapid = ap.scan.network_id.data();
|
---|
656 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iapid);
|
---|
657 | if (ptr) {
|
---|
658 | bool changed = false;
|
---|
659 |
|
---|
660 | ptr->mutex.lock();
|
---|
661 |
|
---|
662 | if (!ptr->isValid) {
|
---|
663 | ptr->isValid = true;
|
---|
664 | changed = true;
|
---|
665 | }
|
---|
666 |
|
---|
667 | /* If this config is the current active one, we do not set it
|
---|
668 | * to discovered.
|
---|
669 | */
|
---|
670 | if ((ptr->state != QNetworkConfiguration::Discovered) &&
|
---|
671 | (ptr->state != QNetworkConfiguration::Active)) {
|
---|
672 | ptr->state = QNetworkConfiguration::Discovered;
|
---|
673 | changed = true;
|
---|
674 | }
|
---|
675 |
|
---|
676 | toIcdConfig(ptr)->network_attrs = ap.scan.network_attrs;
|
---|
677 | toIcdConfig(ptr)->service_id = ap.scan.service_id;
|
---|
678 | toIcdConfig(ptr)->service_type = ap.scan.service_type;
|
---|
679 | toIcdConfig(ptr)->service_attrs = ap.scan.service_attrs;
|
---|
680 |
|
---|
681 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
682 | qDebug("IAP: %s, ssid: %s, discovered",
|
---|
683 | iapid.toAscii().data(), toIcdConfig(ptr)->network_id.data());
|
---|
684 | #endif
|
---|
685 |
|
---|
686 | ptr->mutex.unlock();
|
---|
687 |
|
---|
688 | if (changed) {
|
---|
689 | mutex.unlock();
|
---|
690 | emit configurationChanged(ptr);
|
---|
691 | mutex.lock();
|
---|
692 | }
|
---|
693 |
|
---|
694 | if (!ap.scan.network_type.startsWith(QLatin1String("WLAN")))
|
---|
695 | continue; // not a wlan AP
|
---|
696 |
|
---|
697 | /* Remove scanned AP from discovered WLAN configurations so that we can
|
---|
698 | * emit configurationRemoved signal later
|
---|
699 | */
|
---|
700 | ptr->mutex.lock();
|
---|
701 | QList<SSIDInfo* > known_iaps = notDiscoveredWLANConfigs.values(toIcdConfig(ptr)->network_id);
|
---|
702 | rescan_list:
|
---|
703 | if (!known_iaps.isEmpty()) {
|
---|
704 | for (int k=0; k<known_iaps.size(); ++k) {
|
---|
705 | SSIDInfo *iap = known_iaps.at(k);
|
---|
706 |
|
---|
707 | if (iap->wlan_security ==
|
---|
708 | network_attrs_to_security(ap.scan.network_attrs)) {
|
---|
709 | /* Remove IAP from the list */
|
---|
710 | notDiscoveredWLANConfigs.remove(toIcdConfig(ptr)->network_id, iap);
|
---|
711 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
712 | qDebug() << "Removed IAP" << iap->iap_id << "from unknown config";
|
---|
713 | #endif
|
---|
714 | known_iaps.removeAt(k);
|
---|
715 | delete iap;
|
---|
716 | goto rescan_list;
|
---|
717 | }
|
---|
718 | }
|
---|
719 | }
|
---|
720 | ptr->mutex.unlock();
|
---|
721 | }
|
---|
722 | } else {
|
---|
723 | /* Non saved access point data */
|
---|
724 | QByteArray scanned_ssid = ap.scan.network_id;
|
---|
725 | if (!accessPointConfigurations.contains(scanned_ssid)) {
|
---|
726 | IcdNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate;
|
---|
727 | QString hrs = scanned_ssid.data();
|
---|
728 |
|
---|
729 | cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name;
|
---|
730 | cpPriv->isValid = true;
|
---|
731 | cpPriv->id = scanned_ssid.data(); // Note: id is now ssid, it should be set to IAP id if the IAP is saved
|
---|
732 | cpPriv->network_id = scanned_ssid;
|
---|
733 | cpPriv->iap_type = ap.scan.network_type;
|
---|
734 | cpPriv->bearerType = bearerTypeFromIapType(cpPriv->iap_type);
|
---|
735 | cpPriv->network_attrs = ap.scan.network_attrs;
|
---|
736 | cpPriv->service_id = ap.scan.service_id;
|
---|
737 | cpPriv->service_type = ap.scan.service_type;
|
---|
738 | cpPriv->service_attrs = ap.scan.service_attrs;
|
---|
739 |
|
---|
740 | cpPriv->type = QNetworkConfiguration::InternetAccessPoint;
|
---|
741 | cpPriv->state = QNetworkConfiguration::Undefined;
|
---|
742 |
|
---|
743 | #ifdef BEARER_MANAGEMENT_DEBUG
|
---|
744 | qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan.";
|
---|
745 | #endif
|
---|
746 |
|
---|
747 | QNetworkConfigurationPrivatePointer ptr(cpPriv);
|
---|
748 | accessPointConfigurations.insert(ptr->id, ptr);
|
---|
749 |
|
---|
750 | mutex.unlock();
|
---|
751 | emit configurationAdded(ptr);
|
---|
752 | mutex.lock();
|
---|
753 | } else {
|
---|
754 | knownConfigs.removeOne(scanned_ssid);
|
---|
755 | }
|
---|
756 | }
|
---|
757 | }
|
---|
758 | }
|
---|
759 |
|
---|
760 | if (!firstUpdate) {
|
---|
761 | // Update Defined status to all defined WLAN IAPs which
|
---|
762 | // could not be found when access points were scanned
|
---|
763 | QHashIterator<QByteArray, SSIDInfo* > i(notDiscoveredWLANConfigs);
|
---|
764 | while (i.hasNext()) {
|
---|
765 | i.next();
|
---|
766 | SSIDInfo *iap = i.value();
|
---|
767 | QString iap_id = iap->iap_id;
|
---|
768 | //qDebug() << i.key() << ": " << iap_id;
|
---|
769 |
|
---|
770 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iap_id);
|
---|
771 | if (ptr) {
|
---|
772 | QMutexLocker configLocker(&ptr->mutex);
|
---|
773 |
|
---|
774 | // WLAN AccessPoint configuration could not be Discovered
|
---|
775 | // => Make sure that configuration state is Defined
|
---|
776 | if (ptr->state > QNetworkConfiguration::Defined) {
|
---|
777 | ptr->state = QNetworkConfiguration::Defined;
|
---|
778 |
|
---|
779 | configLocker.unlock();
|
---|
780 | mutex.unlock();
|
---|
781 | emit configurationChanged(ptr);
|
---|
782 | mutex.lock();
|
---|
783 | }
|
---|
784 | }
|
---|
785 | }
|
---|
786 |
|
---|
787 | /* Remove non existing iaps since last update */
|
---|
788 | foreach (const QString &oldIface, knownConfigs) {
|
---|
789 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface);
|
---|
790 | if (ptr) {
|
---|
791 | mutex.unlock();
|
---|
792 | emit configurationRemoved(ptr);
|
---|
793 | mutex.lock();
|
---|
794 | //if we would have SNAP support we would have to remove the references
|
---|
795 | //from existing ServiceNetworks to the removed access point configuration
|
---|
796 | }
|
---|
797 | }
|
---|
798 | }
|
---|
799 |
|
---|
800 | QMutableHashIterator<QByteArray, SSIDInfo* > i(notDiscoveredWLANConfigs);
|
---|
801 | while (i.hasNext()) {
|
---|
802 | i.next();
|
---|
803 | SSIDInfo *iap = i.value();
|
---|
804 | delete iap;
|
---|
805 | i.remove();
|
---|
806 | }
|
---|
807 |
|
---|
808 | if (!firstUpdate) {
|
---|
809 | mutex.unlock();
|
---|
810 | emit updateCompleted();
|
---|
811 | mutex.lock();
|
---|
812 | }
|
---|
813 |
|
---|
814 | if (firstUpdate)
|
---|
815 | firstUpdate = false;
|
---|
816 | }
|
---|
817 |
|
---|
818 | QNetworkConfigurationPrivatePointer QIcdEngine::defaultConfiguration()
|
---|
819 | {
|
---|
820 | QMutexLocker locker(&mutex);
|
---|
821 |
|
---|
822 | if (!ensureDBusConnection())
|
---|
823 | return QNetworkConfigurationPrivatePointer();
|
---|
824 |
|
---|
825 | // Here we just return [ANY] request to icd and let the icd decide which IAP to connect.
|
---|
826 | return userChoiceConfigurations.value(OSSO_IAP_ANY);
|
---|
827 | }
|
---|
828 |
|
---|
829 | void QIcdEngine::startListeningStateSignalsForAllConnections()
|
---|
830 | {
|
---|
831 | // Start listening ICD_DBUS_API_STATE_SIG signals
|
---|
832 | m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE,
|
---|
833 | ICD_DBUS_API_PATH,
|
---|
834 | ICD_DBUS_API_INTERFACE,
|
---|
835 | ICD_DBUS_API_STATE_SIG,
|
---|
836 | this, SLOT(connectionStateSignalsSlot(QDBusMessage)));
|
---|
837 | }
|
---|
838 |
|
---|
839 | void QIcdEngine::getIcdInitialState()
|
---|
840 | {
|
---|
841 | /* Instead of requesting ICD status asynchronously, we ask it synchronously.
|
---|
842 | * It ensures that we always get right icd status BEFORE initialize() ends.
|
---|
843 | * If not, initialize() might end before we got icd status and
|
---|
844 | * QNetworkConfigurationManager::updateConfigurations()
|
---|
845 | * call from user might also end before receiving icd status.
|
---|
846 | * In such case, we come up to a bug:
|
---|
847 | * QNetworkConfigurationManagerPrivate::isOnline() will be false even
|
---|
848 | * if we are connected.
|
---|
849 | */
|
---|
850 | Maemo::Icd icd;
|
---|
851 | QList<Maemo::IcdStateResult> state_results;
|
---|
852 | QNetworkConfigurationPrivatePointer ptr;
|
---|
853 |
|
---|
854 | if (icd.state(state_results) && !state_results.isEmpty()) {
|
---|
855 |
|
---|
856 | if (!(state_results.first().params.network_attrs == 0 &&
|
---|
857 | state_results.first().params.network_id.isEmpty())) {
|
---|
858 |
|
---|
859 | switch (state_results.first().state) {
|
---|
860 | case ICD_STATE_CONNECTED:
|
---|
861 | m_onlineIapId = state_results.first().params.network_id;
|
---|
862 |
|
---|
863 | ptr = accessPointConfigurations.value(m_onlineIapId);
|
---|
864 | if (ptr) {
|
---|
865 | QMutexLocker configLocker(&ptr->mutex);
|
---|
866 | ptr->state = QNetworkConfiguration::Active;
|
---|
867 | configLocker.unlock();
|
---|
868 |
|
---|
869 | mutex.unlock();
|
---|
870 | emit configurationChanged(ptr);
|
---|
871 | mutex.lock();
|
---|
872 | }
|
---|
873 | break;
|
---|
874 | default:
|
---|
875 | break;
|
---|
876 | }
|
---|
877 | }
|
---|
878 | }
|
---|
879 | }
|
---|
880 |
|
---|
881 | void QIcdEngine::connectionStateSignalsSlot(QDBusMessage msg)
|
---|
882 | {
|
---|
883 | QMutexLocker locker(&mutex);
|
---|
884 |
|
---|
885 | QList<QVariant> arguments = msg.arguments();
|
---|
886 | if (arguments[1].toUInt() != 0 || arguments.count() < 8) {
|
---|
887 | return;
|
---|
888 | }
|
---|
889 |
|
---|
890 | QString iapid = arguments[5].toByteArray().data();
|
---|
891 | uint icd_connection_state = arguments[7].toUInt();
|
---|
892 |
|
---|
893 | switch (icd_connection_state) {
|
---|
894 | case ICD_STATE_CONNECTED:
|
---|
895 | {
|
---|
896 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iapid);
|
---|
897 | if (ptr) {
|
---|
898 | QMutexLocker configLocker(&ptr->mutex);
|
---|
899 |
|
---|
900 | ptr->type = QNetworkConfiguration::InternetAccessPoint;
|
---|
901 | if (ptr->state != QNetworkConfiguration::Active) {
|
---|
902 | ptr->state = QNetworkConfiguration::Active;
|
---|
903 |
|
---|
904 | configLocker.unlock();
|
---|
905 | locker.unlock();
|
---|
906 | emit configurationChanged(ptr);
|
---|
907 | locker.relock();
|
---|
908 |
|
---|
909 | m_onlineIapId = iapid;
|
---|
910 | }
|
---|
911 | } else {
|
---|
912 | // This gets called when new WLAN IAP is created using Connection dialog
|
---|
913 | // At this point Undefined WLAN configuration has SSID as iap id
|
---|
914 | // => Because of that configuration can not be found from
|
---|
915 | // accessPointConfigurations using correct iap id
|
---|
916 | m_onlineIapId = iapid;
|
---|
917 | }
|
---|
918 | break;
|
---|
919 | }
|
---|
920 | case ICD_STATE_DISCONNECTED:
|
---|
921 | {
|
---|
922 | QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iapid);
|
---|
923 | if (ptr) {
|
---|
924 | QMutexLocker configLocker(&ptr->mutex);
|
---|
925 |
|
---|
926 | ptr->type = QNetworkConfiguration::InternetAccessPoint;
|
---|
927 | if (ptr->state == QNetworkConfiguration::Active) {
|
---|
928 | ptr->state = QNetworkConfiguration::Discovered;
|
---|
929 |
|
---|
930 | configLocker.unlock();
|
---|
931 | locker.unlock();
|
---|
932 | emit configurationChanged(ptr);
|
---|
933 | locker.relock();
|
---|
934 |
|
---|
935 | // Note: If ICD switches used IAP from one to another:
|
---|
936 | // 1) new IAP is reported to be online first
|
---|
937 | // 2) old IAP is reported to be offline then
|
---|
938 | // => Device can be reported to be offline only
|
---|
939 | // if last known online IAP is reported to be disconnected
|
---|
940 | if (iapid == m_onlineIapId) {
|
---|
941 | // It's known that there is only one global ICD connection
|
---|
942 | // => Because ICD state was reported to be DISCONNECTED, Device is offline
|
---|
943 | m_onlineIapId.clear();
|
---|
944 | }
|
---|
945 | }
|
---|
946 | } else {
|
---|
947 | // Disconnected IAP was not found from accessPointConfigurations
|
---|
948 | // => Reason: Online IAP was removed which resulted ICD to disconnect
|
---|
949 | if (iapid == m_onlineIapId) {
|
---|
950 | // It's known that there is only one global ICD connection
|
---|
951 | // => Because ICD state was reported to be DISCONNECTED, Device is offline
|
---|
952 | m_onlineIapId.clear();
|
---|
953 | }
|
---|
954 | }
|
---|
955 | break;
|
---|
956 | }
|
---|
957 | default:
|
---|
958 | break;
|
---|
959 | }
|
---|
960 |
|
---|
961 | locker.unlock();
|
---|
962 | emit iapStateChanged(iapid, icd_connection_state);
|
---|
963 | locker.relock();
|
---|
964 | }
|
---|
965 |
|
---|
966 | void QIcdEngine::icdServiceOwnerChanged(const QString &serviceName, const QString &oldOwner,
|
---|
967 | const QString &newOwner)
|
---|
968 | {
|
---|
969 | Q_UNUSED(serviceName);
|
---|
970 | Q_UNUSED(oldOwner);
|
---|
971 |
|
---|
972 | QMutexLocker locker(&mutex);
|
---|
973 |
|
---|
974 | if (newOwner.isEmpty()) {
|
---|
975 | // Disconnected from ICD, remove all configurations
|
---|
976 | cleanup();
|
---|
977 | delete iapMonitor;
|
---|
978 | iapMonitor = 0;
|
---|
979 | delete m_dbusInterface;
|
---|
980 | m_dbusInterface = 0;
|
---|
981 |
|
---|
982 | QMutableHashIterator<QString, QNetworkConfigurationPrivatePointer> i(accessPointConfigurations);
|
---|
983 | while (i.hasNext()) {
|
---|
984 | i.next();
|
---|
985 |
|
---|
986 | QNetworkConfigurationPrivatePointer ptr = i.value();
|
---|
987 | i.remove();
|
---|
988 |
|
---|
989 | locker.unlock();
|
---|
990 | emit configurationRemoved(ptr);
|
---|
991 | locker.relock();
|
---|
992 | }
|
---|
993 |
|
---|
994 | userChoiceConfigurations.clear();
|
---|
995 | } else {
|
---|
996 | // Connected to ICD ensure connection.
|
---|
997 | ensureDBusConnection();
|
---|
998 | }
|
---|
999 | }
|
---|
1000 |
|
---|
1001 | void QIcdEngine::requestUpdate()
|
---|
1002 | {
|
---|
1003 | QMutexLocker locker(&mutex);
|
---|
1004 |
|
---|
1005 | if (!ensureDBusConnection()) {
|
---|
1006 | locker.unlock();
|
---|
1007 | emit updateCompleted();
|
---|
1008 | locker.relock();
|
---|
1009 | return;
|
---|
1010 | }
|
---|
1011 |
|
---|
1012 | if (m_scanGoingOn)
|
---|
1013 | return;
|
---|
1014 |
|
---|
1015 | m_scanGoingOn = true;
|
---|
1016 |
|
---|
1017 | m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE,
|
---|
1018 | ICD_DBUS_API_PATH,
|
---|
1019 | ICD_DBUS_API_INTERFACE,
|
---|
1020 | ICD_DBUS_API_SCAN_SIG,
|
---|
1021 | this, SLOT(asyncUpdateConfigurationsSlot(QDBusMessage)));
|
---|
1022 |
|
---|
1023 | QDBusMessage msg = m_dbusInterface->call(ICD_DBUS_API_SCAN_REQ,
|
---|
1024 | (uint)ICD_SCAN_REQUEST_ACTIVE);
|
---|
1025 | m_typesToBeScanned = msg.arguments()[0].value<QStringList>();
|
---|
1026 | m_scanTimer.start(ICD_SHORT_SCAN_TIMEOUT);
|
---|
1027 | }
|
---|
1028 |
|
---|
1029 | void QIcdEngine::cancelAsyncConfigurationUpdate()
|
---|
1030 | {
|
---|
1031 | if (!ensureDBusConnection())
|
---|
1032 | return;
|
---|
1033 |
|
---|
1034 | if (!m_scanGoingOn)
|
---|
1035 | return;
|
---|
1036 |
|
---|
1037 | m_scanGoingOn = false;
|
---|
1038 |
|
---|
1039 | if (m_scanTimer.isActive())
|
---|
1040 | m_scanTimer.stop();
|
---|
1041 |
|
---|
1042 | m_dbusInterface->connection().disconnect(ICD_DBUS_API_INTERFACE,
|
---|
1043 | ICD_DBUS_API_PATH,
|
---|
1044 | ICD_DBUS_API_INTERFACE,
|
---|
1045 | ICD_DBUS_API_SCAN_SIG,
|
---|
1046 | this, SLOT(asyncUpdateConfigurationsSlot(QDBusMessage)));
|
---|
1047 |
|
---|
1048 | // Stop scanning rounds by calling ICD_DBUS_API_SCAN_CANCEL
|
---|
1049 | // <=> If ICD_DBUS_API_SCAN_CANCEL is not called, new scanning round will
|
---|
1050 | // be started after the module scan timeout.
|
---|
1051 | m_dbusInterface->call(ICD_DBUS_API_SCAN_CANCEL);
|
---|
1052 | }
|
---|
1053 |
|
---|
1054 | void QIcdEngine::finishAsyncConfigurationUpdate()
|
---|
1055 | {
|
---|
1056 | QMutexLocker locker(&mutex);
|
---|
1057 |
|
---|
1058 | cancelAsyncConfigurationUpdate();
|
---|
1059 | doRequestUpdate(m_scanResult);
|
---|
1060 | m_scanResult.clear();
|
---|
1061 | }
|
---|
1062 |
|
---|
1063 | void QIcdEngine::asyncUpdateConfigurationsSlot(QDBusMessage msg)
|
---|
1064 | {
|
---|
1065 | QMutexLocker locker(&mutex);
|
---|
1066 |
|
---|
1067 | QList<QVariant> arguments = msg.arguments();
|
---|
1068 | uint icd_scan_status = arguments.takeFirst().toUInt();
|
---|
1069 | if (icd_scan_status == ICD_SCAN_COMPLETE) {
|
---|
1070 | m_typesToBeScanned.removeOne(arguments[6].toString());
|
---|
1071 | if (!m_typesToBeScanned.count()) {
|
---|
1072 | locker.unlock();
|
---|
1073 | finishAsyncConfigurationUpdate();
|
---|
1074 | locker.relock();
|
---|
1075 | }
|
---|
1076 | } else {
|
---|
1077 | Maemo::IcdScanResult scanResult;
|
---|
1078 | scanResult.status = icd_scan_status;
|
---|
1079 | scanResult.timestamp = arguments.takeFirst().toUInt();
|
---|
1080 | scanResult.scan.service_type = arguments.takeFirst().toString();
|
---|
1081 | scanResult.service_name = arguments.takeFirst().toString();
|
---|
1082 | scanResult.scan.service_attrs = arguments.takeFirst().toUInt();
|
---|
1083 | scanResult.scan.service_id = arguments.takeFirst().toString();
|
---|
1084 | scanResult.service_priority = arguments.takeFirst().toInt();
|
---|
1085 | scanResult.scan.network_type = arguments.takeFirst().toString();
|
---|
1086 | scanResult.network_name = arguments.takeFirst().toString();
|
---|
1087 | scanResult.scan.network_attrs = arguments.takeFirst().toUInt();
|
---|
1088 | scanResult.scan.network_id = arguments.takeFirst().toByteArray();
|
---|
1089 | scanResult.network_priority = arguments.takeFirst().toInt();
|
---|
1090 | scanResult.signal_strength = arguments.takeFirst().toInt();
|
---|
1091 | scanResult.station_id = arguments.takeFirst().toString();
|
---|
1092 | scanResult.signal_dB = arguments.takeFirst().toInt();
|
---|
1093 |
|
---|
1094 | m_scanResult.append(scanResult);
|
---|
1095 | }
|
---|
1096 | }
|
---|
1097 |
|
---|
1098 | void QIcdEngine::cleanup()
|
---|
1099 | {
|
---|
1100 | if (m_scanGoingOn) {
|
---|
1101 | m_scanTimer.stop();
|
---|
1102 | m_dbusInterface->call(ICD_DBUS_API_SCAN_CANCEL);
|
---|
1103 | }
|
---|
1104 | if (iapMonitor)
|
---|
1105 | iapMonitor->cleanup();
|
---|
1106 | }
|
---|
1107 |
|
---|
1108 | bool QIcdEngine::hasIdentifier(const QString &id)
|
---|
1109 | {
|
---|
1110 | QMutexLocker locker(&mutex);
|
---|
1111 |
|
---|
1112 | return accessPointConfigurations.contains(id) ||
|
---|
1113 | snapConfigurations.contains(id) ||
|
---|
1114 | userChoiceConfigurations.contains(id);
|
---|
1115 | }
|
---|
1116 |
|
---|
1117 | QNetworkSessionPrivate *QIcdEngine::createSessionBackend()
|
---|
1118 | {
|
---|
1119 | return new QNetworkSessionPrivateImpl(this);
|
---|
1120 | }
|
---|
1121 |
|
---|
1122 | #include "qicdengine.moc"
|
---|
1123 |
|
---|
1124 | QT_END_NAMESPACE
|
---|
1125 |
|
---|
1126 | #endif // QT_NO_BEARERMANAGEMENT
|
---|