summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGatis Paeglis <gatis.paeglis@theqtcompany.com>2015-01-15 14:53:36 +0100
committerGatis Paeglis <gatis.paeglis@theqtcompany.com>2015-02-09 13:26:58 +0200
commita6176aedcfe6893c24f2f2975a6874273e9df15e (patch)
treeb62056433c52da73ebab9b0ee3c57b3b6f5d3251 /src
parentbc2eb4cfa109cad3950e175679166e6341746c07 (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.cpp2
-rw-r--r--src/wifi/qwifimanager.cpp26
-rw-r--r--src/wifi/qwifinetworklistmodel.cpp3
-rw-r--r--src/wifi/qwifiutils.cpp135
-rw-r--r--src/wifi/qwifiutils_p.h37
-rw-r--r--src/wifi/wifi.pro6
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