58 |
58 |
59 IcdNetworkConfigurationPrivate::~IcdNetworkConfigurationPrivate() |
59 IcdNetworkConfigurationPrivate::~IcdNetworkConfigurationPrivate() |
60 { |
60 { |
61 } |
61 } |
62 |
62 |
63 QString IcdNetworkConfigurationPrivate::bearerName() const |
63 QString IcdNetworkConfigurationPrivate::bearerTypeName() const |
64 { |
64 { |
65 if (iap_type == QLatin1String("WLAN_INFRA") || |
65 QMutexLocker locker(&mutex); |
66 iap_type == QLatin1String("WLAN_ADHOC")) { |
66 |
67 return QLatin1String("WLAN"); |
67 return iap_type; |
68 } else if (iap_type == QLatin1String("GPRS")) { |
|
69 return QLatin1String("HSPA"); |
|
70 } else { |
|
71 return iap_type; |
|
72 } |
|
73 } |
68 } |
74 |
69 |
75 /* The IapAddTimer is a helper class that makes sure we update |
70 /* The IapAddTimer is a helper class that makes sure we update |
76 * the configuration only after all db additions to certain |
71 * the configuration only after all db additions to certain |
77 * iap are finished (after a certain timeout) |
72 * iap are finished (after a certain timeout) |
220 QString id = iap_id; |
215 QString id = iap_id; |
221 d->deleteConfiguration(id); |
216 d->deleteConfiguration(id); |
222 } |
217 } |
223 |
218 |
224 QIcdEngine::QIcdEngine(QObject *parent) |
219 QIcdEngine::QIcdEngine(QObject *parent) |
225 : QBearerEngine(parent), iapMonitor(new IapMonitor), m_dbusInterface(0), |
220 : QBearerEngine(parent), iapMonitor(0), m_dbusInterface(0), |
226 firstUpdate(true), m_scanGoingOn(false) |
221 firstUpdate(true), m_scanGoingOn(false) |
227 { |
222 { |
228 } |
223 } |
229 |
224 |
230 QIcdEngine::~QIcdEngine() |
225 QIcdEngine::~QIcdEngine() |
261 |
256 |
262 /* Turn on IAP state monitoring */ |
257 /* Turn on IAP state monitoring */ |
263 startListeningStateSignalsForAllConnections(); |
258 startListeningStateSignalsForAllConnections(); |
264 |
259 |
265 /* Turn on IAP add/remove monitoring */ |
260 /* Turn on IAP add/remove monitoring */ |
|
261 iapMonitor = new IapMonitor; |
266 iapMonitor->setup(this); |
262 iapMonitor->setup(this); |
267 |
263 |
268 /* We create a default configuration which is a pseudo config */ |
264 /* We create a default configuration which is a pseudo config */ |
269 QNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; |
265 QNetworkConfigurationPrivate *cpPriv = new IcdNetworkConfigurationPrivate; |
270 cpPriv->name = "UserChoice"; |
266 cpPriv->name = "UserChoice"; |
398 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(ssid); |
396 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(ssid); |
399 if (ptr) { |
397 if (ptr) { |
400 ptr->mutex.lock(); |
398 ptr->mutex.lock(); |
401 ptr->id = iap_id; |
399 ptr->id = iap_id; |
402 toIcdConfig(ptr)->iap_type = iap_type; |
400 toIcdConfig(ptr)->iap_type = iap_type; |
|
401 ptr->bearerType = bearerTypeFromIapType(iap_type); |
403 toIcdConfig(ptr)->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
402 toIcdConfig(ptr)->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
404 toIcdConfig(ptr)->network_id = ssid; |
403 toIcdConfig(ptr)->network_id = ssid; |
405 toIcdConfig(ptr)->service_id = saved_iap.value("service_id").toString(); |
404 toIcdConfig(ptr)->service_id = saved_iap.value("service_id").toString(); |
406 toIcdConfig(ptr)->service_type = saved_iap.value("service_type").toString(); |
405 toIcdConfig(ptr)->service_type = saved_iap.value("service_type").toString(); |
407 if (m_onlineIapId == iap_id) { |
406 if (m_onlineIapId == iap_id) { |
422 if (cpPriv->name.isEmpty()) |
421 if (cpPriv->name.isEmpty()) |
423 cpPriv->name = iap_id; |
422 cpPriv->name = iap_id; |
424 cpPriv->isValid = true; |
423 cpPriv->isValid = true; |
425 cpPriv->id = iap_id; |
424 cpPriv->id = iap_id; |
426 cpPriv->iap_type = iap_type; |
425 cpPriv->iap_type = iap_type; |
|
426 cpPriv->bearerType = bearerTypeFromIapType(iap_type); |
427 cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
427 cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
428 cpPriv->service_id = saved_iap.value("service_id").toString(); |
428 cpPriv->service_id = saved_iap.value("service_id").toString(); |
429 cpPriv->service_type = saved_iap.value("service_type").toString(); |
429 cpPriv->service_type = saved_iap.value("service_type").toString(); |
430 if (iap_type.startsWith(QLatin1String("WLAN"))) { |
430 if (iap_type.startsWith(QLatin1String("WLAN"))) { |
431 QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); |
431 QByteArray ssid = saved_iap.value("wlan_ssid").toByteArray(); |
478 if (ptr->name.isEmpty()) |
478 if (ptr->name.isEmpty()) |
479 ptr->name = iap_id; |
479 ptr->name = iap_id; |
480 ptr->isValid = true; |
480 ptr->isValid = true; |
481 if (toIcdConfig(ptr)->iap_type != iap_type) { |
481 if (toIcdConfig(ptr)->iap_type != iap_type) { |
482 toIcdConfig(ptr)->iap_type = iap_type; |
482 toIcdConfig(ptr)->iap_type = iap_type; |
|
483 ptr->bearerType = bearerTypeFromIapType(iap_type); |
483 update_needed = true; |
484 update_needed = true; |
484 } |
485 } |
485 if (iap_type.startsWith(QLatin1String("WLAN"))) { |
486 if (iap_type.startsWith(QLatin1String("WLAN"))) { |
486 QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray(); |
487 QByteArray ssid = changed_iap.value("wlan_ssid").toByteArray(); |
487 if (ssid.isEmpty()) { |
488 if (ssid.isEmpty()) { |
520 } |
521 } |
521 } |
522 } |
522 |
523 |
523 void QIcdEngine::doRequestUpdate(QList<Maemo::IcdScanResult> scanned) |
524 void QIcdEngine::doRequestUpdate(QList<Maemo::IcdScanResult> scanned) |
524 { |
525 { |
525 QMutexLocker locker(&mutex); |
|
526 |
|
527 /* Contains all known iap_ids from storage */ |
526 /* Contains all known iap_ids from storage */ |
528 QList<QString> knownConfigs = accessPointConfigurations.keys(); |
527 QList<QString> knownConfigs = accessPointConfigurations.keys(); |
529 |
528 |
530 /* Contains all known WLAN network ids (like ssid) from storage */ |
529 /* Contains all known WLAN network ids (like ssid) from storage */ |
531 QMultiHash<QByteArray, SSIDInfo* > notDiscoveredWLANConfigs; |
530 QMultiHash<QByteArray, SSIDInfo* > notDiscoveredWLANConfigs; |
578 cpPriv->isValid = true; |
577 cpPriv->isValid = true; |
579 cpPriv->id = iap_id; |
578 cpPriv->id = iap_id; |
580 cpPriv->network_id = ssid; |
579 cpPriv->network_id = ssid; |
581 cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
580 cpPriv->network_attrs = getNetworkAttrs(true, iap_id, iap_type, QString()); |
582 cpPriv->iap_type = iap_type; |
581 cpPriv->iap_type = iap_type; |
|
582 cpPriv->bearerType = bearerTypeFromIapType(iap_type); |
583 cpPriv->service_id = saved_ap.value("service_id").toString(); |
583 cpPriv->service_id = saved_ap.value("service_id").toString(); |
584 cpPriv->service_type = saved_ap.value("service_type").toString(); |
584 cpPriv->service_type = saved_ap.value("service_type").toString(); |
585 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
585 cpPriv->type = QNetworkConfiguration::InternetAccessPoint; |
586 cpPriv->state = QNetworkConfiguration::Defined; |
586 cpPriv->state = QNetworkConfiguration::Defined; |
587 |
587 |
588 QNetworkConfigurationPrivatePointer ptr(cpPriv); |
588 QNetworkConfigurationPrivatePointer ptr(cpPriv); |
589 accessPointConfigurations.insert(iap_id, ptr); |
589 accessPointConfigurations.insert(iap_id, ptr); |
590 |
590 |
591 locker.unlock(); |
591 mutex.unlock(); |
592 emit configurationAdded(ptr); |
592 emit configurationAdded(ptr); |
593 locker.relock(); |
593 mutex.lock(); |
594 |
594 |
595 #ifdef BEARER_MANAGEMENT_DEBUG |
595 #ifdef BEARER_MANAGEMENT_DEBUG |
596 qDebug("IAP: %s, name: %s, ssid: %s, added to known list", |
596 qDebug("IAP: %s, name: %s, ssid: %s, added to known list", |
597 iap_id.toAscii().data(), ptr->name.toAscii().data(), |
597 iap_id.toAscii().data(), ptr->name.toAscii().data(), |
598 !ssid.isEmpty() ? ssid.data() : "-"); |
598 !ssid.isEmpty() ? ssid.data() : "-"); |
686 cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; |
690 cpPriv->name = ap.network_name.isEmpty() ? hrs : ap.network_name; |
687 cpPriv->isValid = true; |
691 cpPriv->isValid = true; |
688 cpPriv->id = scanned_ssid.data(); // Note: id is now ssid, it should be set to IAP id if the IAP is saved |
692 cpPriv->id = scanned_ssid.data(); // Note: id is now ssid, it should be set to IAP id if the IAP is saved |
689 cpPriv->network_id = scanned_ssid; |
693 cpPriv->network_id = scanned_ssid; |
690 cpPriv->iap_type = ap.scan.network_type; |
694 cpPriv->iap_type = ap.scan.network_type; |
|
695 cpPriv->bearerType = bearerTypeFromIapType(cpPriv->iap_type); |
691 cpPriv->network_attrs = ap.scan.network_attrs; |
696 cpPriv->network_attrs = ap.scan.network_attrs; |
692 cpPriv->service_id = ap.scan.service_id; |
697 cpPriv->service_id = ap.scan.service_id; |
693 cpPriv->service_type = ap.scan.service_type; |
698 cpPriv->service_type = ap.scan.service_type; |
694 cpPriv->service_attrs = ap.scan.service_attrs; |
699 cpPriv->service_attrs = ap.scan.service_attrs; |
695 |
700 |
731 // => Make sure that configuration state is Defined |
736 // => Make sure that configuration state is Defined |
732 if (ptr->state > QNetworkConfiguration::Defined) { |
737 if (ptr->state > QNetworkConfiguration::Defined) { |
733 ptr->state = QNetworkConfiguration::Defined; |
738 ptr->state = QNetworkConfiguration::Defined; |
734 |
739 |
735 configLocker.unlock(); |
740 configLocker.unlock(); |
736 locker.unlock(); |
741 mutex.unlock(); |
737 emit configurationChanged(ptr); |
742 emit configurationChanged(ptr); |
738 locker.relock(); |
743 mutex.lock(); |
739 } |
744 } |
740 } |
745 } |
741 } |
746 } |
742 |
747 |
743 /* Remove non existing iaps since last update */ |
748 /* Remove non existing iaps since last update */ |
744 foreach (const QString &oldIface, knownConfigs) { |
749 foreach (const QString &oldIface, knownConfigs) { |
745 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface); |
750 QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.take(oldIface); |
746 if (ptr) { |
751 if (ptr) { |
747 locker.unlock(); |
752 mutex.unlock(); |
748 emit configurationRemoved(ptr); |
753 emit configurationRemoved(ptr); |
749 locker.relock(); |
754 mutex.lock(); |
750 //if we would have SNAP support we would have to remove the references |
755 //if we would have SNAP support we would have to remove the references |
751 //from existing ServiceNetworks to the removed access point configuration |
756 //from existing ServiceNetworks to the removed access point configuration |
752 } |
757 } |
753 } |
758 } |
754 } |
759 } |
779 return userChoiceConfigurations.value(OSSO_IAP_ANY); |
784 return userChoiceConfigurations.value(OSSO_IAP_ANY); |
780 } |
785 } |
781 |
786 |
782 void QIcdEngine::startListeningStateSignalsForAllConnections() |
787 void QIcdEngine::startListeningStateSignalsForAllConnections() |
783 { |
788 { |
784 QMutexLocker locker(&mutex); |
|
785 |
|
786 // Start listening ICD_DBUS_API_STATE_SIG signals |
789 // Start listening ICD_DBUS_API_STATE_SIG signals |
787 m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, |
790 m_dbusInterface->connection().connect(ICD_DBUS_API_INTERFACE, |
788 ICD_DBUS_API_PATH, |
791 ICD_DBUS_API_PATH, |
789 ICD_DBUS_API_INTERFACE, |
792 ICD_DBUS_API_INTERFACE, |
790 ICD_DBUS_API_STATE_SIG, |
793 ICD_DBUS_API_STATE_SIG, |
791 this, SLOT(connectionStateSignalsSlot(QDBusMessage))); |
794 this, SLOT(connectionStateSignalsSlot(QDBusMessage))); |
792 |
795 } |
793 // Calling ICD_DBUS_API_STATE_REQ makes sure that initial state will be updated immediately |
796 |
794 m_gettingInitialConnectionState = true; |
797 void QIcdEngine::getIcdInitialState() |
795 m_dbusInterface->call(ICD_DBUS_API_STATE_REQ); |
798 { |
|
799 /* Instead of requesting ICD status asynchronously, we ask it synchronously. |
|
800 * It ensures that we always get right icd status BEFORE initialize() ends. |
|
801 * If not, initialize() might end before we got icd status and |
|
802 * QNetworkConfigurationManager::updateConfigurations() |
|
803 * call from user might also end before receiving icd status. |
|
804 * In such case, we come up to a bug: |
|
805 * QNetworkConfigurationManagerPrivate::isOnline() will be false even |
|
806 * if we are connected. |
|
807 */ |
|
808 Maemo::Icd icd; |
|
809 QList<Maemo::IcdStateResult> state_results; |
|
810 QNetworkConfigurationPrivatePointer ptr; |
|
811 |
|
812 if (icd.state(state_results) && !state_results.isEmpty()) { |
|
813 |
|
814 if (!(state_results.first().params.network_attrs == 0 && |
|
815 state_results.first().params.network_id.isEmpty())) { |
|
816 |
|
817 switch (state_results.first().state) { |
|
818 case ICD_STATE_CONNECTED: |
|
819 m_onlineIapId = state_results.first().params.network_id; |
|
820 |
|
821 ptr = accessPointConfigurations.value(m_onlineIapId); |
|
822 if (ptr) { |
|
823 QMutexLocker configLocker(&ptr->mutex); |
|
824 ptr->state = QNetworkConfiguration::Active; |
|
825 configLocker.unlock(); |
|
826 |
|
827 mutex.unlock(); |
|
828 emit configurationChanged(ptr); |
|
829 mutex.lock(); |
|
830 } |
|
831 break; |
|
832 default: |
|
833 break; |
|
834 } |
|
835 } |
|
836 } |
796 } |
837 } |
797 |
838 |
798 void QIcdEngine::connectionStateSignalsSlot(QDBusMessage msg) |
839 void QIcdEngine::connectionStateSignalsSlot(QDBusMessage msg) |
799 { |
840 { |
800 QMutexLocker locker(&mutex); |
841 QMutexLocker locker(&mutex); |
815 QMutexLocker configLocker(&ptr->mutex); |
856 QMutexLocker configLocker(&ptr->mutex); |
816 |
857 |
817 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
858 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
818 if (ptr->state != QNetworkConfiguration::Active) { |
859 if (ptr->state != QNetworkConfiguration::Active) { |
819 ptr->state = QNetworkConfiguration::Active; |
860 ptr->state = QNetworkConfiguration::Active; |
820 if (!m_gettingInitialConnectionState) { |
861 |
821 configLocker.unlock(); |
862 configLocker.unlock(); |
822 locker.unlock(); |
863 locker.unlock(); |
823 emit configurationChanged(ptr); |
864 emit configurationChanged(ptr); |
824 locker.relock(); |
865 locker.relock(); |
825 } |
866 |
826 m_onlineIapId = iapid; |
867 m_onlineIapId = iapid; |
827 } |
868 } |
828 } else { |
869 } else { |
829 // This gets called when new WLAN IAP is created using Connection dialog |
870 // This gets called when new WLAN IAP is created using Connection dialog |
830 // At this point Undefined WLAN configuration has SSID as iap id |
871 // At this point Undefined WLAN configuration has SSID as iap id |
841 QMutexLocker configLocker(&ptr->mutex); |
882 QMutexLocker configLocker(&ptr->mutex); |
842 |
883 |
843 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
884 ptr->type = QNetworkConfiguration::InternetAccessPoint; |
844 if (ptr->state == QNetworkConfiguration::Active) { |
885 if (ptr->state == QNetworkConfiguration::Active) { |
845 ptr->state = QNetworkConfiguration::Discovered; |
886 ptr->state = QNetworkConfiguration::Discovered; |
846 if (!m_gettingInitialConnectionState) { |
887 |
847 configLocker.unlock(); |
888 configLocker.unlock(); |
848 locker.unlock(); |
889 locker.unlock(); |
849 emit configurationChanged(ptr); |
890 emit configurationChanged(ptr); |
850 locker.relock(); |
891 locker.relock(); |
851 |
892 |
852 // Note: If ICD switches used IAP from one to another: |
893 // Note: If ICD switches used IAP from one to another: |
853 // 1) new IAP is reported to be online first |
894 // 1) new IAP is reported to be online first |
854 // 2) old IAP is reported to be offline then |
895 // 2) old IAP is reported to be offline then |
855 // => Device can be reported to be offline only |
896 // => Device can be reported to be offline only |
856 // if last known online IAP is reported to be disconnected |
897 // if last known online IAP is reported to be disconnected |
857 if (iapid == m_onlineIapId) { |
898 if (iapid == m_onlineIapId) { |
858 // It's known that there is only one global ICD connection |
899 // It's known that there is only one global ICD connection |
859 // => Because ICD state was reported to be DISCONNECTED, Device is offline |
900 // => Because ICD state was reported to be DISCONNECTED, Device is offline |
860 m_onlineIapId.clear(); |
901 m_onlineIapId.clear(); |
861 } |
|
862 } |
902 } |
863 } |
903 } |
864 } else { |
904 } else { |
865 // Disconnected IAP was not found from accessPointConfigurations |
905 // Disconnected IAP was not found from accessPointConfigurations |
866 // => Reason: Online IAP was removed which resulted ICD to disconnect |
906 // => Reason: Online IAP was removed which resulted ICD to disconnect |
945 QList<QVariant> arguments = msg.arguments(); |
981 QList<QVariant> arguments = msg.arguments(); |
946 uint icd_scan_status = arguments.takeFirst().toUInt(); |
982 uint icd_scan_status = arguments.takeFirst().toUInt(); |
947 if (icd_scan_status == ICD_SCAN_COMPLETE) { |
983 if (icd_scan_status == ICD_SCAN_COMPLETE) { |
948 m_typesToBeScanned.removeOne(arguments[6].toString()); |
984 m_typesToBeScanned.removeOne(arguments[6].toString()); |
949 if (!m_typesToBeScanned.count()) { |
985 if (!m_typesToBeScanned.count()) { |
|
986 locker.unlock(); |
950 finishAsyncConfigurationUpdate(); |
987 finishAsyncConfigurationUpdate(); |
|
988 locker.relock(); |
951 } |
989 } |
952 } else { |
990 } else { |
953 Maemo::IcdScanResult scanResult; |
991 Maemo::IcdScanResult scanResult; |
954 scanResult.status = icd_scan_status; |
992 scanResult.status = icd_scan_status; |
955 scanResult.timestamp = arguments.takeFirst().toUInt(); |
993 scanResult.timestamp = arguments.takeFirst().toUInt(); |