From fb78d28b6f5107ebe16193bfbd4778bb8627bd14 Mon Sep 17 00:00:00 2001 From: Teemu Holappa Date: Wed, 3 Feb 2016 14:23:24 +0200 Subject: Merge Boot2Qt Wifi module into Network Settings Plugin. Added wpasupplicant as alternative backend for the network settings. Change-Id: Ic05b3e87def2c9a143c30e4045a36db294ce8719 Reviewed-by: Risto Avila --- src/qtdevicesettings/devicesettings.pro | 11 - .../networksettings/connman.pri | 22 + .../connman/qnetworksettingsmanager_p.cpp | 5 + .../connman/qnetworksettingsmanager_p.h | 1 + .../connman/qnetworksettingsservice_p.cpp | 5 +- .../connman/qnetworksettingsuseragent_p.cpp | 6 +- .../connman/qnetworksettingsuseragent_p.h | 2 + .../networksettings/networksettings.pri | 38 -- .../networksettings/qnetworksettings.h | 14 +- .../qnetworksettingsinterfacemodel.cpp | 7 + .../qnetworksettingsinterfacemodel.h | 1 + .../networksettings/qnetworksettingsmanager.cpp | 6 + .../networksettings/qnetworksettingsmanager.h | 2 + .../qnetworksettingsservicemodel.cpp | 12 + .../networksettings/qnetworksettingsservicemodel.h | 3 +- .../networksettings/qnetworksettingsuseragent.cpp | 12 + .../networksettings/qnetworksettingsuseragent.h | 4 + .../networksettings/wpasupplicant.pri | 28 ++ .../wpasupplicant/qnetworksettingsinterface_p.cpp | 71 ++++ .../wpasupplicant/qnetworksettingsinterface_p.h | 88 ++++ .../wpasupplicant/qnetworksettingsmanager_p.cpp | 433 ++++++++++++++++++++ .../wpasupplicant/qnetworksettingsmanager_p.h | 94 +++++ .../wpasupplicant/qnetworksettingsservice_p.cpp | 127 ++++++ .../wpasupplicant/qnetworksettingsservice_p.h | 87 ++++ .../wpasupplicant/qnetworksettingsuseragent_p.cpp | 57 +++ .../wpasupplicant/qnetworksettingsuseragent_p.h | 56 +++ .../wpasupplicant/qwificontroller.cpp | 285 +++++++++++++ .../wpasupplicant/qwificontroller_p.h | 116 ++++++ .../networksettings/wpasupplicant/qwifidevice.cpp | 94 +++++ .../networksettings/wpasupplicant/qwifidevice.h | 44 ++ .../wpasupplicant/qwifisupplicant.cpp | 443 +++++++++++++++++++++ .../wpasupplicant/qwifisupplicant_p.h | 65 +++ .../networksettingsplugin.pro | 30 +- .../networksettingsplugin_plugin.cpp | 21 +- .../networksettingsplugin_plugin.h | 1 + src/qtdevicesettings/qtdevicesettings.pro | 11 + 36 files changed, 2233 insertions(+), 69 deletions(-) delete mode 100644 src/qtdevicesettings/devicesettings.pro create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/connman.pri delete mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/networksettings.pri create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant.pri create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.h create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.h create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.h create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.h create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller_p.h create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.h create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant.cpp create mode 100644 src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant_p.h create mode 100644 src/qtdevicesettings/qtdevicesettings.pro (limited to 'src/qtdevicesettings') diff --git a/src/qtdevicesettings/devicesettings.pro b/src/qtdevicesettings/devicesettings.pro deleted file mode 100644 index c49e6fb..0000000 --- a/src/qtdevicesettings/devicesettings.pro +++ /dev/null @@ -1,11 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += \ - settingscomponents \ - networksettingsplugin \ - generalsettingsplugin \ - timedateplugin \ - settingsui \ - localesettingsplugin \ - bluetoothsettingsplugin \ - -CONFIG += ordered diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/connman.pri b/src/qtdevicesettings/networksettingsplugin/networksettings/connman.pri new file mode 100644 index 0000000..4e9e6b3 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/connman.pri @@ -0,0 +1,22 @@ +QT += core network dbus + +INCLUDEPATH += $${PWD}/connman + +DBUS_INTERFACES = \ + networksettings/connman/connman_manager.xml \ + networksettings/connman/connman_service.xml \ + networksettings/connman/connman_technology.xml + +SOURCES += \ + $$PWD/connman/qnetworksettingsinterface_p.cpp \ + $$PWD/connman/qnetworksettingsservice_p.cpp \ + $$PWD/connman/qnetworksettingsuseragent_p.cpp \ + $$PWD/connman/qnetworksettingsmanager_p.cpp \ + $$PWD/connman/connmancommon.cpp + +HEADERS += \ + $$PWD/connman/qnetworksettingsinterface_p.h \ + $$PWD/connman/qnetworksettingsservice_p.h \ + $$PWD/connman/qnetworksettingsuseragent_p.h \ + $$PWD/connman/qnetworksettingsmanager_p.h \ + $$PWD/connman/connmancommon.h diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.cpp index 2d4a0d3..8df7276 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.cpp @@ -161,3 +161,8 @@ void QNetworkSettingsManagerPrivate::servicesChanged(ConnmanMapList changed, con m_serviceModel.append(service); } } + +void QNetworkSettingsManagerPrivate::setUserAgent(QNetworkSettingsUserAgent *agent) +{ + +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.h index 6883d74..cadf63f 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsmanager_p.h @@ -52,6 +52,7 @@ class QNetworkSettingsManagerPrivate : public QObject public: explicit QNetworkSettingsManagerPrivate(QNetworkSettingsManager *parent); QNetworkSettingsManager *q_ptr; + void setUserAgent(QNetworkSettingsUserAgent *agent); public slots: void getServicesFinished(QDBusPendingCallWatcher *watcher); diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsservice_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsservice_p.cpp index 95181ed..9e2e83c 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsservice_p.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsservice_p.cpp @@ -376,7 +376,7 @@ void QNetworkSettingsServicePrivate::updateProperty(const QString& key, const QV else if (key == PropertySecurity) { QStringList value = qdbus_cast(val); foreach (const QString str, value) { - if (str == AttributeNone) { + if (str == AttributeNone || str == AttributeWps) { m_wifiConfig.setSecurity(QNetworkSettingsWireless::None); } else if (str == AttributeWep) { @@ -388,9 +388,6 @@ void QNetworkSettingsServicePrivate::updateProperty(const QString& key, const QV else if (str == AttributeIeee) { m_wifiConfig.setSecurity(QNetworkSettingsWireless::WPA2); } - else if (str == AttributeWps) { - m_wifiConfig.setSecurity(QNetworkSettingsWireless::WPS); - } } } } diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.cpp index 918c8b8..3b10bed 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.cpp @@ -90,9 +90,11 @@ QVariantMap QNetworkSettingsUserAgentPrivate::RequestInput(const QDBusObjectPath void QNetworkSettingsUserAgentPrivate::setUserCredentials(const QString& username, const QString& password) { + m_username = username; + m_passphrase = password; QVariantMap response; - response[PropertyName] = username; - response[PropertyPassphrase] = password; + response[PropertyName] = m_username; + response[PropertyPassphrase] = m_passphrase; m_reply << response; m_pendingReply = false; QDBusConnection::systemBus().send(m_reply); diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.h index 8c480a5..92e1516 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/connman/qnetworksettingsuseragent_p.h @@ -70,6 +70,8 @@ private: QNetworkSettingsUserAgent *q_ptr; QDBusMessage m_reply; bool m_pendingReply; + QString m_passphrase; + QString m_username; }; #endif // QNETWORKSETTINGSUSERAGENTPRIVATE_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/networksettings.pri b/src/qtdevicesettings/networksettingsplugin/networksettings/networksettings.pri deleted file mode 100644 index d067eb7..0000000 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/networksettings.pri +++ /dev/null @@ -1,38 +0,0 @@ -QT += core network dbus - -INCLUDEPATH += $${PWD}/connman -INCLUDEPATH += $${PWD} - -DBUS_INTERFACES = \ - networksettings/connman/connman_manager.xml \ - networksettings/connman/connman_service.xml \ - networksettings/connman/connman_technology.xml - -SOURCES += \ - $$PWD/qnetworksettingsinterfacemodel.cpp \ - $$PWD/qnetworksettingsmanager.cpp \ - $$PWD/qnetworksettingsaddressmodel.cpp \ - $$PWD/qnetworksettingsservicemodel.cpp \ - $$PWD/qnetworksettingsservice.cpp \ - $$PWD/qnetworksettingsuseragent.cpp \ - $$PWD/qnetworksettingsinterface.cpp \ - $$PWD/connman/qnetworksettingsinterface_p.cpp \ - $$PWD/connman/qnetworksettingsservice_p.cpp \ - $$PWD/connman/qnetworksettingsuseragent_p.cpp \ - $$PWD/connman/qnetworksettingsmanager_p.cpp \ - $$PWD/connman/connmancommon.cpp - -HEADERS += \ - $$PWD/qnetworksettingsinterfacemodel.h \ - $$PWD/qnetworksettings.h \ - $$PWD/qnetworksettingsmanager.h \ - $$PWD/qnetworksettingsaddressmodel.h \ - $$PWD/qnetworksettingsservicemodel.h \ - $$PWD/qnetworksettingsservice.h \ - $$PWD/qnetworksettingsuseragent.h \ - $$PWD/qnetworksettingsinterface.h \ - $$PWD/connman/qnetworksettingsinterface_p.h \ - $$PWD/connman/qnetworksettingsservice_p.h \ - $$PWD/connman/qnetworksettingsuseragent_p.h \ - $$PWD/connman/qnetworksettingsmanager_p.h \ - $$PWD/connman/connmancommon.h diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettings.h b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettings.h index 6a0604b..fdf677b 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettings.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettings.h @@ -346,12 +346,13 @@ class QNetworkSettingsWireless : public QObject Q_OBJECT Q_PROPERTY(int signalStrength READ signalStrength WRITE setSignalStrength NOTIFY signalStrengthChanged) Q_PROPERTY(bool hidden READ hidden NOTIFY hiddenChanged) + Q_PROPERTY(bool isOutOfRange READ outOfRange WRITE setOutOfRange NOTIFY outOfRangeChanged) public: explicit QNetworkSettingsWireless(QObject* parent = 0) : QObject(parent) { } - enum SecurityFlags {None=1, WEP=2, WPA=4, WPA2=8, WPS=16}; + enum SecurityFlags {None=1, WEP=2, WPA=4, WPA2=8}; Q_INVOKABLE bool supportsSecurity(SecurityFlags security) { if (m_securityFlags & security) { @@ -387,13 +388,24 @@ public: } } + void setOutOfRange(const bool aOutOfRange) { + m_isOutOfRange = aOutOfRange; + emit outOfRangeChanged(); + } + + bool outOfRange() const { + return m_isOutOfRange; + } + signals: void hiddenChanged(); void signalStrengthChanged(); void passwordChanged(); + void outOfRangeChanged(); private: quint16 m_securityFlags; bool m_hidden; int m_signalStrength; + bool m_isOutOfRange; }; #endif //QNETWORKSETTINGS_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.cpp index a4ea477..a539756 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.cpp @@ -106,6 +106,13 @@ void QNetworkSettingsInterfaceModel::insert(int row, QNetworkSettingsInterface* endInsertRows(); } +void QNetworkSettingsInterfaceModel::remove(int row) +{ + beginRemoveRows(QModelIndex(), row, row); + m_items.removeFirst(); + endRemoveRows(); +} + QList QNetworkSettingsInterfaceModel::getModel() { return m_items; diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.h b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.h index c44733a..2105061 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsinterfacemodel.h @@ -55,6 +55,7 @@ public: void append(QNetworkSettingsInterface* networkInterface); void insert(int row, QNetworkSettingsInterface* networkInterface); + void remove(int row); QList getModel(); enum Roles { diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.cpp index f4a8918..954d639 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.cpp @@ -69,3 +69,9 @@ QNetworkSettingsService* QNetworkSettingsManager::getService(const QString& name } return NULL; } + +void QNetworkSettingsManager::setUserAgent(QNetworkSettingsUserAgent *agent) +{ + Q_D(QNetworkSettingsManager); + d->setUserAgent(agent); +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.h b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.h index 03921b2..b0cb7fe 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsmanager.h @@ -43,6 +43,7 @@ QT_FORWARD_DECLARE_CLASS(QNetworkSettingsManagerPrivate) QT_FORWARD_DECLARE_CLASS(QNetworkSettingsService) +QT_FORWARD_DECLARE_CLASS(QNetworkSettingsUserAgent) class QNetworkSettingsManager : public QObject { @@ -54,6 +55,7 @@ public: explicit QNetworkSettingsManager(QObject* parent = 0); QAbstractItemModel* services(); QAbstractItemModel* interfaces(); + void setUserAgent(QNetworkSettingsUserAgent *agent); Q_INVOKABLE QNetworkSettingsService* getService(const QString& name, const int type); diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.cpp index ff5406d..6a80369 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.cpp @@ -100,6 +100,18 @@ void QNetworkSettingsServiceModel::insert(int row, QNetworkSettingsService* item endInsertRows(); } +void QNetworkSettingsServiceModel::remove(int row) +{ + beginRemoveRows(QModelIndex(), row, row); + m_items.removeAt(row); + endRemoveRows(); +} + +void QNetworkSettingsServiceModel::updated(int row) +{ + dataChanged(createIndex(row, 0), createIndex(row, 0)); +} + QList QNetworkSettingsServiceModel::getModel() { return m_items; diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.h b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.h index 0b520ef..50b0242 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsservicemodel.h @@ -53,6 +53,8 @@ public: void append(QNetworkSettingsService* networkService); void insert(int row, QNetworkSettingsService* networkInterface); + void remove(int row); + void updated(int row); QList getModel(); enum Roles { @@ -82,7 +84,6 @@ signals: void typeChanged(); private: QNetworkSettingsType::Types m_type; - }; #endif // QNETWORKSETTINGSSERVICEMODEL_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.cpp index 0e7b637..f1b0590 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.cpp @@ -53,3 +53,15 @@ void QNetworkSettingsUserAgent::cancelInput() Q_D(QNetworkSettingsUserAgent); d->cancel(); } + +QString QNetworkSettingsUserAgent::passPhrase() const +{ + Q_D(const QNetworkSettingsUserAgent); + return d->m_passphrase; +} + +QString QNetworkSettingsUserAgent::userName() const +{ + Q_D(const QNetworkSettingsUserAgent); + return d->m_username; +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.h b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.h index 6f4dc22..be6dff3 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/qnetworksettingsuseragent.h @@ -47,9 +47,13 @@ public: explicit QNetworkSettingsUserAgent(QObject *parent = 0); Q_INVOKABLE void setUserCredentials(const QString& username, const QString& passphrase); Q_INVOKABLE void cancelInput(); + QString passPhrase() const; + QString userName() const; + signals: void showUserCredentialsInput(); void error(); + void ready(bool cancel); private: QNetworkSettingsUserAgentPrivate *d_ptr; diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant.pri b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant.pri new file mode 100644 index 0000000..db89315 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant.pri @@ -0,0 +1,28 @@ +QT += core network + +INCLUDEPATH += $${PWD}/wpasupplicant + +HEADERS += \ + $$PWD/wpasupplicant/qnetworksettingsinterface_p.h \ + $$PWD/wpasupplicant/qnetworksettingsmanager_p.h \ + $$PWD/wpasupplicant/qwifisupplicant_p.h \ + $$PWD/wpasupplicant/qwificontroller_p.h \ + $$PWD/wpasupplicant/qnetworksettingsservice_p.h \ + $$PWD/wpasupplicant/qnetworksettingsuseragent_p.h \ + $$PWD/wpasupplicant/qwifidevice.h + +SOURCES += \ + $$PWD/wpasupplicant/qnetworksettingsinterface_p.cpp \ + $$PWD/wpasupplicant/qnetworksettingsmanager_p.cpp \ + $$[QT_SYSROOT]/usr/include/wpa-supplicant/wpa_ctrl.c \ + $$[QT_SYSROOT]/usr/include/wpa-supplicant/os_unix.c \ + $$PWD/wpasupplicant/qwifisupplicant.cpp \ + $$PWD/wpasupplicant/qwificontroller.cpp \ + $$PWD/wpasupplicant/qnetworksettingsservice_p.cpp \ + $$PWD/wpasupplicant/qnetworksettingsuseragent_p.cpp \ + $$PWD/wpasupplicant/qwifidevice.cpp + +DEFINES += \ + CONFIG_CTRL_IFACE \ + CONFIG_CTRL_IFACE_UNIX + diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.cpp new file mode 100644 index 0000000..7370421 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.cpp @@ -0,0 +1,71 @@ + +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qnetworksettingsinterface_p.h" +#include "qnetworksettingsmanager_p.h" +#include "qwifidevice.h" + +QNetworkSettingsInterfacePrivate::QNetworkSettingsInterfacePrivate(QNetworkSettingsInterface* parent) + :QObject(parent) + ,q_ptr(parent) +{ + m_name = QWifiDevice::wifiInterfaceName(); + m_type.setType(QNetworkSettingsType::Wifi); + m_powered = true; //We don't really know +} + +void QNetworkSettingsInterfacePrivate::setManager(QNetworkSettingsManagerPrivate *manager) +{ + m_manager = manager; +} + +void QNetworkSettingsInterfacePrivate::setPowered(const bool power) +{ + //Not supported + Q_UNUSED(power); +} + +void QNetworkSettingsInterfacePrivate::setState(QNetworkSettingsState::States aState) +{ + Q_Q(QNetworkSettingsInterface); + m_state.setState(aState); + emit q->stateChanged(); +} + +void QNetworkSettingsInterfacePrivate::scan() +{ + m_manager->call(QStringLiteral("SCAN")); +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.h new file mode 100644 index 0000000..d8964c3 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsinterface_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QNETWORKSETTINGSINTERFACEPRIVATE_H +#define QNETWORKSETTINGSINTERFACEPRIVATE_H + +#include +#include "qnetworksettings.h" +#include "qnetworksettingsinterface.h" +#include "qnetworksettingsmanager_p.h" + +class QNetworkSettingsInterfacePrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(QNetworkSettingsInterface) +public: + explicit QNetworkSettingsInterfacePrivate(QNetworkSettingsInterface* parent); + void initialize(const QString& path, const QVariantMap& properties); + void setPowered(const bool power); + void setState(QNetworkSettingsState::States aState); + void setManager(QNetworkSettingsManagerPrivate *manager); + void scan(); + +signals: + +protected: + QString m_name; + QNetworkSettingsType m_type; + QNetworkSettingsState m_state; + bool m_powered; + QNetworkSettingsManagerPrivate *m_manager; //not owned + QNetworkSettingsInterface *q_ptr; +}; + +class WpaSupplicantSettingsInterface : public QNetworkSettingsInterface +{ + Q_OBJECT +public: + WpaSupplicantSettingsInterface(QNetworkSettingsManagerPrivate* manager) + :QNetworkSettingsInterface(manager) + { + Q_D(QNetworkSettingsInterface); + d->setManager(manager); + } + + void setState(QNetworkSettingsState::States aState) { + Q_D(QNetworkSettingsInterface); + d->setState(aState); + } + + virtual ~WpaSupplicantSettingsInterface() { + } +}; + +#endif // QNETWORKSETTINGSINTERFACEPRIVATE_H + diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.cpp new file mode 100644 index 0000000..17a1f2f --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.cpp @@ -0,0 +1,433 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include "qnetworksettingsmanager_p.h" +#include "qwificontroller_p.h" +#include "qnetworksettingsinterface_p.h" +#include "qnetworksettingsservice_p.h" +#include "qnetworksettingsuseragent.h" +#include "qwifisupplicant_p.h" + +QNetworkSettingsManagerPrivate::QNetworkSettingsManagerPrivate(QNetworkSettingsManager *parent) + :QObject(parent) + ,q_ptr(parent) +{ + m_serviceFilter.setSourceModel(&m_serviceModel); + m_wifiController = new QWifiController(this); + m_wifiController->asyncCall(QWifiController::InitializeBackend); + + QObject::connect(m_wifiController, &QWifiController::backendStateChanged, + this, &QNetworkSettingsManagerPrivate::handleBackendStateChanged); + QObject::connect(m_wifiController, &QWifiController::dhcpRequestFinished, + this, &QNetworkSettingsManagerPrivate::handleDhcpRequestFinished); + + QObject::connect(m_wifiController, &QWifiController::raiseError, this, &QNetworkSettingsManagerPrivate::updateLastError); + m_wifiController->start(); + + updateWifiState(); +} + +QNetworkSettingsManagerPrivate::~QNetworkSettingsManagerPrivate() +{ + m_wifiController->asyncCall(QWifiController::ExitEventLoop); + m_wifiController->wait(); + delete m_wifiController; +} + +bool QNetworkSettingsManagerPrivate::event(QEvent *event) +{ + switch ((int) event->type()) { + case WIFI_SCAN_RESULTS: + parseScanResults(call(QStringLiteral("SCAN_RESULTS"))); + return true; + case WIFI_CONNECTED: + handleConnected(); + return true; + case WIFI_DISCONNECTED: + handleDisconneced(); + return true; + case WIFI_AUTHENTICATING: + handleAuthenticating(static_cast(event)); + return true; + case WIFI_HANDSHAKE_FAILED: + updateNetworkState(QNetworkSettingsState::Failure); + return true; + } + return QObject::event(event); +} + +void QNetworkSettingsManagerPrivate::connectNetwork(const QString& ssid) +{ + if (m_backendState != QWifiController::Running) { + qCWarning(B2QT_WIFI) << "start wifi backend before calling connect()"; + return; + } + + call(QStringLiteral("DISABLE_NETWORK all")); + m_currentSSID = ssid; + emit m_agent->showUserCredentialsInput(); +} + +void QNetworkSettingsManagerPrivate::userInteractionReady(bool cancel) +{ + if (cancel) { + m_currentSSID = ""; + return; + } + bool networkKnown = false; + QString id; + const QStringList configuredNetworks = call(QStringLiteral("LIST_NETWORKS")).split('\n'); + for (int i = 1; i < configuredNetworks.length(); ++i) { + const QStringList networkFields = configuredNetworks.at(i).split('\t'); + const QString ssid = QWifiSupplicant::decodeSsid(networkFields.at(1)); + if (ssid == m_currentSSID) { + id = networkFields.at(0); + networkKnown = true; + break; + } + } + + if (!networkKnown) { + bool ok; + id = call(QStringLiteral("ADD_NETWORK")); + id.toInt(&ok); + if (!ok) { + updateLastError(QStringLiteral("failed to add network")); + return; + } + } + + bool ok = true; + QChar q = QLatin1Char('"'); + QString setNetworkCommand = QLatin1String("SET_NETWORK ") + id; + if (!networkKnown) { + ok = ok && checkedCall(setNetworkCommand + QLatin1String(" ssid ") + q + m_currentSSID + q); + } + + QString key_mgmt; + WpaSupplicantService *service = networkForSSID(m_currentSSID); + if (!service) { + return; + } + QString psk = m_agent->passPhrase(); + + // --------------------- configure network ------------------------------ + // ref: http://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf + // ref: https://www.freebsd.org/cgi/man.cgi?wpa_supplicant.conf + // ---------------------------------------------------------------------- + if (service->wirelessConfig()->supportsSecurity(QNetworkSettingsWireless::WPA) || + service->wirelessConfig()->supportsSecurity(QNetworkSettingsWireless::WPA2)) { + // ### TODO - password length has limits (see IEEE 802.11), we need to check + // for those limits here. Supplicant gives only a meaningless "fail" message. + ok = ok && checkedCall(setNetworkCommand + QLatin1String(" psk ") + q + psk + q); + key_mgmt = QLatin1String("WPA-PSK"); + } else if (service->wirelessConfig()->supportsSecurity(QNetworkSettingsWireless::WEP)) { + ok = ok && checkedCall(setNetworkCommand + QLatin1String(" wep_key0 ") + q + psk + q); + ok = ok && checkedCall(setNetworkCommand + QLatin1String(" auth_alg OPEN SHARED")); + key_mgmt = QLatin1String("NONE"); + } else if (service->wirelessConfig()->supportsSecurity(QNetworkSettingsWireless::None)) { + // open network + key_mgmt = QLatin1String("NONE"); + } + + if (service->wirelessConfig()->hidden()) + ok = ok && checkedCall(setNetworkCommand + QLatin1String(" scan_ssid 1")); + + ok = ok && checkedCall(setNetworkCommand + QLatin1String(" key_mgmt ") + key_mgmt); + if (!ok) { + if (!networkKnown) + call(QLatin1String("REMOVE_NETWORK ") + id); + updateLastError(QLatin1String("failed to set properties on network: ") + id); + return; + } + + call(QLatin1String("SELECT_NETWORK ") + id); + call(QStringLiteral("RECONNECT")); +} + +void QNetworkSettingsManagerPrivate::disconnectNetwork() +{ + call(QStringLiteral("DISCONNECT")); + m_wifiController->asyncCall(QWifiController::StopDhcp); +} + +void QNetworkSettingsManagerPrivate::handleBackendStateChanged(QWifiController::BackendState backendState) +{ + switch (backendState) { + case QWifiController::NotRunning: + updateNetworkState(QNetworkSettingsState::Disconnect); + break; + default: + break; + } + updateBackendState(backendState); +} + +void QNetworkSettingsManagerPrivate::handleDhcpRequestFinished(const QString &status) +{ + qCDebug(B2QT_WIFI) << "handleDhcpRequestFinished: " << status << " for " << m_currentSSID; + if (status == QLatin1String("success")) { + updateNetworkState(QNetworkSettingsState::Online); + call(QStringLiteral("SAVE_CONFIG")); + } else { + updateNetworkState(QNetworkSettingsState::Failure); + } +} + +void QNetworkSettingsManagerPrivate::setUserAgent(QNetworkSettingsUserAgent *agent) +{ + m_agent = agent; + connect(m_agent, &QNetworkSettingsUserAgent::ready, this, &QNetworkSettingsManagerPrivate::userInteractionReady); +} + +void QNetworkSettingsManagerPrivate::setCurrentSSID(const QString &ssid) +{ + qCDebug(B2QT_WIFI) << "current SSID: " << m_currentSSID << " -> " << ssid; + if (m_currentSSID == ssid) + return; + + m_currentSSID = ssid; +} + +void QNetworkSettingsManagerPrivate::handleAuthenticating(QWifiEvent *event) +{ + QString data = event->data().trimmed(); + QString ssid = data.mid(data.indexOf(QLatin1String("SSID")) + 6); + ssid = ssid.left(ssid.lastIndexOf(QLatin1Char('\''))); + + setCurrentSSID(QWifiSupplicant::decodeSsid(ssid)); + updateNetworkState(QNetworkSettingsState::Association); +} + +void QNetworkSettingsManagerPrivate::handleConnected() +{ + qCDebug(B2QT_WIFI) << "connected network: " << m_currentSSID; + updateNetworkState(QNetworkSettingsState::Ready); + m_wifiController->asyncCall(QWifiController::AcquireIPAddress); +} + +void QNetworkSettingsManagerPrivate::handleDisconneced() +{ + updateNetworkState(QNetworkSettingsState::Disconnect); +} + +void QNetworkSettingsManagerPrivate::updateNetworkState(QNetworkSettingsState::States networkState) +{ + //Update interface + if (!m_interfaceModel.getModel().isEmpty()) { + WpaSupplicantSettingsInterface* interface = qobject_cast(m_interfaceModel.getModel().first()); + if (interface && interface->state() != networkState) { + interface->setState(networkState); + } + } + + //Update service state + WpaSupplicantService *service = networkForSSID(m_currentSSID); + if (service) { + service->setState(networkState); + } +} + +void QNetworkSettingsManagerPrivate::updateBackendState(QWifiController::BackendState backendState) +{ + if (m_backendState == backendState) + return; + + m_backendState = backendState; + + if (m_backendState == QWifiController::Running && m_interfaceModel.getModel().isEmpty()) { + WpaSupplicantSettingsInterface *interface = new WpaSupplicantSettingsInterface(this); + m_interfaceModel.append(interface); + } else if (m_backendState == QWifiController::NotRunning && m_interfaceModel.getModel().size() > 0){ + m_interfaceModel.remove(0); + } +} + +void QNetworkSettingsManagerPrivate::updateWifiState() +{ + QProcess ps; + ps.start(QStringLiteral("ps")); + if (!ps.waitForStarted()) { + updateLastError(ps.program() + QLatin1String(": ") + ps.errorString()); + return; + } + + ps.waitForFinished(); + bool supplicantRunning = ps.readAll().contains("wpa_supplicant"); + if (supplicantRunning && m_wifiController->resetSupplicantSocket()) + m_backendState = QWifiController::Running; +} + +QString QNetworkSettingsManagerPrivate::call(const QString &command) +{ + if (m_backendState != QWifiController::Running) + return QString(); + + QByteArray reply; + bool success = m_wifiController->supplicant()->sendCommand(command, &reply); + if (!success) { + qCDebug(B2QT_WIFI) << "call to supplicant failed"; + return QString(); + } + + return QLatin1String(reply.trimmed()); +} + +bool QNetworkSettingsManagerPrivate::checkedCall(const QString &command) +{ + return call(command).toUpper() == QLatin1String("OK"); +} + +void QNetworkSettingsManagerPrivate::updateLastError(const QString &error) +{ + qCWarning(B2QT_WIFI) << error; + if (!m_interfaceModel.getModel().isEmpty()) { + WpaSupplicantSettingsInterface* interface = qobject_cast(m_interfaceModel.getModel().first()); + if (interface) { + interface->setState(QNetworkSettingsState::Failure); + } + } +} + +WpaSupplicantService* QNetworkSettingsManagerPrivate::networkForSSID(const QString& ssid) +{ + int pos = 0; + return networkForSSID(ssid, pos); +} + +WpaSupplicantService* QNetworkSettingsManagerPrivate::networkForSSID(const QString& ssid, int& pos) +{ + QList services = m_serviceModel.getModel(); + pos = 0; + foreach (QNetworkSettingsService *service, services) { + if (service->name() == ssid) { + return qobject_cast(service); + } + pos++; + } + pos = -1; + return NULL; +} + +WpaSupplicantService* QNetworkSettingsManagerPrivate::outOfRangeListContains(const QString& ssid) +{ + QList services = m_outOfRangeServiceModel.getModel(); + foreach (QNetworkSettingsService *service, services) { + if (service->name() == ssid) { + return qobject_cast(service); + } + } + return NULL; +} + +void QNetworkSettingsManagerPrivate::parseScanResults(const QString &results) +{ + QStringList lines = results.split('\n'); + QSet sensibleNetworks; + + for (int i = 1; i < lines.size(); ++i) { + QStringList info = lines.at(i).split('\t'); + if (info.size() < 5 || info.at(4).isEmpty() || info.at(0).isEmpty()) + continue; + int pos = 0; + + QString ssid = QWifiSupplicant::decodeSsid(info.at(4)); + if (ssid.isEmpty()) + continue; + + sensibleNetworks.insert(ssid); + WpaSupplicantService *knownNetwork = networkForSSID(ssid, pos); + + if (!knownNetwork) { + knownNetwork = outOfRangeListContains(ssid); + m_outOfRangeServiceModel.getModel().removeOne(knownNetwork); + } + + int signalStrength = info.at(2).trimmed().toInt(); + if (signalStrength < 0) { + // signal is reported in dBm, rough conversion: best = -40, worst = -100 + int val = qAbs(qMax(-100, qMin(signalStrength, -40)) + 40); // clamp and normalize to 0 + signalStrength = 100 - (int) ((100.0 * (double) val) / 60.0); + } else if (signalStrength > 100) { + qCWarning(B2QT_WIFI) << "unexpected value for a signal level: " << signalStrength; + } + + if (!knownNetwork) { + WpaSupplicantService *network = new WpaSupplicantService(this); + network->setId(info.at(0)); + network->setFlags(info.at(3)); + network->wirelessConfig()->setSignalStrength(signalStrength); + network->setName(ssid); + m_serviceModel.append(network); + } else { + if (knownNetwork->wirelessConfig()->outOfRange()) { + // known network has come back into a range + knownNetwork->wirelessConfig()->setOutOfRange(false); + m_serviceModel.append(knownNetwork); + pos = m_serviceModel.getModel().size() - 1; + } + // ssids are the same, compare bssids.. + if (knownNetwork->id() == info.at(0)) { + // same access point, simply update the signal strength + knownNetwork->wirelessConfig()->setSignalStrength(signalStrength); + knownNetwork->wirelessConfig()->setOutOfRange(false); + m_serviceModel.updated(pos); + } else if (knownNetwork->wirelessConfig()->signalStrength() < signalStrength) { + // replace with a stronger access point within the same network + knownNetwork->wirelessConfig()->setOutOfRange(false); + knownNetwork->setId(info.at(0)); + knownNetwork->setFlags(info.at(3)); + knownNetwork->wirelessConfig()->setSignalStrength(signalStrength); + knownNetwork->setName(ssid); + m_serviceModel.updated(pos); + } + } + } + // remove out-of-range networks from the data model + QList networks; + for (int i = 0; i < networks.size();) { + if (!sensibleNetworks.contains(networks.at(i)->name())) { + WpaSupplicantService *n = qobject_cast(networks.at(i)); + m_serviceModel.remove(i); + if (n) { + n->wirelessConfig()->setOutOfRange(true); + m_outOfRangeServiceModel.append(n); + } + } else { + ++i; + } + } +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.h new file mode 100644 index 0000000..fa20fb4 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsmanager_p.h @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QNETWORKSETTINGSMANAGERPRIVATE_H +#define QNETWORKSETTINGSMANAGERPRIVATE_H + +#include +#include "qnetworksettings.h" +#include "qnetworksettingsmanager.h" +#include "qnetworksettingsinterfacemodel.h" +#include "qnetworksettingsservicemodel.h" +#include "qwificontroller_p.h" + +class WpaSupplicantService; + +class QNetworkSettingsManagerPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(QNetworkSettingsManager) +public: + explicit QNetworkSettingsManagerPrivate(QNetworkSettingsManager *parent); + virtual ~QNetworkSettingsManagerPrivate(); + QNetworkSettingsManager *q_ptr; + void setUserAgent(QNetworkSettingsUserAgent *agent); + void connectNetwork(const QString& ssid); + void disconnectNetwork(); + QString call(const QString &command); + bool checkedCall(const QString &command); +protected: + bool event(QEvent *event); + +private slots: + void handleBackendStateChanged(QWifiController::BackendState backendState); + void handleDhcpRequestFinished(const QString &status); + void userInteractionReady(bool cancel); + void updateLastError(const QString &error); +private: + void setCurrentSSID(const QString &ssid); + void handleConnected(); + void handleDisconneced(); + void handleAuthenticating(QWifiEvent *event); + void updateNetworkState(QNetworkSettingsState::States networkState); + void updateBackendState(QWifiController::BackendState backendState); + void updateWifiState(); + void parseScanResults(const QString &results); + WpaSupplicantService* networkForSSID(const QString& ssid); + WpaSupplicantService* networkForSSID(const QString& ssid, int& pos); + WpaSupplicantService* outOfRangeListContains(const QString& ssid); + + QNetworkSettingsInterfaceModel m_interfaceModel; + QNetworkSettingsServiceModel m_serviceModel; + QNetworkSettingsServiceModel m_outOfRangeServiceModel; + QNetworkSettingsServiceFilter m_serviceFilter; + QWifiController *m_wifiController; + QNetworkSettingsUserAgent *m_agent; //Not owned + + QWifiController::BackendState m_backendState; + QString m_currentSSID; +}; + + +#endif // QNETWORKSETTINGSMANAGERPRIVATE_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.cpp new file mode 100644 index 0000000..b5d4545 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.cpp @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qnetworksettingsservice_p.h" +#include "qnetworksettingsmanager_p.h" + +QNetworkSettingsServicePrivate::QNetworkSettingsServicePrivate(const QString& bssid, QNetworkSettingsService *parent) : + QObject(parent) + ,q_ptr(parent) + ,m_id(bssid) +{ + m_type.setType(QNetworkSettingsType::Wifi); +} + +void QNetworkSettingsServicePrivate::setManager(QNetworkSettingsManagerPrivate *manager) +{ + m_manager = manager; +} + +void QNetworkSettingsServicePrivate::connectService() +{ + m_manager->connectNetwork(m_name); +} + +void QNetworkSettingsServicePrivate::disconnectService() +{ + m_manager->disconnectNetwork(); +} + +void QNetworkSettingsServicePrivate::setupIpv6Config() +{ + //Not supported +} + +void QNetworkSettingsServicePrivate::setupNameserversConfig() +{ + //Not supported +} + +void QNetworkSettingsServicePrivate::setupDomainsConfig() +{ + //Not supported +} + +void QNetworkSettingsServicePrivate::setupQNetworkSettingsProxy() +{ + //Not supported +} + +void QNetworkSettingsServicePrivate::setupIpv4Config() +{ + //Not supported +} + +WpaSupplicantService::WpaSupplicantService(QNetworkSettingsManagerPrivate* manager, QObject* parent) + :QNetworkSettingsService("", parent) +{ + Q_D(QNetworkSettingsService); + d->setManager(manager); +} + +void WpaSupplicantService::setId(const QString& aId) +{ + Q_D(QNetworkSettingsService); + d->m_id = aId; +} + +void WpaSupplicantService::setName(const QString& aName) +{ + Q_D(QNetworkSettingsService); + d->m_name = aName; + emit nameChanged(); +} + +void WpaSupplicantService::setFlags(const QString& aFlags) +{ + Q_D(QNetworkSettingsService); + + if (aFlags.contains("WPA-")) { + d->m_wifiConfig.setSecurity(QNetworkSettingsWireless::WPA); + } + if (aFlags.contains("WPA2-")) { + d->m_wifiConfig.setSecurity(QNetworkSettingsWireless::WPA2); + } + if (aFlags.contains("WEP-")) { + d->m_wifiConfig.setSecurity(QNetworkSettingsWireless::WEP); + } +} + +void WpaSupplicantService::setState(QNetworkSettingsState::States aState) +{ + Q_D(QNetworkSettingsService); + d->m_state.setState(aState); + emit stateChanged(); +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.h new file mode 100644 index 0000000..12cc193 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsservice_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QNETWORKSETTINGSSERVICEPRIVATE_H +#define QNETWORKSETTINGSSERVICEPRIVATE_H + +#include +#include "qnetworksettings.h" +#include "qnetworksettingsservice.h" + +class QNetworkSettingsManagerPrivate; + +class QNetworkSettingsServicePrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(QNetworkSettingsService) +public: + QNetworkSettingsServicePrivate(const QString& aServiceId, QNetworkSettingsService *parent=0); + void setManager(QNetworkSettingsManagerPrivate *manager); + QNetworkSettingsService *q_ptr; + + void setAutoConnect(const bool autoconnect); + void setupIpv4Config(); + void setupIpv6Config(); + void setupNameserversConfig(); + void setupDomainsConfig(); + void setupQNetworkSettingsProxy(); + void connectService(); + void disconnectService(); + + QString m_id; + QString m_name; + QNetworkSettingsState m_state; + QNetworkSettingsIPv4 m_ipv4config; + QNetworkSettingsIPv6 m_ipv6config; + QNetworkSettingsAddressModel m_domainsConfig; + QNetworkSettingsAddressModel m_nameserverConfig; + QNetworkSettingsProxy m_proxyConfig; + QNetworkSettingsWireless m_wifiConfig; + QNetworkSettingsType m_type; + QNetworkSettingsManagerPrivate *m_manager; //Not owned +}; + +class WpaSupplicantService : public QNetworkSettingsService +{ + Q_OBJECT +public: + explicit WpaSupplicantService(QNetworkSettingsManagerPrivate* manager, QObject* parent=0); + void setId(const QString& aId); + void setName(const QString& aName); + void setFlags(const QString& aFlags); + void setState(QNetworkSettingsState::States aState); +}; + +#endif // QNETWORKSETTINGSSERVICEPRIVATE_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.cpp new file mode 100644 index 0000000..4e636c0 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qnetworksettingsuseragent_p.h" + +QNetworkSettingsUserAgentPrivate::QNetworkSettingsUserAgentPrivate(QNetworkSettingsUserAgent* parent) + :QObject(parent) + ,q_ptr(parent) +{ + +} + +void QNetworkSettingsUserAgentPrivate::setUserCredentials(const QString& aUsername, const QString& aPassword) +{ + Q_Q(QNetworkSettingsUserAgent); + m_passphrase = aPassword; + m_username = aUsername; + emit q->ready(false); +} + +void QNetworkSettingsUserAgentPrivate::cancel() +{ + Q_Q(QNetworkSettingsUserAgent); + emit q->ready(true); +} diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.h new file mode 100644 index 0000000..fc717dc --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qnetworksettingsuseragent_p.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Device Utilities module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QNETWORKSETTINGSUSERAGENTPRIVATE_H +#define QNETWORKSETTINGSUSERAGENTPRIVATE_H + +#include +#include "qnetworksettingsuseragent.h" + +class QNetworkSettingsUserAgentPrivate : public QObject +{ + Q_OBJECT + Q_DECLARE_PUBLIC(QNetworkSettingsUserAgent) +public: + explicit QNetworkSettingsUserAgentPrivate(QNetworkSettingsUserAgent* parent); + virtual ~QNetworkSettingsUserAgentPrivate() {} + void setUserCredentials(const QString& aUsername, const QString& aPassword); + void cancel(); + QString m_passphrase; + QString m_username; + QNetworkSettingsUserAgent *q_ptr; +}; + +#endif // QNETWORKSETTINGSUSERAGENTPRIVATE_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller.cpp new file mode 100644 index 0000000..8e6cfff --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://www.qt.io +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://www.qt.io +** +****************************************************************************/ +#include "qwificontroller_p.h" +#include "qnetworksettingsmanager_p.h" +#include "qwifisupplicant_p.h" +#include "qwifidevice.h" + +#include +#include + +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(B2QT_WIFI, "qt.b2qt.wifi") + +class QWifiEventThread : public QThread +{ +public: + QWifiEventThread(QWifiController *controller) + : m_controller(controller) + { + } + + void run() { + qCDebug(B2QT_WIFI) << "running wifi event thread"; + QWifiEvent *event = 0; + char buffer[2048]; + forever { + int size = m_controller->supplicant()->waitForEvent(buffer, sizeof(buffer) - 1); + if (size > 0) { + buffer[size] = 0; + event = 0; + qCDebug(B2QT_WIFI) << "[event]: " << buffer; + + if (m_controller->isWifiThreadExitRequested()) { + qCDebug(B2QT_WIFI) << "exit wifi event thread"; + return; + } + + if (strstr(buffer, "SCAN-RESULTS")) { + event = new QWifiEvent(WIFI_SCAN_RESULTS); + } else if (strstr(buffer, "CTRL-EVENT-CONNECTED")) { + event = new QWifiEvent(WIFI_CONNECTED); + } else if (strstr(buffer, "CTRL-EVENT-DISCONNECTED")) { + event = new QWifiEvent(WIFI_DISCONNECTED); + } else if (strstr(buffer, "Trying to associate")) { + event = new QWifiEvent(WIFI_AUTHENTICATING, QLatin1String(buffer)); + } else if (strstr(buffer, "Handshake failed")) { + event = new QWifiEvent(WIFI_HANDSHAKE_FAILED); + } + + if (event) { + QCoreApplication::postEvent(m_controller->manager(), event); + } + } + } + } + +private: + QWifiController *m_controller; +}; + + +QWifiController::QWifiController(QNetworkSettingsManagerPrivate *manager) : + m_manager(manager), + m_exitEventThread(false), + m_interface(QWifiDevice::wifiInterfaceName()), + m_eventThread(new QWifiEventThread(this)), + m_supplicant(new QWifiSupplicant(this)) +{ + qRegisterMetaType("BackendState"); + connect(m_supplicant, &QWifiSupplicant::raiseError, this, &QWifiController::raiseError); +} + +QWifiController::~QWifiController() +{ + exitWifiEventThread(); + delete m_eventThread; +} + +void QWifiController::run() +{ + qCDebug(B2QT_WIFI) << "running wifi backend controller thread"; + Method method; + forever { + m_methodsMutex.lock(); + if (m_methods.isEmpty()) + methodCallRequested.wait(&m_methodsMutex); + method = m_methods.takeFirst(); + m_methodsMutex.unlock(); + switch (method) { + case InitializeBackend: + initializeBackend(); + break; + case TerminateBackend: + terminateBackend(); + break; + case AcquireIPAddress: + acquireIPAddress(); + break; + case StopDhcp: + stopDhcp(); + break; + case ExitEventLoop: + qCDebug(B2QT_WIFI) << "exit wifi backend controller thread"; + return; + } + } +} + +void QWifiController::asyncCall(Method method) +{ + QMutexLocker locker(&m_methodsMutex); + m_methods.append(method); + methodCallRequested.wakeOne(); +} + +void QWifiController::initializeBackend() +{ + qCDebug(B2QT_WIFI) << "initializing wifi backend"; + emit backendStateChanged(QWifiController::Initializing); + + QProcess rfkill; + rfkill.start(QStringLiteral("rfkill"), + QStringList() << QStringLiteral("unblock") << QStringLiteral("wifi")); + rfkill.waitForFinished(); + + QProcess ifconfig; + ifconfig.start(QStringLiteral("ifconfig"), + QStringList() << QLatin1String(m_interface) << QStringLiteral("up")); + if (!ifconfig.waitForStarted()) { + emit raiseError(ifconfig.program() + QLatin1String(": ") + ifconfig.errorString()); + return; + } + + ifconfig.waitForFinished(); + bool initFailed = false; + QByteArray error = ifconfig.readAllStandardError(); + if (!error.isEmpty()) { + emit raiseError(QLatin1String("failed to bring up wifi interface: " + error)); + initFailed = true; + } + if (!initFailed && resetSupplicantSocket()) + emit backendStateChanged(QWifiController::Running); + else + emit backendStateChanged(QWifiController::NotRunning); +} + +bool QWifiController::resetSupplicantSocket() +{ + qCDebug(B2QT_WIFI) << "reset supplicant socket"; + exitWifiEventThread(); + m_supplicant->stopSupplicant(); + m_supplicant->closeSupplicantConnection(); + if (!m_supplicant->startSupplicant()) + return false; + if (!m_supplicant->connectToSupplicant()) + return false; + + startWifiEventThread(); + return true; +} + +void QWifiController::terminateBackend() +{ + qCDebug(B2QT_WIFI) << "terminating wifi backend"; + emit backendStateChanged(QWifiController::Terminating); + + exitWifiEventThread(); + m_supplicant->stopSupplicant(); + m_supplicant->closeSupplicantConnection(); + + QProcess ifconfig; + ifconfig.start(QStringLiteral("ifconfig"), + QStringList() << QLatin1String(m_interface) << QStringLiteral("down")); + if (!ifconfig.waitForStarted()) { + emit raiseError(ifconfig.program() + QLatin1String(": ") + ifconfig.errorString()); + return; + } + + ifconfig.waitForFinished(); + QByteArray error = ifconfig.readAllStandardError(); + if (!error.isEmpty()) + emit raiseError(QLatin1String("failed to bring down wifi interface: " + error)); + + stopDhcp(); + emit backendStateChanged(QWifiController::NotRunning); +} + +void QWifiController::startWifiEventThread() +{ + m_exitEventThread = false; + m_eventThread->start(); +} + +void QWifiController::exitWifiEventThread() +{ + if (m_eventThread->isRunning()) { + m_exitEventThread = true; + m_manager->call(QStringLiteral("SCAN")); + if (!m_eventThread->wait(8000)) + qCWarning(B2QT_WIFI, "timed out waiting for wifi event thread to exit"); + } +} + +void QWifiController::killDhcpProcess(const QString &path) const +{ + QFile pidFile(path); + if (!pidFile.exists()) + return; + + if (!pidFile.open(QIODevice::ReadOnly)) { + qCWarning(B2QT_WIFI) << "could not open pid file: " << path; + return; + } + + bool ok; + int pid = pidFile.readAll().trimmed().toInt(&ok); + if (!ok) { + qCWarning(B2QT_WIFI) << "pid is not a number"; + return; + } + + kill(pid, 9); +} + +void QWifiController::acquireIPAddress() +{ + qCDebug(B2QT_WIFI, "acquireIPAddress"); + QString filePath = QLatin1String("/var/run/udhcpc." + m_interface + ".pid"); + killDhcpProcess(filePath); + QStringList args; + args << QStringLiteral("-R") << QStringLiteral("-n") << QStringLiteral("-p") + << filePath << QStringLiteral("-i") << QLatin1String(m_interface); + + QProcess udhcpc; + udhcpc.start(QStringLiteral("udhcpc"), args); + if (!udhcpc.waitForStarted()) { + emit raiseError(udhcpc.program() + QLatin1String(": ") + udhcpc.errorString()); + emit dhcpRequestFinished(QLatin1String("failed")); + return; + } + + udhcpc.waitForFinished(); + QByteArray error = udhcpc.readAllStandardError(); + QString status = QLatin1String("success"); + if (!error.isEmpty()) { + emit raiseError(QLatin1String("udhcpc failed: " + error)); + status = QLatin1String("failed"); + } else { + if (udhcpc.readAllStandardOutput().contains("No lease")) + status = QLatin1String("failed"); + } + + emit dhcpRequestFinished(status); +} + +void QWifiController::stopDhcp() const +{ + qCDebug(B2QT_WIFI, "stopDhcp"); + QString filePath = QLatin1String("/var/run/udhcpc." + m_interface + ".pid"); + killDhcpProcess(filePath); +} + +QT_END_NAMESPACE diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller_p.h new file mode 100644 index 0000000..902bc6e --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwificontroller_p.h @@ -0,0 +1,116 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://www.qt.io +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://www.qt.io +** +****************************************************************************/ +#ifndef QWIFICONTROLLER_H +#define QWIFICONTROLLER_H + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI) + +const QEvent::Type WIFI_SCAN_RESULTS = (QEvent::Type) (QEvent::User + 2001); +const QEvent::Type WIFI_CONNECTED = (QEvent::Type) (QEvent::User + 2002); +const QEvent::Type WIFI_HANDSHAKE_FAILED = (QEvent::Type) (QEvent::User + 2003); +const QEvent::Type WIFI_AUTHENTICATING = (QEvent::Type) (QEvent::User + 2004); +const QEvent::Type WIFI_DISCONNECTED = (QEvent::Type) (QEvent::User + 2005); + +class QWifiEventThread; +class QWifiSupplicant; +class QNetworkSettingsManagerPrivate; + +class QWifiEvent : public QEvent +{ +public: + QWifiEvent(QEvent::Type type, const QString &data = QString()) + : QEvent(type) + , m_data(data) + { + } + QString data() const { return m_data; } + +private: + QString m_data; +}; + +class QWifiController : public QThread +{ + Q_OBJECT + Q_ENUMS(BackendState) +public: + enum Method { + InitializeBackend, + TerminateBackend, + AcquireIPAddress, + StopDhcp, + ExitEventLoop + }; + + enum BackendState { + Initializing, + Running, + Terminating, + NotRunning + }; + + explicit QWifiController(QNetworkSettingsManagerPrivate *manager); + ~QWifiController(); + + void asyncCall(Method method); + QNetworkSettingsManagerPrivate *manager() const { return m_manager; } + bool isWifiThreadExitRequested() const { return m_exitEventThread; } + void startWifiEventThread(); + void acquireIPAddress(); + void stopDhcp() const; + bool resetSupplicantSocket(); + QWifiSupplicant *supplicant() const { return m_supplicant; } + +signals: + void backendStateChanged(BackendState backendState); + void dhcpRequestFinished(const QString &status); + void raiseError(const QString &error); + +protected: + void run(); + void initializeBackend(); + void terminateBackend(); + void exitWifiEventThread(); + void killDhcpProcess(const QString &path) const; + +private: + QNetworkSettingsManagerPrivate *m_manager; //not owned + bool m_exitEventThread; + QByteArray m_interface; + QVector m_methods; + QWifiEventThread *m_eventThread; + QMutex m_methodsMutex; + QWaitCondition methodCallRequested; + QWifiSupplicant *m_supplicant; +}; + +Q_DECLARE_METATYPE(QWifiController::BackendState) + +QT_END_NAMESPACE + +#endif // QWIFICONTROLLER_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.cpp new file mode 100644 index 0000000..a6812e7 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://www.qt.io +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://www.qt.io +** +****************************************************************************/ +#include "qwifidevice.h" + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QWifiDevice + \inmodule B2Qt.Wifi.Cpp + \ingroup wifi-cppclasses + \brief Represents a physical device. + + Use this class to query if a device is Wifi capable, before attempting + to use the functionality of QWifiManager. + + \code + QWifiManager *m_wifiManager = 0; + if (QWifiDevice::wifiSupported()) + m_wifiManager = QWifiManager::instance(); + + if (m_wifiManager) { + m_wifiManager->start(); + // and other wifi related code + } + \endcode + */ + +QWifiDevice::QWifiDevice() +{ +} + +QWifiDevice::~QWifiDevice() +{ +} + +/*! + Returns \c true if a device is Wifi capable - Wifi driver and firmware has been + successfully loaded by the system, otherwise returns \c false. +*/ +bool QWifiDevice::wifiSupported() +{ + QByteArray ifc = wifiInterfaceName(); + bool hasInterface = QDir().exists(QString::fromLatin1("/sys/class/net/" + ifc)); + if (!hasInterface) + qCWarning(B2QT_WIFI) << "could not find wifi interface in \"/sys/class/net/\", " + "looking for interface named: " << ifc; + return hasInterface; +} + +/*! + Returns Wifi interface name. + + Interface name is read from the \c B2QT_WIFI_INTERFACE + environment variable if it is set, otherwise, the default interface + name ("\e{wlan0}") is used. + + \sa setWifiInterfaceName() + */ +QByteArray QWifiDevice::wifiInterfaceName() +{ + return qEnvironmentVariableIsSet("B2QT_WIFI_INTERFACE") ? qgetenv("B2QT_WIFI_INTERFACE") : "wlan0"; +} + +/*! + A conveniece method to set the Wifi interface \a name. + + \sa wifiInterfaceName() + */ +void QWifiDevice::setWifiInterfaceName(const QByteArray &name) +{ + qputenv("B2QT_WIFI_INTERFACE", name); +} + +QT_END_NAMESPACE diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.h new file mode 100644 index 0000000..80b4891 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifidevice.h @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://www.qt.io +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://www.qt.io +** +****************************************************************************/ +#ifndef QWIFIDEVICE_H +#define QWIFIDEVICE_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI) + +class Q_DECL_EXPORT QWifiDevice : public QObject +{ + Q_OBJECT +public: + explicit QWifiDevice(); + virtual ~QWifiDevice(); + + Q_INVOKABLE static bool wifiSupported(); + static QByteArray wifiInterfaceName(); + static void setWifiInterfaceName(const QByteArray &name); +}; + +QT_END_NAMESPACE + +#endif // QWIFIDEVICE_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant.cpp b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant.cpp new file mode 100644 index 0000000..779475e --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant.cpp @@ -0,0 +1,443 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://www.qt.io +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://www.qt.io +** +****************************************************************************/ +#include "qwifisupplicant_p.h" +#include "qwifidevice.h" + +#include +#include +#include +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(B2QT_WIFI_VERBOSE, "qt.b2qt.wifi.verbose") + +#define CONFIG_FILE "/etc/wpa_supplicant.qtwifi.conf" +#define CONTROL_INTERFACE_PATH "/var/run/wpa_supplicant/" + +QWifiSupplicant::QWifiSupplicant(QObject *parent) : + QObject(parent), + ctrl_conn(0), + monitor_conn(0), + interface(QWifiDevice::wifiInterfaceName()) +{ + createSupplicantConfig(); +} + +void QWifiSupplicant::createSupplicantConfig() +{ + QFile supplicantConfig(QLatin1String(CONFIG_FILE)); + if (supplicantConfig.exists()) + return; + + if (supplicantConfig.open(QIODevice::WriteOnly)) { + supplicantConfig.write("ctrl_interface=" CONTROL_INTERFACE_PATH "\n" + "ctrl_interface_group=0\n" + "update_config=1\n"); + } else { + emit raiseError(QLatin1String("failed to create wpa_supplicant configuration file.")); + } +} + +bool QWifiSupplicant::startSupplicant() +{ + QString pidFile = QLatin1String("/var/run/wpa_supplicant." + interface + ".pid"); + QString driver(QStringLiteral("nl80211,wext")); + + QStringList arg; + arg << QStringLiteral("--start") << QStringLiteral("--quiet") << QStringLiteral("--name"); + arg << QStringLiteral("wpa_supplicant") << QStringLiteral("--startas"); + arg << QStringLiteral("/usr/sbin/wpa_supplicant") << QStringLiteral("--pidfile") << pidFile; + arg << QStringLiteral("--") << QStringLiteral("-B") << QStringLiteral("-P") << pidFile; + arg << QStringLiteral("-i") << QLatin1String(interface) << QStringLiteral("-c"); + arg << QLatin1String(CONFIG_FILE) << QStringLiteral("-D") << driver; + + QProcess startStopDaemon; + startStopDaemon.setProcessChannelMode(QProcess::MergedChannels); + startStopDaemon.start(QStringLiteral("start-stop-daemon"), arg); + if (!startStopDaemon.waitForStarted()) { + emit raiseError(startStopDaemon.program() + QLatin1String(": ") + startStopDaemon.errorString()); + return false; + } + startStopDaemon.waitForFinished(); + // if the interface socket exists then wpa-supplicant was invoked successfully + if (!QFile(QLatin1String(CONTROL_INTERFACE_PATH + interface)).exists()) { + emit raiseError(QLatin1String("failed to invoke wpa_supplicant: " + + startStopDaemon.readAll())); + return false; + } + // reset sockets used for exiting from hung state + exit_sockets[0] = exit_sockets[1] = -1; + return true; +} + +bool QWifiSupplicant::stopSupplicant() +{ + QString pidFile = QLatin1String("/var/run/wpa_supplicant." + interface + ".pid"); + + if (QFile(pidFile).exists()) { + QStringList arg; + arg << QStringLiteral("--stop") << QStringLiteral("--quiet") << QStringLiteral("--name"); + arg << QStringLiteral("wpa_supplicant") << QStringLiteral("--pidfile") << pidFile; + + QProcess startStopDaemon; + startStopDaemon.start(QStringLiteral("start-stop-daemon"), arg); + if (!startStopDaemon.waitForStarted()) { + emit raiseError(startStopDaemon.program() + QLatin1String(": ") + startStopDaemon.errorString()); + return false; + } + startStopDaemon.waitForFinished(); + QByteArray error = startStopDaemon.readAllStandardError(); + if (!error.isEmpty()) { + emit raiseError(QLatin1String("failed to stop a wpa_supplicant process" + error)); + return false; + } + + QFile::remove(pidFile); + } + + QFile::remove(QLatin1String(CONTROL_INTERFACE_PATH + interface)); + + // workaround for QTEE-957 + QProcess killall; + killall.start(QStringLiteral("killall"), QStringList() << QStringLiteral("-9") << QStringLiteral("wpa_supplicant")); + killall.waitForFinished(); + + return true; +} + +/*! \internal + * + wpa_supplicant socket communication code (Apache License 2.0) with few modifications + from https://android.googlesource.com/platform/hardware/libhardware_legacy/ + + */ +bool QWifiSupplicant::connectToSupplicant() +{ + static char path[4096]; + snprintf(path, sizeof(path), "%s/%s", CONTROL_INTERFACE_PATH, interface.constData()); + bool connected = true; + + ctrl_conn = wpa_ctrl_open(path); + if (ctrl_conn == NULL) { + qCWarning(B2QT_WIFI, "Unable to open connection to wpa_supplicant on \"%s\": %s", + path, strerror(errno)); + connected = false; + } + monitor_conn = wpa_ctrl_open(path); + if (monitor_conn == NULL) { + wpa_ctrl_close(ctrl_conn); + ctrl_conn = NULL; + connected = false; + } + if (wpa_ctrl_attach(monitor_conn) != 0) { + wpa_ctrl_close(monitor_conn); + wpa_ctrl_close(ctrl_conn); + ctrl_conn = monitor_conn = NULL; + connected = false; + } + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) { + wpa_ctrl_close(monitor_conn); + wpa_ctrl_close(ctrl_conn); + ctrl_conn = monitor_conn = NULL; + connected = false; + } + + if (!connected) + emit raiseError(QLatin1String("failed to connect to wpa_supplicant")); + return connected; +} + +void QWifiSupplicant::closeSupplicantConnection() +{ + if (ctrl_conn != NULL) { + wpa_ctrl_close(ctrl_conn); + ctrl_conn = NULL; + } + + if (monitor_conn != NULL) { + wpa_ctrl_close(monitor_conn); + monitor_conn = NULL; + } + + if (exit_sockets[0] >= 0) { + close(exit_sockets[0]); + exit_sockets[0] = -1; + } + + if (exit_sockets[1] >= 0) { + close(exit_sockets[1]); + exit_sockets[1] = -1; + } +} + +int QWifiSupplicant::waitForEvent(char *buf, size_t buflen) +{ + size_t nread = buflen - 1; + int result; + char *match, *match2; + + if (monitor_conn == NULL) + return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed"); + + result = receiveEvent(buf, &nread); + + // Terminate reception on exit socket + if (result == -2) + return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed"); + + if (result < 0) { + qCWarning(B2QT_WIFI, "receiveEvent failed: %s", strerror(errno)); + return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - recv error"); + } + + buf[nread] = '\0'; + // Check for EOF on the socket + if (result == 0 && nread == 0) { + // Fabricate an event to pass up + qCWarning(B2QT_WIFI, "Received EOF on supplicant socket"); + return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - signal 0 received"); + } + + /* + * Events strings are in the format + * + * IFNAME=iface CTRL-EVENT-XXX + * or + * CTRL-EVENT-XXX + * + * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG, + * etc.) and XXX is the event name. The level information is not useful + * to us, so strip it off. + */ + + if (strncmp(buf, "IFNAME=", (sizeof("IFNAME=") - 1)) == 0) { + match = strchr(buf, ' '); + if (match != NULL) { + if (match[1] == '<') { + match2 = strchr(match + 2, '>'); + if (match2 != NULL) { + nread -= (match2 - match); + memmove(match + 1, match2 + 1, nread - (match - buf) + 1); + } + } + } else { + return snprintf(buf, buflen, "%s", "CTRL-EVENT-IGNORE "); + } + } else if (buf[0] == '<') { + match = strchr(buf, '>'); + if (match != NULL) { + nread -= (match + 1 - buf); + memmove(buf, match + 1, nread + 1); + //qCWarning(B2QT_WIFI, "supplicant generated event without interface - %s", buf); + } + } else { + // let the event go as is! + qCWarning(B2QT_WIFI, "supplicant generated event without interface and without message level - %s", buf); + } + + return nread; +} + +bool QWifiSupplicant::sendCommand(const QString &command, QByteArray *reply) +{ + QByteArray cmd = command.toLocal8Bit(); + qCDebug(B2QT_WIFI) << "[command]: " << cmd; + + if (ctrl_conn == NULL) { + qCWarning(B2QT_WIFI, "Not connected to wpa_supplicant"); + return false; + } + + char data[8192]; + size_t len = sizeof(data) - 1; // -1: room to add a 0-terminator + int ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), data, &len, NULL); + if (ret == -2) { + qCWarning(B2QT_WIFI) << "command timed out"; + // unblocks the monitor receive socket for termination + TEMP_FAILURE_RETRY(write(exit_sockets[0], "T", 1)); + return false; + } else if (ret < 0 || strncmp(data, "FAIL", 4) == 0) { + return false; + } + + if (len == sizeof(data) - 1) { + qCWarning(B2QT_WIFI) << "possible buffer overflow detected"; + return false; + } + + data[len] = 0; + qCDebug(B2QT_WIFI_VERBOSE) << "[response]: " << data; + *reply = QByteArray(data, len); + + return true; +} + +int QWifiSupplicant::receiveEvent(char *reply, size_t *reply_len) +{ + int res = 0; + int ctrlfd = wpa_ctrl_get_fd(monitor_conn); + struct pollfd rfds[2]; + + memset(rfds, 0, 2 * sizeof(struct pollfd)); + rfds[0].fd = ctrlfd; + rfds[0].events |= POLLIN; + rfds[1].fd = exit_sockets[1]; + rfds[1].events |= POLLIN; + res = TEMP_FAILURE_RETRY(poll(rfds, 2, -1)); + if (res < 0) { + qCWarning(B2QT_WIFI, "Error poll = %d", res); + return res; + } + if (rfds[0].revents & POLLIN) { + return wpa_ctrl_recv(monitor_conn, reply, reply_len); + } + + /* it is not rfds[0], then it must be rfts[1] (i.e. the exit socket) + * or we timed out. In either case, this call has failed .. + */ + return -2; +} + +static inline int hex2num(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static inline int hex2byte(const char *hex) +{ + int a, b; + a = hex2num(*hex++); + if (a < 0) + return -1; + b = hex2num(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +static inline int printf_decode(char *buf, int maxlen, const char *str) +{ + const char *pos = str; + int len = 0; + int val; + + while (*pos) { + if (len + 1 >= maxlen) + break; + switch (*pos) { + case '\\': + pos++; + switch (*pos) { + case '\\': + buf[len++] = '\\'; + pos++; + break; + case '"': + buf[len++] = '"'; + pos++; + break; + case 'n': + buf[len++] = '\n'; + pos++; + break; + case 'r': + buf[len++] = '\r'; + pos++; + break; + case 't': + buf[len++] = '\t'; + pos++; + break; + case 'e': + buf[len++] = '\033'; + pos++; + break; + case 'x': + pos++; + val = hex2byte(pos); + if (val < 0) { + val = hex2num(*pos); + if (val < 0) + break; + buf[len++] = val; + pos++; + } else { + buf[len++] = val; + pos += 2; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + val = *pos++ - '0'; + if (*pos >= '0' && *pos <= '7') + val = val * 8 + (*pos++ - '0'); + if (*pos >= '0' && *pos <= '7') + val = val * 8 + (*pos++ - '0'); + buf[len++] = val; + break; + default: + break; + } + break; + default: + buf[len++] = *pos++; + break; + } + } + if (maxlen > len) + buf[len] = '\0'; + + return len; +} + +/*! \internal + * + Decode wpa_supplicant encoded string, see file hostapd/src/utils/common.c + in git://w1.fi/hostap.git repository. + + For Ascii encoded string, any octet < 32 or > 127 is encoded as a "\\x" + followed by the hex representation of the octet. Exception chars are ", + \\, \\e, \\n, \\r, \\t which are escaped by a backslash + + */ +QString QWifiSupplicant::decodeSsid(const QString &encoded) +{ + static char ssid[2048]; + printf_decode(ssid, sizeof(ssid), encoded.toLatin1().constData()); + return QString::fromUtf8(ssid); +} + +QT_END_NAMESPACE diff --git a/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant_p.h b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant_p.h new file mode 100644 index 0000000..13855c0 --- /dev/null +++ b/src/qtdevicesettings/networksettingsplugin/networksettings/wpasupplicant/qwifisupplicant_p.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc +** All rights reserved. +** For any questions to Digia, please use the contact form at +** http://www.qt.io +** +** This file is part of Qt Enterprise Embedded. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** the contact form at http://www.qt.io +** +****************************************************************************/ +#ifndef QWIFISUPPLICANT_H +#define QWIFISUPPLICANT_H + +#include +#include +#include + +#include "wpa-supplicant/wpa_ctrl.h" + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI) +Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI_VERBOSE) + +class QWifiManagerPrivate; + +class QWifiSupplicant : public QObject +{ + Q_OBJECT +public: + explicit QWifiSupplicant(QObject *parent); + + void createSupplicantConfig(); + bool startSupplicant(); + bool stopSupplicant(); + bool connectToSupplicant(); + void closeSupplicantConnection(); + int waitForEvent(char *buf, size_t buflen); + bool sendCommand(const QString &command, QByteArray *reply); + static QString decodeSsid(const QString &encoded); + +signals: + void raiseError(const QString& error); + +protected: + int receiveEvent(char *reply, size_t *reply_len); + +private: + wpa_ctrl *ctrl_conn; + wpa_ctrl *monitor_conn; + int exit_sockets[2]; + QByteArray interface; +}; + +QT_END_NAMESPACE + +#endif // QWIFISUPPLICANT_H diff --git a/src/qtdevicesettings/networksettingsplugin/networksettingsplugin.pro b/src/qtdevicesettings/networksettingsplugin/networksettingsplugin.pro index 1024f91..1fb23e6 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettingsplugin.pro +++ b/src/qtdevicesettings/networksettingsplugin/networksettingsplugin.pro @@ -5,13 +5,37 @@ CONFIG += qt plugin uri = com.theqtcompany.settings.network -include(networksettings/networksettings.pri) +wpasupplicant { + include(networksettings/wpasupplicant.pri) +} +else { + include(networksettings/connman.pri) +} + + +INCLUDEPATH += $${PWD}/networksettings # Input SOURCES += \ - networksettingsplugin_plugin.cpp + networksettingsplugin_plugin.cpp \ + networksettings/qnetworksettingsinterfacemodel.cpp \ + networksettings/qnetworksettingsmanager.cpp \ + networksettings/qnetworksettingsaddressmodel.cpp \ + networksettings/qnetworksettingsservicemodel.cpp \ + networksettings/qnetworksettingsservice.cpp \ + networksettings/qnetworksettingsuseragent.cpp \ + networksettings/qnetworksettingsinterface.cpp \ + HEADERS += \ - networksettingsplugin_plugin.h + networksettingsplugin_plugin.h \ + networksettings/qnetworksettingsinterfacemodel.h \ + networksettings/qnetworksettings.h \ + networksettings/qnetworksettingsmanager.h \ + networksettings/qnetworksettingsaddressmodel.h \ + networksettings/qnetworksettingsservicemodel.h \ + networksettings/qnetworksettingsservice.h \ + networksettings/qnetworksettingsuseragent.h \ + networksettings/qnetworksettingsinterface.h \ DISTFILES = qmldir diff --git a/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.cpp b/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.cpp index 3480b56..badb5ef 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.cpp +++ b/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.cpp @@ -43,13 +43,6 @@ #include #include -template -QObject *instance(QQmlEngine *engine, QJSEngine *) { - T *t = new T(engine); - t->setObjectName(T::staticMetaObject.className()); - return t; -} - void NetworksettingspluginPlugin::registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("com.theqtcompany.settings.network")); @@ -59,6 +52,16 @@ void NetworksettingspluginPlugin::registerTypes(const char *uri) qmlRegisterUncreatableType(uri, 1, 0, "NetworkSettingsProxy", "Cannot be instantiated directly."); qmlRegisterUncreatableType(uri, 1, 0, "NetworkSettingsType", "Cannot be instantiated directly."); qmlRegisterUncreatableType(uri, 1, 0, "NetworkSettingsState", "Cannot be instantiated directly."); - qmlRegisterSingletonType(uri, 1, 0, "NetworkSettingsManager", &instance); - qmlRegisterSingletonType(uri, 1, 0, "NetworkSettingsUserAgent", &instance); +} + + +void NetworksettingspluginPlugin::initializeEngine(QQmlEngine * engine, const char * uri) +{ + Q_ASSERT(QLatin1String(uri) == QLatin1String("com.theqtcompany.settings.network")); + QNetworkSettingsManager* networkManager = new QNetworkSettingsManager(engine); + QNetworkSettingsUserAgent* userAgent = new QNetworkSettingsUserAgent(engine); + networkManager->setUserAgent(userAgent); + + engine->rootContext()->setContextProperty("NetworkSettingsManager", networkManager); + engine->rootContext()->setContextProperty("NetworkSettingsUserAgent", userAgent); } diff --git a/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.h b/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.h index 40e02e2..f47b964 100644 --- a/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.h +++ b/src/qtdevicesettings/networksettingsplugin/networksettingsplugin_plugin.h @@ -45,6 +45,7 @@ class NetworksettingspluginPlugin : public QQmlExtensionPlugin public: void registerTypes(const char *uri); + void initializeEngine(QQmlEngine * engine, const char * uri); }; #endif // NETWORKSETTINGSPLUGIN_PLUGIN_H diff --git a/src/qtdevicesettings/qtdevicesettings.pro b/src/qtdevicesettings/qtdevicesettings.pro new file mode 100644 index 0000000..c49e6fb --- /dev/null +++ b/src/qtdevicesettings/qtdevicesettings.pro @@ -0,0 +1,11 @@ +TEMPLATE = subdirs +SUBDIRS += \ + settingscomponents \ + networksettingsplugin \ + generalsettingsplugin \ + timedateplugin \ + settingsui \ + localesettingsplugin \ + bluetoothsettingsplugin \ + +CONFIG += ordered -- cgit v1.2.3