summaryrefslogtreecommitdiffstats
path: root/src/imports/wifi/qwifimanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/imports/wifi/qwifimanager.cpp')
-rw-r--r--src/imports/wifi/qwifimanager.cpp129
1 files changed, 79 insertions, 50 deletions
diff --git a/src/imports/wifi/qwifimanager.cpp b/src/imports/wifi/qwifimanager.cpp
index bc4b6fe..af6f5d3 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);
/*
* This function is borrowed from /system/core/libnetutils/dhcp_utils.c
@@ -89,28 +90,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 = 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);
}
}
}
@@ -161,6 +164,8 @@ public:
\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
@@ -212,8 +217,8 @@ public:
/*!
\qmlproperty WifiNetworkListModel WifiManager::networks
- This property holds a list of networks that can be sensed by a device and should be used as a
- data model in ListView. List is updated every 5 seconds.
+ 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.
@@ -313,9 +318,10 @@ public:
*/
/*!
- \qmlsignal void WifiManager::networkStateChanged()
+ \qmlsignal void WifiManager::networkStateChanged(WifiNetwork network)
- This signal is emitted whenever changes in a network state occur.
+ This signal is emitted whenever changes in a network state occur. Network \a network is the
+ the currently active network connection.
\sa networkState
*/
@@ -338,12 +344,14 @@ public:
*/
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);
@@ -361,15 +369,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();
}
@@ -378,12 +386,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;
}
@@ -395,14 +398,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;
}
@@ -428,12 +429,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();
}
@@ -462,15 +467,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 (wifi_stop_supplicant(0) < 0)
qWarning("QWifiManager: failed to stop supplicant");
wifi_close_supplicant_connection(m_interface.constData());
@@ -479,9 +481,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;
@@ -517,15 +528,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) {
@@ -541,10 +564,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()) {
@@ -552,16 +578,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;
}
@@ -569,7 +592,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");
@@ -612,9 +635,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);
}
@@ -622,7 +644,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;
@@ -631,8 +653,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;
}
@@ -641,6 +661,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"));
}