diff options
author | Gatis Paeglis <gatis.paeglis@theqtcompany.com> | 2015-01-15 14:53:36 +0100 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@theqtcompany.com> | 2015-02-09 13:26:58 +0200 |
commit | a6176aedcfe6893c24f2f2975a6874273e9df15e (patch) | |
tree | b62056433c52da73ebab9b0ee3c57b3b6f5d3251 /src | |
parent | bc2eb4cfa109cad3950e175679166e6341746c07 (diff) |
Decode ASCII encoded SSID names
This patch adds a decodeHexEncoded() utility function
for decoding wpa_supplicant's hex encoded strings.
Task-number: QTEE-817
Change-Id: I257a8892cdc48ce285561fd879b8a9ab0a50bfc4
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/wifi/qwificontroller.cpp | 2 | ||||
-rw-r--r-- | src/wifi/qwifimanager.cpp | 26 | ||||
-rw-r--r-- | src/wifi/qwifinetworklistmodel.cpp | 3 | ||||
-rw-r--r-- | src/wifi/qwifiutils.cpp | 135 | ||||
-rw-r--r-- | src/wifi/qwifiutils_p.h | 37 | ||||
-rw-r--r-- | src/wifi/wifi.pro | 6 |
6 files changed, 194 insertions, 15 deletions
diff --git a/src/wifi/qwificontroller.cpp b/src/wifi/qwificontroller.cpp index 2c6baac..f63b554 100644 --- a/src/wifi/qwificontroller.cpp +++ b/src/wifi/qwificontroller.cpp @@ -33,7 +33,7 @@ #ifdef Q_OS_ANDROID_NO_SDK /* - * Work API differences between Android versions + * Workaround API differences between Android versions */ int q_wifi_start_supplicant() { diff --git a/src/wifi/qwifimanager.cpp b/src/wifi/qwifimanager.cpp index bc236f2..319c9d9 100644 --- a/src/wifi/qwifimanager.cpp +++ b/src/wifi/qwifimanager.cpp @@ -20,6 +20,8 @@ #include "qwifinetworklistmodel_p.h" #include "qwifinetwork_p.h" #include "qwifimanager_p.h" +#include "qwifiutils_p.h" + #include "qwifidevice.h" #include <QtCore/QFile> @@ -98,7 +100,7 @@ void QWifiManagerPrivate::handleConnected() if (connectedNetwork.isEmpty()) return; - m_currentSSID = connectedNetwork.split('\t').at(1); + m_currentSSID = QWifiUtils::decodeHexEncoded(connectedNetwork.split('\t').at(1)); qCDebug(B2QT_WIFI) << "connected network: " << m_currentSSID; updateNetworkState(QWifiManager::ObtainingIPAddress); m_wifiController->call(QWifiController::AcquireIPAddress); @@ -167,20 +169,21 @@ QString QWifiManagerPrivate::call(const QString &command) actualCommand.prepend(prefix); #endif #endif - if (q_wifi_command(m_interface, actualCommand.toLatin1(), data, &len) < 0) { - qCDebug(B2QT_WIFI) << "call to supplicant failed: " << actualCommand; + qCDebug(B2QT_WIFI) << "call command: " << actualCommand.toLocal8Bit(); + if (q_wifi_command(m_interface, actualCommand.toLocal8Bit(), data, &len) < 0) { + qCDebug(B2QT_WIFI) << "call to supplicant failed!"; return QString(); } if (len < sizeof(data)) data[len] = 0; QString result = QLatin1String(data); - return result; + return result.trimmed(); } bool QWifiManagerPrivate::checkedCall(const QString &command) { - return call(command).trimmed().toUpper() == QLatin1String("OK"); + return call(command).toUpper() == QLatin1String("OK"); } void QWifiManagerPrivate::updateLastError(const QString &error) @@ -472,11 +475,12 @@ bool QWifiManager::connect(QWifiConfiguration *config) d->m_currentSSID = config->ssid(); bool networkKnown = false; QString id; - QString listResult = d->call(QStringLiteral("LIST_NETWORKS")); - QStringList lines = listResult.split('\n'); - foreach (const QString &line, lines) { - if (line.contains(d->m_currentSSID)) { - id = line.split('\t').at(0); + 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 = QWifiUtils::decodeHexEncoded(networkFields.at(1)); + if (ssid == d->m_currentSSID) { + id = networkFields.at(0); networkKnown = true; break; } @@ -484,7 +488,7 @@ bool QWifiManager::connect(QWifiConfiguration *config) if (!networkKnown) { bool ok; - id = d->call(QStringLiteral("ADD_NETWORK")).trimmed(); + id = d->call(QStringLiteral("ADD_NETWORK")); id.toInt(&ok); if (!ok) { d->updateLastError(QStringLiteral("failed to add network!")); diff --git a/src/wifi/qwifinetworklistmodel.cpp b/src/wifi/qwifinetworklistmodel.cpp index 6f53295..e562b2b 100644 --- a/src/wifi/qwifinetworklistmodel.cpp +++ b/src/wifi/qwifinetworklistmodel.cpp @@ -18,6 +18,7 @@ ****************************************************************************/ #include "qwifinetworklistmodel_p.h" #include "qwifinetwork_p.h" +#include "qwifiutils_p.h" #include "qwifimanager.h" @@ -123,7 +124,7 @@ void QWifiNetworkListModel::parseScanResults(const QString &results) continue; int pos = 0; - QString ssid = info.at(4); + QString ssid = QWifiUtils::decodeHexEncoded(info.at(4)); sensibleNetworks.insert(ssid); QWifiNetwork *knownNetwork = networkForSSID(ssid, &pos); if (!knownNetwork) diff --git a/src/wifi/qwifiutils.cpp b/src/wifi/qwifiutils.cpp new file mode 100644 index 0000000..21c440b --- /dev/null +++ b/src/wifi/qwifiutils.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 "qwifiutils_p.h" + +QT_BEGIN_NAMESPACE + +int QWifiUtils::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; +} + +int QWifiUtils::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; +} + +// the logic of this function is taken from wpa_supplicant source code (BSD +// licensed code) see http://w1.fi/cgit file hostapd/src/utils/common.c +// 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 QWifiUtils::decodeHexEncoded(const QString &encoded) +{ + int maxlen = encoded.size() + 1; + QByteArray buf; + buf.resize(maxlen); + const char *pos = encoded.toLocal8Bit().constData(); + 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 QString::fromUtf8(buf); +} + +QT_END_NAMESPACE diff --git a/src/wifi/qwifiutils_p.h b/src/wifi/qwifiutils_p.h new file mode 100644 index 0000000..8b3e54a --- /dev/null +++ b/src/wifi/qwifiutils_p.h @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2015 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 QWIFIUTILS_H +#define QWIFIUTILS_H + +#include <QtCore/QString> + +QT_BEGIN_NAMESPACE + +class QWifiUtils +{ +public: + static int hex2num(char c); + static int hex2byte(const char *hex); + + static QString decodeHexEncoded(const QString &encoded); +}; + +QT_END_NAMESPACE + +#endif // QWIFIUTILS_H diff --git a/src/wifi/wifi.pro b/src/wifi/wifi.pro index e558081..f248774 100644 --- a/src/wifi/wifi.pro +++ b/src/wifi/wifi.pro @@ -16,7 +16,8 @@ HEADERS += \ $$PWD/qwifinetworklistmodel_p.h \ $$PWD/qwificontroller_p.h \ $$PWD/qwifidevice.h \ - $$PWD/qwificonfiguration.h + $$PWD/qwificonfiguration.h \ + $$PWD/qwifiutils_p.h SOURCES += \ $$PWD/qwifimanager.cpp \ @@ -24,7 +25,8 @@ SOURCES += \ $$PWD/qwifinetworklistmodel.cpp \ $$PWD/qwificontroller.cpp \ $$PWD/qwifidevice.cpp \ - $$PWD/qwificonfiguration.cpp + $$PWD/qwificonfiguration.cpp \ + $$PWD/qwifiutils.cpp android: { LIBS += -lhardware_legacy -lcutils |