From 1386f2dc628071b0e14c9d21337402101e179380 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 19 Jan 2016 14:40:23 +0100 Subject: Use lastError to report relevant errors This improves the error handling situation in the module. Change-Id: I9a67038efd3d82d7a2b87c2184cce52ad5b855e7 Task-number: QTEE-1037 Reviewed-by: Teemu Holappa --- src/wifi/qwificontroller.cpp | 77 ++++++++++++++++++++++++++------------------ src/wifi/qwifimanager.cpp | 13 +++++--- src/wifi/qwifisupplicant.cpp | 44 ++++++++++++++++--------- src/wifi/qwifisupplicant_p.h | 5 ++- 4 files changed, 87 insertions(+), 52 deletions(-) diff --git a/src/wifi/qwificontroller.cpp b/src/wifi/qwificontroller.cpp index 61f5761..a260050 100644 --- a/src/wifi/qwificontroller.cpp +++ b/src/wifi/qwificontroller.cpp @@ -86,7 +86,7 @@ QWifiController::QWifiController(QWifiManager *manager, QWifiManagerPrivate *man m_exitEventThread(false), m_interface(QWifiDevice::wifiInterfaceName()), m_eventThread(new QWifiEventThread(this)), - m_supplicant(new QWifiSupplicant(this)) + m_supplicant(new QWifiSupplicant(this, m_managerPrivate)) { qRegisterMetaType("QWifiManager::BackendState"); } @@ -138,40 +138,39 @@ void QWifiController::initializeBackend() { qCDebug(B2QT_WIFI) << "initializing wifi backend"; emit backendStateChanged(QWifiManager::Initializing); - qCDebug(B2QT_WIFI) << "run ifconfig (up)"; + QProcess ifconfig; - ifconfig.start(QStringLiteral("ifconfig"), QStringList() << QLatin1String(m_interface) << QStringLiteral("up")); + ifconfig.start(QStringLiteral("ifconfig"), + QStringList() << QLatin1String(m_interface) << QStringLiteral("up")); + if (!ifconfig.waitForStarted()) { + m_managerPrivate->updateLastError(ifconfig.program() + QLatin1String(": ") + ifconfig.errorString()); + return; + } + ifconfig.waitForFinished(); bool initFailed = false; - if (ifconfig.exitStatus() != QProcess::NormalExit && ifconfig.exitCode() != 0) { - qCWarning(B2QT_WIFI) << "failed to bring up wifi interface!"; + QByteArray error = ifconfig.readAllStandardError(); + if (!error.isEmpty()) { + m_managerPrivate->updateLastError(QLatin1String("failed to bring up wifi interface: " + error)); initFailed = true; } - if (!initFailed && resetSupplicantSocket()) { - qCDebug(B2QT_WIFI) << "wifi backend started successfully"; + if (!initFailed && resetSupplicantSocket()) emit backendStateChanged(QWifiManager::Running); - } else { + else emit backendStateChanged(QWifiManager::NotRunning); - } } bool QWifiController::resetSupplicantSocket() { qCDebug(B2QT_WIFI) << "reset supplicant socket"; exitWifiEventThread(); - if (!m_supplicant->stopSupplicant()) - qCWarning(B2QT_WIFI) << "failed to stop supplicant!"; + m_supplicant->stopSupplicant(); m_supplicant->closeSupplicantConnection(); - qCDebug(B2QT_WIFI) << "start supplicant"; - if (!m_supplicant->startSupplicant()) { - qCWarning(B2QT_WIFI) << "failed to start a supplicant!"; + if (!m_supplicant->startSupplicant()) return false; - } - qCDebug(B2QT_WIFI) << "connect to supplicant"; - if (!m_supplicant->connectToSupplicant()) { - qCWarning(B2QT_WIFI) << "failed to connect to a supplicant!"; + if (!m_supplicant->connectToSupplicant()) return false; - } + startWifiEventThread(); return true; } @@ -180,20 +179,25 @@ void QWifiController::terminateBackend() { qCDebug(B2QT_WIFI) << "terminating wifi backend"; emit backendStateChanged(QWifiManager::Terminating); + exitWifiEventThread(); - if (!m_supplicant->stopSupplicant()) - qCWarning(B2QT_WIFI) << "failed to stop supplicant!"; + m_supplicant->stopSupplicant(); m_supplicant->closeSupplicantConnection(); - qCDebug(B2QT_WIFI) << "run ifconfig (down)"; QProcess ifconfig; - ifconfig.start(QStringLiteral("ifconfig"), QStringList() << QLatin1String(m_interface) << QStringLiteral("down")); + ifconfig.start(QStringLiteral("ifconfig"), + QStringList() << QLatin1String(m_interface) << QStringLiteral("down")); + if (!ifconfig.waitForStarted()) { + m_managerPrivate->updateLastError(ifconfig.program() + QLatin1String(": ") + ifconfig.errorString()); + return; + } + ifconfig.waitForFinished(); - if (ifconfig.exitStatus() != QProcess::NormalExit && ifconfig.exitCode() != 0) - qCWarning(B2QT_WIFI) << "failed to bring down wifi interface!"; + QByteArray error = ifconfig.readAllStandardError(); + if (!error.isEmpty()) + m_managerPrivate->updateLastError(QLatin1String("failed to bring down wifi interface: " + error)); stopDhcp(); - qCDebug(B2QT_WIFI) << "wifi backend stopped successfully"; emit backendStateChanged(QWifiManager::NotRunning); } @@ -209,7 +213,7 @@ void QWifiController::exitWifiEventThread() m_exitEventThread = true; m_managerPrivate->call(QStringLiteral("SCAN")); if (!m_eventThread->wait(8000)) - qCWarning(B2QT_WIFI, "timed out waiting for wifi event thread to exit!"); + qCWarning(B2QT_WIFI, "timed out waiting for wifi event thread to exit"); } } @@ -227,7 +231,7 @@ void QWifiController::killDhcpProcess(const QString &path) const bool ok; int pid = pidFile.readAll().trimmed().toInt(&ok); if (!ok) { - qCWarning(B2QT_WIFI) << "pid is not a number!"; + qCWarning(B2QT_WIFI) << "pid is not a number"; return; } @@ -245,13 +249,22 @@ void QWifiController::acquireIPAddress() QProcess udhcpc; udhcpc.start(QStringLiteral("udhcpc"), args); - udhcpc.waitForFinished(); - if (udhcpc.exitStatus() != QProcess::NormalExit && udhcpc.exitCode() != 0) - qCWarning(B2QT_WIFI) << "udhcpc process failed!"; + if (!udhcpc.waitForStarted()) { + m_managerPrivate->updateLastError(udhcpc.program() + QLatin1String(": ") + udhcpc.errorString()); + emit dhcpRequestFinished(QLatin1String("failed")); + return; + } + udhcpc.waitForFinished(); + QByteArray error = udhcpc.readAllStandardError(); QString status = QLatin1String("success"); - if (udhcpc.readAll().contains("No lease")) + if (!error.isEmpty()) { + m_managerPrivate->updateLastError(QLatin1String("udhcpc failed: " + error)); status = QLatin1String("failed"); + } else { + if (udhcpc.readAllStandardOutput().contains("No lease")) + status = QLatin1String("failed"); + } emit dhcpRequestFinished(status); } diff --git a/src/wifi/qwifimanager.cpp b/src/wifi/qwifimanager.cpp index 6f733ba..0448ec7 100644 --- a/src/wifi/qwifimanager.cpp +++ b/src/wifi/qwifimanager.cpp @@ -110,6 +110,11 @@ void QWifiManagerPrivate::updateWifiState() { QProcess ps; ps.start(QStringLiteral("ps")); + if (!ps.waitForStarted()) { + updateLastError(ps.program() + QLatin1String(": ") + ps.errorString()); + return; + } + ps.waitForFinished(); bool supplicantRunning = ps.readAll().contains("wpa_supplicant"); if (supplicantRunning && m_wifiController->resetSupplicantSocket()) @@ -124,7 +129,7 @@ QString QWifiManagerPrivate::call(const QString &command) QByteArray reply; bool success = m_wifiController->supplicant()->sendCommand(command, &reply); if (!success) { - qCDebug(B2QT_WIFI) << "call to supplicant failed!"; + qCDebug(B2QT_WIFI) << "call to supplicant failed"; return QString(); } @@ -216,7 +221,7 @@ QWifiManager::QWifiManager() if (!QWifiDevice::wifiSupported()) qCWarning(B2QT_WIFI) << "WifiManager may not work as expected on this device. Use the API provided by QtWifi " - "library to verify if device has support for Wi-Fi before creating an instance of wifi manager!"; + "library to verify if device has support for Wi-Fi before creating an instance of wifi manager"; d->m_wifiController = new QWifiController(this, d_ptr); QObject::connect(d->m_wifiController, &QWifiController::backendStateChanged, @@ -413,7 +418,7 @@ bool QWifiManager::connect(QWifiConfiguration *config) { Q_D(QWifiManager); if (d->m_backendState != Running) { - qCWarning(B2QT_WIFI) << "start wifi backend before calling connect() !"; + qCWarning(B2QT_WIFI) << "start wifi backend before calling connect()"; return false; } @@ -438,7 +443,7 @@ bool QWifiManager::connect(QWifiConfiguration *config) id = d->call(QStringLiteral("ADD_NETWORK")); id.toInt(&ok); if (!ok) { - d->updateLastError(QStringLiteral("failed to add network!")); + d->updateLastError(QStringLiteral("failed to add network")); return false; } } diff --git a/src/wifi/qwifisupplicant.cpp b/src/wifi/qwifisupplicant.cpp index b2ec497..5bab8c4 100644 --- a/src/wifi/qwifisupplicant.cpp +++ b/src/wifi/qwifisupplicant.cpp @@ -18,6 +18,7 @@ ****************************************************************************/ #include "qwifisupplicant_p.h" #include "qwifidevice.h" +#include "qwifimanager_p.h" #include #include @@ -33,11 +34,12 @@ 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) : +QWifiSupplicant::QWifiSupplicant(QObject *parent, QWifiManagerPrivate *managerPrivate) : QObject(parent), ctrl_conn(0), monitor_conn(0), - interface(QWifiDevice::wifiInterfaceName()) + interface(QWifiDevice::wifiInterfaceName()), + m_managerPrivate(managerPrivate) { createSupplicantConfig(); } @@ -53,7 +55,7 @@ void QWifiSupplicant::createSupplicantConfig() const "ctrl_interface_group=0\n" "update_config=1\n"); } else { - qCWarning(B2QT_WIFI) << "failed to create supplicant configuration file."; + m_managerPrivate->updateLastError(QLatin1String("failed to create wpa_supplicant configuration file.")); } } @@ -71,13 +73,17 @@ bool QWifiSupplicant::startSupplicant() arg << QLatin1String(CONFIG_FILE) << QStringLiteral("-D") << driver; QProcess startStopDaemon; + startStopDaemon.setProcessChannelMode(QProcess::MergedChannels); startStopDaemon.start(QStringLiteral("start-stop-daemon"), arg); + if (!startStopDaemon.waitForStarted()) { + m_managerPrivate->updateLastError(startStopDaemon.program() + QLatin1String(": ") + startStopDaemon.errorString()); + return false; + } 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(); + m_managerPrivate->updateLastError(QLatin1String("failed to invoke wpa_supplicant: " + + startStopDaemon.readAll())); return false; } // reset sockets used for exiting from hung state @@ -96,9 +102,14 @@ bool QWifiSupplicant::stopSupplicant() QProcess startStopDaemon; startStopDaemon.start(QStringLiteral("start-stop-daemon"), arg); + if (!startStopDaemon.waitForStarted()) { + m_managerPrivate->updateLastError(startStopDaemon.program() + QLatin1String(": ") + startStopDaemon.errorString()); + return false; + } startStopDaemon.waitForFinished(); - if (startStopDaemon.exitStatus() != QProcess::NormalExit) { - qCWarning(B2QT_WIFI) << "failed to stop a supplicant process!\n" << startStopDaemon.readAll(); + QByteArray error = startStopDaemon.readAllStandardError(); + if (!error.isEmpty()) { + m_managerPrivate->updateLastError(QLatin1String("failed to stop a wpa_supplicant process" + error)); return false; } @@ -119,34 +130,37 @@ bool QWifiSupplicant::connectToSupplicant() { static char path[4096]; snprintf(path, sizeof(path), "%s/%s", CONTROL_INTERFACE_PATH, interface.constData()); + bool connected = true; ctrl_conn = wpa_ctrl_open(path); if (ctrl_conn == NULL) { - qCWarning(B2QT_WIFI, "Unable to open connection to supplicant on \"%s\": %s", + qCWarning(B2QT_WIFI, "Unable to open connection to wpa_supplicant on \"%s\": %s", path, strerror(errno)); - return false; + connected = false; } monitor_conn = wpa_ctrl_open(path); if (monitor_conn == NULL) { wpa_ctrl_close(ctrl_conn); ctrl_conn = NULL; - return false; + connected = 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; + connected = 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; + connected = false; } - return true; + if (!connected) + m_managerPrivate->updateLastError(QLatin1String("failed to connect to wpa_supplicant")); + return connected; } void QWifiSupplicant::closeSupplicantConnection() @@ -263,7 +277,7 @@ bool QWifiSupplicant::sendCommand(const QString &command, QByteArray *reply) } if (len == sizeof(data) - 1) { - qCWarning(B2QT_WIFI) << "possible buffer overflow detected!"; + qCWarning(B2QT_WIFI) << "possible buffer overflow detected"; return false; } diff --git a/src/wifi/qwifisupplicant_p.h b/src/wifi/qwifisupplicant_p.h index 3b18380..0a6a964 100644 --- a/src/wifi/qwifisupplicant_p.h +++ b/src/wifi/qwifisupplicant_p.h @@ -30,11 +30,13 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI) Q_DECLARE_LOGGING_CATEGORY(B2QT_WIFI_VERBOSE) +class QWifiManagerPrivate; + class QWifiSupplicant : public QObject { Q_OBJECT public: - explicit QWifiSupplicant(QObject *parent = 0); + explicit QWifiSupplicant(QObject *parent, QWifiManagerPrivate *managerPrivate); void createSupplicantConfig() const; bool startSupplicant(); @@ -53,6 +55,7 @@ private: wpa_ctrl *monitor_conn; int exit_sockets[2]; QByteArray interface; + QWifiManagerPrivate *const m_managerPrivate; }; QT_END_NAMESPACE -- cgit v1.2.3