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/imports/imports.pro | 2 +- src/imports/wifi/pluginmain.cpp | 363 -------------- src/imports/wifi/plugins.qmltypes | 90 ---- src/imports/wifi/qmldir | 3 - src/imports/wifi/wifi.pro | 12 - 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 + src/src.pro | 2 +- src/wifi/qwificonfiguration.cpp | 146 ------ src/wifi/qwificonfiguration.h | 57 --- src/wifi/qwificontroller.cpp | 284 ----------- src/wifi/qwificontroller_p.h | 109 ----- src/wifi/qwifidevice.cpp | 94 ---- src/wifi/qwifidevice.h | 44 -- src/wifi/qwifimanager.cpp | 534 --------------------- src/wifi/qwifimanager.h | 118 ----- src/wifi/qwifimanager_p.h | 68 --- src/wifi/qwifinetwork.cpp | 48 -- src/wifi/qwifinetwork_p.h | 66 --- src/wifi/qwifinetworklistmodel.cpp | 195 -------- src/wifi/qwifinetworklistmodel_p.h | 57 --- src/wifi/qwifisupplicant.cpp | 444 ----------------- src/wifi/qwifisupplicant_p.h | 63 --- src/wifi/wifi.pro | 36 -- 58 files changed, 2235 insertions(+), 2902 deletions(-) delete mode 100644 src/imports/wifi/pluginmain.cpp delete mode 100644 src/imports/wifi/plugins.qmltypes delete mode 100644 src/imports/wifi/qmldir delete mode 100644 src/imports/wifi/wifi.pro 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 delete mode 100644 src/wifi/qwificonfiguration.cpp delete mode 100644 src/wifi/qwificonfiguration.h delete mode 100644 src/wifi/qwificontroller.cpp delete mode 100644 src/wifi/qwificontroller_p.h delete mode 100644 src/wifi/qwifidevice.cpp delete mode 100644 src/wifi/qwifidevice.h delete mode 100644 src/wifi/qwifimanager.cpp delete mode 100644 src/wifi/qwifimanager.h delete mode 100644 src/wifi/qwifimanager_p.h delete mode 100644 src/wifi/qwifinetwork.cpp delete mode 100644 src/wifi/qwifinetwork_p.h delete mode 100644 src/wifi/qwifinetworklistmodel.cpp delete mode 100644 src/wifi/qwifinetworklistmodel_p.h delete mode 100644 src/wifi/qwifisupplicant.cpp delete mode 100644 src/wifi/qwifisupplicant_p.h delete mode 100644 src/wifi/wifi.pro (limited to 'src') diff --git a/src/imports/imports.pro b/src/imports/imports.pro index 0b5a551..38f61c3 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,2 +1,2 @@ TEMPLATE = subdirs -SUBDIRS += utils wifi +SUBDIRS += utils diff --git a/src/imports/wifi/pluginmain.cpp b/src/imports/wifi/pluginmain.cpp deleted file mode 100644 index b498b66..0000000 --- a/src/imports/wifi/pluginmain.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/**************************************************************************** -** -** 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 -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -/*! - \qmlmodule B2Qt.Wifi 1.0 - \title B2Qt Wifi QML Module - \ingroup qtee-qmlmodules - \brief A module for managing wireless network connectivity. - -*/ - -/*! - \page b2qt-addon-wifi.html - \title B2Qt Wifi Module - \ingroup qtee-modules - \brief A module for managing wireless network connectivity. - - B2Qt.Wifi provides QML types and C++ classes for: - - \list - \li Wifi backend handling - \li Retrieval of information from Wifi network access points - \li Wifi connection handling - \li System's network interface configuration - \li Other tasks that allow the device to access network - \endlist - - \section1 Writing the Code - - Depending on what fits best with the application, you can choose to use - either C++ or QML for accessing Wifi functionality. If the majority of the - user interface is written in QML, it is recommended that you use the QML - types, which provide a simpler and declarative way to handle Wifi networks. - - \list - \li \l{Getting Started with B2Qt.Wifi in QML} - \li \l{Getting Started with B2Qt.Wifi in C++} - \endlist - - \section1 API Reference - - \section2 QML Types - - \annotatedlist wifi-qmltypes - - \section2 C++ Classes - - \annotatedlist wifi-cppclasses -*/ - -/*! - \module B2Qt.Wifi.Cpp 1.0 - \title B2Qt Wifi C++ Module - \ingroup qtee-cppmodules - \brief A module for managing wireless network connectivity. -*/ - -/*! - \qmltype WifiManager - \inqmlmodule B2Qt.Wifi - \ingroup wifi-qmltypes - \brief Main interface to the Wifi functionality. - - WifiManager is a singleton type that is a central point for handling Wifi functionality - related tasks. You can use WifiManager's API to control the Wifi backend, scan surroundings for - Wifi access points and connect a device to a wireless network. - - When scanning for networks, WifiManager packs the results in a list-based data model which can - be used with Qt's Model/View classes. Information about the Wifi networks is supplied via the model's - interface, accessed with the following roles: - - \list - \li \e ssid - informal (human) name of a Wifi network (string) - \li \e bssid - basic service set identification of a network, used to uniquely identify BSS (string) - \li \e signalStrength - strength of a Wifi signal represented as percentage (0-100) (int) - \li \e supportsWPA - holds whether network access point supports WPA security protocol (bool) - \li \e supportsWPA2 - holds whether network access point supports WPA2 security protocol (bool) - \li \e supportsWEP - holds whether network access point supports WEP security protocol (bool) - \li \e supportsWPS - holds whether network access point supports WPS security protocol (bool) - \endlist - */ - -/*! - \qmlproperty enumeration WifiManager::NetworkState - \readonly - - This property holds the current state of the network connection. - - \list - \li \e WifiManager.Disconnected - Not connected to any network - \li \e WifiManager.Authenticating - Verifying password with the network provider - \li \e WifiManager.HandshakeFailed - Incorrect password provided - \li \e WifiManager.ObtainingIPAddress - Requesting IP address from DHCP server - \li \e WifiManager.DhcpRequestFailed - Could not retrieve IP address - \li \e WifiManager.Connected - Ready to process network requests - \endlist -*/ - -/*! - \qmlproperty enumeration WifiManager::BackendState - \readonly - - This property holds the current state of the Wifi backend. - - \list - \li \e WifiManager.Initializing - Wireless supplicant is starting up - \li \e WifiManager.Running - Supplicant is initialized and ready to process commands - \li \e WifiManager.Terminating - Shutting down wireless supplicant - \li \e WifiManager.NotRunning - Wireless supplicant process is not running - \endlist -*/ - -/*! - \qmlsignal WifiManager::networkStateChanged(NetworkState networkState) - - This signal is emitted whenever changes in a network state occur. The network name for - which the NetworkState change events are send can be obtained from currentSSID. - - \sa NetworkState, currentSSID -*/ - -/*! - \qmlsignal WifiManager::backendStateChanged(BackendState backendState) - - This signal is emitted whenever changes in a backend state occur. - - \sa start, stop -*/ - -/*! - \qmlsignal WifiManager::currentSSIDChanged(string currentSSID) - - This signal is emitted when switching between different Wifi networks. - - \sa start, stop -*/ - -/*! - \qmlsignal WifiManager::scanningChanged(bool scanning) - - This signal is emitted when device starts or stops to scan for available Wifi networks. - - \sa scanning -*/ - -/*! - \qmlsignal WifiManager::lastErrorChanged(string error) - - This signal is emitted if some internal process has failed, \a error contains - a message on what has failed. - - \sa connect -*/ - -/*! - \qmlproperty model WifiManager::networks - \readonly - - This property holds a list-based data model of networks that can be sensed by a device. - Model can be used with Qt's Model/View classes like ListView. Data in the model is updated - every 5 seconds if scanning is enabled. - - \sa scanning -*/ - -/*! - \qmlproperty string WifiManager::currentSSID - \readonly - - This property holds a network name of last selected network, the network for - which the NetworkState change events are sent. Property can contain an empty - string when no active network connection exists. -*/ - -/*! - \qmlmethod WifiManager::start() - - Start the Wifi backend. This function returns immediately, the BackendState - change events are delivered asynchronously. - - \sa stop, BackendState -*/ - -/*! - \qmlmethod WifiManager::stop() - - Stop the Wifi backend and if connected to any network shut down the network connection. - This function returns immediately, the BackendState change events are delivered asynchronously. - - \sa start, BackendState -*/ - -/*! - \qmlproperty bool WifiManager::scanning - - This property holds whether or not the backend is scanning for Wifi networks. To - preserve battery energy, set this property to false when scanning is not required. - When enabled, new readings are taken every 5 seconds. - - For scanning to work, first you need to initialize the Wifi backend. - - \sa start -*/ - -/*! - \qmlproperty string WifiManager::lastError - \readonly - - This property holds an error message if some internal process has failed. - - \sa connect -*/ - -/*! - \qmlmethod bool WifiManager::connect(WifiConfiguration config) - - Connect a device to a network using the \a config network configuration. - This method returns \a true if the network with provoded configuration could be - successfully added by the backend or \a false on failure, to obtain an error message - read lastError property. - - \sa disconnect, NetworkState, lastError -*/ - -/*! - \qmlmethod WifiManager::disconnect() - - Disconnect from currently connected network connection. - - \sa connect, NetworkState -*/ - -/*! - \qmltype WifiDevice - \inqmlmodule B2Qt.Wifi - \ingroup wifi-qmltypes - \brief Represents a physical device. - - Use this element to query if a device is Wifi capable, before attempting - to use the functionality of WifiManager. - - \qml - import B2Qt.Wifi 1.0 - - GroupBox { - id: wifiOptions - title: "Wifi" - visible: false - - Component.onCompleted: { - if (WifiDevice.wifiSupported()) { - var component = Qt.createComponent("WifiGroupBoxContent.qml") - var wifi = component.createObject(wifiOptions.contentItem) - if (wifi) - wifiOptions.visible = true - } else { - print("Wifi functionality not available on this device.") - } - } - } - \endqml -*/ - -/*! - \qmlmethod bool WifiDevice::wifiSupported() - - Returns \a true if a device is Wifi capable - Wifi driver and firmware has been - successfully loaded by the system, otherwise returns \a false. -*/ - -/*! - \qmltype WifiConfiguration - \inqmlmodule B2Qt.Wifi - \ingroup wifi-qmltypes - \brief Used to define a network configuration. - - WifiConfiguration object represents a single network configuration. Use this object - to configure a properties of your network, for example what passphrase and security - protocol to use. WifiManager's connect() function takes this object and connects a - device to a network that matches the provided configuration. -*/ - -/*! - \qmlproperty string WifiConfiguration::ssid - - This property holds informal (human) name of a Wifi network. -*/ - -/*! - \qmlproperty string WifiConfiguration::passphrase - - This property holds the passphrase to use for authenticating with a network. -*/ - -/*! - \qmlproperty string WifiConfiguration::protocol - - This property holds the security protocols to use for Wifi connection. - WPA is used by default if property is not set, supported values are: WPA, WPA2, WEP, WPS. -*/ - -/*! - \qmlproperty bool WifiConfiguration::ssidHidden - - If a Wifi access point does not broadcast its SSID, setting this property - to \c true ensures that the Wifi backend can detect the specified network. - - By default this property is set to \c false. -*/ - -static QObject *globalWifiDevice(QQmlEngine *, QJSEngine *) -{ - return new QWifiDevice; -} - -static QObject *globalWifiManager(QQmlEngine *, QJSEngine *) -{ - return QWifiManager::instance(); -} - -class QWifiPlugin : public QQmlExtensionPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0") - -public: - virtual void registerTypes(const char *uri) - { - Q_ASSERT(QLatin1String(uri) == QLatin1String("B2Qt.Wifi")); - - qmlRegisterType(); - qmlRegisterSingletonType(uri, 1, 0, "WifiManager", globalWifiManager); - qmlRegisterSingletonType(uri, 1, 0, "WifiDevice", globalWifiDevice); - qmlRegisterType(uri, 1, 0, "WifiConfiguration"); - } -}; - -QT_END_NAMESPACE - -#include "pluginmain.moc" diff --git a/src/imports/wifi/plugins.qmltypes b/src/imports/wifi/plugins.qmltypes deleted file mode 100644 index c59d12c..0000000 --- a/src/imports/wifi/plugins.qmltypes +++ /dev/null @@ -1,90 +0,0 @@ -import QtQuick.tooling 1.1 - -// This file describes the plugin-supplied types contained in the library. -// It is used for QML tooling purposes only. -// -// This file was auto-generated by: -// 'qmlplugindump -nonrelocatable B2Qt.Wifi 1.0 /system/qml/B2Qt/Wifi/' - -Module { - Component { - name: "QWifiConfiguration" - prototype: "QObject" - exports: ["B2Qt.Wifi/WifiConfiguration 1.0"] - exportMetaObjectRevisions: [0] - Property { name: "ssid"; type: "string" } - Property { name: "passphrase"; type: "string" } - Property { name: "protocol"; type: "string" } - } - Component { - name: "QWifiDevice" - prototype: "QObject" - exports: ["B2Qt.Wifi/WifiDevice 1.0"] - isCreatable: false - isSingleton: true - exportMetaObjectRevisions: [0] - Method { name: "wifiSupported"; type: "bool" } - } - Component { - name: "QWifiManager" - prototype: "QObject" - exports: ["B2Qt.Wifi/WifiManager 1.0"] - isCreatable: false - isSingleton: true - exportMetaObjectRevisions: [0] - Enum { - name: "NetworkState" - values: { - "Disconnected": 0, - "Authenticating": 1, - "HandshakeFailed": 2, - "ObtainingIPAddress": 3, - "DhcpRequestFailed": 4, - "Connected": 5 - } - } - Enum { - name: "BackendState" - values: { - "Initializing": 0, - "Running": 1, - "Terminating": 2, - "NotRunning": 3 - } - } - Property { name: "networkState"; type: "NetworkState"; isReadonly: true } - Property { name: "backendState"; type: "BackendState"; isReadonly: true } - Property { name: "scanning"; type: "bool" } - Property { name: "currentSSID"; type: "string"; isReadonly: true } - Property { name: "lastError"; type: "string"; isReadonly: true } - Property { name: "networks"; type: "QAbstractListModel"; isReadonly: true; isPointer: true } - Signal { - name: "scanningChanged" - Parameter { name: "scanning"; type: "bool" } - } - Signal { - name: "networkStateChanged" - Parameter { name: "networkState"; type: "NetworkState" } - } - Signal { - name: "backendStateChanged" - Parameter { name: "backendState"; type: "BackendState" } - } - Signal { - name: "currentSSIDChanged" - Parameter { name: "currentSSID"; type: "string" } - } - Signal { - name: "lastErrorChanged" - Parameter { name: "error"; type: "string" } - } - Method { name: "start" } - Method { name: "stop" } - Method { - name: "connect" - type: "bool" - Parameter { name: "config"; type: "QWifiConfiguration"; isPointer: true } - } - Method { name: "disconnect" } - } -} diff --git a/src/imports/wifi/qmldir b/src/imports/wifi/qmldir deleted file mode 100644 index 7e99b56..0000000 --- a/src/imports/wifi/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -module B2Qt.Wifi -plugin b2qtwifiplugin -typeinfo plugins.qmltypes diff --git a/src/imports/wifi/wifi.pro b/src/imports/wifi/wifi.pro deleted file mode 100644 index b130587..0000000 --- a/src/imports/wifi/wifi.pro +++ /dev/null @@ -1,12 +0,0 @@ -CXX_MODULE = qml -TARGET = b2qtwifiplugin -TARGETPATH = B2Qt/Wifi -IMPORT_VERSION = 1.0 - -QT += qml b2qtwifi - -SOURCES += pluginmain.cpp - -OTHER_FILES += qmldir - -load(qml_plugin) 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 diff --git a/src/src.pro b/src/src.pro index ebe58b5..d9d67ad 100644 --- a/src/src.pro +++ b/src/src.pro @@ -2,6 +2,6 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ utils \ - wifi \ + qtdevicesettings \ imports \ doc diff --git a/src/wifi/qwificonfiguration.cpp b/src/wifi/qwificonfiguration.cpp deleted file mode 100644 index b532620..0000000 --- a/src/wifi/qwificonfiguration.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/**************************************************************************** -** -** 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 "qwificonfiguration.h" - -QT_BEGIN_NAMESPACE - -class QWifiConfigurationPrivate -{ - Q_DECLARE_PUBLIC(QWifiConfiguration) -public: - QWifiConfigurationPrivate(QWifiConfiguration *config); - - // member variables - QWifiConfiguration *const q_ptr; - QString m_ssid; - QString m_psk; - QString m_protocol; - bool m_ssidHidden; -}; - -QWifiConfigurationPrivate::QWifiConfigurationPrivate(QWifiConfiguration *config) - : q_ptr(config) - , m_ssidHidden(false) -{ -} - -/*! - \class QWifiConfiguration - \inmodule B2Qt.Wifi.Cpp - \ingroup wifi-cppclasses - \brief Used to define a network configuration. - - QWifiConfiguration object represents a single network configuration. Use it - to configure properties of your network. For example, passphrase, security - protocol to use, and so on. QWifiManager::connect() function uses this - information to find a network that matches the provided configuration, before - establishing a connection. - */ - -/*! - Constructs a configuration object with parent \a parent. -*/ -QWifiConfiguration::QWifiConfiguration(QObject *parent) - : QObject(parent) - , d_ptr(new QWifiConfigurationPrivate(this)) -{ -} - -/*! - Destroys the configuration object. -*/ -QWifiConfiguration::~QWifiConfiguration() -{ - delete d_ptr; -} - -/*! - \property QWifiConfiguration::ssid - \brief a human-readable name of a Wifi network -*/ -QString QWifiConfiguration::ssid() const -{ - Q_D(const QWifiConfiguration); - return d->m_ssid; -} - -void QWifiConfiguration::setSsid(const QString &ssid) -{ - Q_D(QWifiConfiguration); - d->m_ssid = ssid; -} - -/*! - \property QWifiConfiguration::passphrase - \brief a passphrase to use for authenticating access to a network -*/ -QString QWifiConfiguration::passphrase() const -{ - Q_D(const QWifiConfiguration); - return d->m_psk; -} - -void QWifiConfiguration::setPassphrase(const QString &passphrase) -{ - Q_D(QWifiConfiguration); - d->m_psk = passphrase; -} - -/*! - \property QWifiConfiguration::protocol - \brief a security protocol to use for Wifi connection - - WPA is used by default if protocol is not explicitly set. - Supported values are: WPA, WPA2, WEP, WPS. -*/ -QString QWifiConfiguration::protocol() const -{ - Q_D(const QWifiConfiguration); - return d->m_protocol; -} - -void QWifiConfiguration::setProtocol(const QString &protocol) -{ - Q_D(QWifiConfiguration); - d->m_protocol = protocol; -} - -/*! - \property QWifiConfiguration::ssidHidden - \brief Holds whether a Wifi access point broadcasts its SSID - - If a Wifi access point does not broadcast its SSID, setting this - property to \c true ensures that the Wifi backend can detect the - specified network. - - By default this property is set to \c false. -*/ -bool QWifiConfiguration::isSsidHidden() const -{ - Q_D(const QWifiConfiguration); - return d->m_ssidHidden; -} - -void QWifiConfiguration::setSsidHidden(bool hidden) -{ - Q_D(QWifiConfiguration); - d->m_ssidHidden = hidden; -} - -QT_END_NAMESPACE diff --git a/src/wifi/qwificonfiguration.h b/src/wifi/qwificonfiguration.h deleted file mode 100644 index cdeb453..0000000 --- a/src/wifi/qwificonfiguration.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** 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 QWIFICONFIGURATION_H -#define QWIFICONFIGURATION_H - -#include -#include - -class QWifiConfigurationPrivate; - -QT_BEGIN_NAMESPACE - -class Q_DECL_EXPORT QWifiConfiguration : public QObject -{ - Q_OBJECT - Q_PROPERTY(QString ssid READ ssid WRITE setSsid) - Q_PROPERTY(QString passphrase READ passphrase WRITE setPassphrase) - Q_PROPERTY(QString protocol READ protocol WRITE setProtocol) - Q_PROPERTY(bool ssidHidden READ isSsidHidden WRITE setSsidHidden) -public: - explicit QWifiConfiguration(QObject *parent = 0); - virtual ~QWifiConfiguration(); - - void setSsid(const QString &ssid); - QString ssid() const; - void setPassphrase(const QString &passphrase); - QString passphrase() const; - void setProtocol(const QString &protocol); - QString protocol() const; - void setSsidHidden(bool hidden); - bool isSsidHidden() const; - -private: - Q_DISABLE_COPY(QWifiConfiguration) - Q_DECLARE_PRIVATE(QWifiConfiguration) - QWifiConfigurationPrivate *const d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QWIFICONFIGURATION_H diff --git a/src/wifi/qwificontroller.cpp b/src/wifi/qwificontroller.cpp deleted file mode 100644 index f5ed741..0000000 --- a/src/wifi/qwificontroller.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/**************************************************************************** -** -** 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 "qwifimanager_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->wifiManager(), event); - } - } - } - -private: - QWifiController *m_controller; -}; - - -QWifiController::QWifiController(QWifiManager *manager, QWifiManagerPrivate *managerPrivate) : - m_manager(manager), - m_managerPrivate(managerPrivate), - m_exitEventThread(false), - m_interface(QWifiDevice::wifiInterfaceName()), - m_eventThread(new QWifiEventThread(this)), - m_supplicant(new QWifiSupplicant(this, m_managerPrivate)) -{ - qRegisterMetaType("QWifiManager::BackendState"); -} - -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(QWifiManager::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()) { - m_managerPrivate->updateLastError(ifconfig.program() + QLatin1String(": ") + ifconfig.errorString()); - return; - } - - ifconfig.waitForFinished(); - bool initFailed = false; - QByteArray error = ifconfig.readAllStandardError(); - if (!error.isEmpty()) { - m_managerPrivate->updateLastError(QLatin1String("failed to bring up wifi interface: " + error)); - initFailed = true; - } - if (!initFailed && resetSupplicantSocket()) - emit backendStateChanged(QWifiManager::Running); - else - emit backendStateChanged(QWifiManager::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(QWifiManager::Terminating); - - exitWifiEventThread(); - m_supplicant->stopSupplicant(); - m_supplicant->closeSupplicantConnection(); - - QProcess ifconfig; - ifconfig.start(QStringLiteral("ifconfig"), - QStringList() << QLatin1String(m_interface) << QStringLiteral("down")); - if (!ifconfig.waitForStarted()) { - m_managerPrivate->updateLastError(ifconfig.program() + QLatin1String(": ") + ifconfig.errorString()); - return; - } - - ifconfig.waitForFinished(); - QByteArray error = ifconfig.readAllStandardError(); - if (!error.isEmpty()) - m_managerPrivate->updateLastError(QLatin1String("failed to bring down wifi interface: " + error)); - - stopDhcp(); - emit backendStateChanged(QWifiManager::NotRunning); -} - -void QWifiController::startWifiEventThread() -{ - m_exitEventThread = false; - m_eventThread->start(); -} - -void QWifiController::exitWifiEventThread() -{ - if (m_eventThread->isRunning()) { - m_exitEventThread = true; - m_managerPrivate->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()) { - m_managerPrivate->updateLastError(udhcpc.program() + QLatin1String(": ") + udhcpc.errorString()); - emit dhcpRequestFinished(QLatin1String("failed")); - return; - } - - udhcpc.waitForFinished(); - QByteArray error = udhcpc.readAllStandardError(); - QString status = QLatin1String("success"); - if (!error.isEmpty()) { - m_managerPrivate->updateLastError(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/wifi/qwificontroller_p.h b/src/wifi/qwificontroller_p.h deleted file mode 100644 index 45751fa..0000000 --- a/src/wifi/qwificontroller_p.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** 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 "qwifimanager.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 QWifiManager; -class QWifiManagerPrivate; -class QWifiEventThread; -class QWifiSupplicant; - -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 -public: - enum Method { - InitializeBackend, - TerminateBackend, - AcquireIPAddress, - StopDhcp, - ExitEventLoop - }; - - explicit QWifiController(QWifiManager *manager, QWifiManagerPrivate *managerPrivate); - ~QWifiController(); - - void asyncCall(Method method); - QWifiManager *wifiManager() 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(QWifiManager::BackendState backendState); - void dhcpRequestFinished(const QString &status); - -protected: - void run(); - void initializeBackend(); - void terminateBackend(); - void exitWifiEventThread(); - void killDhcpProcess(const QString &path) const; - -private: - QWifiManager *m_manager; - QWifiManagerPrivate *const m_managerPrivate; - bool m_exitEventThread; - QByteArray m_interface; - QVector m_methods; - QWifiEventThread *m_eventThread; - QMutex m_methodsMutex; - QWaitCondition methodCallRequested; - QWifiSupplicant *m_supplicant; -}; - -QT_END_NAMESPACE - -#endif // QWIFICONTROLLER_H diff --git a/src/wifi/qwifidevice.cpp b/src/wifi/qwifidevice.cpp deleted file mode 100644 index a6812e7..0000000 --- a/src/wifi/qwifidevice.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** 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/wifi/qwifidevice.h b/src/wifi/qwifidevice.h deleted file mode 100644 index 80b4891..0000000 --- a/src/wifi/qwifidevice.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** 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/wifi/qwifimanager.cpp b/src/wifi/qwifimanager.cpp deleted file mode 100644 index 0448ec7..0000000 --- a/src/wifi/qwifimanager.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** -** -** 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 "qwifinetworklistmodel_p.h" -#include "qwifinetwork_p.h" -#include "qwifimanager_p.h" -#include "qwifisupplicant_p.h" - -#include "qwifidevice.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -// must be in the same order as in enum {} definiton -const char *nsText[] = { "Disconnected", "Authenticating", "HandshakeFailed", - "ObtainingIPAddress", "DhcpRequestFailed", "Connected" }; -const char *bsText[] = { "Initializing", "Running", "Terminating", "NotRunning" }; - -QWifiManagerPrivate::QWifiManagerPrivate(QWifiManager *manager) - : q_ptr(manager) - , m_networkListModel(new QWifiNetworkListModel(manager)) - , m_scanTimer(0) - , m_scanning(false) - , m_interface(QWifiDevice::wifiInterfaceName()) - , m_backendState(QWifiManager::NotRunning) - , m_networkState(QWifiManager::Disconnected) -{ - qCDebug(B2QT_WIFI) << "using wifi interface: " << m_interface; -} - -QWifiManagerPrivate::~QWifiManagerPrivate() -{ - delete m_wifiController; -} - -void QWifiManagerPrivate::setCurrentSSID(const QString &ssid) -{ - Q_Q(QWifiManager); - qCDebug(B2QT_WIFI) << "current SSID: " << m_currentSSID << " -> " << ssid; - if (m_currentSSID == ssid) - return; - - m_currentSSID = ssid; - emit q->currentSSIDChanged(m_currentSSID); -} - -void QWifiManagerPrivate::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(QWifiManager::Authenticating); -} - -void QWifiManagerPrivate::handleConnected() -{ - qCDebug(B2QT_WIFI) << "connected network: " << m_currentSSID; - updateNetworkState(QWifiManager::ObtainingIPAddress); - m_wifiController->asyncCall(QWifiController::AcquireIPAddress); -} - -void QWifiManagerPrivate::handleDisconneced() -{ - updateNetworkState(QWifiManager::Disconnected); -} - -void QWifiManagerPrivate::updateNetworkState(QWifiManager::NetworkState networkState) -{ - Q_Q(QWifiManager); - qCDebug(B2QT_WIFI, "network state: %s -> %s", nsText[m_networkState], nsText[networkState]); - if (m_networkState == networkState) - return; - - m_networkState = networkState; - emit q->networkStateChanged(m_networkState); -} - -void QWifiManagerPrivate::updateBackendState(QWifiManager::BackendState backendState) -{ - Q_Q(QWifiManager); - qCDebug(B2QT_WIFI, "backend state: %s -> %s", bsText[m_backendState], bsText[backendState]); - if (m_backendState == backendState) - return; - - m_backendState = backendState; - emit q->backendStateChanged(m_backendState); -} - -void QWifiManagerPrivate::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 = QWifiManager::Running; -} - -QString QWifiManagerPrivate::call(const QString &command) -{ - if (m_backendState != QWifiManager::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 QWifiManagerPrivate::checkedCall(const QString &command) -{ - return call(command).toUpper() == QLatin1String("OK"); -} - -void QWifiManagerPrivate::updateLastError(const QString &error) -{ - Q_Q(QWifiManager); - qCWarning(B2QT_WIFI) << error; - m_lastError = error; - emit q->lastErrorChanged(m_lastError); -} - -/*! - \class QWifiManager - \inmodule B2Qt.Wifi.Cpp - \ingroup wifi-cppclasses - \brief Enables an application to be Wifi-capable. - - QWifiManager is a singleton class that handles Wifi-related tasks. You can - use QWifiManager to control the Wifi backend, scan for Wifi access points, - and connect to a wireless network. - - QWifiManager packs the scan results in a list-based data model, which can - be used with Qt's Model/View classes. Information about a Wifi network can - be accessed using the QWifiManager::Roles data roles. -*/ - -/*! - \enum QWifiManager::NetworkState - - Describes current state of the network connection. - - \value Disconnected Not connected to any network - \value Authenticating Verifying password with the network provider - \value HandshakeFailed Incorrect password provided - \value ObtainingIPAddress Requesting IP address from DHCP server - \value DhcpRequestFailed Could not retrieve IP address - \value Connected Ready to process network requests -*/ - -/*! - \enum QWifiManager::BackendState - - Describes current state of the Wifi backend. - - \value Initializing Wireless supplicant is starting up - \value Running Supplicant is initialized and ready to process commands - \value Terminating Shutting down wireless supplicant - \value NotRunning Wireless supplicant process is not running -*/ - -/*! - \enum QWifiManager::Roles - - Data roles supported by the data model returned from QWifiManager::networks() - - \value SSID informal (human) name of a Wifi network (QString) - \value BSSID basic service set identification of a network, used to uniquely identify BSS (QString) - \value SignalStrength strength of a Wifi signal represented as percentage (0-100) (int) - \value WPASupported holds whether network access point supports WPA security protocol (bool) - \value WPA2Supported holds whether network access point supports WPA2 security protocol (bool) - \value WEPSupported holds whether network access point supports WEP security protocol (bool) - \value WPSSupported holds whether network access point supports WPS security protocol (bool) -*/ - -QWifiManager* QWifiManager::m_instance = 0; - -/*! - Returns a singleton instance of QWifiManager. -*/ -QWifiManager* QWifiManager::instance() -{ - if (!m_instance) - m_instance = new QWifiManager(); - return m_instance; -} - -QWifiManager::QWifiManager() - : d_ptr(new QWifiManagerPrivate(this)) -{ - Q_D(QWifiManager); - - if (!QWifiDevice::wifiSupported()) - qCWarning(B2QT_WIFI) << "WifiManager may not work as expected on this device. Use the API provided by QtWifi " - "library to verify if device has support for Wi-Fi before creating an instance of wifi manager"; - - d->m_wifiController = new QWifiController(this, d_ptr); - QObject::connect(d->m_wifiController, &QWifiController::backendStateChanged, - this, &QWifiManager::handleBackendStateChanged); - QObject::connect(d->m_wifiController, &QWifiController::dhcpRequestFinished, - this, &QWifiManager::handleDhcpRequestFinished); - d->m_wifiController->start(); - - d->updateWifiState(); -} - -/*! - Destroys the QWifiManager singleton instance. - */ -QWifiManager::~QWifiManager() -{ - Q_D(QWifiManager); - d->m_wifiController->asyncCall(QWifiController::ExitEventLoop); - d->m_wifiController->wait(); - delete d_ptr; -} - -/*! - \property QWifiManager::networks - \brief a list-based data model of networks - - Returns a list-based data model of networks that can be sensed by a device. - Model can be used with Qt's Model/View classes such as QListView. Data in - the model is updated every 5 seconds if scanning is enabled. - - \sa isScanning() -*/ -QAbstractListModel *QWifiManager::networks() const -{ - Q_D(const QWifiManager); - return d->m_networkListModel; -} - -/*! - \property QWifiManager::currentSSID - \brief a network name of the last selected network - - The network for which the NetworkState change signals are emitted. - Property can contain an empty string when there is no active network - connection. -*/ -QString QWifiManager::currentSSID() const -{ - Q_D(const QWifiManager); - return d->m_currentSSID; -} - -/*! - \property QWifiManager::networkState - \brief the current network state - - Returns the current network state. -*/ -QWifiManager::NetworkState QWifiManager::networkState() const -{ - Q_D(const QWifiManager); - return d->m_networkState; -} - -/*! - \property QWifiManager::backendState - \brief the current backend state. - - Returns the current backend state. -*/ -QWifiManager::BackendState QWifiManager::backendState() const -{ - Q_D(const QWifiManager); - return d->m_backendState; -} - -/*! - Start the Wifi backend. This function returns immediately, the BackendState - change events are delivered asynchronously. - - \sa stop(), BackendState -*/ -void QWifiManager::start() -{ - Q_D(QWifiManager); - d->m_wifiController->asyncCall(QWifiController::InitializeBackend); -} - -/*! - Stop the Wifi backend. Closes the open network connection if any. - This function returns immediately, and the BackendState change events are - delivered asynchronously. - - \sa start(), BackendState -*/ -void QWifiManager::stop() -{ - Q_D(QWifiManager); - d->m_wifiController->asyncCall(QWifiController::TerminateBackend); -} - -/*! - \property QWifiManager::scanning - \brief whether the backend is scanning for Wifi networks. - - Sets whether to scan the environment for Wifi access points. - - To preserve battery energy, set this property to false when scanning is not required. - When enabled, new readings are taken every 5 seconds. - - \note You must initialize the Wifi backend to scan for networks. - - \sa start() -*/ -bool QWifiManager::isScanning() const -{ - Q_D(const QWifiManager); - return d->m_scanning; -} - -void QWifiManager::setScanning(bool scanning) -{ - Q_D(QWifiManager); - if (d->m_scanning == scanning) - return; - - d->m_scanning = scanning; - emit scanningChanged(d->m_scanning); - if (d->m_scanning) { - d->call(QStringLiteral("SCAN")); - // ### TODO expose this with a property - d->m_scanTimer = startTimer(5000); - } else { - killTimer(d->m_scanTimer); - } -} - -/*! - \property QWifiManager::lastError - \brief a QString containing the last error message set by QWifiManager. - - Returns a QString containing the last error message set by QWifiManager. - This helps in diagnosing the internal process failures. - - \sa connect() -*/ -QString QWifiManager::lastError() const -{ - Q_D(const QWifiManager); - return d->m_lastError; -} - -/*! \reimp */ -bool QWifiManager::event(QEvent *event) -{ - Q_D(QWifiManager); - switch ((int) event->type()) { - case WIFI_SCAN_RESULTS: - d->m_networkListModel->parseScanResults(d->call(QStringLiteral("SCAN_RESULTS"))); - return true; - case WIFI_CONNECTED: - d->handleConnected(); - return true; - case WIFI_DISCONNECTED: - d->handleDisconneced(); - return true; - case WIFI_AUTHENTICATING: - d->handleAuthenticating(static_cast(event)); - return true; - case WIFI_HANDSHAKE_FAILED: - d->updateNetworkState(QWifiManager::HandshakeFailed); - return true; - case QEvent::Timer: { - int tid = static_cast(event)->timerId(); - if (tid == d->m_scanTimer) { - d->call(QStringLiteral("SCAN")); - return true; - } - break; - } - } - return QObject::event(event); -} - -/*! - Connect a device to a network using the \a config network configuration. - This method returns \c true if the network with the provided configuration - could be successfully added by the backend or \c false on failure. - Use lastError() to obtain the error message on failure. - - \sa disconnect(), NetworkState, lastError() -*/ -bool QWifiManager::connect(QWifiConfiguration *config) -{ - Q_D(QWifiManager); - if (d->m_backendState != Running) { - qCWarning(B2QT_WIFI) << "start wifi backend before calling connect()"; - return false; - } - - d->call(QStringLiteral("DISABLE_NETWORK all")); - d->setCurrentSSID(config->ssid()); - - bool networkKnown = false; - QString id; - const QStringList configuredNetworks = d->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 == d->m_currentSSID) { - id = networkFields.at(0); - networkKnown = true; - break; - } - } - - if (!networkKnown) { - bool ok; - id = d->call(QStringLiteral("ADD_NETWORK")); - id.toInt(&ok); - if (!ok) { - d->updateLastError(QStringLiteral("failed to add network")); - return false; - } - } - - bool ok = true; - QChar q = QLatin1Char('"'); - QString setNetworkCommand = QLatin1String("SET_NETWORK ") + id; - if (!networkKnown) { - ok = ok && d->checkedCall(setNetworkCommand + QLatin1String(" ssid ") + q + d->m_currentSSID + q); - } - - QString key_mgmt; - QString protocol = config->protocol().toUpper(); - QString psk = config->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 (protocol.isEmpty() || protocol.contains(QStringLiteral("WPA"))) { - // ### 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 && d->checkedCall(setNetworkCommand + QLatin1String(" psk ") + q + psk + q); - key_mgmt = QLatin1String("WPA-PSK"); - } else if (protocol.contains(QStringLiteral("WEP"))) { - ok = ok && d->checkedCall(setNetworkCommand + QLatin1String(" wep_key0 ") + q + psk + q); - ok = ok && d->checkedCall(setNetworkCommand + QLatin1String(" auth_alg OPEN SHARED")); - key_mgmt = QLatin1String("NONE"); - } else if (protocol.contains(QStringLiteral("WPS")) && psk.length() == 0) { - // open network - key_mgmt = QLatin1String("NONE"); - } - - if (config->isSsidHidden()) - ok = ok && d->checkedCall(setNetworkCommand + QLatin1String(" scan_ssid 1")); - - ok = ok && d->checkedCall(setNetworkCommand + QLatin1String(" key_mgmt ") + key_mgmt); - if (!ok) { - if (!networkKnown) - d->call(QLatin1String("REMOVE_NETWORK ") + id); - d->updateLastError(QLatin1String("failed to set properties on network: ") + id); - return false; - } - - d->call(QLatin1String("SELECT_NETWORK ") + id); - d->call(QStringLiteral("RECONNECT")); - - return true; -} - -/*! - Disconnect from currently connected network connection. - - \sa connect(), networkState() -*/ -void QWifiManager::disconnect() -{ - Q_D(QWifiManager); - d->call(QStringLiteral("DISCONNECT")); - d->m_wifiController->asyncCall(QWifiController::StopDhcp); -} - -void QWifiManager::handleBackendStateChanged(BackendState backendState) -{ - Q_D(QWifiManager); - switch (backendState) { - case NotRunning: - d->updateNetworkState(Disconnected); - break; - default: - break; - } - d->updateBackendState(backendState); -} - -void QWifiManager::handleDhcpRequestFinished(const QString &status) -{ - Q_D(QWifiManager); - qCDebug(B2QT_WIFI) << "handleDhcpRequestFinished: " << status << " for " << d->m_currentSSID; - if (status == QLatin1String("success")) { - d->updateNetworkState(Connected); - d->call(QStringLiteral("SAVE_CONFIG")); - } else { - d->updateNetworkState(DhcpRequestFailed); - } -} - -QT_END_NAMESPACE diff --git a/src/wifi/qwifimanager.h b/src/wifi/qwifimanager.h deleted file mode 100644 index 7fc658c..0000000 --- a/src/wifi/qwifimanager.h +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** 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 QWIFIMANAGER_H -#define QWIFIMANAGER_H - -#include "qwificonfiguration.h" - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI) - -class QWifiManagerPrivate; -class QAbstractListModel; -class QWifiController; -class QWifiNetworkListModel; - -class Q_DECL_EXPORT QWifiManager : public QObject -{ - Q_OBJECT - Q_ENUMS(NetworkState) - Q_ENUMS(BackendState) - Q_PROPERTY(NetworkState networkState READ networkState NOTIFY networkStateChanged) - Q_PROPERTY(BackendState backendState READ backendState NOTIFY backendStateChanged) - Q_PROPERTY(bool scanning READ isScanning WRITE setScanning NOTIFY scanningChanged) - Q_PROPERTY(QString currentSSID READ currentSSID NOTIFY currentSSIDChanged) - Q_PROPERTY(QString lastError READ lastError NOTIFY lastErrorChanged) - Q_PROPERTY(QAbstractListModel *networks READ networks CONSTANT) -public: - enum NetworkState { - Disconnected, - Authenticating, - HandshakeFailed, - ObtainingIPAddress, - DhcpRequestFailed, - Connected - }; - - enum BackendState { - Initializing, - Running, - Terminating, - NotRunning - }; - - enum Roles { - SSID = Qt::UserRole + 1, - BSSID = Qt::UserRole + 2, - SignalStrength = Qt::UserRole + 3, - WPASupported = Qt::UserRole + 4, - WPA2Supported = Qt::UserRole + 5, - WEPSupported = Qt::UserRole + 6, - WPSSupported = Qt::UserRole + 7 - }; - - static QWifiManager *instance(); - virtual ~QWifiManager(); - - QAbstractListModel *networks() const; - QString currentSSID() const; - bool isScanning() const; - void setScanning(bool scanning); - NetworkState networkState() const; - BackendState backendState() const; - QString lastError() const; - -public slots: - void start(); - void stop(); - bool connect(QWifiConfiguration *config); - void disconnect(); - -signals: - void scanningChanged(bool scanning); - void networkStateChanged(NetworkState networkState); - void backendStateChanged(BackendState backendState); - void currentSSIDChanged(const QString ¤tSSID); - void lastErrorChanged(const QString &error); - -protected: - bool event(QEvent *event); - -private slots: - void handleBackendStateChanged(BackendState backendState); - void handleDhcpRequestFinished(const QString &status); - -private: - QWifiManager(); - static QWifiManager* m_instance; - friend class QWifiController; - Q_DISABLE_COPY(QWifiManager) - Q_DECLARE_PRIVATE(QWifiManager) - QWifiManagerPrivate *const d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QWIFIMANAGER_H diff --git a/src/wifi/qwifimanager_p.h b/src/wifi/qwifimanager_p.h deleted file mode 100644 index 5449551..0000000 --- a/src/wifi/qwifimanager_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** 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 QWIFIMANAGER_P_H -#define QWIFIMANAGER_P_H - -#include "qwifimanager.h" -#include "qwifidevice.h" - -#include - -QT_BEGIN_NAMESPACE - -class QWifiEvent; - -class QWifiManagerPrivate -{ - Q_DECLARE_PUBLIC(QWifiManager) -public: - QWifiManagerPrivate(QWifiManager *manager); - virtual ~QWifiManagerPrivate(); - - // methods - void setCurrentSSID(const QString &ssid); - void handleConnected(); - void handleDisconneced(); - void handleAuthenticating(QWifiEvent *event); - - void updateNetworkState(QWifiManager::NetworkState networkState); - void updateBackendState(QWifiManager::BackendState backendState); - void updateWifiState(); - - QString call(const QString &command); - bool checkedCall(const QString &command); - void updateLastError(const QString &error); - - // member variables - QWifiManager *const q_ptr; - QWifiController *m_wifiController; - QWifiNetworkListModel *m_networkListModel; - - int m_scanTimer; - bool m_scanning; - QByteArray m_interface; - QWifiManager::BackendState m_backendState; - QWifiManager::NetworkState m_networkState; - QString m_currentSSID; - QString m_lastError; -}; - -QT_END_NAMESPACE - -#endif // QWIFIMANAGER_P_H diff --git a/src/wifi/qwifinetwork.cpp b/src/wifi/qwifinetwork.cpp deleted file mode 100644 index eb2b669..0000000 --- a/src/wifi/qwifinetwork.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** 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 "qwifinetwork_p.h" - -QT_BEGIN_NAMESPACE - -QWifiNetwork::QWifiNetwork(QObject *parent) - : QObject(parent) - , m_isOutOfRange(false) -{ -} - -QWifiNetwork::~QWifiNetwork() -{ -} - -void QWifiNetwork::setSsid(const QString &ssid) -{ - m_ssid = ssid; -} - -void QWifiNetwork::setSignalStrength(int strength) -{ - m_signalStrength = strength; -} - -void QWifiNetwork::setOutOfRange(bool outOfRange) -{ - m_isOutOfRange = outOfRange; -} - -QT_END_NAMESPACE diff --git a/src/wifi/qwifinetwork_p.h b/src/wifi/qwifinetwork_p.h deleted file mode 100644 index db65e2d..0000000 --- a/src/wifi/qwifinetwork_p.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** 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 QWIFINETWORK_H -#define QWIFINETWORK_H - -#include -#include - -QT_BEGIN_NAMESPACE - -class QWifiNetwork : public QObject -{ - Q_OBJECT -public: - explicit QWifiNetwork(QObject *parent = 0); - virtual ~QWifiNetwork(); - - void setBssid(const QString &bssid) { m_bssid = bssid; } - QString bssid() const { return m_bssid; } - void setSsid(const QString &ssid); - QString ssid() const { return m_ssid; } - - void setSignalStrength(int strength); - int signalStrength() const { return m_signalStrength; } - - void setOutOfRange(bool isOutOfRange); - // this could be exposed in QWifiManager::Roles, - // if there is a use case for it, this would require keeping - // the out of range networks in data model, currently they are - // removed from the model. - bool isOutOfRange() const { return m_isOutOfRange; } - - void setFlags(const QString &flags) { m_flags = flags; } - QString flags() const { return m_flags; } - bool supportsWPA2() const { return m_flags.contains(QStringLiteral("WPA2")); } - bool supportsWPA() const { return m_flags.contains(QStringLiteral("WPA")); } - bool supportsWEP() const { return m_flags.contains(QStringLiteral("WEP")); } - bool supportsWPS() const { return m_flags.contains(QStringLiteral("WPS")); } - -private: - QString m_bssid; - QString m_ssid; - int m_signalStrength; - QString m_flags; - bool m_isOutOfRange; -}; - -QT_END_NAMESPACE - -#endif // QWIFINETWORK_H diff --git a/src/wifi/qwifinetworklistmodel.cpp b/src/wifi/qwifinetworklistmodel.cpp deleted file mode 100644 index fa3f7dc..0000000 --- a/src/wifi/qwifinetworklistmodel.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** 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 "qwifinetworklistmodel_p.h" -#include "qwifinetwork_p.h" -#include "qwifisupplicant_p.h" - -#include "qwifimanager.h" - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -QWifiNetworkListModel::QWifiNetworkListModel(QObject *parent) - : QAbstractListModel(parent) -{ -} - -QWifiNetworkListModel::~QWifiNetworkListModel() -{ - qDeleteAll(m_networks); - qDeleteAll(m_outOfRangeNetworks); - m_networks.clear(); - m_outOfRangeNetworks.clear(); -} - -QHash QWifiNetworkListModel::roleNames() const -{ - QHash names; - names.insert(QWifiManager::SSID, "ssid"); - names.insert(QWifiManager::BSSID, "bssid"); - names.insert(QWifiManager::SignalStrength, "signalStrength"); - names.insert(QWifiManager::WPASupported, "supportsWPA"); - names.insert(QWifiManager::WPA2Supported, "supportsWPA2"); - names.insert(QWifiManager::WEPSupported, "supportsWEP"); - names.insert(QWifiManager::WPSSupported, "supportsWPS"); - return names; -} - -QVariant QWifiNetworkListModel::data(const QModelIndex &index, int role) const -{ - QWifiNetwork *n = m_networks.at(index.row()); - - switch (role) { - case QWifiManager::SSID: - return n->ssid(); - break; - case QWifiManager::BSSID: - return n->bssid(); - break; - case QWifiManager::SignalStrength: - return n->signalStrength(); - break; - case QWifiManager::WPASupported: - return n->supportsWPA(); - break; - case QWifiManager::WPA2Supported: - return n->supportsWPA2(); - break; - case QWifiManager::WEPSupported: - return n->supportsWEP(); - break; - case QWifiManager::WPSSupported: - return n->supportsWPS(); - break; - default: - break; - } - - return QVariant(); -} - -QWifiNetwork *QWifiNetworkListModel::networkForSSID(const QString &ssid) -{ - int pos = 0; // unused - return networkForSSID(ssid, &pos); -} - -QWifiNetwork *QWifiNetworkListModel::networkForSSID(const QString &ssid, int *pos) -{ - for (int i = 0; i < m_networks.size(); ++i) { - if (m_networks.at(i)->ssid() == ssid) { - if (pos) - *pos = i; - return m_networks.at(i); - } - } - return 0; -} - -QWifiNetwork *QWifiNetworkListModel::outOfRangeListContains(const QString &ssid) -{ - for (int i = 0; i < m_outOfRangeNetworks.length(); ++i) - if (m_outOfRangeNetworks.at(i)->ssid() == ssid) - return m_outOfRangeNetworks.takeAt(i); - return 0; -} - -void QWifiNetworkListModel::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); - QWifiNetwork *knownNetwork = networkForSSID(ssid, &pos); - if (!knownNetwork) - knownNetwork = outOfRangeListContains(ssid); - - 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) { - QWifiNetwork *network = new QWifiNetwork(); - network->setOutOfRange(false); - network->setBssid(info.at(0)); - network->setFlags(info.at(3)); - network->setSignalStrength(signalStrength); - network->setSsid(ssid); - beginInsertRows(QModelIndex(), m_networks.size(), m_networks.size()); - m_networks << network; - endInsertRows(); - } else { - if (knownNetwork->isOutOfRange()) { - // known network has come back into a range - knownNetwork->setOutOfRange(false); - beginInsertRows(QModelIndex(), m_networks.size(), m_networks.size()); - m_networks << knownNetwork; - endInsertRows(); - pos = m_networks.length() - 1; - } - // ssids are the same, compare bssids.. - if (knownNetwork->bssid() == info.at(0)) { - // same access point, simply update the signal strength - knownNetwork->setSignalStrength(signalStrength); - knownNetwork->setOutOfRange(false); - dataChanged(createIndex(pos, 0), createIndex(pos, 0)); - } else if (knownNetwork->signalStrength() < signalStrength) { - // replace with a stronger access point within the same network - m_networks.at(pos)->setOutOfRange(false); - m_networks.at(pos)->setBssid(info.at(0)); - m_networks.at(pos)->setFlags(info.at(3)); - m_networks.at(pos)->setSignalStrength(signalStrength); - m_networks.at(pos)->setSsid(ssid); - dataChanged(createIndex(pos, 0), createIndex(pos, 0)); - } - } - } - // remove out-of-range networks from the data model - for (int i = 0; i < m_networks.size();) { - if (!sensibleNetworks.contains(m_networks.at(i)->ssid())) { - beginRemoveRows(QModelIndex(), i, i); - QWifiNetwork *n = m_networks.takeAt(i); - n->setOutOfRange(true); - m_outOfRangeNetworks.append(n); - endRemoveRows(); - } else { - ++i; - } - } -} - -QT_END_NAMESPACE diff --git a/src/wifi/qwifinetworklistmodel_p.h b/src/wifi/qwifinetworklistmodel_p.h deleted file mode 100644 index 25a2b31..0000000 --- a/src/wifi/qwifinetworklistmodel_p.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** 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 QWIFINETWORKLISTMODEL_H -#define QWIFINETWORKLISTMODEL_H - -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI) - -class QWifiNetwork; - -class QWifiNetworkListModel : public QAbstractListModel -{ - Q_OBJECT -public: - explicit QWifiNetworkListModel(QObject *parent = 0); - virtual ~QWifiNetworkListModel(); - - int rowCount(const QModelIndex &) const { return m_networks.size(); } - QVariant data(const QModelIndex &index, int role) const; - QHash roleNames() const; - - void parseScanResults(const QString &data); - QWifiNetwork *networkForSSID(const QString &ssid); - QWifiNetwork *networkForSSID(const QString &ssid, int *pos); - QWifiNetwork *outOfRangeListContains(const QString &ssid); - -private: - QList m_networks; - QList m_outOfRangeNetworks; -}; - -QT_END_NAMESPACE - -#endif // QWIFINETWORKLISTMODEL_H diff --git a/src/wifi/qwifisupplicant.cpp b/src/wifi/qwifisupplicant.cpp deleted file mode 100644 index d87ac80..0000000 --- a/src/wifi/qwifisupplicant.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/**************************************************************************** -** -** 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 "qwifimanager_p.h" - -#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, QWifiManagerPrivate *managerPrivate) : - QObject(parent), - ctrl_conn(0), - monitor_conn(0), - interface(QWifiDevice::wifiInterfaceName()), - m_managerPrivate(managerPrivate) -{ - createSupplicantConfig(); -} - -void QWifiSupplicant::createSupplicantConfig() const -{ - 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 { - m_managerPrivate->updateLastError(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()) { - m_managerPrivate->updateLastError(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()) { - m_managerPrivate->updateLastError(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()) { - m_managerPrivate->updateLastError(startStopDaemon.program() + QLatin1String(": ") + startStopDaemon.errorString()); - return false; - } - startStopDaemon.waitForFinished(); - QByteArray error = startStopDaemon.readAllStandardError(); - if (!error.isEmpty()) { - m_managerPrivate->updateLastError(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) - m_managerPrivate->updateLastError(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/wifi/qwifisupplicant_p.h b/src/wifi/qwifisupplicant_p.h deleted file mode 100644 index 0a6a964..0000000 --- a/src/wifi/qwifisupplicant_p.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** 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, QWifiManagerPrivate *managerPrivate); - - void createSupplicantConfig() const; - 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); - -protected: - int receiveEvent(char *reply, size_t *reply_len); - -private: - wpa_ctrl *ctrl_conn; - wpa_ctrl *monitor_conn; - int exit_sockets[2]; - QByteArray interface; - QWifiManagerPrivate *const m_managerPrivate; -}; - -QT_END_NAMESPACE - -#endif // QWIFISUPPLICANT_H diff --git a/src/wifi/wifi.pro b/src/wifi/wifi.pro deleted file mode 100644 index faf15f2..0000000 --- a/src/wifi/wifi.pro +++ /dev/null @@ -1,36 +0,0 @@ -load(qt_build_config) - -TARGET = B2QtWifi -VERSION = 1.0 -CONFIG += dll warn_on - -QT += core network - -MODULE = b2qtwifi -load(qt_module) - -HEADERS += \ - $$PWD/qwifimanager.h \ - $$PWD/qwifimanager_p.h \ - $$PWD/qwifinetwork_p.h \ - $$PWD/qwifinetworklistmodel_p.h \ - $$PWD/qwificontroller_p.h \ - $$PWD/qwifidevice.h \ - $$PWD/qwificonfiguration.h \ - $$PWD/qwifisupplicant_p.h - -SOURCES += \ - $$PWD/qwifimanager.cpp \ - $$PWD/qwifinetwork.cpp \ - $$PWD/qwifinetworklistmodel.cpp \ - $$PWD/qwificontroller.cpp \ - $$PWD/qwifidevice.cpp \ - $$PWD/qwificonfiguration.cpp \ - $$PWD/qwifisupplicant.cpp \ - $$[QT_SYSROOT]/usr/include/wpa-supplicant/wpa_ctrl.c \ - $$[QT_SYSROOT]/usr/include/wpa-supplicant/os_unix.c - -DEFINES += \ - CONFIG_CTRL_IFACE \ - CONFIG_CTRL_IFACE_UNIX - -- cgit v1.2.3