summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGatis Paeglis <gatis.paeglis@theqtcompany.com>2015-07-07 15:58:02 +0200
committerGatis Paeglis <gatis.paeglis@digia.com>2015-07-10 11:58:05 +0000
commit8c25e376947637d51d3f1ae475a4f7f7a1f81fc4 (patch)
tree06eb9b27b8a0c2cf8e6f5c1f49e7f77e624e2689 /src
parent9095f6ef77c87b6114b0613d71fe26cfe0b0d8ff (diff)
Wifi: more refactoring
Move supplicant related code into a proper class. Before it was implementad as C-style API to match with Android code. Change-Id: Idf9610ab9c42bbca34f69b8d5041efb75bb61f57 Reviewed-by: aavit <eirik.aavitsland@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/wifi/qwificontroller.cpp50
-rw-r--r--src/wifi/qwificontroller_p.h7
-rw-r--r--src/wifi/qwifidevice.cpp38
-rw-r--r--src/wifi/qwifidevice.h7
-rw-r--r--src/wifi/qwifielinux.cpp337
-rw-r--r--src/wifi/qwifielinux_p.h42
-rw-r--r--src/wifi/qwifimanager.cpp36
-rw-r--r--src/wifi/qwifimanager_p.h1
-rw-r--r--src/wifi/qwifinetworklistmodel.cpp4
-rw-r--r--src/wifi/qwifisupplicant.cpp420
-rw-r--r--src/wifi/qwifisupplicant_p.h (renamed from src/wifi/qwifiutils_p.h)38
-rw-r--r--src/wifi/qwifiutils.cpp135
-rw-r--r--src/wifi/wifi.pro6
13 files changed, 503 insertions, 618 deletions
diff --git a/src/wifi/qwificontroller.cpp b/src/wifi/qwificontroller.cpp
index 779b2a5..61f5761 100644
--- a/src/wifi/qwificontroller.cpp
+++ b/src/wifi/qwificontroller.cpp
@@ -18,8 +18,12 @@
****************************************************************************/
#include "qwificontroller_p.h"
#include "qwifimanager_p.h"
+#include "qwifisupplicant_p.h"
#include "qwifidevice.h"
+#include <sys/types.h>
+#include <signal.h>
+
#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QByteArray>
@@ -35,7 +39,6 @@ public:
QWifiEventThread(QWifiController *controller)
: m_controller(controller)
{
- m_interface = QWifiDevice::wifiInterfaceName();
}
void run() {
@@ -43,7 +46,7 @@ public:
QWifiEvent *event = 0;
char buffer[2048];
forever {
- int size = q_wifi_wait_for_event(m_interface, buffer, sizeof(buffer) - 1);
+ int size = m_controller->supplicant()->waitForEvent(buffer, sizeof(buffer) - 1);
if (size > 0) {
buffer[size] = 0;
event = 0;
@@ -74,7 +77,6 @@ public:
private:
QWifiController *m_controller;
- QByteArray m_interface;
};
@@ -82,11 +84,10 @@ QWifiController::QWifiController(QWifiManager *manager, QWifiManagerPrivate *man
m_manager(manager),
m_managerPrivate(managerPrivate),
m_exitEventThread(false),
- m_eventThread(0)
+ m_interface(QWifiDevice::wifiInterfaceName()),
+ m_eventThread(new QWifiEventThread(this)),
+ m_supplicant(new QWifiSupplicant(this))
{
- m_interface = QWifiDevice::wifiInterfaceName();
- m_eventThread = new QWifiEventThread(this);
-
qRegisterMetaType<QWifiManager::BackendState>("QWifiManager::BackendState");
}
@@ -126,7 +127,7 @@ void QWifiController::run()
}
}
-void QWifiController::call(Method method)
+void QWifiController::asyncCall(Method method)
{
QMutexLocker locker(&m_methodsMutex);
m_methods.append(method);
@@ -158,16 +159,16 @@ bool QWifiController::resetSupplicantSocket()
{
qCDebug(B2QT_WIFI) << "reset supplicant socket";
exitWifiEventThread();
- if (q_wifi_stop_supplicant() < 0)
+ if (!m_supplicant->stopSupplicant())
qCWarning(B2QT_WIFI) << "failed to stop supplicant!";
- q_wifi_close_supplicant_connection(m_interface);
+ m_supplicant->closeSupplicantConnection();
qCDebug(B2QT_WIFI) << "start supplicant";
- if (q_wifi_start_supplicant() != 0) {
+ if (!m_supplicant->startSupplicant()) {
qCWarning(B2QT_WIFI) << "failed to start a supplicant!";
return false;
}
qCDebug(B2QT_WIFI) << "connect to supplicant";
- if (q_wifi_connect_to_supplicant(m_interface) != 0) {
+ if (!m_supplicant->connectToSupplicant()) {
qCWarning(B2QT_WIFI) << "failed to connect to a supplicant!";
return false;
}
@@ -180,9 +181,9 @@ void QWifiController::terminateBackend()
qCDebug(B2QT_WIFI) << "terminating wifi backend";
emit backendStateChanged(QWifiManager::Terminating);
exitWifiEventThread();
- if (q_wifi_stop_supplicant() < 0)
+ if (!m_supplicant->stopSupplicant())
qCWarning(B2QT_WIFI) << "failed to stop supplicant!";
- q_wifi_close_supplicant_connection(m_interface);
+ m_supplicant->closeSupplicantConnection();
qCDebug(B2QT_WIFI) << "run ifconfig (down)";
QProcess ifconfig;
@@ -215,17 +216,22 @@ void QWifiController::exitWifiEventThread()
void QWifiController::killDhcpProcess(const QString &path) const
{
QFile pidFile(path);
- if (!pidFile.exists() || !pidFile.open(QIODevice::ReadOnly)) {
- qCWarning(B2QT_WIFI) << "could not read pid file: " << path;
+ if (!pidFile.exists())
+ return;
+
+ if (!pidFile.open(QIODevice::ReadOnly)) {
+ qCWarning(B2QT_WIFI) << "could not open pid file: " << path;
+ return;
+ }
+
+ bool ok;
+ int pid = pidFile.readAll().trimmed().toInt(&ok);
+ if (!ok) {
+ qCWarning(B2QT_WIFI) << "pid is not a number!";
return;
}
- QByteArray pid = pidFile.readAll();
- QProcess kill;
- kill.start(QStringLiteral("kill"), QStringList() << QStringLiteral("-9") << QLatin1String(pid.trimmed()));
- kill.waitForFinished();
- if (kill.exitStatus() != QProcess::NormalExit && kill.exitCode() != 0)
- qCWarning(B2QT_WIFI) << "killing dhcp process failed!";
+ kill(pid, 9);
}
void QWifiController::acquireIPAddress()
diff --git a/src/wifi/qwificontroller_p.h b/src/wifi/qwificontroller_p.h
index 952b8d4..45751fa 100644
--- a/src/wifi/qwificontroller_p.h
+++ b/src/wifi/qwificontroller_p.h
@@ -28,8 +28,6 @@
#include <QtCore/QWaitCondition>
#include <QtCore/QLoggingCategory>
-#include "qwifielinux_p.h"
-
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI)
@@ -43,6 +41,7 @@ const QEvent::Type WIFI_DISCONNECTED = (QEvent::Type) (QEvent::User + 2005);
class QWifiManager;
class QWifiManagerPrivate;
class QWifiEventThread;
+class QWifiSupplicant;
class QWifiEvent : public QEvent
{
@@ -73,13 +72,14 @@ public:
explicit QWifiController(QWifiManager *manager, QWifiManagerPrivate *managerPrivate);
~QWifiController();
- void call(Method method);
+ void asyncCall(Method method);
QWifiManager *wifiManager() const { return m_manager; }
bool isWifiThreadExitRequested() const { return m_exitEventThread; }
void startWifiEventThread();
void acquireIPAddress();
void stopDhcp() const;
bool resetSupplicantSocket();
+ QWifiSupplicant *supplicant() const { return m_supplicant; }
signals:
void backendStateChanged(QWifiManager::BackendState backendState);
@@ -101,6 +101,7 @@ private:
QWifiEventThread *m_eventThread;
QMutex m_methodsMutex;
QWaitCondition methodCallRequested;
+ QWifiSupplicant *m_supplicant;
};
QT_END_NAMESPACE
diff --git a/src/wifi/qwifidevice.cpp b/src/wifi/qwifidevice.cpp
index 5ddc02b..a6812e7 100644
--- a/src/wifi/qwifidevice.cpp
+++ b/src/wifi/qwifidevice.cpp
@@ -18,44 +18,12 @@
****************************************************************************/
#include "qwifidevice.h"
+#include <QtCore/QString>
#include <QtCore/QByteArray>
#include <QtCore/QDir>
QT_BEGIN_NAMESPACE
-class QWifiDevicePrivate
-{
- Q_DECLARE_PUBLIC(QWifiDevice)
-public:
- QWifiDevicePrivate(QWifiDevice *device);
-
- // methods
- void createSupplicantConfig();
- // member variables
- QWifiDevice *const q_ptr;
-};
-
-QWifiDevicePrivate::QWifiDevicePrivate(QWifiDevice *device)
- : q_ptr(device)
-{
-}
-
-void QWifiDevicePrivate::createSupplicantConfig()
-{
- QFile supplicantConfig(QStringLiteral("/etc/wpa_supplicant.qtwifi.conf"));
- if (supplicantConfig.exists())
- return;
-
- if (supplicantConfig.open(QIODevice::WriteOnly)) {
- supplicantConfig.write("ctrl_interface=/var/run/wpa_supplicant\n"
- "ctrl_interface_group=0\n"
- "update_config=1\n");
- } else {
- qCWarning(B2QT_WIFI) << "failed to create supplicant configuration file.";
- }
-}
-
-
/*!
\class QWifiDevice
\inmodule B2Qt.Wifi.Cpp
@@ -78,9 +46,7 @@ void QWifiDevicePrivate::createSupplicantConfig()
*/
QWifiDevice::QWifiDevice()
- : d_ptr(new QWifiDevicePrivate(this))
{
- d_ptr->createSupplicantConfig();
}
QWifiDevice::~QWifiDevice()
@@ -104,7 +70,7 @@ bool QWifiDevice::wifiSupported()
/*!
Returns Wifi interface name.
- Interface name is obtained from the \c B2QT_WIFI_INTERFACE
+ Interface name is read from the \c B2QT_WIFI_INTERFACE
environment variable if it is set, otherwise, the default interface
name ("\e{wlan0}") is used.
diff --git a/src/wifi/qwifidevice.h b/src/wifi/qwifidevice.h
index 02724b4..80b4891 100644
--- a/src/wifi/qwifidevice.h
+++ b/src/wifi/qwifidevice.h
@@ -23,8 +23,6 @@
#include <QtCore/QByteArray>
#include <QtCore/QLoggingCategory>
-class QWifiDevicePrivate;
-
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI)
@@ -39,11 +37,6 @@ public:
Q_INVOKABLE static bool wifiSupported();
static QByteArray wifiInterfaceName();
static void setWifiInterfaceName(const QByteArray &name);
-
-private:
- Q_DISABLE_COPY(QWifiDevice)
- Q_DECLARE_PRIVATE(QWifiDevice)
- QWifiDevicePrivate *const d_ptr;
};
QT_END_NAMESPACE
diff --git a/src/wifi/qwifielinux.cpp b/src/wifi/qwifielinux.cpp
deleted file mode 100644
index 1f3c67a..0000000
--- a/src/wifi/qwifielinux.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 "qwifielinux_p.h"
-#include "qwifidevice.h"
-
-#include <QtCore/QFile>
-#include <QtCore/QProcess>
-
-#include "wpa-supplicant/wpa_ctrl.h"
-
-#include <poll.h>
-#include <unistd.h>
-#include <sys/socket.h>
-
-QT_BEGIN_NAMESPACE
-
-// TODO: When cleaning up the library from Android code move this into a proper class
-// (QWifiDevice?) since we won't depend on C style API from Android anymore.
-
-const char SUPP_CONFIG_FILE[] = "/etc/wpa_supplicant.qtwifi.conf";
-const char IFACE_DIR[] = "/var/run/wpa_supplicant/";
-const char WPA_EVENT_IGNORE[] = "CTRL-EVENT-IGNORE ";
-
-static struct wpa_ctrl *ctrl_conn;
-static struct wpa_ctrl *monitor_conn;
-// socket pair used to exit from a blocking read
-static int exit_sockets[2];
-
-int wifi_connect_on_socket_path(const char *path);
-int wifi_ctrl_recv(char *reply, size_t *reply_len);
-int wifi_wait_on_socket(char *buf, size_t buflen);
-int wifi_send_command(const char *cmd, char *reply, size_t *reply_len);
-void wifi_close_sockets();
-
-QByteArray controlInterfacePath()
-{
- QByteArray path;
- QFile configFile;
- configFile.setFileName(QLatin1String(SUPP_CONFIG_FILE));
- if (configFile.open(QFile::ReadOnly)) {
- while (!configFile.atEnd()) {
- QByteArray line = configFile.readLine().trimmed();
- if (line.startsWith("ctrl_interface")) {
- path = line.mid(15);
- if (path.isEmpty())
- qCWarning(B2QT_WIFI) << "ctrl_interface is not set in " << SUPP_CONFIG_FILE;
- break;
- }
- }
- configFile.close();
- } else {
- qCWarning(B2QT_WIFI) << "could not find/read wpa_supplicant configuration file in" << SUPP_CONFIG_FILE;
- }
- return path;
-}
-
-int q_wifi_start_supplicant()
-{
- QByteArray ifc = QWifiDevice::wifiInterfaceName();
- QString pidFile = QLatin1String("/var/run/wpa_supplicant." + ifc + ".pid");
- QString driver(QStringLiteral("nl80211,wext"));
-
- QStringList arg;
- arg << QStringLiteral("--start") << QStringLiteral("--quiet") << QStringLiteral("--name");
- arg << QStringLiteral("wpa_supplicant") << QStringLiteral("--startas");
- arg << QStringLiteral("/usr/sbin/wpa_supplicant") << QStringLiteral("--pidfile") << pidFile;
- arg << QStringLiteral("--") << QStringLiteral("-B") << QStringLiteral("-P") << pidFile;
- arg << QStringLiteral("-i") << QLatin1String(ifc) << QStringLiteral("-c");
- arg << QLatin1String(SUPP_CONFIG_FILE) << QStringLiteral("-D") << driver;
-
- QProcess ssDaemon;
- ssDaemon.start(QStringLiteral("start-stop-daemon"), arg);
- ssDaemon.waitForFinished();
- qCDebug(B2QT_WIFI) << ssDaemon.readAll();
-
- QByteArray path = controlInterfacePath();
- if (path.isEmpty())
- return -1;
-
- // if the interface socket exists then wpa-supplicant was invoked successfully
- if (!QFile(QLatin1String(path + "/" + ifc)).exists()) {
- qCWarning(B2QT_WIFI) << "failed to invoke wpa_supplicant!\n" << ssDaemon.readAll();
- return -1;
- }
- // reset sockets used for exiting from hung state
- exit_sockets[0] = exit_sockets[1] = -1;
- return 0;
-}
-
-int q_wifi_stop_supplicant()
-{
- QByteArray ifc = QWifiDevice::wifiInterfaceName();
- QString pidFile = QLatin1String("/var/run/wpa_supplicant." + ifc + ".pid");
-
- if (QFile(pidFile).exists()) {
- QStringList arg;
- arg << QStringLiteral("--stop") << QStringLiteral("--quiet") << QStringLiteral("--name");
- arg << QStringLiteral("wpa_supplicant") << QStringLiteral("--pidfile") << pidFile;
-
- QProcess ssDaemon;
- ssDaemon.start(QStringLiteral("start-stop-daemon"), arg);
- ssDaemon.waitForFinished();
- if (ssDaemon.exitStatus() != QProcess::NormalExit) {
- qCWarning(B2QT_WIFI) << "failed to stop a supplicant process!\n" << ssDaemon.readAll();;
- return -1;
- }
-
- QFile::remove(pidFile);
- }
-
- QByteArray path = controlInterfacePath();
- if (path.isEmpty())
- return -1;
-
- QFile::remove(QLatin1String(path + "/" + ifc));
-
- // workaround for QTEE-957
- QProcess killall;
- killall.start(QStringLiteral("killall"), QStringList() << QStringLiteral("-9") << QStringLiteral("wpa_supplicant"));
- killall.waitForFinished();
-
- return 0;
-}
-
-int q_wifi_connect_to_supplicant(const char *ifname)
-{
- static char path[4096];
- snprintf(path, sizeof(path), "%s/%s", IFACE_DIR, ifname);
- return wifi_connect_on_socket_path(path);
-}
-
-int wifi_connect_on_socket_path(const char *path)
-{
- // establishes the control and monitor socket connections on the interface
- ctrl_conn = wpa_ctrl_open(path);
- if (ctrl_conn == NULL) {
- qCWarning(B2QT_WIFI, "Unable to open connection to supplicant on \"%s\": %s",
- path, strerror(errno));
- return -1;
- }
- monitor_conn = wpa_ctrl_open(path);
- if (monitor_conn == NULL) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- return -1;
- }
- if (wpa_ctrl_attach(monitor_conn) != 0) {
- wpa_ctrl_close(monitor_conn);
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = monitor_conn = NULL;
- return -1;
- }
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
- wpa_ctrl_close(monitor_conn);
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = monitor_conn = NULL;
- return -1;
- }
-
- return 0;
-}
-
-int q_wifi_wait_for_event(const char *ifname, char *buf, size_t buflen)
-{
- Q_UNUSED(ifname);
- return wifi_wait_on_socket(buf, buflen);
-}
-
-int wifi_wait_on_socket(char *buf, size_t buflen)
-{
- size_t nread = buflen - 1;
- int result;
- char *match, *match2;
-
- if (monitor_conn == NULL) {
- return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed");
- }
-
- result = wifi_ctrl_recv(buf, &nread);
-
- /* Terminate reception on exit socket */
- if (result == -2) {
- return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed");
- }
-
- if (result < 0) {
- qCWarning(B2QT_WIFI, "wifi_ctrl_recv failed: %s", strerror(errno));
- return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - recv error");
- }
- buf[nread] = '\0';
- /* Check for EOF on the socket */
- if (result == 0 && nread == 0) {
- /* Fabricate an event to pass up */
- qCWarning(B2QT_WIFI, "Received EOF on supplicant socket");
- return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - signal 0 received");
- }
- /*
- * Events strings are in the format
- *
- * IFNAME=iface <N>CTRL-EVENT-XXX
- * or
- * <N>CTRL-EVENT-XXX
- *
- * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,
- * etc.) and XXX is the event name. The level information is not useful
- * to us, so strip it off.
- */
-
- if (strncmp(buf, "IFNAME=", (sizeof("IFNAME=") - 1)) == 0) {
- match = strchr(buf, ' ');
- if (match != NULL) {
- if (match[1] == '<') {
- match2 = strchr(match + 2, '>');
- if (match2 != NULL) {
- nread -= (match2 - match);
- memmove(match + 1, match2 + 1, nread - (match - buf) + 1);
- }
- }
- } else {
- return snprintf(buf, buflen, "%s", WPA_EVENT_IGNORE);
- }
- } else if (buf[0] == '<') {
- match = strchr(buf, '>');
- if (match != NULL) {
- nread -= (match + 1 - buf);
- memmove(buf, match + 1, nread + 1);
- //qCWarning(B2QT_WIFI, "supplicant generated event without interface - %s", buf);
- }
- } else {
- /* let the event go as is! */
- qCWarning(B2QT_WIFI, "supplicant generated event without interface and without message level - %s", buf);
- }
-
- return nread;
-}
-
-int wifi_ctrl_recv(char *reply, size_t *reply_len)
-{
- int res = 0;
- int ctrlfd = wpa_ctrl_get_fd(monitor_conn);
- struct pollfd rfds[2];
-
- memset(rfds, 0, 2 * sizeof(struct pollfd));
- rfds[0].fd = ctrlfd;
- rfds[0].events |= POLLIN;
- rfds[1].fd = exit_sockets[1];
- rfds[1].events |= POLLIN;
- res = TEMP_FAILURE_RETRY(poll(rfds, 2, -1));
- if (res < 0) {
- qCWarning(B2QT_WIFI, "Error poll = %d", res);
- return res;
- }
- if (rfds[0].revents & POLLIN) {
- return wpa_ctrl_recv(monitor_conn, reply, reply_len);
- }
-
- /* it is not rfds[0], then it must be rfts[1] (i.e. the exit socket)
- * or we timed out. In either case, this call has failed ..
- */
- return -2;
-}
-
-int wifi_send_command(const char *cmd, char *reply, size_t *reply_len)
-{
- int ret;
- if (ctrl_conn == NULL) {
- qCWarning(B2QT_WIFI, "Not connected to wpa_supplicant - \"%s\" command dropped.", cmd);
- return -1;
- }
- ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), reply, reply_len, NULL);
- if (ret == -2) {
- qCWarning(B2QT_WIFI, "'%s' command timed out.", cmd);
- /* unblocks the monitor receive socket for termination */
- TEMP_FAILURE_RETRY(write(exit_sockets[0], "T", 1));
- return -2;
- } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) {
- return -1;
- }
- if (strncmp(cmd, "PING", 4) == 0) {
- reply[*reply_len] = '\0';
- }
- return 0;
-}
-
-int q_wifi_command(const char *ifname, const char *command, char *reply, size_t *reply_len)
-{
- Q_UNUSED(ifname);
- return wifi_send_command(command, reply, reply_len);
-}
-
-void q_wifi_close_supplicant_connection(const char *ifname)
-{
- Q_UNUSED(ifname)
- wifi_close_sockets();
-}
-
-void wifi_close_sockets()
-{
- if (ctrl_conn != NULL) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (monitor_conn != NULL) {
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
-
- if (exit_sockets[0] >= 0) {
- close(exit_sockets[0]);
- exit_sockets[0] = -1;
- }
-
- if (exit_sockets[1] >= 0) {
- close(exit_sockets[1]);
- exit_sockets[1] = -1;
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/wifi/qwifielinux_p.h b/src/wifi/qwifielinux_p.h
deleted file mode 100644
index bef90c3..0000000
--- a/src/wifi/qwifielinux_p.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 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 LOCAL_WIFI_H
-#define LOCAL_WIFI_H
-
-#include <QtCore/QLoggingCategory>
-
-#include <string.h>
-
-QT_BEGIN_NAMESPACE
-
-Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI)
-
-// This API mirrors Android's Wi-Fi libraries interface [1] and parts of implementation.
-// [1] http://androidxref.com/4.4.2_r2/xref/hardware/libhardware_legacy/include/hardware_legacy/wifi.h
-
-int q_wifi_command(const char *ifname, const char *command, char *reply, size_t *reply_len);
-int q_wifi_wait_for_event(const char *ifname, char *buf, size_t buflen);
-int q_wifi_connect_to_supplicant(const char *ifname);
-void q_wifi_close_supplicant_connection(const char *ifname);
-int q_wifi_start_supplicant();
-int q_wifi_stop_supplicant();
-
-QT_END_NAMESPACE
-
-#endif // LOCAL_WIFI_H
diff --git a/src/wifi/qwifimanager.cpp b/src/wifi/qwifimanager.cpp
index 697af4c..6bace8f 100644
--- a/src/wifi/qwifimanager.cpp
+++ b/src/wifi/qwifimanager.cpp
@@ -20,7 +20,7 @@
#include "qwifinetworklistmodel_p.h"
#include "qwifinetwork_p.h"
#include "qwifimanager_p.h"
-#include "qwifiutils_p.h"
+#include "qwifisupplicant_p.h"
#include "qwifidevice.h"
@@ -36,8 +36,7 @@ const char *bsText[] = { "Initializing", "Running", "Terminating", "NotRunning"
QWifiManagerPrivate::QWifiManagerPrivate(QWifiManager *manager)
: q_ptr(manager)
- , m_networkListModel(new QWifiNetworkListModel())
- , m_device(new QWifiDevice())
+ , m_networkListModel(new QWifiNetworkListModel(manager))
, m_scanTimer(0)
, m_scanning(false)
, m_interface(QWifiDevice::wifiInterfaceName())
@@ -50,8 +49,6 @@ QWifiManagerPrivate::QWifiManagerPrivate(QWifiManager *manager)
QWifiManagerPrivate::~QWifiManagerPrivate()
{
delete m_wifiController;
- delete m_networkListModel;
- delete m_device;
}
void QWifiManagerPrivate::setCurrentSSID(const QString &ssid)
@@ -71,7 +68,7 @@ void QWifiManagerPrivate::handleAuthenticating(QWifiEvent *event)
QString ssid = data.mid(data.indexOf(QLatin1String("SSID")) + 6);
ssid = ssid.left(ssid.lastIndexOf(QLatin1Char('\'')));
- setCurrentSSID(QWifiUtils::decodeHexEncoded(ssid));
+ setCurrentSSID(QWifiSupplicant::decodeHexEncoded(ssid));
updateNetworkState(QWifiManager::Authenticating);
}
@@ -79,7 +76,7 @@ void QWifiManagerPrivate::handleConnected()
{
qCDebug(B2QT_WIFI) << "connected network: " << m_currentSSID;
updateNetworkState(QWifiManager::ObtainingIPAddress);
- m_wifiController->call(QWifiController::AcquireIPAddress);
+ m_wifiController->asyncCall(QWifiController::AcquireIPAddress);
}
void QWifiManagerPrivate::handleDisconneced()
@@ -124,19 +121,14 @@ QString QWifiManagerPrivate::call(const QString &command)
if (m_backendState != QWifiManager::Running)
return QString();
- char data[2048];
- size_t len = sizeof(data) - 1; // -1: room to add a 0-terminator
- QString actualCommand = command;
- qCDebug(B2QT_WIFI) << "call command: " << actualCommand.toLocal8Bit();
- if (q_wifi_command(m_interface, actualCommand.toLocal8Bit(), data, &len) < 0) {
+ QByteArray reply;
+ bool success = m_wifiController->supplicant()->sendCommand(command, &reply);
+ if (!success) {
qCDebug(B2QT_WIFI) << "call to supplicant failed!";
return QString();
}
- if (len < sizeof(data))
- data[len] = 0;
- QString result = QLatin1String(data);
- return result.trimmed();
+ return QLatin1String(reply.trimmed());
}
bool QWifiManagerPrivate::checkedCall(const QString &command)
@@ -242,7 +234,7 @@ QWifiManager::QWifiManager()
QWifiManager::~QWifiManager()
{
Q_D(QWifiManager);
- d->m_wifiController->call(QWifiController::ExitEventLoop);
+ d->m_wifiController->asyncCall(QWifiController::ExitEventLoop);
d->m_wifiController->wait();
delete d_ptr;
}
@@ -310,7 +302,7 @@ QWifiManager::BackendState QWifiManager::backendState() const
void QWifiManager::start()
{
Q_D(QWifiManager);
- d->m_wifiController->call(QWifiController::InitializeBackend);
+ d->m_wifiController->asyncCall(QWifiController::InitializeBackend);
}
/*!
@@ -323,7 +315,7 @@ void QWifiManager::start()
void QWifiManager::stop()
{
Q_D(QWifiManager);
- d->m_wifiController->call(QWifiController::TerminateBackend);
+ d->m_wifiController->asyncCall(QWifiController::TerminateBackend);
}
/*!
@@ -433,7 +425,7 @@ bool QWifiManager::connect(QWifiConfiguration *config)
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));
+ const QString ssid = QWifiSupplicant::decodeHexEncoded(networkFields.at(1));
if (ssid == d->m_currentSSID) {
id = networkFields.at(0);
networkKnown = true;
@@ -467,7 +459,7 @@ bool QWifiManager::connect(QWifiConfiguration *config)
// ref: https://www.freebsd.org/cgi/man.cgi?wpa_supplicant.conf
// ----------------------------------------------------------------------
if (protocol.isEmpty() || protocol.contains(QStringLiteral("WPA"))) {
- // ### todo - password length has limits (see IEEE 802.11), we need to check
+ // ### TODO - password length has limits (see IEEE 802.11), we need to check
// for those limits here. Supplicant gives only a meaningless "fail" message.
ok = ok && d->checkedCall(setNetworkCommand + QLatin1String(" psk ") + q + psk + q);
key_mgmt = QLatin1String("WPA-PSK");
@@ -506,7 +498,7 @@ void QWifiManager::disconnect()
{
Q_D(QWifiManager);
d->call(QStringLiteral("DISCONNECT"));
- d->m_wifiController->call(QWifiController::StopDhcp);
+ d->m_wifiController->asyncCall(QWifiController::StopDhcp);
}
void QWifiManager::handleBackendStateChanged(BackendState backendState)
diff --git a/src/wifi/qwifimanager_p.h b/src/wifi/qwifimanager_p.h
index 1046880..5449551 100644
--- a/src/wifi/qwifimanager_p.h
+++ b/src/wifi/qwifimanager_p.h
@@ -53,7 +53,6 @@ public:
QWifiManager *const q_ptr;
QWifiController *m_wifiController;
QWifiNetworkListModel *m_networkListModel;
- QWifiDevice *m_device;
int m_scanTimer;
bool m_scanning;
diff --git a/src/wifi/qwifinetworklistmodel.cpp b/src/wifi/qwifinetworklistmodel.cpp
index 9d6202f..a1f825f 100644
--- a/src/wifi/qwifinetworklistmodel.cpp
+++ b/src/wifi/qwifinetworklistmodel.cpp
@@ -18,7 +18,7 @@
****************************************************************************/
#include "qwifinetworklistmodel_p.h"
#include "qwifinetwork_p.h"
-#include "qwifiutils_p.h"
+#include "qwifisupplicant_p.h"
#include "qwifimanager.h"
@@ -124,7 +124,7 @@ void QWifiNetworkListModel::parseScanResults(const QString &results)
continue;
int pos = 0;
- QString ssid = QWifiUtils::decodeHexEncoded(info.at(4));
+ QString ssid = QWifiSupplicant::decodeHexEncoded(info.at(4));
if (ssid.isEmpty())
continue;
diff --git a/src/wifi/qwifisupplicant.cpp b/src/wifi/qwifisupplicant.cpp
new file mode 100644
index 0000000..34a40af
--- /dev/null
+++ b/src/wifi/qwifisupplicant.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 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 "qwifisupplicant_p.h"
+#include "qwifidevice.h"
+
+#include <poll.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QProcess>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(B2QT_WIFI_VERBOSE, "qt.b2qt.wifi.verbose")
+
+#define CONFIG_FILE "/etc/wpa_supplicant.qtwifi.conf"
+#define CONTROL_INTERFACE_PATH "/var/run/wpa_supplicant/"
+
+QWifiSupplicant::QWifiSupplicant(QObject *parent) :
+ QObject(parent),
+ ctrl_conn(0),
+ monitor_conn(0),
+ interface(QWifiDevice::wifiInterfaceName())
+{
+ createSupplicantConfig();
+}
+
+void QWifiSupplicant::createSupplicantConfig() const
+{
+ QFile supplicantConfig(QLatin1String(CONFIG_FILE));
+ if (supplicantConfig.exists())
+ return;
+
+ if (supplicantConfig.open(QIODevice::WriteOnly)) {
+ supplicantConfig.write("ctrl_interface=" CONTROL_INTERFACE_PATH "\n"
+ "ctrl_interface_group=0\n"
+ "update_config=1\n");
+ } else {
+ qCWarning(B2QT_WIFI) << "failed to create supplicant configuration file.";
+ }
+}
+
+bool QWifiSupplicant::startSupplicant()
+{
+ QString pidFile = QLatin1String("/var/run/wpa_supplicant." + interface + ".pid");
+ QString driver(QStringLiteral("nl80211,wext"));
+
+ QStringList arg;
+ arg << QStringLiteral("--start") << QStringLiteral("--quiet") << QStringLiteral("--name");
+ arg << QStringLiteral("wpa_supplicant") << QStringLiteral("--startas");
+ arg << QStringLiteral("/usr/sbin/wpa_supplicant") << QStringLiteral("--pidfile") << pidFile;
+ arg << QStringLiteral("--") << QStringLiteral("-B") << QStringLiteral("-P") << pidFile;
+ arg << QStringLiteral("-i") << QLatin1String(interface) << QStringLiteral("-c");
+ arg << QLatin1String(CONFIG_FILE) << QStringLiteral("-D") << driver;
+
+ QProcess startStopDaemon;
+ startStopDaemon.start(QStringLiteral("start-stop-daemon"), arg);
+ startStopDaemon.waitForFinished();
+ qCDebug(B2QT_WIFI) << startStopDaemon.readAll();
+
+ // if the interface socket exists then wpa-supplicant was invoked successfully
+ if (!QFile(QLatin1String(CONTROL_INTERFACE_PATH + interface)).exists()) {
+ qCWarning(B2QT_WIFI) << "failed to invoke wpa_supplicant!\n" << startStopDaemon.readAll();
+ return false;
+ }
+ // reset sockets used for exiting from hung state
+ exit_sockets[0] = exit_sockets[1] = -1;
+ return true;
+}
+
+bool QWifiSupplicant::stopSupplicant()
+{
+ QString pidFile = QLatin1String("/var/run/wpa_supplicant." + interface + ".pid");
+
+ if (QFile(pidFile).exists()) {
+ QStringList arg;
+ arg << QStringLiteral("--stop") << QStringLiteral("--quiet") << QStringLiteral("--name");
+ arg << QStringLiteral("wpa_supplicant") << QStringLiteral("--pidfile") << pidFile;
+
+ QProcess startStopDaemon;
+ startStopDaemon.start(QStringLiteral("start-stop-daemon"), arg);
+ startStopDaemon.waitForFinished();
+ if (startStopDaemon.exitStatus() != QProcess::NormalExit) {
+ qCWarning(B2QT_WIFI) << "failed to stop a supplicant process!\n" << startStopDaemon.readAll();
+ return false;
+ }
+
+ QFile::remove(pidFile);
+ }
+
+ QFile::remove(QLatin1String(CONTROL_INTERFACE_PATH + interface));
+
+ // workaround for QTEE-957
+ QProcess killall;
+ killall.start(QStringLiteral("killall"), QStringList() << QStringLiteral("-9") << QStringLiteral("wpa_supplicant"));
+ killall.waitForFinished();
+
+ return true;
+}
+
+bool QWifiSupplicant::connectToSupplicant()
+{
+ static char path[4096];
+ snprintf(path, sizeof(path), "%s/%s", CONTROL_INTERFACE_PATH, interface.constData());
+
+ ctrl_conn = wpa_ctrl_open(path);
+ if (ctrl_conn == NULL) {
+ qCWarning(B2QT_WIFI, "Unable to open connection to supplicant on \"%s\": %s",
+ path, strerror(errno));
+ return false;
+ }
+ monitor_conn = wpa_ctrl_open(path);
+ if (monitor_conn == NULL) {
+ wpa_ctrl_close(ctrl_conn);
+ ctrl_conn = NULL;
+ return false;
+ }
+ if (wpa_ctrl_attach(monitor_conn) != 0) {
+ wpa_ctrl_close(monitor_conn);
+ wpa_ctrl_close(ctrl_conn);
+ ctrl_conn = monitor_conn = NULL;
+ return false;
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
+ wpa_ctrl_close(monitor_conn);
+ wpa_ctrl_close(ctrl_conn);
+ ctrl_conn = monitor_conn = NULL;
+ return false;
+ }
+
+ return true;
+}
+
+void QWifiSupplicant::closeSupplicantConnection()
+{
+ if (ctrl_conn != NULL) {
+ wpa_ctrl_close(ctrl_conn);
+ ctrl_conn = NULL;
+ }
+
+ if (monitor_conn != NULL) {
+ wpa_ctrl_close(monitor_conn);
+ monitor_conn = NULL;
+ }
+
+ if (exit_sockets[0] >= 0) {
+ close(exit_sockets[0]);
+ exit_sockets[0] = -1;
+ }
+
+ if (exit_sockets[1] >= 0) {
+ close(exit_sockets[1]);
+ exit_sockets[1] = -1;
+ }
+}
+
+int QWifiSupplicant::waitForEvent(char *buf, size_t buflen)
+{
+ size_t nread = buflen - 1;
+ int result;
+ char *match, *match2;
+
+ if (monitor_conn == NULL)
+ return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed");
+
+ result = receiveEvent(buf, &nread);
+
+ // Terminate reception on exit socket
+ if (result == -2)
+ return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - connection closed");
+
+ if (result < 0) {
+ qCWarning(B2QT_WIFI, "receiveEvent failed: %s", strerror(errno));
+ return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - recv error");
+ }
+
+ buf[nread] = '\0';
+ // Check for EOF on the socket
+ if (result == 0 && nread == 0) {
+ // Fabricate an event to pass up
+ qCWarning(B2QT_WIFI, "Received EOF on supplicant socket");
+ return snprintf(buf, buflen, WPA_EVENT_TERMINATING " - signal 0 received");
+ }
+
+ /*
+ * Events strings are in the format
+ *
+ * IFNAME=iface <N>CTRL-EVENT-XXX
+ * or
+ * <N>CTRL-EVENT-XXX
+ *
+ * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,
+ * etc.) and XXX is the event name. The level information is not useful
+ * to us, so strip it off.
+ */
+
+ if (strncmp(buf, "IFNAME=", (sizeof("IFNAME=") - 1)) == 0) {
+ match = strchr(buf, ' ');
+ if (match != NULL) {
+ if (match[1] == '<') {
+ match2 = strchr(match + 2, '>');
+ if (match2 != NULL) {
+ nread -= (match2 - match);
+ memmove(match + 1, match2 + 1, nread - (match - buf) + 1);
+ }
+ }
+ } else {
+ return snprintf(buf, buflen, "%s", "CTRL-EVENT-IGNORE ");
+ }
+ } else if (buf[0] == '<') {
+ match = strchr(buf, '>');
+ if (match != NULL) {
+ nread -= (match + 1 - buf);
+ memmove(buf, match + 1, nread + 1);
+ //qCWarning(B2QT_WIFI, "supplicant generated event without interface - %s", buf);
+ }
+ } else {
+ // let the event go as is!
+ qCWarning(B2QT_WIFI, "supplicant generated event without interface and without message level - %s", buf);
+ }
+
+ return nread;
+}
+
+bool QWifiSupplicant::sendCommand(const QString &command, QByteArray *reply)
+{
+ QByteArray cmd = command.toLocal8Bit();
+ qCDebug(B2QT_WIFI) << "[command]: " << cmd;
+
+ if (ctrl_conn == NULL) {
+ qCWarning(B2QT_WIFI, "Not connected to wpa_supplicant");
+ return false;
+ }
+
+ char data[8192];
+ size_t len = sizeof(data) - 1; // -1: room to add a 0-terminator
+ int ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), data, &len, NULL);
+ if (ret == -2) {
+ qCWarning(B2QT_WIFI) << "command timed out";
+ // unblocks the monitor receive socket for termination
+ TEMP_FAILURE_RETRY(write(exit_sockets[0], "T", 1));
+ return false;
+ } else if (ret < 0 || strncmp(data, "FAIL", 4) == 0) {
+ return false;
+ }
+
+ if (len == sizeof(data) - 1) {
+ qCWarning(B2QT_WIFI) << "possible buffer overflow detected!";
+ return false;
+ }
+
+ data[len] = 0;
+ qCDebug(B2QT_WIFI_VERBOSE) << "[response]: " << data;
+ *reply = QByteArray(data, len);
+
+ return true;
+}
+
+int QWifiSupplicant::receiveEvent(char *reply, size_t *reply_len)
+{
+ int res = 0;
+ int ctrlfd = wpa_ctrl_get_fd(monitor_conn);
+ struct pollfd rfds[2];
+
+ memset(rfds, 0, 2 * sizeof(struct pollfd));
+ rfds[0].fd = ctrlfd;
+ rfds[0].events |= POLLIN;
+ rfds[1].fd = exit_sockets[1];
+ rfds[1].events |= POLLIN;
+ res = TEMP_FAILURE_RETRY(poll(rfds, 2, -1));
+ if (res < 0) {
+ qCWarning(B2QT_WIFI, "Error poll = %d", res);
+ return res;
+ }
+ if (rfds[0].revents & POLLIN) {
+ return wpa_ctrl_recv(monitor_conn, reply, reply_len);
+ }
+
+ /* it is not rfds[0], then it must be rfts[1] (i.e. the exit socket)
+ * or we timed out. In either case, this call has failed ..
+ */
+ return -2;
+}
+
+/*! \internal
+ *
+ Decode wpa_supplicant encoded string, see file hostapd/src/utils/common.c
+ in git://w1.fi/hostap.git repository.
+
+ 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 QWifiSupplicant::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);
+}
+
+int QWifiSupplicant::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 QWifiSupplicant::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;
+}
+
+QT_END_NAMESPACE
diff --git a/src/wifi/qwifiutils_p.h b/src/wifi/qwifisupplicant_p.h
index 8b3e54a..5119f9c 100644
--- a/src/wifi/qwifiutils_p.h
+++ b/src/wifi/qwifisupplicant_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 Digia Plc
+** Copyright (C) 2014 Digia Plc
** All rights reserved.
** For any questions to Digia, please use the contact form at
** http://www.qt.io
@@ -16,22 +16,46 @@
** the contact form at http://www.qt.io
**
****************************************************************************/
-#ifndef QWIFIUTILS_H
-#define QWIFIUTILS_H
+#ifndef QWIFISUPPLICANT_H
+#define QWIFISUPPLICANT_H
-#include <QtCore/QString>
+#include <QObject>
+#include <QByteArray>
+
+#include "wpa-supplicant/wpa_ctrl.h"
QT_BEGIN_NAMESPACE
-class QWifiUtils
+Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI)
+Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI_VERBOSE)
+
+class QWifiSupplicant : public QObject
{
+ Q_OBJECT
public:
+ explicit QWifiSupplicant(QObject *parent = 0);
+
+ void createSupplicantConfig() const;
+ bool startSupplicant();
+ bool stopSupplicant();
+ bool connectToSupplicant();
+ void closeSupplicantConnection();
+ int waitForEvent(char *buf, size_t buflen);
+ bool sendCommand(const QString &command, QByteArray *reply);
+ static QString decodeHexEncoded(const QString &encoded);
+
+protected:
+ int receiveEvent(char *reply, size_t *reply_len);
static int hex2num(char c);
static int hex2byte(const char *hex);
- static QString decodeHexEncoded(const QString &encoded);
+private:
+ wpa_ctrl *ctrl_conn;
+ wpa_ctrl *monitor_conn;
+ int exit_sockets[2];
+ QByteArray interface;
};
QT_END_NAMESPACE
-#endif // QWIFIUTILS_H
+#endif // QWIFISUPPLICANT_H
diff --git a/src/wifi/qwifiutils.cpp b/src/wifi/qwifiutils.cpp
deleted file mode 100644
index 21c440b..0000000
--- a/src/wifi/qwifiutils.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
-**
-** 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/wifi.pro b/src/wifi/wifi.pro
index e674c95..faf15f2 100644
--- a/src/wifi/wifi.pro
+++ b/src/wifi/wifi.pro
@@ -17,8 +17,7 @@ HEADERS += \
$$PWD/qwificontroller_p.h \
$$PWD/qwifidevice.h \
$$PWD/qwificonfiguration.h \
- $$PWD/qwifiutils_p.h \
- $$PWD/qwifielinux_p.h
+ $$PWD/qwifisupplicant_p.h
SOURCES += \
$$PWD/qwifimanager.cpp \
@@ -27,8 +26,7 @@ SOURCES += \
$$PWD/qwificontroller.cpp \
$$PWD/qwifidevice.cpp \
$$PWD/qwificonfiguration.cpp \
- $$PWD/qwifiutils.cpp \
- $$PWD/qwifielinux.cpp \
+ $$PWD/qwifisupplicant.cpp \
$$[QT_SYSROOT]/usr/include/wpa-supplicant/wpa_ctrl.c \
$$[QT_SYSROOT]/usr/include/wpa-supplicant/os_unix.c