From 2215248c450b6bd3f728e813f289f099d4301523 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Thu, 26 Apr 2018 11:57:16 +0300 Subject: Add support for wi-fi networks with hidden SSID Task-number: QTBUG-62661 Change-Id: I894f37d2ac397ca2a10db92b1daec9997a9733bb Reviewed-by: Teemu Holappa --- .../connman/qnetworksettingsmanager_p.cpp | 55 +++++++++++++++++++ .../connman/qnetworksettingsmanager_p.h | 10 ++++ .../connman/qnetworksettingsservice_p.cpp | 10 ++++ .../connman/qnetworksettingsuseragent_p.cpp | 62 ++++++++++++++++------ .../connman/qnetworksettingsuseragent_p.h | 3 ++ 5 files changed, 124 insertions(+), 16 deletions(-) (limited to 'src/networksettings/connman') diff --git a/src/networksettings/connman/qnetworksettingsmanager_p.cpp b/src/networksettings/connman/qnetworksettingsmanager_p.cpp index b3373ee..ea9e682 100644 --- a/src/networksettings/connman/qnetworksettingsmanager_p.cpp +++ b/src/networksettings/connman/qnetworksettingsmanager_p.cpp @@ -44,6 +44,7 @@ QNetworkSettingsManagerPrivate::QNetworkSettingsManagerPrivate(QNetworkSettingsM , m_serviceFilter(Q_NULLPTR) , m_manager(Q_NULLPTR) , m_agent(Q_NULLPTR) + , m_currentWifiConnection(Q_NULLPTR) { qDBusRegisterMetaType(); qDBusRegisterMetaType(); @@ -86,6 +87,40 @@ void QNetworkSettingsManagerPrivate::requestInput(const QString& service, const emit m_agent->showUserCredentialsInput(); } +void QNetworkSettingsManagerPrivate::connectBySsid(const QString &name) +{ + m_unnamedServicesForSsidConnection = m_unnamedServices; + tryNextConnection(); + m_currentSsid = name; +} + +void QNetworkSettingsManagerPrivate::clearConnectionState() +{ + m_unnamedServicesForSsidConnection.clear(); + m_currentSsid.clear(); +} + +void QNetworkSettingsManagerPrivate::tryNextConnection() +{ + Q_Q(QNetworkSettingsManager); + QNetworkSettingsService* service = nullptr; + if (!m_currentSsid.isEmpty()) { + service = m_serviceModel->getByName(m_currentSsid); + m_currentSsid.clear(); + } + if (!service) { + if (!m_unnamedServicesForSsidConnection.isEmpty()) { + service = *m_unnamedServicesForSsidConnection.begin(); + m_unnamedServicesForSsidConnection.erase(m_unnamedServicesForSsidConnection.begin()); + } else { + q->clearConnectionState(); + } + } + if (service) { + service->doConnectService(); + } +} + void QNetworkSettingsManagerPrivate::getServicesFinished(QDBusPendingCallWatcher *watcher) { Q_Q(QNetworkSettingsManager); @@ -129,6 +164,11 @@ void QNetworkSettingsManagerPrivate::onServicesChanged(ConnmanMapStructList chan { foreach (QDBusObjectPath path, removed) { m_serviceModel->removeService(path.path()); + auto serviceIter = m_unnamedServices.find(path.path()); + if (serviceIter != m_unnamedServices.end()) { + serviceIter.value()->deleteLater(); + m_unnamedServices.erase(serviceIter); + } } QStringList newServices; @@ -155,6 +195,14 @@ void QNetworkSettingsManagerPrivate::handleNewService(const QString &servicePath QNetworkSettingsService *service = new QNetworkSettingsService(servicePath, this); + connect(service, &QNetworkSettingsService::connectionStateCleared, + q, &QNetworkSettingsManager::clearConnectionState); + + connect(service, &QNetworkSettingsService::serviceConnected, + q, &QNetworkSettingsManager::setCurrentWifiConnection); + connect(service, &QNetworkSettingsService::serviceDisconnected, + q, &QNetworkSettingsManager::clearCurrentWifiConnection); + if (service->name().length() > 0 && service->type() != QNetworkSettingsType::Unknown) { m_serviceModel->append(service); emit q->servicesChanged(); @@ -179,8 +227,15 @@ void QNetworkSettingsManagerPrivate::serviceReady() Q_Q(QNetworkSettingsManager); QNetworkSettingsService* service = qobject_cast(sender()); + + if (service->type() != QNetworkSettingsType::Unknown + && service->type() == QNetworkSettingsType::Wifi) { + m_unnamedServices.insert(service->id(), service); + } + if (service->name().length() > 0 && service->type() != QNetworkSettingsType::Unknown) { service->disconnect(this); + m_unnamedServices.remove(service->id()); m_serviceModel->append(service); emit q->servicesChanged(); if (service->type() == QNetworkSettingsType::Wired) { diff --git a/src/networksettings/connman/qnetworksettingsmanager_p.h b/src/networksettings/connman/qnetworksettingsmanager_p.h index 579d857..cfc2e64 100644 --- a/src/networksettings/connman/qnetworksettingsmanager_p.h +++ b/src/networksettings/connman/qnetworksettingsmanager_p.h @@ -42,6 +42,7 @@ #include #include +#include #include "connmancommon.h" #include "qnetworksettingsmanager.h" #include "qnetworksettingsinterfacemodel.h" @@ -66,6 +67,11 @@ public: QNetworkSettingsInterfaceModel* interfaceModel() {return &m_interfaceModel;} QNetworkSettingsServiceModel* serviceModel() const {return m_serviceModel;} QNetworkSettingsServiceFilter* serviceFilter() const {return m_serviceFilter;} + void connectBySsid(const QString &name); + void clearConnectionState(); + void tryNextConnection(); + void setCurrentWifiConnection(QNetworkSettingsService *connection) {m_currentWifiConnection = connection;} + QNetworkSettingsService* currentWifiConnection() const {return m_currentWifiConnection;} public slots: void getServicesFinished(QDBusPendingCallWatcher *watcher); @@ -78,10 +84,14 @@ private: protected: QNetworkSettingsInterfaceModel m_interfaceModel; QNetworkSettingsServiceModel *m_serviceModel; + QMap m_unnamedServices; + QMap m_unnamedServicesForSsidConnection; QNetworkSettingsServiceFilter *m_serviceFilter; private: NetConnmanManagerInterface *m_manager; QNetworkSettingsUserAgent *m_agent; + QString m_currentSsid; + QNetworkSettingsService *m_currentWifiConnection; }; QT_END_NAMESPACE diff --git a/src/networksettings/connman/qnetworksettingsservice_p.cpp b/src/networksettings/connman/qnetworksettingsservice_p.cpp index 3912ec2..65653aa 100644 --- a/src/networksettings/connman/qnetworksettingsservice_p.cpp +++ b/src/networksettings/connman/qnetworksettingsservice_p.cpp @@ -396,8 +396,14 @@ void QNetworkSettingsServicePrivate::updateProperty(const QString& key, const QV } else if (key == PropertyState) { QString value = qdbus_cast(val); + QNetworkSettingsState oldState; + oldState.setState(m_state.state()); value >> m_state; emit q->stateChanged(); + if (m_state.state() == QNetworkSettingsState::Ready && m_type.type() == QNetworkSettingsType::Wifi) + emit q->serviceConnected(q); + if (m_state.state() == QNetworkSettingsState::Disconnect && m_type.type() == QNetworkSettingsType::Wifi) + emit q->serviceDisconnected(q); } else if (key == PropertyName) { m_name = qdbus_cast(val); @@ -407,6 +413,10 @@ void QNetworkSettingsServicePrivate::updateProperty(const QString& key, const QV QString value = qdbus_cast(val); value >> m_type; emit q->typeChanged(); + if (m_state.state() == QNetworkSettingsState::Ready && m_type.type() == QNetworkSettingsType::Wifi) + emit q->serviceConnected(q); + if (m_state.state() == QNetworkSettingsState::Disconnect && m_type.type() == QNetworkSettingsType::Wifi) + emit q->serviceDisconnected(q); } else if (key == PropertyStrength) { m_wifiConfig.setSignalStrength(val.toInt()); diff --git a/src/networksettings/connman/qnetworksettingsuseragent_p.cpp b/src/networksettings/connman/qnetworksettingsuseragent_p.cpp index e9e8063..5052b74 100644 --- a/src/networksettings/connman/qnetworksettingsuseragent_p.cpp +++ b/src/networksettings/connman/qnetworksettingsuseragent_p.cpp @@ -67,7 +67,10 @@ void QNetworkSettingsUserAgentPrivate::ReportError(const QDBusObjectPath &path, Q_Q(QNetworkSettingsUserAgent); Q_UNUSED(path); Q_UNUSED(param); - emit q->error(); + if (!m_ssid.isEmpty()) + q->requestNextConnection(); + else + emit q->error(); } void QNetworkSettingsUserAgentPrivate::registerAgent() @@ -80,28 +83,55 @@ QVariantMap QNetworkSettingsUserAgentPrivate::RequestInput(const QDBusObjectPath { Q_Q(QNetworkSettingsUserAgent); Q_UNUSED(path); - Q_UNUSED(params); - msg.setDelayedReply(true); - - m_pendingReply = true; - m_pendingMessage = msg; - emit q->showUserCredentialsInput(); - return QVariantMap(); + QVariant name = params[PropertyName]; + if (!name.isValid()) { + m_ssid.clear(); + } + QVariantMap response; + QVariant passPhrase = params[PropertyPassphrase]; + if (name.isValid() && !m_ssid.isEmpty()) { + response[PropertyName] = m_ssid; + } + if (passPhrase.isValid()) { + if (!m_passphrase.isEmpty()) { + response[PropertyPassphrase] = m_passphrase; + } else { + msg.setDelayedReply(true); + m_pendingMessage = msg; + m_pendingReply = true; + emit q->showUserCredentialsInput(); + return QVariantMap(); + } + } + return response; } void QNetworkSettingsUserAgentPrivate::setPassphrase(const QString& passphrase) { m_passphrase = passphrase; - if (!m_pendingReply) - return; + if (m_pendingReply) { + QVariantMap response; + if (!m_ssid.isEmpty()) { + response[PropertyName] = m_ssid; + } + response[PropertyPassphrase] = m_passphrase; + QDBusMessage reply = m_pendingMessage.createReply(); + reply << response; + m_pendingReply = false; + QDBusConnection::systemBus().send(reply); + } +} - QVariantMap response; - response[PropertyPassphrase] = m_passphrase; +void QNetworkSettingsUserAgentPrivate::setSsidAndPassphrase(const QString &ssid, const QString &passphrase) +{ + m_ssid = ssid; + m_passphrase = passphrase; +} - QDBusMessage reply = m_pendingMessage.createReply(); - reply << response; - m_pendingReply = false; - QDBusConnection::systemBus().send(reply); +void QNetworkSettingsUserAgentPrivate::clearConnectionState() +{ + m_passphrase.clear(); + m_ssid.clear(); } QT_END_NAMESPACE diff --git a/src/networksettings/connman/qnetworksettingsuseragent_p.h b/src/networksettings/connman/qnetworksettingsuseragent_p.h index 180eea5..31170d3 100644 --- a/src/networksettings/connman/qnetworksettingsuseragent_p.h +++ b/src/networksettings/connman/qnetworksettingsuseragent_p.h @@ -65,6 +65,8 @@ public: QString passphrase() const {return m_passphrase;} void cancel(); void release(); + void setSsidAndPassphrase(const QString &ssid, const QString &passphrase); + void clearConnectionState(); public Q_SLOTS: // Dbus methods void ReportError(const QDBusObjectPath &path, const QString ¶m); QVariantMap RequestInput(const QDBusObjectPath &path, const QVariantMap ¶ms, @@ -75,6 +77,7 @@ private: QDBusMessage m_pendingMessage; bool m_pendingReply; QString m_passphrase; + QString m_ssid; }; QT_END_NAMESPACE -- cgit v1.2.3