204 { |
204 { |
205 QString id = iap_id; |
205 QString id = iap_id; |
206 d->deleteConfiguration(id); |
206 d->deleteConfiguration(id); |
207 } |
207 } |
208 |
208 |
209 |
|
210 |
|
211 void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities() |
209 void QNetworkConfigurationManagerPrivate::registerPlatformCapabilities() |
212 { |
210 { |
213 capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces; |
211 capFlags |= QNetworkConfigurationManager::CanStartAndStopInterfaces; |
214 capFlags |= QNetworkConfigurationManager::DataStatistics; |
212 capFlags |= QNetworkConfigurationManager::DataStatistics; |
215 capFlags |= QNetworkConfigurationManager::ForcedRoaming; |
213 capFlags |= QNetworkConfigurationManager::ForcedRoaming; |
216 } |
214 capFlags |= QNetworkConfigurationManager::NetworkSessionRequired; |
217 |
215 } |
|
216 |
|
217 void QNetworkConfigurationManagerPrivate::init() |
|
218 { |
|
219 // Setup DBus Interface for ICD |
|
220 m_dbusInterface = new QDBusInterface(ICD_DBUS_API_INTERFACE, |
|
221 ICD_DBUS_API_PATH, |
|
222 ICD_DBUS_API_INTERFACE, |
|
223 QDBusConnection::systemBus(), |
|
224 this); |
|
225 connect(&m_scanTimer, SIGNAL(timeout()), this, SLOT(finishAsyncConfigurationUpdate())); |
|
226 m_scanTimer.setSingleShot(true); |
|
227 |
|
228 /* Turn on IAP state monitoring */ |
|
229 startListeningStateSignalsForAllConnections(); |
|
230 |
|
231 /* Turn on IAP add/remove monitoring */ |
|
232 iapMonitor()->setup(this); |
|
233 |
|
234 /* We create a default configuration which is a pseudo config */ |
|
235 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
236 cpPriv->name = "UserChoice"; |
|
237 cpPriv->state = QNetworkConfiguration::Discovered; |
|
238 cpPriv->isValid = true; |
|
239 cpPriv->id = OSSO_IAP_ANY; |
|
240 cpPriv->type = QNetworkConfiguration::UserChoice; |
|
241 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
242 cpPriv->roamingSupported = false; |
|
243 cpPriv->manager = this; |
|
244 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
245 userChoiceConfigurations.insert(cpPriv->id, ptr); |
|
246 } |
218 |
247 |
219 static inline QString network_attrs_to_security(uint network_attrs) |
248 static inline QString network_attrs_to_security(uint network_attrs) |
220 { |
249 { |
221 uint cap = 0; |
250 uint cap = 0; |
222 nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */ |
251 nwattr2cap(network_attrs, &cap); /* from libicd-network-wlan-dev.h */ |
318 } |
346 } |
319 |
347 |
320 |
348 |
321 void QNetworkConfigurationManagerPrivate::addConfiguration(QString& iap_id) |
349 void QNetworkConfigurationManagerPrivate::addConfiguration(QString& iap_id) |
322 { |
350 { |
|
351 // Note: When new IAP is created, this function gets called multiple times |
|
352 // in a row. |
|
353 // For example: Empty type & name for WLAN was stored into newly |
|
354 // created IAP data in gconf when this function gets |
|
355 // called for the first time. |
|
356 // WLAN type & name are updated into IAP data in gconf |
|
357 // as soon as WLAN connection is up and running. |
|
358 // => And this function gets called again. |
|
359 |
323 if (!accessPointConfigurations.contains(iap_id)) { |
360 if (!accessPointConfigurations.contains(iap_id)) { |
324 Maemo::IAPConf saved_iap(iap_id); |
361 Maemo::IAPConf saved_iap(iap_id); |
325 QString iap_type = saved_iap.value("type").toString(); |
362 QString iap_type = saved_iap.value("type").toString(); |
326 if (!iap_type.isEmpty()) { |
363 QString iap_name = saved_iap.value("name").toString(); |
327 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
364 QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); |
328 cpPriv->name = saved_iap.value("name").toString(); |
365 if (!iap_type.isEmpty() && !iap_name.isEmpty()) { |
329 if (cpPriv->name.isEmpty()) |
366 // Check if new IAP is actually Undefined WLAN configuration |
330 cpPriv->name = iap_id; |
367 // Note: SSID is used as an iap id for Undefined WLAN configurations |
331 cpPriv->isValid = true; |
368 // => configuration must be searched using SSID |
332 cpPriv->id = iap_id; |
369 if (!ssid.isEmpty() && accessPointConfigurations.contains(ssid)) { |
333 cpPriv->iap_type = iap_type; |
370 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = accessPointConfigurations.take(ssid); |
334 cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
371 if (ptr.data()) { |
335 cpPriv->service_id = saved_iap.value("service_id").toString(); |
372 QString iap_type = saved_iap.value("type").toString(); |
336 cpPriv->service_type = saved_iap.value("service_type").toString(); |
373 ptr->id = iap_id; |
337 if (iap_type.startsWith("WLAN")) { |
374 ptr->iap_type = iap_type; |
338 QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); |
375 ptr->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
339 if (ssid.isEmpty()) { |
376 ptr->network_id = ssid; |
340 qWarning() << "Cannot get ssid for" << iap_id; |
377 ptr->service_id = saved_iap.value("service_id").toString(); |
341 } |
378 ptr->service_type = saved_iap.value("service_type").toString(); |
342 } |
379 if (m_onlineIapId == iap_id) { |
343 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
380 ptr->state = QNetworkConfiguration::Active; |
344 cpPriv->state = QNetworkConfiguration::Defined; |
381 } else { |
345 |
382 ptr->state = QNetworkConfiguration::Defined; |
346 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
383 } |
347 accessPointConfigurations.insert(iap_id, ptr); |
384 accessPointConfigurations.insert(iap_id, ptr); |
348 |
385 configurationChanged(ptr.data()); |
349 #ifdef BEARER_MANAGEMENT_DEBUG |
386 } |
350 qDebug("IAP: %s, name: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data()); |
387 } else { |
351 #endif |
388 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
352 |
389 cpPriv->name = saved_iap.value("name").toString(); |
353 QNetworkConfiguration item; |
390 if (cpPriv->name.isEmpty()) |
354 item.d = ptr; |
391 cpPriv->name = iap_id; |
355 emit configurationAdded(item); |
392 cpPriv->isValid = true; |
356 configChanged(ptr.data(), true); |
393 cpPriv->id = iap_id; |
357 } else { |
394 cpPriv->iap_type = iap_type; |
358 qWarning("IAP %s does not have \"type\" field defined, skipping this IAP.", iap_id.toAscii().data()); |
395 cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
359 } |
396 cpPriv->service_id = saved_iap.value("service_id").toString(); |
|
397 cpPriv->service_type = saved_iap.value("service_type").toString(); |
|
398 if (iap_type.startsWith("WLAN")) { |
|
399 QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); |
|
400 if (ssid.isEmpty()) { |
|
401 qWarning() << "Cannot get ssid for" << iap_id; |
|
402 } |
|
403 cpPriv->network_id = ssid; |
|
404 } |
|
405 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
|
406 if (m_onlineIapId == iap_id) { |
|
407 cpPriv->state = QNetworkConfiguration::Active; |
|
408 } else { |
|
409 cpPriv->state = QNetworkConfiguration::Defined; |
|
410 } |
|
411 cpPriv->manager = this; |
|
412 |
|
413 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
414 accessPointConfigurations.insert(iap_id, ptr); |
|
415 |
|
416 #ifdef BEARER_MANAGEMENT_DEBUG |
|
417 qDebug("IAP: %s, name: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data()); |
|
418 #endif |
|
419 QNetworkConfiguration item; |
|
420 item.d = ptr; |
|
421 emit configurationAdded(item); |
|
422 } |
|
423 } else { |
|
424 qWarning("IAP %s does not have \"type\" or \"name\" fields defined, skipping this IAP.", iap_id.toAscii().data()); |
|
425 } |
360 } else { |
426 } else { |
361 #ifdef BEARER_MANAGEMENT_DEBUG |
427 #ifdef BEARER_MANAGEMENT_DEBUG |
362 qDebug() << "IAP" << iap_id << "already in db."; |
428 qDebug() << "IAP" << iap_id << "already in db."; |
363 #endif |
429 #endif |
364 |
430 |
365 /* Check if the data in db changed and update configuration accordingly |
431 /* Check if the data in db changed and update configuration accordingly |
366 */ |
432 */ |
367 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = accessPointConfigurations.take(iap_id); |
433 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = accessPointConfigurations.value(iap_id); |
368 if (ptr.data()) { |
434 if (ptr.data()) { |
369 Maemo::IAPConf changed_iap(iap_id); |
435 Maemo::IAPConf changed_iap(iap_id); |
370 QString iap_type = changed_iap.value("type").toString(); |
436 QString iap_type = changed_iap.value("type").toString(); |
371 bool update_needed = false; /* if IAP type or ssid changed, we need to change the state */ |
437 bool update_needed = false; /* if IAP type or ssid changed, we need to change the state */ |
372 |
438 |
381 ptr->isValid = true; |
447 ptr->isValid = true; |
382 if (ptr->iap_type != iap_type) { |
448 if (ptr->iap_type != iap_type) { |
383 ptr->iap_type = iap_type; |
449 ptr->iap_type = iap_type; |
384 update_needed = true; |
450 update_needed = true; |
385 } |
451 } |
386 if (iap_type.startsWith("WLAN")) { |
452 if (iap_type.startsWith(QLatin1String("WLAN"))) { |
387 QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray(); |
453 QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray(); |
388 if (ssid.isEmpty()) { |
454 if (ssid.isEmpty()) { |
389 qWarning() << "Cannot get ssid for" << iap_id; |
455 qWarning() << "Cannot get ssid for" << iap_id; |
390 } |
456 } |
391 if (ptr->network_id != ssid) { |
457 if (ptr->network_id != ssid) { |
392 ptr->network_id = ssid; |
458 ptr->network_id = ssid; |
393 update_needed = true; |
459 update_needed = true; |
394 } |
460 } |
395 } |
461 } |
396 } |
462 } |
397 accessPointConfigurations.insert(iap_id, ptr); |
|
398 if (update_needed) { |
463 if (update_needed) { |
399 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
464 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
400 if (ptr->state != QNetworkConfiguration::Defined) { |
465 if (m_onlineIapId == iap_id) { |
|
466 if (ptr->state < QNetworkConfiguration::Active) { |
|
467 ptr->state = QNetworkConfiguration::Active; |
|
468 configurationChanged(ptr.data()); |
|
469 } |
|
470 } else if (ptr->state < QNetworkConfiguration::Defined) { |
401 ptr->state = QNetworkConfiguration::Defined; |
471 ptr->state = QNetworkConfiguration::Defined; |
402 configurationChanged(ptr.data()); |
472 configurationChanged(ptr.data()); |
403 } |
473 } |
404 } |
474 } |
405 } else { |
475 } else { |
406 qWarning("Cannot find IAP %s from current configuration although it should be there.", iap_id.toAscii().data()); |
476 qWarning("Cannot find IAP %s from current configuration although it should be there.", iap_id.toAscii().data()); |
407 } |
477 } |
408 } |
478 } |
409 } |
479 } |
410 |
480 |
411 |
|
412 void QNetworkConfigurationManagerPrivate::updateConfigurations() |
481 void QNetworkConfigurationManagerPrivate::updateConfigurations() |
413 { |
482 { |
414 /* Contains known network id (like ssid) from storage */ |
483 doUpdateConfigurations(); |
415 QMultiHash<QByteArray, SSIDInfo* > knownConfigs; |
484 } |
416 |
485 |
417 /* All the scanned access points */ |
486 void QNetworkConfigurationManagerPrivate::doUpdateConfigurations(QList<Maemo::IcdScanResult> scanned) |
418 QList<Maemo::IcdScanResult> scanned; |
487 { |
419 |
488 /* Contains all known iap_ids from storage */ |
420 /* Turn on IAP monitoring */ |
489 QList<QString> knownConfigs = accessPointConfigurations.keys(); |
421 iapMonitor()->setup(this); |
490 |
422 |
491 /* Contains all known WLAN network ids (like ssid) from storage */ |
423 if (firstUpdate) { |
492 QMultiHash<QByteArray, SSIDInfo* > notDiscoveredWLANConfigs; |
424 /* We create a default configuration which is a pseudo config */ |
493 |
425 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
|
426 cpPriv->name = "UserChoice"; |
|
427 cpPriv->state = QNetworkConfiguration::Discovered; |
|
428 cpPriv->isValid = true; |
|
429 cpPriv->id = OSSO_IAP_ANY; |
|
430 cpPriv->type = QNetworkConfiguration::UserChoice; |
|
431 cpPriv->purpose = QNetworkConfiguration::UnknownPurpose; |
|
432 cpPriv->roamingSupported = false; |
|
433 cpPriv->manager = this; |
|
434 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
|
435 userChoiceConfigurations.insert(cpPriv->id, ptr); |
|
436 } |
|
437 |
|
438 /* We return currently configured IAPs in the first run and do the WLAN |
|
439 * scan in subsequent runs. |
|
440 */ |
|
441 QList<QString> all_iaps; |
494 QList<QString> all_iaps; |
442 Maemo::IAPConf::getAll(all_iaps); |
495 Maemo::IAPConf::getAll(all_iaps); |
443 |
496 |
444 foreach (QString iap_id, all_iaps) { |
497 foreach (const QString &iap_id, all_iaps) { |
445 QByteArray ssid; |
498 QByteArray ssid; |
446 |
499 |
447 Maemo::IAPConf saved_ap(iap_id); |
500 Maemo::IAPConf saved_ap(iap_id); |
448 bool is_temporary = saved_ap.value("temporary").toBool(); |
501 bool is_temporary = saved_ap.value("temporary").toBool(); |
449 if (is_temporary) { |
502 if (is_temporary) { |
450 #ifdef BEARER_MANAGEMENT_DEBUG |
503 #ifdef BEARER_MANAGEMENT_DEBUG |
451 qDebug() << "IAP" << iap_id << "is temporary, skipping it."; |
504 qDebug() << "IAP" << iap_id << "is temporary, skipping it."; |
452 #endif |
505 #endif |
453 continue; |
506 continue; |
454 } |
507 } |
455 |
508 |
456 QString iap_type = saved_ap.value("type").toString(); |
509 QString iap_type = saved_ap.value("type").toString(); |
457 if (iap_type.startsWith("WLAN")) { |
510 if (iap_type.startsWith(QLatin1String("WLAN"))) { |
458 ssid = saved_ap.value("wlan_ssid").toByteArray(); |
511 ssid = saved_ap.value("wlan_ssid").toByteArray(); |
459 if (ssid.isEmpty()) { |
512 if (ssid.isEmpty()) { |
460 qWarning() << "Cannot get ssid for" << iap_id; |
513 qWarning() << "Cannot get ssid for" << iap_id; |
461 continue; |
514 continue; |
462 } |
515 } |
463 |
516 |
464 QString security_method = saved_ap.value("wlan_security").toString(); |
517 QString security_method = saved_ap.value("wlan_security").toString(); |
465 SSIDInfo *info = new SSIDInfo; |
518 SSIDInfo *info = new SSIDInfo; |
466 info->iap_id = iap_id; |
519 info->iap_id = iap_id; |
467 info->wlan_security = security_method; |
520 info->wlan_security = security_method; |
468 knownConfigs.insert(ssid, info); |
521 notDiscoveredWLANConfigs.insert(ssid, info); |
469 } else if (iap_type.isEmpty()) { |
522 } else if (iap_type.isEmpty()) { |
470 qWarning() << "IAP" << iap_id << "network type is not set! Skipping it"; |
523 qWarning() << "IAP" << iap_id << "network type is not set! Skipping it"; |
471 continue; |
524 continue; |
472 } else { |
525 } else { |
473 #ifdef BEARER_MANAGEMENT_DEBUG |
526 #ifdef BEARER_MANAGEMENT_DEBUG |
501 |
554 |
502 #ifdef BEARER_MANAGEMENT_DEBUG |
555 #ifdef BEARER_MANAGEMENT_DEBUG |
503 qDebug("IAP: %s, name: %s, ssid: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); |
556 qDebug("IAP: %s, name: %s, ssid: %s, added to known list", iap_id.toAscii().data(), cpPriv->name.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); |
504 #endif |
557 #endif |
505 } else { |
558 } else { |
|
559 knownConfigs.removeOne(iap_id); |
506 #ifdef BEARER_MANAGEMENT_DEBUG |
560 #ifdef BEARER_MANAGEMENT_DEBUG |
507 qDebug("IAP: %s, ssid: %s, already exists in the known list", iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); |
561 qDebug("IAP: %s, ssid: %s, already exists in the known list", iap_id.toAscii().data(), !ssid.isEmpty() ? ssid.data() : "-"); |
508 #endif |
562 #endif |
509 } |
563 } |
510 } |
564 } |
511 |
|
512 if (!firstUpdate) { |
|
513 QStringList scannedNetworkTypes; |
|
514 QStringList networkTypesToScan; |
|
515 QString error; |
|
516 Maemo::Icd icd(ICD_SHORT_SCAN_TIMEOUT); |
|
517 |
|
518 scannedNetworkTypes = icd.scan(ICD_SCAN_REQUEST_ACTIVE, |
|
519 networkTypesToScan, |
|
520 scanned, |
|
521 error); |
|
522 if (!error.isEmpty()) { |
|
523 qWarning() << "Network scanning failed" << error; |
|
524 } else { |
|
525 #ifdef BEARER_MANAGEMENT_DEBUG |
|
526 if (!scanned.isEmpty()) |
|
527 qDebug() << "Scan returned" << scanned.size() << "networks"; |
|
528 else |
|
529 qDebug() << "Scan returned nothing."; |
|
530 #endif |
|
531 } |
|
532 } |
|
533 |
|
534 |
565 |
535 /* This is skipped in the first update as scanned size is zero */ |
566 /* This is skipped in the first update as scanned size is zero */ |
536 if (!scanned.isEmpty()) |
567 if (!scanned.isEmpty()) |
537 for (int i=0; i<scanned.size(); ++i) { |
568 for (int i=0; i<scanned.size(); ++i) { |
538 const Maemo::IcdScanResult ap = scanned.at(i); |
569 const Maemo::IcdScanResult ap = scanned.at(i); |
539 |
570 |
540 if (ap.scan.network_attrs & ICD_NW_ATTR_IAPNAME) { |
571 if (ap.scan.network_attrs & ICD_NW_ATTR_IAPNAME) { |
541 /* The network_id is IAP id, so the IAP is a known one */ |
572 /* The network_id is IAP id, so the IAP is a known one */ |
542 QString iapid = ap.scan.network_id.data(); |
573 QString iapid = ap.scan.network_id.data(); |
543 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(iapid); |
574 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iapid); |
544 if (priv.data()) { |
575 if (priv.data()) { |
545 priv->state = QNetworkConfiguration::Discovered; /* Defined is set automagically */ |
576 bool stateChanged = false; |
|
577 // Check if state is not already Discovered or Active |
|
578 if (priv->state < QNetworkConfiguration::Discovered) { |
|
579 priv->state = QNetworkConfiguration::Discovered; /* Defined is set automagically */ |
|
580 stateChanged = true; |
|
581 } |
546 priv->network_attrs = ap.scan.network_attrs; |
582 priv->network_attrs = ap.scan.network_attrs; |
547 priv->service_id = ap.scan.service_id; |
583 priv->service_id = ap.scan.service_id; |
548 priv->service_type = ap.scan.service_type; |
584 priv->service_type = ap.scan.service_type; |
549 priv->service_attrs = ap.scan.service_attrs; |
585 priv->service_attrs = ap.scan.service_attrs; |
550 |
586 |
551 configurationChanged(priv.data()); |
587 if (stateChanged) { |
552 accessPointConfigurations.insert(iapid, priv); |
588 configurationChanged(priv.data()); |
|
589 } |
553 #ifdef BEARER_MANAGEMENT_DEBUG |
590 #ifdef BEARER_MANAGEMENT_DEBUG |
554 qDebug("IAP: %s, ssid: %s, discovered", iapid.toAscii().data(), priv->network_id.data()); |
591 qDebug("IAP: %s, ssid: %s, discovered", iapid.toAscii().data(), priv->network_id.data()); |
555 #endif |
592 #endif |
556 |
593 |
557 if (!ap.scan.network_type.startsWith("WLAN")) |
594 if (!ap.scan.network_type.startsWith(QLatin1String("WLAN"))) |
558 continue; // not a wlan AP |
595 continue; // not a wlan AP |
559 |
596 |
560 /* Remove scanned AP from known configurations so that we can |
597 /* Remove scanned AP from discovered WLAN configurations so that we can |
561 * emit configurationRemoved signal later |
598 * emit configurationRemoved signal later |
562 */ |
599 */ |
563 QList<SSIDInfo* > known_iaps = knownConfigs.values(priv->network_id); |
600 QList<SSIDInfo* > known_iaps = notDiscoveredWLANConfigs.values(priv->network_id); |
564 rescan_list: |
601 rescan_list: |
565 if (!known_iaps.isEmpty()) { |
602 if (!known_iaps.isEmpty()) { |
566 for (int k=0; k<known_iaps.size(); ++k) { |
603 for (int k=0; k<known_iaps.size(); ++k) { |
567 SSIDInfo *iap = known_iaps.at(k); |
604 SSIDInfo *iap = known_iaps.at(k); |
568 |
605 |
586 } else { |
623 } else { |
587 qWarning() << "IAP" << iapid << "is missing in configuration."; |
624 qWarning() << "IAP" << iapid << "is missing in configuration."; |
588 } |
625 } |
589 |
626 |
590 } else { |
627 } else { |
591 /* Non saved access point data */ |
628 /* Non saved access point data */ |
592 QByteArray scanned_ssid = ap.scan.network_id; |
629 QByteArray scanned_ssid = ap.scan.network_id; |
593 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
630 if (!accessPointConfigurations.contains(scanned_ssid)) { |
594 QString hrs = scanned_ssid.data(); |
631 QNetworkConfigurationPrivate* cpPriv = new QNetworkConfigurationPrivate(); |
595 |
632 QString hrs = scanned_ssid.data(); |
596 cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; |
633 |
597 cpPriv->isValid = true; |
634 cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; |
598 cpPriv->id = scanned_ssid.data(); // Note: id is now ssid, it should be set to IAP id if the IAP is saved |
635 cpPriv->isValid = true; |
599 cpPriv->network_id = scanned_ssid; |
636 cpPriv->id = scanned_ssid.data(); // Note: id is now ssid, it should be set to IAP id if the IAP is saved |
600 cpPriv->iap_type = ap.scan.network_type; |
637 cpPriv->network_id = scanned_ssid; |
601 cpPriv->network_attrs = ap.scan.network_attrs; |
638 cpPriv->iap_type = ap.scan.network_type; |
602 cpPriv->service_id = ap.scan.service_id; |
639 cpPriv->network_attrs = ap.scan.network_attrs; |
603 cpPriv->service_type = ap.scan.service_type; |
640 cpPriv->service_id = ap.scan.service_id; |
604 cpPriv->service_attrs = ap.scan.service_attrs; |
641 cpPriv->service_type = ap.scan.service_type; |
605 cpPriv->manager = this; |
642 cpPriv->service_attrs = ap.scan.service_attrs; |
606 |
643 cpPriv->manager = this; |
607 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
644 |
608 cpPriv->state = QNetworkConfiguration::Undefined; |
645 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
609 |
646 cpPriv->state = QNetworkConfiguration::Undefined; |
610 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
647 |
611 accessPointConfigurations.insert(cpPriv->id, ptr); |
648 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr(cpPriv); |
612 |
649 accessPointConfigurations.insert(cpPriv->id, ptr); |
613 #ifdef BEARER_MANAGEMENT_DEBUG |
650 |
614 qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan."; |
651 #ifdef BEARER_MANAGEMENT_DEBUG |
615 #endif |
652 qDebug() << "IAP with network id" << cpPriv->id << "was found in the scan."; |
616 |
653 #endif |
617 QNetworkConfiguration item; |
654 |
618 item.d = ptr; |
655 QNetworkConfiguration item; |
619 emit configurationAdded(item); |
656 item.d = ptr; |
620 } |
657 emit configurationAdded(item); |
621 } |
658 } else { |
622 |
659 knownConfigs.removeOne(scanned_ssid); |
623 |
660 } |
624 /* Remove non existing iaps since last update */ |
661 } |
|
662 } |
|
663 |
625 if (!firstUpdate) { |
664 if (!firstUpdate) { |
626 QHashIterator<QByteArray, SSIDInfo* > i(knownConfigs); |
665 // Update Defined status to all defined WLAN IAPs which |
|
666 // could not be found when access points were scanned |
|
667 QHashIterator<QByteArray, SSIDInfo* > i(notDiscoveredWLANConfigs); |
627 while (i.hasNext()) { |
668 while (i.hasNext()) { |
628 i.next(); |
669 i.next(); |
629 SSIDInfo *iap = i.value(); |
670 SSIDInfo *iap = i.value(); |
630 QString iap_id = iap->iap_id; |
671 QString iap_id = iap->iap_id; |
631 //qDebug() << i.key() << ": " << iap_id; |
672 //qDebug() << i.key() << ": " << iap_id; |
632 |
673 |
633 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(iap_id); |
674 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.value(iap_id); |
634 if (priv.data()) { |
675 if (priv.data()) { |
635 priv->isValid = false; |
676 // WLAN AccessPoint configuration could not be Discovered |
636 #ifdef BEARER_MANAGEMENT_DEBUG |
677 // => Make sure that configuration state is Defined |
637 qDebug() << "IAP" << iap_id << "was removed as it was not found in scan."; |
678 if (priv->state > QNetworkConfiguration::Defined) { |
638 #endif |
679 priv->state = QNetworkConfiguration::Defined; |
639 |
680 configurationChanged(priv.data()); |
640 QNetworkConfiguration item; |
681 } |
641 item.d = priv; |
682 } |
642 emit configurationRemoved(item); |
683 } |
643 configChanged(priv.data(), false); |
684 |
644 |
685 /* Remove non existing iaps since last update */ |
|
686 foreach (QString oldIface, knownConfigs) { |
|
687 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> priv = accessPointConfigurations.take(oldIface); |
|
688 if (priv.data()) { |
|
689 priv->isValid = false; |
|
690 QNetworkConfiguration item; |
|
691 item.d = priv; |
|
692 emit configurationRemoved(item); |
645 //if we would have SNAP support we would have to remove the references |
693 //if we would have SNAP support we would have to remove the references |
646 //from existing ServiceNetworks to the removed access point configuration |
694 //from existing ServiceNetworks to the removed access point configuration |
647 } |
695 } |
648 } |
696 } |
649 } |
697 } |
650 |
698 |
651 |
699 QMutableHashIterator<QByteArray, SSIDInfo* > i(notDiscoveredWLANConfigs); |
652 QMutableHashIterator<QByteArray, SSIDInfo* > i(knownConfigs); |
|
653 while (i.hasNext()) { |
700 while (i.hasNext()) { |
654 i.next(); |
701 i.next(); |
655 SSIDInfo *iap = i.value(); |
702 SSIDInfo *iap = i.value(); |
656 delete iap; |
703 delete iap; |
657 i.remove(); |
704 i.remove(); |
674 if (userChoiceConfigurations.contains(OSSO_IAP_ANY)) |
720 if (userChoiceConfigurations.contains(OSSO_IAP_ANY)) |
675 item.d = userChoiceConfigurations.value(OSSO_IAP_ANY); |
721 item.d = userChoiceConfigurations.value(OSSO_IAP_ANY); |
676 return item; |
722 return item; |
677 } |
723 } |
678 |
724 |
|
725 void QNetworkConfigurationManagerPrivate::startListeningStateSignalsForAllConnections() |
|
726 { |
|
727 // Start listening ICD_DBUS_API_STATE_SIG signals |
|
728 m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, |
|
729 ICD_DBUS_API_PATH, |
|
730 ICD_DBUS_API_INTERFACE, |
|
731 ICD_DBUS_API_STATE_SIG, |
|
732 this, SLOT(connectionStateSignalsSlot(QDBusMessage))); |
|
733 |
|
734 // Calling ICD_DBUS_API_STATE_REQ makes sure that initial state will be updated immediately |
|
735 m_gettingInitialConnectionState = true; |
|
736 m_dbusInterface->call(ICD_DBUS_API_STATE_REQ); |
|
737 } |
|
738 |
|
739 void QNetworkConfigurationManagerPrivate::connectionStateSignalsSlot(QDBusMessage msg) |
|
740 { |
|
741 QList<QVariant> arguments = msg.arguments(); |
|
742 if (arguments[1].toUInt() != 0 || arguments.count() < 8) { |
|
743 return; |
|
744 } |
|
745 |
|
746 QString iapid = arguments[5].toByteArray().data(); |
|
747 uint icd_connection_state = arguments[7].toUInt(); |
|
748 |
|
749 switch (icd_connection_state) { |
|
750 case ICD_STATE_CONNECTED: |
|
751 { |
|
752 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = accessPointConfigurations.value(iapid); |
|
753 if (ptr.data()) { |
|
754 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
|
755 if (ptr->state != QNetworkConfiguration::Active) { |
|
756 ptr->state = QNetworkConfiguration::Active; |
|
757 if (!m_gettingInitialConnectionState) { |
|
758 configurationChanged(ptr.data()); |
|
759 if (m_onlineIapId.isEmpty()) { |
|
760 emit onlineStateChanged(true); |
|
761 } |
|
762 } |
|
763 m_onlineIapId = iapid; |
|
764 } |
|
765 } else { |
|
766 // This gets called when new WLAN IAP is created using Connection dialog |
|
767 // At this point Undefined WLAN configuration has SSID as iap id |
|
768 // => Because of that configuration can not be found from |
|
769 // accessPointConfigurations using correct iap id |
|
770 emit onlineStateChanged(true); |
|
771 m_onlineIapId = iapid; |
|
772 } |
|
773 break; |
|
774 } |
|
775 case ICD_STATE_DISCONNECTED: |
|
776 { |
|
777 QExplicitlySharedDataPointer<QNetworkConfigurationPrivate> ptr = accessPointConfigurations.value(iapid); |
|
778 if (ptr.data()) { |
|
779 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
|
780 if (ptr->state == QNetworkConfiguration::Active) { |
|
781 ptr->state = QNetworkConfiguration::Discovered; |
|
782 if (!m_gettingInitialConnectionState) { |
|
783 configurationChanged(ptr.data()); |
|
784 |
|
785 // Note: If ICD switches used IAP from one to another: |
|
786 // 1) new IAP is reported to be online first |
|
787 // 2) old IAP is reported to be offline then |
|
788 // => Device can be reported to be offline only |
|
789 // if last known online IAP is reported to be disconnected |
|
790 if (iapid == m_onlineIapId) { |
|
791 // It's known that there is only one global ICD connection |
|
792 // => Because ICD state was reported to be DISCONNECTED, Device is offline |
|
793 m_onlineIapId = QString(); |
|
794 emit onlineStateChanged(false); |
|
795 } |
|
796 } |
|
797 } |
|
798 } else { |
|
799 // Disconnected IAP was not found from accessPointConfigurations |
|
800 // => Reason: Online IAP was removed which resulted ICD to disconnect |
|
801 if (iapid == m_onlineIapId) { |
|
802 // It's known that there is only one global ICD connection |
|
803 // => Because ICD state was reported to be DISCONNECTED, Device is offline |
|
804 m_onlineIapId = QString(); |
|
805 emit onlineStateChanged(false); |
|
806 } |
|
807 } |
|
808 break; |
|
809 } |
|
810 default: |
|
811 break; |
|
812 } |
|
813 |
|
814 emit iapStateChanged(iapid, icd_connection_state); |
|
815 |
|
816 m_gettingInitialConnectionState = false; |
|
817 } |
679 |
818 |
680 void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() |
819 void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() |
681 { |
820 { |
682 QTimer::singleShot(0, this, SLOT(updateConfigurations())); |
821 if (m_scanGoingOn) { |
683 } |
822 return; |
684 |
823 } |
|
824 m_scanGoingOn = true; |
|
825 |
|
826 m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, |
|
827 ICD_DBUS_API_PATH, |
|
828 ICD_DBUS_API_INTERFACE, |
|
829 ICD_DBUS_API_SCAN_SIG, |
|
830 this, SLOT(asyncUpdateConfigurationsSlot(QDBusMessage))); |
|
831 |
|
832 QDBusMessage msg = m_dbusInterface->call(ICD_DBUS_API_SCAN_REQ, |
|
833 (uint)ICD_SCAN_REQUEST_ACTIVE); |
|
834 m_typesToBeScanned = msg.arguments()[0].value<QStringList>(); |
|
835 m_scanTimer.start(ICD_SHORT_SCAN_TIMEOUT); |
|
836 } |
|
837 |
|
838 void QNetworkConfigurationManagerPrivate::cancelAsyncConfigurationUpdate() |
|
839 { |
|
840 if (!m_scanGoingOn) { |
|
841 return; |
|
842 } |
|
843 m_scanGoingOn = false; |
|
844 |
|
845 if (m_scanTimer.isActive()) { |
|
846 m_scanTimer.stop(); |
|
847 } |
|
848 |
|
849 m_dbusInterface->connection().disconnect(ICD_DBUS_API_INTERFACE, |
|
850 ICD_DBUS_API_PATH, |
|
851 ICD_DBUS_API_INTERFACE, |
|
852 ICD_DBUS_API_SCAN_SIG, |
|
853 this, SLOT(asyncUpdateConfigurationsSlot(QDBusMessage))); |
|
854 |
|
855 // Stop scanning rounds by calling ICD_DBUS_API_SCAN_CANCEL |
|
856 // <=> If ICD_DBUS_API_SCAN_CANCEL is not called, new scanning round will |
|
857 // be started after the module scan timeout. |
|
858 m_dbusInterface->call(ICD_DBUS_API_SCAN_CANCEL); |
|
859 } |
|
860 |
|
861 void QNetworkConfigurationManagerPrivate::finishAsyncConfigurationUpdate() |
|
862 { |
|
863 cancelAsyncConfigurationUpdate(); |
|
864 doUpdateConfigurations(m_scanResult); |
|
865 m_scanResult.clear(); |
|
866 } |
|
867 |
|
868 void QNetworkConfigurationManagerPrivate::asyncUpdateConfigurationsSlot(QDBusMessage msg) |
|
869 { |
|
870 QList<QVariant> arguments = msg.arguments(); |
|
871 uint icd_scan_status = arguments.takeFirst().toUInt(); |
|
872 if (icd_scan_status == ICD_SCAN_COMPLETE) { |
|
873 m_typesToBeScanned.removeOne(arguments[6].toString()); |
|
874 if (!m_typesToBeScanned.count()) { |
|
875 finishAsyncConfigurationUpdate(); |
|
876 } |
|
877 } else { |
|
878 Maemo::IcdScanResult scanResult; |
|
879 scanResult.status = icd_scan_status; |
|
880 scanResult.timestamp = arguments.takeFirst().toUInt(); |
|
881 scanResult.scan.service_type = arguments.takeFirst().toString(); |
|
882 scanResult.service_name = arguments.takeFirst().toString(); |
|
883 scanResult.scan.service_attrs = arguments.takeFirst().toUInt(); |
|
884 scanResult.scan.service_id = arguments.takeFirst().toString(); |
|
885 scanResult.service_priority = arguments.takeFirst().toInt(); |
|
886 scanResult.scan.network_type = arguments.takeFirst().toString(); |
|
887 scanResult.network_name = arguments.takeFirst().toString(); |
|
888 scanResult.scan.network_attrs = arguments.takeFirst().toUInt(); |
|
889 scanResult.scan.network_id = arguments.takeFirst().toByteArray(); |
|
890 scanResult.network_priority = arguments.takeFirst().toInt(); |
|
891 scanResult.signal_strength = arguments.takeFirst().toInt(); |
|
892 scanResult.station_id = arguments.takeFirst().toString(); |
|
893 scanResult.signal_dB = arguments.takeFirst().toInt(); |
|
894 |
|
895 m_scanResult.append(scanResult); |
|
896 } |
|
897 } |
685 |
898 |
686 void QNetworkConfigurationManagerPrivate::cleanup() |
899 void QNetworkConfigurationManagerPrivate::cleanup() |
687 { |
900 { |
|
901 if (m_scanGoingOn) { |
|
902 m_scanTimer.stop(); |
|
903 m_dbusInterface->call(ICD_DBUS_API_SCAN_CANCEL); |
|
904 } |
688 iapMonitor()->cleanup(); |
905 iapMonitor()->cleanup(); |
689 } |
906 } |
690 |
|
691 |
|
692 void QNetworkConfigurationManagerPrivate::configChanged(QNetworkConfigurationPrivate *ptr, bool added) |
|
693 { |
|
694 if (added) { |
|
695 if (ptr && ptr->state == QNetworkConfiguration::Active) { |
|
696 onlineConfigurations++; |
|
697 if (!firstUpdate && onlineConfigurations == 1) |
|
698 emit onlineStateChanged(true); |
|
699 } |
|
700 } else { |
|
701 if (ptr && ptr->state == QNetworkConfiguration::Active) { |
|
702 onlineConfigurations--; |
|
703 if (!firstUpdate && onlineConfigurations == 0) |
|
704 emit onlineStateChanged(false); |
|
705 if (onlineConfigurations < 0) |
|
706 onlineConfigurations = 0; |
|
707 } |
|
708 } |
|
709 } |
|
710 |
|
711 |
907 |
712 #include "qnetworkconfigmanager_maemo.moc" |
908 #include "qnetworkconfigmanager_maemo.moc" |
713 #include "moc_qnetworkconfigmanager_maemo_p.cpp" |
909 #include "moc_qnetworkconfigmanager_maemo_p.cpp" |
714 |
910 |
715 QTM_END_NAMESPACE |
911 QTM_END_NAMESPACE |