summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/imports/wifi/qwifimanager.cpp200
-rw-r--r--src/imports/wifi/qwifimanager.h2
-rw-r--r--src/imports/wifi/qwifimodule.pro6
-rw-r--r--src/imports/wifi/qwifinetwork.cpp6
-rw-r--r--src/imports/wifi/qwifinetwork.h2
5 files changed, 140 insertions, 76 deletions
diff --git a/src/imports/wifi/qwifimanager.cpp b/src/imports/wifi/qwifimanager.cpp
index 984e8da..1ba3d64 100644
--- a/src/imports/wifi/qwifimanager.cpp
+++ b/src/imports/wifi/qwifimanager.cpp
@@ -4,14 +4,52 @@
#include <hardware_legacy/wifi.h>
#include <cutils/properties.h>
-
+#include <unistd.h>
#define WLAN_INTERFACE "wlan0"
-static bool WIFI_DEBUG = !qgetenv("WIFI_DEBUG").isEmpty();
+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);
+
+static int q_wifi_start_supplicant()
+{
+#if Q_ANDROID_VERSION_MAJOR > 4 || (Q_ANDROID_VERSION_MAJOR == 4 && Q_ANDROID_VERSION_MINOR >= 1)
+ return wifi_start_supplicant(0);
+#else
+ return wifi_start_supplicant();
+#endif
+}
+
+static int q_wifi_connect_to_supplicant()
+{
+#if Q_ANDROID_VERSION_MAJOR > 4 || (Q_ANDROID_VERSION_MAJOR == 4 && Q_ANDROID_VERSION_MINOR >= 1)
+ return wifi_connect_to_supplicant(WLAN_INTERFACE);
+#else
+ return wifi_connect_to_supplicant();
+#endif
+}
+
+static int q_wifi_command(const char *command, char *reply, size_t *reply_len)
+{
+#if Q_ANDROID_VERSION_MAJOR > 4 || (Q_ANDROID_VERSION_MAJOR == 4 && Q_ANDROID_VERSION_MINOR >= 1)
+ return wifi_command(WLAN_INTERFACE, command, reply, reply_len);
+#else
+ return wifi_command(command, reply, reply_len);
+#endif
+
+}
+
+static int q_wifi_wait_for_event(char *buf, size_t len)
+{
+#if Q_ANDROID_VERSION_MAJOR > 4 || (Q_ANDROID_VERSION_MAJOR == 4 && Q_ANDROID_VERSION_MINOR >= 1)
+ return wifi_wait_for_event(WLAN_INTERFACE, buf, len);
+#else
+ return wifi_wait_for_event(buf, len);
+#endif
+}
-const QEvent::Type WIFI_SCAN_RESULTS = (QEvent::Type) (QEvent::User + 1);
-const QEvent::Type WIFI_CONNECTED = (QEvent::Type) (QEvent::User + 2);
class QWifiManagerEvent : public QEvent
{
@@ -40,14 +78,14 @@ public:
}
void run() {
- if (WIFI_DEBUG) qDebug("EventReceiver thread is running");
+ if (QT_WIFI_DEBUG) qDebug("EventReceiver thread is running");
char buffer[2048];
while (1) {
- int size = wifi_wait_for_event(WLAN_INTERFACE, buffer, sizeof(buffer) - 1);
+ int size = q_wifi_wait_for_event(buffer, sizeof(buffer) - 1);
if (size > 0) {
buffer[size] = 0;
- if (WIFI_DEBUG) qDebug("EVENT: %s", buffer);
+ if (QT_WIFI_DEBUG) qDebug("EVENT: %s", buffer);
char *event = &buffer[11];
if (strstr(event, "SCAN-RESULTS")) {
@@ -79,7 +117,7 @@ QWifiManager::QWifiManager()
void QWifiManager::start()
{
- if (WIFI_DEBUG) qDebug("QWifiManager: start");
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager: start");
connectToBackend();
}
@@ -94,11 +132,11 @@ void QWifiManager::setScanning(bool scanning)
emit scanningChanged(scanning);
if (m_scanning) {
- if (WIFI_DEBUG) qDebug("QWifiManager: scanning");
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager: scanning");
call("SCAN");
m_scanTimer = startTimer(5000);
} else {
- if (WIFI_DEBUG) qDebug("QWifiManager: stop scanning");
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager: stop scanning");
killTimer(m_scanTimer);
}
}
@@ -123,26 +161,29 @@ QByteArray int_to_ip(int i) {
void QWifiManager::connectToBackend()
{
if (m_internalState == IS_Uninitialized)
+ m_internalState = IS_LoadDriver;
+
+ if (m_internalState == IS_LoadDriver && (is_wifi_driver_loaded() || wifi_load_driver() >= 0))
m_internalState = IS_StartBackend;
- if (m_internalState == IS_StartBackend
- && wifi_start_supplicant(0) >= 0)
+ if (m_internalState == IS_StartBackend && q_wifi_start_supplicant() >= 0) {
m_internalState = IS_ConnectToBackend;
+ sleep(3); //###
+ }
- if (m_internalState == IS_ConnectToBackend
- && wifi_connect_to_supplicant(WLAN_INTERFACE) >= 0)
+ if (m_internalState == IS_ConnectToBackend && q_wifi_connect_to_supplicant() >= 0)
m_internalState = IS_UpAndRunning;
if (m_internalState == IS_UpAndRunning) {
+ qDebug("QWifiManager: started successfully");
+
emit readyChanged(true);
m_eventThread = new QWifiManagerEventThread(this);
m_eventThread->start();
- qDebug("QWifiManager: started successfully");
-
handleConnected();
} else {
- if (WIFI_DEBUG) qWarning("QWifiManager: stuck at internal state level: %d", m_internalState);
+ qWarning("QWifiManager: stuck at internal state level: %d", m_internalState);
}
}
@@ -150,17 +191,25 @@ void QWifiManager::connectToBackend()
QByteArray QWifiManager::call(const char *command)
{
char data[2048];
- size_t len = sizeof(data);
- if (wifi_command(WLAN_INTERFACE, command, data, &len) < 0) {
+ size_t len = sizeof(data) - 1; // -1: room to add a 0-terminator
+ if (q_wifi_command(command, data, &len) < 0) {
qWarning("QWifiManager: call failed: %s", command);
return QByteArray();
}
+ if (len < sizeof(data))
+ data[len] = 0;
QByteArray result = QByteArray::fromRawData(data, len);
- qDebug("QWifiManager::call: %s ==>\n%s", command, result.constData());
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager::call: %s ==>\n%s", command, result.constData());
return result;
}
+bool QWifiManager::checkedCall(const char *command)
+{
+ return call(command).trimmed().toUpper() == "OK";
+}
+
+
bool QWifiManager::event(QEvent *e)
{
switch ((int) e->type()) {
@@ -176,7 +225,8 @@ bool QWifiManager::event(QEvent *e)
call("SCAN");
return true;
}
- break; }
+ break;
+ }
}
return QObject::event(e);
@@ -185,59 +235,79 @@ bool QWifiManager::event(QEvent *e)
void QWifiManager::connect(QWifiNetwork *network, const QString &passphrase)
{
if (network->ssid() == m_connectedSSID) {
- if (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;
}
- QByteArray listResult = call("LIST_NETWORKS");
+ call("DISABLE_NETWORK all");
+ if (!m_connectedSSID.isEmpty()) {
+ m_connectedSSID.clear();
+ emit connectedSSIDChanged(m_connectedSSID);
+ //also possibly change online state
+ }
- if (listResult.contains(network->ssid())) {
- QList<QByteArray> lines = listResult.split('\n');
- for (int i=1; i<lines.size(); ++i) {
- const QByteArray &line = lines.at(i);
- if (line.contains(network->ssid())) {
- int networkId = line.toInt();
- if (line.contains("[CURRENT]")) {
- if (WIFI_DEBUG) qDebug("QWifiManager::connect(), network is already current");
- handleConnected();
- } else {
- if (WIFI_DEBUG) qDebug("QWifiManager::connect(), network known, but not enabled");
- call(QByteArray("ENABLE_NETWORK ") + QByteArray::number(networkId));
- }
- return;
- }
+ 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);
+ networkKnown = true;
+ break;
}
}
- bool ok;
- QByteArray id = call("ADD_NETWORK").trimmed();
- id.toInt(&ok);
- if (!ok) {
- qWarning("QWifiManager::connect(), failed to add network");
- return;
+ if (!networkKnown) {
+ bool ok;
+ QByteArray id = call("ADD_NETWORK").trimmed();
+ id.toInt(&ok);
+ if (!ok) {
+ qWarning("QWifiManager::connect(), failed to add network");
+ return;
+ }
}
QByteArray setNetworkCommand = QByteArray("SET_NETWORK ") + id;
- QByteArray ssidOK = call(setNetworkCommand + QByteArray(" ssid ") + '"' + network->ssid() + '"');
- QByteArray pskOK = call(setNetworkCommand + QByteArray(" psk ") + '"' + passphrase.toLatin1() + '"');
+ bool ok = true;
+ if (!networkKnown)
+ ok = ok && checkedCall(setNetworkCommand + QByteArray(" ssid ") + '"' + network->ssid() + '"');
+
+ QByteArray key_mgmt;
+ if (network->supportsWPA() || network->supportsWPA2()) {
+ ok = ok && checkedCall(setNetworkCommand + QByteArray(" psk ") + '"' + passphrase.toLatin1() + '"');
+ key_mgmt = "WPA_PSK";
+ } else if (network->supportsWEP()) {
+ ok = ok && checkedCall(setNetworkCommand + QByteArray(" wep_key0 ") + '"' + passphrase.toLatin1() + '"');
+ ok = ok && checkedCall(setNetworkCommand + QByteArray(" auth_alg OPEN SHARED"));
+ key_mgmt = "NONE";
+ } else if (!network->supportsWPS() && passphrase.length() == 0) {
+ // open network
+ key_mgmt = "NONE";
+ }
+ ok = ok && checkedCall(setNetworkCommand + QByteArray(" key_mgmt ") + key_mgmt);
- if (ssidOK.trimmed() != QByteArray("OK") || pskOK.trimmed() != QByteArray("OK")) {
- call("REMOVE_NETWORK " + id);
- qWarning("QWifiManager::connect(), failed to set properties on network '%s'.\n'%s'\n'%s'",
- id.constData(),
- ssidOK.constData(),
- pskOK.constData());
+ if (!ok) {
+ if (!networkKnown)
+ call("REMOVE_NETWORK " + id);
+ qWarning("QWifiManager::connect(), failed to set properties on network '%s'", id.constData());
return;
}
- call(QByteArray("ENABLE_NETWORK ") + id);
+ call(QByteArray("SELECT_NETWORK ") + id);
+ call("RECONNECT");
}
class ProcessRunner : public QThread {
public:
void run() {
- QProcess::execute(QStringLiteral("dhcpcd"), QStringList() << QStringLiteral("wlan0"));
+ QStringList args;
+ args << QStringLiteral("-A")
+ << QStringLiteral("-h") << QStringLiteral("KAON") //### hardcoded hostname, for testing
+ << QStringLiteral("wlan0");
+ QProcess::execute(QStringLiteral("dhcpcd"), args);
deleteLater();
}
};
@@ -248,35 +318,32 @@ void QWifiManager::handleConnected()
QList<QByteArray> lists = call("LIST_NETWORKS").split('\n');
QByteArray connectedNetwork;
for (int i=1; i<lists.size(); ++i) {
- if (lists.at(i).contains("[CURRENT]")) {
+ if (lists.at(i).toUpper().contains("[CURRENT]")) {
connectedNetwork = lists.at(i);
break;
}
}
if (connectedNetwork.isEmpty()) {
- if (WIFI_DEBUG)
- qDebug("QWifiManager::handleConnected: not connected to a network...");
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager::handleConnected: not connected to a network...");
m_online = false;
onlineChanged(m_online);
return;
} else {
- if (WIFI_DEBUG)
- qDebug("QWifiManager::handleConnected: current is %s", connectedNetwork.constData());
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager::handleConnected: current is %s", connectedNetwork.constData());
}
QList<QByteArray> info = connectedNetwork.split('\t');
m_connectedSSID = info.at(1);
emit connectedSSIDChanged(m_connectedSSID);
- if (WIFI_DEBUG)
- qDebug("QWifiManager::handleConnected: starting dhcpcd...");
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager::handleConnected: starting dhcpcd...");
QThread *t = new ProcessRunner();
t->start();
int ipaddr, gateway, mask, dns1, dns2, server, lease;
if (do_dhcp_request(&ipaddr, &gateway, &mask, &dns1, &dns2, &server, &lease) == 0) {
- if (WIFI_DEBUG) {
+ if (QT_WIFI_DEBUG) {
printf("ip ........: %s\n"
"gateway ...: %s\n"
"mask ......: %s\n"
@@ -295,12 +362,13 @@ void QWifiManager::handleConnected()
property_set("net.dns1", int_to_ip(dns1).constData());
property_set("net.dns2", int_to_ip(dns2).constData());
+ // Store (possibly updated) settings
+ call("SAVE_CONFIG");
+
m_online = true;
- onlineChanged(false);
+ onlineChanged(m_online);
} else {
- if (WIFI_DEBUG)
- qDebug("QWifiManager::handleConnected: dhcp request failed...");
-
+ if (QT_WIFI_DEBUG) qDebug("QWifiManager::handleConnected: dhcp request failed...");
}
}
diff --git a/src/imports/wifi/qwifimanager.h b/src/imports/wifi/qwifimanager.h
index a2fdb99..5fd74f5 100644
--- a/src/imports/wifi/qwifimanager.h
+++ b/src/imports/wifi/qwifimanager.h
@@ -22,6 +22,7 @@ class QWifiManager : public QObject
public:
enum InternalState {
IS_Uninitialized,
+ IS_LoadDriver,
IS_StartBackend,
IS_ConnectToBackend,
IS_UpAndRunning
@@ -61,6 +62,7 @@ private:
void parseScanResults();
void connectToBackend();
QByteArray call(const char *command);
+ bool checkedCall(const char *command);
QString m_connectedSSID;
QWifiNetworkList m_networks;
diff --git a/src/imports/wifi/qwifimodule.pro b/src/imports/wifi/qwifimodule.pro
index 311baba..449617f 100644
--- a/src/imports/wifi/qwifimodule.pro
+++ b/src/imports/wifi/qwifimodule.pro
@@ -1,9 +1,3 @@
-#-------------------------------------------------
-#
-# Project created by QtCreator 2013-03-11T12:29:12
-#
-#-------------------------------------------------
-
CXX_MODULE = qml
QT += qml quick
TARGET = qwifimodule
diff --git a/src/imports/wifi/qwifinetwork.cpp b/src/imports/wifi/qwifinetwork.cpp
index a3fc038..5de8711 100644
--- a/src/imports/wifi/qwifinetwork.cpp
+++ b/src/imports/wifi/qwifinetwork.cpp
@@ -4,10 +4,10 @@ QWifiNetwork::QWifiNetwork()
{
}
-void QWifiNetwork::setSignalStrength(int strenght)
+void QWifiNetwork::setSignalStrength(int strength)
{
- if (m_signalStrength == strenght)
+ if (m_signalStrength == strength)
return;
- m_signalStrength = strenght;
+ m_signalStrength = strength;
emit signalStrengthChanged(m_signalStrength);
}
diff --git a/src/imports/wifi/qwifinetwork.h b/src/imports/wifi/qwifinetwork.h
index 7a28a58..8bcb410 100644
--- a/src/imports/wifi/qwifinetwork.h
+++ b/src/imports/wifi/qwifinetwork.h
@@ -28,7 +28,7 @@ public:
void setSsid(const QByteArray &id) { m_ssid = id; }
int signalStrength() const { return m_signalStrength; }
- void setSignalStrength(int strenght);
+ void setSignalStrength(int strength);
QByteArray flags() const { return m_flags; }
void setFlags(const QByteArray &f) { m_flags = f; }