summaryrefslogtreecommitdiffstats
path: root/src/imports
diff options
context:
space:
mode:
authorKalle Viironen <kalle.viironen@digia.com>2014-04-16 09:38:20 +0300
committerKalle Viironen <kalle.viironen@digia.com>2014-04-16 09:38:20 +0300
commit83efd639f995fae2d0614a8f98205069eb5a58ee (patch)
tree298111e0c7846e08d48cf50f3533696d7330d4f7 /src/imports
parent4c6c06470f4998506d59de0a6488f40d50ca4154 (diff)
parentcef8834b27a7588886c0439d145004ae9ad33a13 (diff)
Merge branch 'stable' into dev
* stable: (22 commits) Add note about headphones on eAndroid Doc: Relocate unmount instructions Doc: Add ChangeLog for Qt Enterprise Embedded 2.1.0 Doc: Disable code highlighting for command-line instructions doc: update version number to 2.1.0 [Wifi] Add new enums and make some API changes Doc: Add documentation on custom build & deploy steps Doc: Create QML Type reference page Doc: Add information about licenses in embedded Linux images Doc: Improve instructions for deploying existing projects Doc: Separate Building Your Own Linux Image into its own page doc: use same directory for yocto and qt doc: config.<MACHINE> needed only once doc: guide for imx53 and how to setup QtCreator Doc: Be more precise on screen content for Nexus7 Add documentation to QtWifi library Doc: Add note for users to not use root for installation doc: describe how to use network connection for adb Rename misleading class name Remove unnecessary roles from QWifiNetworkList ... Conflicts: src/imports/wifi/qwifimanager.cpp Change-Id: Ie7efa2ec91ac154f1e984600f569d9c7f8383627
Diffstat (limited to 'src/imports')
-rw-r--r--src/imports/wifi/pluginmain.cpp31
-rw-r--r--src/imports/wifi/qwifimanager.cpp339
-rw-r--r--src/imports/wifi/qwifimanager.h20
-rw-r--r--src/imports/wifi/qwifinetwork.cpp75
-rw-r--r--src/imports/wifi/qwifinetwork.h8
-rw-r--r--src/imports/wifi/qwifinetworklistmodel.cpp (renamed from src/imports/wifi/qwifinetworklist.cpp)93
-rw-r--r--src/imports/wifi/qwifinetworklistmodel.h (renamed from src/imports/wifi/qwifinetworklist.h)13
-rw-r--r--src/imports/wifi/wifi.pro4
8 files changed, 478 insertions, 105 deletions
diff --git a/src/imports/wifi/pluginmain.cpp b/src/imports/wifi/pluginmain.cpp
index 3c560f9..fdf07e9 100644
--- a/src/imports/wifi/pluginmain.cpp
+++ b/src/imports/wifi/pluginmain.cpp
@@ -25,6 +25,35 @@
#include <hardware_legacy/wifi.h>
+/*!
+ \qmltype Interface
+ \inqmlmodule Qt.labs.wifi
+ \ingroup wifi-qmltypes
+ \brief The Interface element provides the module API.
+
+ This element cannot be directly created. It can only be accessed via a namespace import.
+
+ \code
+ import Qt.labs.wifi 0.1
+ import Qt.labs.wifi 0.1 as Wifi
+
+ Component.onCompleted: {
+ if (Wifi.Interface.wifiSupported()) {
+ var component = Qt.createComponent("WifiMenu.qml")
+ } else {
+ print("WiFi functionality not available on this device.")
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \qmlmethod bool Interface::wifiSupported()
+
+ Returns true if the device is WiFi capable (provides a WiFi driver), otherwise returns false.
+*/
+
+
class QWifiGlobal : public QObject
{
Q_OBJECT
@@ -68,7 +97,7 @@ public:
Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.wifi"));
qmlRegisterType<QWifiManager>(uri, 0, 1, "WifiManager");
- qmlRegisterType<QWifiNetworkList>();
+ qmlRegisterType<QWifiNetworkListModel>();
qmlRegisterSingletonType<QWifiGlobal>(uri, 0, 1, "Interface", global_object_wifi);
}
};
diff --git a/src/imports/wifi/qwifimanager.cpp b/src/imports/wifi/qwifimanager.cpp
index 160b9a7..7615f70 100644
--- a/src/imports/wifi/qwifimanager.cpp
+++ b/src/imports/wifi/qwifimanager.cpp
@@ -32,6 +32,7 @@ static bool QT_WIFI_DEBUG = !qgetenv("QT_WIFI_DEBUG").isEmpty();
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);
/*
* Work around API differences between Android versions
@@ -151,28 +152,30 @@ public:
}
void run() {
- if (QT_WIFI_DEBUG) qDebug("EventReceiver thread is running");
+ if (QT_WIFI_DEBUG) qDebug("WiFi event thread is running");
+ QWifiManagerEvent *event = 0;
char buffer[2048];
while (1) {
int size = q_wifi_wait_for_event(m_if.constData(), buffer, sizeof(buffer) - 1);
if (size > 0) {
buffer[size] = 0;
-
- if (QT_WIFI_DEBUG) qDebug("EVENT: %s", buffer);
-
- char *event = &buffer[11];
- if (strstr(event, "SCAN-RESULTS")) {
- if (m_manager->exitingEventThread())
+ event = 0;
+ if (strstr(buffer, "SCAN-RESULTS")) {
+ if (m_manager->exitingEventThread()) {
+ if (QT_WIFI_DEBUG) qDebug() << "Exiting WiFi event thread";
return;
- QWifiManagerEvent *e = new QWifiManagerEvent(WIFI_SCAN_RESULTS);
- QCoreApplication::postEvent(m_manager, e);
- } else if (strstr(event, "CONNECTED")) {
- QWifiManagerEvent *e = new QWifiManagerEvent(WIFI_CONNECTED);
- QCoreApplication::postEvent(m_manager, e);
- } else if (strstr(event, "TERMINATING")) {
+ }
+ event = new QWifiManagerEvent(WIFI_SCAN_RESULTS);
+ } else if (strstr(buffer, "CONNECTED")) {
+ event = new QWifiManagerEvent(WIFI_CONNECTED);
+ } else if (strstr(buffer, "Handshake failed")) {
+ event = new QWifiManagerEvent(WIFI_HANDSHAKE_FAILED);
+ } else if (strstr(buffer, "TERMINATING")) {
// stop monitoring for events when supplicant is terminating
return;
}
+ if (event)
+ QCoreApplication::postEvent(m_manager, event);
}
}
}
@@ -181,13 +184,236 @@ public:
QByteArray m_if;
};
+/*!
+ \qmlmodule Qt.labs.wifi 0.1
+ \title WiFi Module
+ \ingroup qtee-qmlmodules
+ \brief Controlling wireless network interfaces.
+
+ Provides QML types for controlling and accessing information about wireless network interfaces.
+
+ The import command for adding these QML types is:
+
+ \code
+ import Qt.labs.wifi 0.1
+ \endcode
+
+ If the module is imported into a namespace, some additional methods become available through the
+ \l Interface element.
+
+ \code
+ import Qt.labs.wifi 0.1 as Wifi
+ \endcode
+
+ \section1 QML Types
+*/
+
+/*!
+
+ \qmltype WifiManager
+ \inqmlmodule Qt.labs.wifi
+ \ingroup wifi-qmltypes
+ \brief Provides information about the WiFi backend and available networks.
+
+ This element is the main interface to the WiFi functionality.
+
+ */
+
+/*!
+ \qmlproperty enumeration WifiManager::networkState
+
+ 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 bool WifiManager::backendReady
+
+ This property holds whether or not the backend has been successfully initialized.
+
+ \code
+ WifiManager {
+ id: wifiManager
+ scanning: backendReady
+ }
+
+ Button {
+ id: wifiOnOffButton
+ text: (wifiManager.backendReady) ? "Switch Off" : "Switch On"
+ onClicked: {
+ if (wifiManager.backendReady) {
+ wifiManager.stop()
+ } else {
+ wifiManager.start()
+ }
+ }
+ }
+ \endcode
+*/
+
+/*!
+ \qmlproperty bool WifiManager::scanning
+
+ This property holds whether or not the backend is scanning for WiFi networks. To
+ preserve battery energy, stop scanning for networks once you are done with configuring a network.
+
+ Before starting to scan for networks, you need to initialize the WiFi backend.
+
+ \sa start
+*/
+
+/*!
+ \qmlproperty string WifiManager::connectedSSID
+
+ This property holds the network name.
+*/
+
+/*!
+ \qmlproperty WifiNetworkListModel WifiManager::networks
+
+ This property holds a list of networks that can be sensed by a device. Use the returned
+ model as data model in ListView, model is updated every 5 seconds.
+
+ WifiNetworkListModel is a simple data model consisting of WifiNetwork objects, accessed with
+ the "network" data role. Instances of WifiNetwork cannot be created directly from the QML system.
+
+ \code
+ WifiManager {
+ id: wifiManager
+ scanning: backendReady
+ Component.onCompleted: start()
+ }
+
+ Component {
+ id: listDelegate
+ Rectangle {
+ id: delegateBackground
+ height: 60
+ width: parent.width
+ color: "#5C5C5C"
+ border.color: "black"
+ border.width: 1
+
+ Text {
+ id: ssidLabel
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.margins: 10
+ font.pixelSize: 20
+ font.bold: true
+ color: "#E6E6E6"
+ text: network.ssid
+ }
+
+ Rectangle {
+ width: Math.max(100 + network.signalStrength, 0) / 100 * parent.width;
+ height: 20
+ radius: 10
+ antialiasing: true
+ anchors.margins: 20
+ anchors.right: parent.right
+ anchors.top: parent.top
+ color: "#BF8888"
+ border.color: "#212126"
+ }
+ }
+ }
+
+
+ ListView {
+ id: networkView
+ anchors.fill: parent
+ model: wifiManager.networks
+ delegate: listDelegate
+ }
+ \endcode
+
+*/
+
+/*!
+ \qmlmethod void WifiManager::start()
+
+ Start an initialization of the WiFi backend.
+
+ \sa stop
+ */
+
+/*!
+ \qmlmethod void WifiManager::stop()
+
+ Stop the WiFi backend and shut down all network functionality.
+
+ \sa start
+ */
+
+/*!
+ \qmlmethod void WifiManager::connect(WifiNetwork network, const string passphrase)
+
+ Connect to network \a network and use passphrase \a passphrase for authentication.
+
+ \sa disconnect, networkState
+ */
+
+/*!
+ \qmlmethod void WifiManager::disconnect()
+
+ Disconnect from currently connected network connection.
+
+ \sa connect, networkState
+ */
+
+/*!
+ \qmlsignal void WifiManager::scanningChanged(bool scanning)
+
+ This signal is emitted when device starts or stops to scan for available wifi networks.
+
+ \sa scanning
+
+*/
+
+/*!
+ \qmlsignal void WifiManager::networkStateChanged(WifiNetwork network)
+
+ This signal is emitted whenever changes in a network state occur. Network \a network is the
+ the currently active network connection.
+
+ \sa networkState
+*/
+
+/*!
+ \qmlsignal void WifiManager::backendReadyChanged()
+
+ This signal is emitted when backend has been successfully initialized or shut down.
+
+ \sa start, stop
+*/
+
+/*!
+ \qmlsignal void WifiManager::connectedSSIDChanged(string ssid)
+
+ This signal is emitted when the device has connected to or disconnected from a network.
+ \a ssid contains the name of the connected network, or an empty string if the network was disconnected.
+
+ \sa connect, disconnect
+*/
+
QWifiManager::QWifiManager()
- : m_networks(this)
+ : m_networkListModel(this)
, m_eventThread(0)
, m_scanTimer(0)
, m_scanning(false)
, m_daemonClientSocket(0)
, m_exitingEventThread(false)
+ , m_startingUp(true)
+ , m_network(0)
{
char interface[PROPERTY_VALUE_MAX];
property_get(WIFI_INTERFACE, interface, NULL);
@@ -205,15 +431,15 @@ QWifiManager::QWifiManager()
qWarning() << "QWifiManager: failed to connect to qconnectivity socket";
}
// check if backend has already been initialized
- char backend_status[PROPERTY_VALUE_MAX];
- if (property_get(QT_WIFI_BACKEND, backend_status, NULL)) {
- if (strcmp(backend_status, "running") == 0) {
+ char backendStatus[PROPERTY_VALUE_MAX];
+ if (property_get(QT_WIFI_BACKEND, backendStatus, NULL)) {
+ if (strcmp(backendStatus, "running") == 0) {
// let it re-connect, in most cases this will see that everything is working properly
// and will do nothing. Special case is when process has crashed or was killed by a system
// signal in previous execution, which results in broken connection to a supplicant,
// connectToBackend will fix it..
connectToBackend();
- } else if (strcmp(backend_status, "stopped") == 0) {
+ } else if (strcmp(backendStatus, "stopped") == 0) {
// same here, cleans up the state
disconnectFromBackend();
}
@@ -222,12 +448,7 @@ QWifiManager::QWifiManager()
QWifiManager::~QWifiManager()
{
- // exit event thread if it is running
- if (m_eventThread->isRunning()) {
- m_exitingEventThread = true;
- call("SCAN");
- m_eventThread->wait();
- }
+ exitEventThread();
delete m_eventThread;
delete m_daemonClientSocket;
}
@@ -239,14 +460,12 @@ void QWifiManager::handleDhcpReply()
receivedMessage = m_daemonClientSocket->readLine(m_daemonClientSocket->bytesAvailable());
if (QT_WIFI_DEBUG) qDebug() << "QWifiManager: reply from qconnectivity: " << receivedMessage;
if (receivedMessage == "success") {
- m_state = Connected;
- emit networkStateChanged();
+ updateNetworkState(Connected);
emit connectedSSIDChanged(m_connectedSSID);
// Store settings of a working wifi connection
call("SAVE_CONFIG");
} else if (receivedMessage == "failed") {
- m_state = DhcpRequestFailed;
- emit networkStateChanged();
+ updateNetworkState(DhcpRequestFailed);
} else {
qWarning() << "QWifiManager: unknown message: " << receivedMessage;
}
@@ -272,12 +491,16 @@ void QWifiManager::connectedToDaemon()
void QWifiManager::start()
{
if (QT_WIFI_DEBUG) qDebug("QWifiManager: connecting to the backend");
+ if (m_backendReady)
+ return;
connectToBackend();
}
void QWifiManager::stop()
{
if (QT_WIFI_DEBUG) qDebug("QWifiManager: shutting down");
+ if (!m_backendReady)
+ return;
disconnectFromBackend();
}
@@ -306,15 +529,12 @@ void QWifiManager::connectToBackend()
if (QT_WIFI_DEBUG) qDebug("QWifiManager: started successfully");
m_exitingEventThread = false;
m_eventThread->start();
- handleConnected();
+ call("SCAN");
}
void QWifiManager::disconnectFromBackend()
{
- m_exitingEventThread = true;
- call("SCAN");
- m_eventThread->wait();
-
+ exitEventThread();
if (q_wifi_stop_supplicant() < 0)
qWarning("QWifiManager: failed to stop supplicant");
q_wifi_close_supplicant_connection(m_interface.constData());
@@ -323,9 +543,18 @@ void QWifiManager::disconnectFromBackend()
emit backendReadyChanged();
}
+void QWifiManager::exitEventThread()
+{
+ if (m_eventThread->isRunning()) {
+ m_exitingEventThread = true;
+ call("SCAN");
+ m_eventThread->wait();
+ }
+}
+
void QWifiManager::setScanning(bool scanning)
{
- if (m_scanning == scanning)
+ if (!m_backendReady || m_scanning == scanning)
return;
m_scanning = scanning;
@@ -361,15 +590,27 @@ bool QWifiManager::checkedCall(const char *command) const
return call(command).trimmed().toUpper() == "OK";
}
+void QWifiManager::updateNetworkState(NetworkState state)
+{
+ m_state = state;
+ if (m_network)
+ emit networkStateChanged(m_network);
+}
+
bool QWifiManager::event(QEvent *e)
{
switch ((int) e->type()) {
case WIFI_SCAN_RESULTS:
- m_networks.parseScanResults(call("SCAN_RESULTS"));
+ m_networkListModel.parseScanResults(call("SCAN_RESULTS"));
+ if (m_startingUp)
+ handleConnected();
return true;
case WIFI_CONNECTED:
handleConnected();
break;
+ case WIFI_HANDSHAKE_FAILED:
+ updateNetworkState(HandshakeFailed);
+ break;
case QEvent::Timer: {
int tid = static_cast<QTimerEvent *>(e)->timerId();
if (tid == m_scanTimer) {
@@ -385,10 +626,13 @@ bool QWifiManager::event(QEvent *e)
void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
{
+ m_network = network;
if (network->ssid() == m_connectedSSID) {
- if (QT_WIFI_DEBUG) qDebug("QWifiManager::connect(), already connected to %s", network->ssid().constData());
+ if (QT_WIFI_DEBUG)
+ qDebug("QWifiManager::connect(), already connected to %s", network->ssid().constData());
return;
}
+ updateNetworkState(Authenticating);
call("DISABLE_NETWORK all");
if (!m_connectedSSID.isEmpty()) {
@@ -396,16 +640,13 @@ void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
emit connectedSSIDChanged(m_connectedSSID);
}
- m_state = ObtainingIPAddress;
- emit networkStateChanged();
bool networkKnown = false;
QByteArray id;
QByteArray listResult = call("LIST_NETWORKS");
QList<QByteArray> lines = listResult.split('\n');
foreach (const QByteArray &line, lines) {
if (line.contains(network->ssid())) {
- int networkId = line.toInt();
- id = QByteArray::number(networkId);
+ id = line.split('\t').at(0);
networkKnown = true;
break;
}
@@ -413,7 +654,7 @@ void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
if (!networkKnown) {
bool ok;
- QByteArray id = call("ADD_NETWORK").trimmed();
+ id = call("ADD_NETWORK").trimmed();
id.toInt(&ok);
if (!ok) {
qWarning("QWifiManager::connect(), failed to add network");
@@ -456,9 +697,8 @@ void QWifiManager::disconnect()
call("DISCONNECT");
QByteArray req = m_interface;
sendDhcpRequest(req.append(" disconnect"));
- m_state = Disconnected;
m_connectedSSID.clear();
- emit networkStateChanged();
+ updateNetworkState(Disconnected);
emit connectedSSIDChanged(m_connectedSSID);
}
@@ -466,7 +706,7 @@ void QWifiManager::handleConnected()
{
QList<QByteArray> lists = call("LIST_NETWORKS").split('\n');
QByteArray connectedNetwork;
- for (int i=1; i<lists.size(); ++i) {
+ for (int i = 1; i < lists.size(); ++i) {
if (lists.at(i).toUpper().contains("[CURRENT]")) {
connectedNetwork = lists.at(i);
break;
@@ -475,8 +715,6 @@ void QWifiManager::handleConnected()
if (connectedNetwork.isEmpty()) {
if (QT_WIFI_DEBUG) qDebug("QWifiManager::handleConnected: not connected to a network...");
- m_state = Disconnected;
- emit networkStateChanged();
return;
}
@@ -485,6 +723,15 @@ void QWifiManager::handleConnected()
QList<QByteArray> info = connectedNetwork.split('\t');
m_connectedSSID = info.at(1);
+ if (m_startingUp) {
+ m_startingUp = false;
+ if (!m_network) {
+ int pos = 0; // unused
+ m_network = m_networkListModel.networkForSSID(info.at(1), &pos);
+ }
+ }
+
+ updateNetworkState(ObtainingIPAddress);
QByteArray req = m_interface;
sendDhcpRequest(req.append(" connect"));
}
diff --git a/src/imports/wifi/qwifimanager.h b/src/imports/wifi/qwifimanager.h
index 432f411..162190e 100644
--- a/src/imports/wifi/qwifimanager.h
+++ b/src/imports/wifi/qwifimanager.h
@@ -25,7 +25,7 @@
#include <cutils/properties.h>
-#include "qwifinetworklist.h"
+#include "qwifinetworklistmodel.h"
class QWifiManagerEventThread;
@@ -37,11 +37,13 @@ class QWifiManager : public QObject
Q_PROPERTY(bool backendReady READ isbackendReady NOTIFY backendReadyChanged)
Q_PROPERTY(bool scanning READ scanning WRITE setScanning NOTIFY scanningChanged)
Q_PROPERTY(QString connectedSSID READ connectedSSID NOTIFY connectedSSIDChanged)
- Q_PROPERTY(QWifiNetworkList *networks READ networks CONSTANT)
+ Q_PROPERTY(QWifiNetworkListModel *networks READ networks CONSTANT)
public:
enum NetworkState {
Disconnected,
+ Authenticating,
+ HandshakeFailed,
ObtainingIPAddress,
DhcpRequestFailed,
Connected
@@ -50,7 +52,7 @@ public:
QWifiManager();
~QWifiManager();
- QWifiNetworkList *networks() { return &m_networks; }
+ QWifiNetworkListModel *networks() { return &m_networkListModel; }
QString connectedSSID() const { return m_connectedSSID; }
bool scanning() const { return m_scanning; }
void setScanning(bool scanning);
@@ -65,10 +67,10 @@ public slots:
void disconnect();
signals:
- void scanningChanged(bool arg);
- void networkStateChanged();
+ void scanningChanged(bool scanning);
+ void networkStateChanged(QWifiNetwork *network);
void backendReadyChanged();
- void connectedSSIDChanged(const QString &);
+ void connectedSSIDChanged(const QString &ssid);
protected:
bool event(QEvent *);
@@ -76,8 +78,10 @@ protected:
void handleConnected();
void connectToBackend();
void disconnectFromBackend();
+ void exitEventThread();
QByteArray call(const char *command) const;
bool checkedCall(const char *command) const;
+ void updateNetworkState(NetworkState state);
protected slots:
void connectedToDaemon();
@@ -87,7 +91,7 @@ private:
friend class QWifiManagerEventThread;
QString m_connectedSSID;
- QWifiNetworkList m_networks;
+ QWifiNetworkListModel m_networkListModel;
QWifiManagerEventThread *m_eventThread;
int m_scanTimer;
@@ -99,6 +103,8 @@ private:
QLocalSocket *m_daemonClientSocket;
QByteArray m_request;
bool m_exitingEventThread;
+ bool m_startingUp;
+ QWifiNetwork *m_network;
};
#endif // QWIFIMANAGER_H
diff --git a/src/imports/wifi/qwifinetwork.cpp b/src/imports/wifi/qwifinetwork.cpp
index a159e59..d4c20ef 100644
--- a/src/imports/wifi/qwifinetwork.cpp
+++ b/src/imports/wifi/qwifinetwork.cpp
@@ -18,7 +18,73 @@
****************************************************************************/
#include "qwifinetwork.h"
-QWifiNetwork::QWifiNetwork()
+/*!
+ \qmltype WifiNetwork
+ \inqmlmodule Qt.labs.wifi
+ \ingroup wifi-qmltypes
+ \brief Represents a single WiFi network access point.
+
+ Instances of WifiNetwork cannot be created directly from the QML system, use
+ WifiManager::networks.
+*/
+
+/*!
+ \qmlproperty string WifiNetwork::bssid
+
+ This property holds basic service set identification of a network, used to uniquely
+ identify BSS.
+
+*/
+
+/*!
+ \qmlproperty string WifiNetwork::ssid
+
+ This property holds a network name. The SSID is the informal (human) name of BSS.
+*/
+
+/*!
+ \qmlproperty int WifiNetwork::signalStrength
+
+ This property holds the current strength of a WiFi signal, measured in dBm. New readings are
+ taken every 5 seconds.
+
+ \sa signalStrengthChanged
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWPA
+
+ This property holds whether network access point supports WPA security protocol.
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWPA2
+
+ This property holds whether network access point supports WPA2 security protocol.
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWEP
+
+ This property holds whether network access point supports WEP security protocol.
+*/
+
+/*!
+ \qmlproperty bool WifiNetwork::supportsWPS
+
+ This property holds whether network access point supports WPS security protocol.
+*/
+
+/*!
+ \qmlsignal void WifiNetwork::signalStrengthChanged(int strength)
+
+ This signal is emitted whenever signal strength has changed comparing the the
+ previous reading, the new signal's strength is \a strength.
+
+*/
+
+QWifiNetwork::QWifiNetwork() :
+ m_outOfRange(false)
{
}
@@ -29,3 +95,10 @@ void QWifiNetwork::setSignalStrength(int strength)
m_signalStrength = strength;
emit signalStrengthChanged(m_signalStrength);
}
+
+void QWifiNetwork::setOutOfRange(bool outOfRange)
+{
+ if (m_outOfRange == outOfRange)
+ return;
+ m_outOfRange = outOfRange;
+}
diff --git a/src/imports/wifi/qwifinetwork.h b/src/imports/wifi/qwifinetwork.h
index 780fc87..5ecc6a3 100644
--- a/src/imports/wifi/qwifinetwork.h
+++ b/src/imports/wifi/qwifinetwork.h
@@ -22,8 +22,6 @@
#include <QtCore/QByteArray>
#include <QtCore/QObject>
-class QWifiManager;
-
class QWifiNetwork : public QObject
{
Q_OBJECT
@@ -48,6 +46,9 @@ public:
int signalStrength() const { return m_signalStrength; }
void setSignalStrength(int strength);
+ void setOutOfRange(bool outOfRange);
+ bool outOfRange() { return m_outOfRange; }
+
QByteArray flags() const { return m_flags; }
void setFlags(const QByteArray &f) { m_flags = f; }
bool supportsWPA2() const { return m_flags.contains("WPA2"); }
@@ -56,7 +57,7 @@ public:
bool supportsWPS() const { return m_flags.contains("WPS"); }
signals:
- void signalStrengthChanged(int arg);
+ void signalStrengthChanged(int strength);
private:
QByteArray m_bssid;
@@ -64,6 +65,7 @@ private:
int m_signalStrength;
QByteArray m_flags;
+ bool m_outOfRange;
};
#endif // QWIFINETWORK_H
diff --git a/src/imports/wifi/qwifinetworklist.cpp b/src/imports/wifi/qwifinetworklistmodel.cpp
index 60fdc53..4fbf25f 100644
--- a/src/imports/wifi/qwifinetworklist.cpp
+++ b/src/imports/wifi/qwifinetworklistmodel.cpp
@@ -16,55 +16,47 @@
** the contact form at http://qt.digia.com/
**
****************************************************************************/
-#include "qwifinetworklist.h"
+#include "qwifinetworklistmodel.h"
#include <QtCore>
-const int ID_BSSID = (Qt::ItemDataRole) (Qt::UserRole + 1);
-const int ID_SSID = (Qt::ItemDataRole) (Qt::UserRole + 2);
-const int ID_SIGNAL = (Qt::ItemDataRole) (Qt::UserRole + 3);
-const int ID_WPA2 = (Qt::ItemDataRole) (Qt::UserRole + 4);
-const int ID_WPA = (Qt::ItemDataRole) (Qt::UserRole + 5);
-const int ID_NETWORK = (Qt::ItemDataRole) (Qt::UserRole + 6);
+const int ID_NETWORK = (Qt::ItemDataRole) (Qt::UserRole + 1);
-QWifiNetworkList::QWifiNetworkList(QWifiManager *manager)
+QWifiNetworkListModel::QWifiNetworkListModel(QWifiManager *manager)
: m_manager(manager)
{
}
-QHash<int, QByteArray> QWifiNetworkList::roleNames() const
+QWifiNetworkListModel::~QWifiNetworkListModel()
+{
+ qDeleteAll(m_networks);
+ qDeleteAll(m_outOfRangeNetworks);
+ m_networks.clear();
+ m_outOfRangeNetworks.clear();
+}
+
+QHash<int, QByteArray> QWifiNetworkListModel::roleNames() const
{
QHash<int, QByteArray> names;
- names.insert(ID_BSSID, "bssid");
- names.insert(ID_SSID, "ssid");
- names.insert(ID_SIGNAL, "strength");
- names.insert(ID_WPA2, "wpa2");
- names.insert(ID_WPA, "wpa");
names.insert(ID_NETWORK, "network");
return names;
}
-QVariant QWifiNetworkList::data(const QModelIndex &index, int role) const
+QVariant QWifiNetworkListModel::data(const QModelIndex &index, int role) const
{
QWifiNetwork *n = m_networks.at(index.row());
-
switch (role) {
- case ID_BSSID: return n->bssid();
- case ID_SSID: return n->ssid();
- case ID_SIGNAL: return n->signalStrength();
- case ID_WPA2: return n->supportsWPA2();
- case ID_WPA: return n->supportsWPA();
- case ID_NETWORK: return QVariant::fromValue((QObject *) n);
+ case ID_NETWORK: return QVariant::fromValue((QObject *) n);
}
- qWarning("QWifiNetworkList::data(), undefined role: %d\n", role);
+ qWarning("QWifiNetworkListModel::data(), undefined role: %d\n", role);
return QVariant();
}
-QWifiNetwork *QWifiNetworkList::networkForSSID(const QByteArray &ssid, int *pos)
+QWifiNetwork *QWifiNetworkListModel::networkForSSID(const QByteArray &ssid, int *pos)
{
- for (int i=0; i<m_networks.size(); ++i) {
+ for (int i = 0; i < m_networks.size(); ++i) {
if (m_networks.at(i)->ssid() == ssid) {
if (pos)
*pos = i;
@@ -74,21 +66,32 @@ QWifiNetwork *QWifiNetworkList::networkForSSID(const QByteArray &ssid, int *pos)
return 0;
}
-void QWifiNetworkList::parseScanResults(const QByteArray &results)
+QWifiNetwork *QWifiNetworkListModel::outOfRangeListContains(const QByteArray &ssid)
{
- QList<QByteArray> lines = results.split('\n');
+ 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 QByteArray &results)
+{
+ QList<QByteArray> lines = results.split('\n');
QSet<QByteArray> sensibleNetworks;
- for (int i=1; i<lines.size(); ++i) {
+
+ for (int i = 1; i < lines.size(); ++i) {
QList<QByteArray> info = lines.at(i).split('\t');
if (info.size() < 5 || info.at(4).isEmpty() || info.at(0).isEmpty())
continue;
int pos = 0;
- if (!sensibleNetworks.contains(info.at(4)))
- sensibleNetworks.insert(info.at(4));
- QWifiNetwork *existingNetwork = networkForSSID(info.at(4), &pos);
- if (!existingNetwork) {
+ sensibleNetworks.insert(info.at(4));
+ QWifiNetwork *knownNetwork = networkForSSID(info.at(4), &pos);
+ if (!knownNetwork)
+ knownNetwork = outOfRangeListContains(info.at(4));
+
+ if (!knownNetwork) {
QWifiNetwork *network = new QWifiNetwork();
+ network->setOutOfRange(false);
network->setBssid(info.at(0));
network->setFlags(info.at(3));
// signal strength is in dBm
@@ -98,13 +101,23 @@ void QWifiNetworkList::parseScanResults(const QByteArray &results)
m_networks << network;
endInsertRows();
} else {
+ if (knownNetwork->outOfRange()) {
+ // 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 (existingNetwork->bssid() == info.at(0)) {
+ if (knownNetwork->bssid() == info.at(0)) {
// same access point, simply update the signal strength
- existingNetwork->setSignalStrength(info.at(2).toInt());
+ knownNetwork->setSignalStrength(info.at(2).toInt());
+ knownNetwork->setOutOfRange(false);
dataChanged(createIndex(pos, 0), createIndex(pos, 0));
- } else if (existingNetwork->signalStrength() < info.at(2).toInt()) {
+ } else if (knownNetwork->signalStrength() < info.at(2).toInt()) {
// 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(info.at(2).toInt());
@@ -113,16 +126,16 @@ void QWifiNetworkList::parseScanResults(const QByteArray &results)
}
}
}
- // remove networks that have gone out of range
- for (int i = 0; i < m_networks.size(); ++i) {
+ // 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);
- delete m_networks.takeAt(i);
+ QWifiNetwork *n = m_networks.takeAt(i);
+ n->setOutOfRange(true);
+ m_outOfRangeNetworks.append(n);
endRemoveRows();
} else {
++i;
}
}
}
-
-
diff --git a/src/imports/wifi/qwifinetworklist.h b/src/imports/wifi/qwifinetworklistmodel.h
index 84e78fc..91ca231 100644
--- a/src/imports/wifi/qwifinetworklist.h
+++ b/src/imports/wifi/qwifinetworklistmodel.h
@@ -16,8 +16,8 @@
** the contact form at http://qt.digia.com/
**
****************************************************************************/
-#ifndef QWIFINETWORKLIST_H
-#define QWIFINETWORKLIST_H
+#ifndef QWIFINETWORKLISTMODEL_H
+#define QWIFINETWORKLISTMODEL_H
#include <QtCore/QAbstractListModel>
#include <QtCore/QList>
@@ -26,17 +26,19 @@
class QWifiManager;
-class QWifiNetworkList : public QAbstractListModel
+class QWifiNetworkListModel : public QAbstractListModel
{
Q_OBJECT
public:
- QWifiNetworkList(QWifiManager *manager);
+ QWifiNetworkListModel(QWifiManager *manager);
+ ~QWifiNetworkListModel();
void parseScanResults(const QByteArray &data);
QWifiNetwork *networkForSSID(const QByteArray &ssid, int *pos);
+ QWifiNetwork *outOfRangeListContains(const QByteArray &ssid);
int rowCount(const QModelIndex &) const { return m_networks.size(); }
QVariant data(const QModelIndex &index, int role) const;
@@ -46,6 +48,7 @@ public:
private:
QWifiManager *m_manager;
QList<QWifiNetwork *> m_networks;
+ QList<QWifiNetwork *> m_outOfRangeNetworks;
};
-#endif // QWIFINETWORKLIST_H
+#endif // QWIFINETWORKLISTMODEL_H
diff --git a/src/imports/wifi/wifi.pro b/src/imports/wifi/wifi.pro
index 0231479..b920978 100644
--- a/src/imports/wifi/wifi.pro
+++ b/src/imports/wifi/wifi.pro
@@ -8,12 +8,12 @@ SOURCES += \
pluginmain.cpp \
qwifimanager.cpp \
qwifinetwork.cpp \
- qwifinetworklist.cpp
+ qwifinetworklistmodel.cpp
HEADERS += \
qwifimanager.h \
qwifinetwork.h \
- qwifinetworklist.h
+ qwifinetworklistmodel.h
LIBS += -lhardware_legacy -lcutils