From 94b7d73c7417c3296c641065eab2305081a3d806 Mon Sep 17 00:00:00 2001 From: aavit Date: Fri, 5 Jul 2013 16:24:34 +0200 Subject: Snapshot of wifi module development, from customer project Corresponds to 0c397d2287d33b08501c48e029306b8908583e6a of github repo Change-Id: I60c140513255394b6728ddd0ff85ac79fa5e88b9 Reviewed-by: Eirik Aavitsland --- src/imports/wifi/qwifimanager.cpp | 200 +++++++++++++++++++++++++------------- src/imports/wifi/qwifimanager.h | 2 + src/imports/wifi/qwifimodule.pro | 6 -- src/imports/wifi/qwifinetwork.cpp | 6 +- src/imports/wifi/qwifinetwork.h | 2 +- 5 files changed, 140 insertions(+), 76 deletions(-) (limited to 'src/imports/wifi') 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 #include - +#include #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 lines = listResult.split('\n'); - for (int i=1; issid())) { - 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 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 lists = call("LIST_NETWORKS").split('\n'); QByteArray connectedNetwork; for (int i=1; i 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; } -- cgit v1.2.3