#include "WifiInterface.h" // Qt #include #include // Project #include "main.h" #include "Logger.h" #include "StorageGlobals.h" using namespace Storage; WifiInterface::WifiInterface(QObject *parent) : QObject(parent) { } void WifiInterface::onInitConnections() { connect(&_scanProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(onScanFinished(int, QProcess::ExitStatus))); } /*! * \brief WifiInterface::init * \details Initializes the class by setting the connections * \return true on first initialization, false if it has already been initialized */ bool WifiInterface::doInit() { if (_init) return false; _init = true; onInitConnections(); LOG_EVENT("UI," + tr("%1 Initialized").arg(metaObject()->className())); return true; } /*! * \brief WifiInterface::quit * Called when the application is exiting. */ void WifiInterface::onQuit() { onQuitThread(); // verified } /*! * \brief WifiInterface::quitThread * \details Moves this object to main thread to be handled by QApplicaiton * It will also be destroyed there. */ void WifiInterface::onQuitThread() { if (!_thread ) return; moveToThread(qApp->thread()); } /*! * \brief WifiInterface::timerEvent * Built in QObject timer * \param event (QTimerEvent*) - the event timer */ void WifiInterface::timerEvent(QTimerEvent *event) { Q_UNUSED(event); } /*! * \brief WifiInterface::doScan * Scans for Wifi Access Points */ void WifiInterface::doScan() { if (_scanRunning) { LOG_DEBUG("Wifi network scan is already running."); return; } LOG_DEBUG("Scanning for Wifi Access Points..."); _scanProcess.setWorkingDirectory(Wifi_Scripts_Dir); _scanRunning = true; emit didScanStatusChanged(_scanRunning); _scanProcess.start(Wifi_Scan_For_Networks); } /*! * \brief WifiInterface::onScanFinished * Called when finished scanning for networks (success or error) * \param vPid - pid of the scan for networks process * \param vExitStatus - the status upon exit */ void WifiInterface::onScanFinished(int vPid, QProcess::ExitStatus vExitStatus) { LOG_DEBUG(QString("%1: %2,%3").arg(__FUNCTION__).arg(vPid).arg(vExitStatus)); QString out = _scanProcess.readAllStandardOutput(); QString err = _scanProcess.readAllStandardError(); LOG_DEBUG(out); LOG_DEBUG(err); _scanRunning = false; emit didScanStatusChanged(_scanRunning); onParseWifiScan(out); } /*! * \brief Network::onParseWifiScan * Extract desired information from the wifi scan output. Sorts by signal stength * * \param output - (QString) output collected from QProcess execution */ void WifiInterface::onParseWifiScan(const QString &output) { QList networks; QStringList temp = output.split("Cell"); const QString signalLevelSearchTerm = "Signal level="; const QString macAddressSearchTerm = "Address:"; const QString ssidSearchTerm = "ESSID:"; const QString groupCipherSearchTerm = "Group Cipher"; const QString authSuitesSearchTerm = "Authentication Suites"; for (const QString &line : temp) { if (line.contains(ssidSearchTerm) && line.contains(macAddressSearchTerm) && line.contains(signalLevelSearchTerm)) { QString ssid = line.split(ssidSearchTerm)[1].split("\n")[0].replace("\"", "").trimmed(); if (ssid == "") continue; QString macAddress = line.split(macAddressSearchTerm)[1].split("\n")[0].trimmed(); int signalLevel = line.split(signalLevelSearchTerm)[1].split("dBm")[0].trimmed().toInt(); bool isCCMP = line.split(groupCipherSearchTerm)[1].split("\n")[0].contains("CCMP"); bool isEnterprise = line.split(authSuitesSearchTerm)[1].split("\n")[0].contains("802.1x"); bool isPersonal = line.split(authSuitesSearchTerm)[1].split("\n")[0].contains("PSK"); Network::SECURITY_LEVEL securityLevel = Network::SECURITY_LEVEL::UNSUPPORTED; if (isPersonal && isCCMP) securityLevel = Network::SECURITY_LEVEL::WPA2_AES_PERSONAL; else if (isEnterprise && isCCMP) securityLevel = Network::SECURITY_LEVEL::WPA2_AES_ENTERPRISE; // TODO: Add support for the other security levels Network network(macAddress,ssid, securityLevel, Network::STATUS::NOT_CONNECTED, signalLevel); emit didAddNetwork(network); } } } /*! * \brief WifiInterface::doJoinNetwork * Handles request to join a network * \param vMacAddress - (QString) the mac address of the network to join * \param vPassword - (QString) the password for the network provided by the user */ void WifiInterface::doJoinNetwork(const Network &vNetwork, const QString &vPassword) { _wifiInterfaceProcess.start(Wifi_Generate_WPA_Supplicant, QStringList() << vNetwork.ssid() << vPassword << _wpaSupplicantConfPath); _wifiInterfaceProcess.start(Wifi_Start_WPA_Supplicant, QStringList() << _iface << _wpaSupplicantConfPath); }