Index: sources/device/DeviceView.cpp =================================================================== diff -u -r2ef03b2ce51b4dc507f66e9671953a8e0824bde9 -r0932b2beee9cc169291cbf69161f902f805237b1 --- sources/device/DeviceView.cpp (.../DeviceView.cpp) (revision 2ef03b2ce51b4dc507f66e9671953a8e0824bde9) +++ sources/device/DeviceView.cpp (.../DeviceView.cpp) (revision 0932b2beee9cc169291cbf69161f902f805237b1) @@ -22,18 +22,28 @@ #include "DeviceController.h" #include "GuiGlobals.h" #include "encryption.h" +#include "MWifiNetwork.h" VIEW_DEF_CLASS(VDevice) void VDevice::initConnections() { DEVICE_VIEW_INIT_CONNECTIONS_LIST - connect(&_DeviceController , SIGNAL(didPOSTOSVersionData(QString)), this , SLOT( onPOSTOSVersionData(QString))); } -// developer implementation section +// ================================================================================================== +// ================================================= developer implementation section +// ================================================================================================== + +// ================================================= OS Version +void VDevice::onPOSTOSVersionData(const QString &vOSVersion) +{ + osVersion(vOSVersion); +} + +// ================================================= Brightness void VDevice::doInitBrightness() { // DEBUG : qDebug() << "HERE Request" << vValue; DeviceBrightnessRequestData data; @@ -89,7 +99,6 @@ } void VDevice::onAttributeResponse(const DeviceCryptSetupResponseData &vData) { - // DEBUG : qDebug() << "HERE Response" << vData.mBrightnessPercent; // this has to be called to let Gui to set to old value that device controller provided. // this response is not updating the cryptsetup attribute. // cryptsetup attribute will containe the command to be sent to the cryptsetup script @@ -174,7 +183,6 @@ } void VDevice::onAttributeResponse(const DeviceRootSSHAccessResponseData &vData) { - // DEBUG : qDebug() << "HERE Response" << vData.mBrightnessPercent; if ( vData.mAccepted ) { rootSSHAccess(vData.mRootSSHAccess); status(""); @@ -258,7 +266,186 @@ response(true); } -void VDevice::onPOSTOSVersionData(const QString &vOSVersion) +// ================================================= WifiList +void VDevice::doInitWifiList() { + wifiListRequest({}); +} + +void VDevice::wifiListRequest(const QStringList &) { + wifiListEnabled(false); + DeviceWifiListRequestData data; + emit didAttributeRequest(data); +} + +void VDevice::onAttributeResponse(const DeviceWifiListResponseData &vData) { + /// When calling a script, the last echo which is before the exit, is not where the script is completed. + /// therefore we need to store the last one to use it when the script is sending the data and then exits, + /// which is when we have the mComp;eted as true. + static QString result; + // DEBUG : + qDebug() << __FUNCTION__ << vData.mMessage << result << vData.mCompleted; + if ( vData.mCompleted ) { + if ( vData.mAccepted ) { + wifiList({ "SSID1" , "SSID2" }); + status(""); + wifiListEnabled(true); // TODO + parseWifiListResult(result); + status(vData.mMessage); + } + else { + // this has to be called to let Gui to set to old value that device controller provided. + // when not accepted could be a message only to update the screen. + emit wifiListChanged({}); + status(vData.mMessage); + } + } + + accepted(vData.mAccepted); + reason (vData.mReason ); + result = vData.mWifiList; + // has to be the last one + response(true); +} + +/*! + * \brief Network::parseWifiListResult + * \details Extract desired information from the WiFi scan output. Sorts by signal stength + * \param vResult - (QString) output collected from QProcess execution + * \return List of the Found SSIDs in a model. + */ +QVariantList VDevice::parseWifiListResult(const QString &vResult) { - osVersion(vOSVersion); + enum SSIDInfo_Enum { + eSSID , + eBSSID , + eFREQ , + eRATE , + eSIGNAL , + eSECURITY , + eWPA_FLAGS , + eRSN_FLAGS , + eIN_USE , + }; + enum ValueUnit_Enum { + eValue , + eUnit , + eCount , + }; + + struct SSIDInfo { + QString mSSID ; + QString mBSSID ; + QString mFREQ_Max ; + QString mRATE_Max ; + quint16 mSIGNAL_Max ; + QString mSECURITY ; + QString mFLAGS ; // eWPA_FLAGS, eRSN_FLAGS are exclusive + bool mIN_USE = false ; + bool mSupported = true ; + QString toString() { + QStringList fields = QStringList() + << mSSID + << mBSSID + << mFREQ_Max + << mRATE_Max + << QString::number(mSIGNAL_Max) + << mSECURITY + << mFLAGS + << (mSupported ? "T" : "") + << (mIN_USE ? "T" : ""); + return fields.join(','); + } + }; + + QString mResult = vResult; + + SSIDInfo data; + QHash mSSIDInfoList; + + // the Freq, Rate units + QString mSSID; + const QString mFREQ_Unit = " MHz"; + const QString mRATE_Unit = " Mbit/s"; + quint32 mFREQ_Value = 0; + quint32 mRATE_Value = 0; + // Removing the units once from the result to accelerate parsing. (will be added when done) + mResult.remove(mFREQ_Unit); + mResult.remove(mRATE_Unit); + + QStringList lines = mResult.split('\n'); + for ( int row = 0; row < lines.count(); row++ ) { + QStringList fields = lines[row].split(','); + if ( fields[eSSID].trimmed().isEmpty() ) continue; // hidden networks, or an incorrect entry + + QString mWPA_FLAGS; + QString mRSN_FLAGS; + + for ( int index = 0; index < fields.count(); index++ ) { // the list has to be sorted and the script is written that way. + QString field = fields[index].trimmed(); + + if ( row ) { // if is not first row + if ( mSSID == fields[eSSID] ) { // if is the same SSID just update necessary fields + quint32 value = 0; + switch (index) { + case eFREQ : + value = QString("%1").arg(field).toInt(); + if ( mFREQ_Value < value ) { mFREQ_Value = value; } break; + case eRATE : + value = QString("%1").arg(field).toInt(); + if ( mRATE_Value < value ) { mRATE_Value = value; } break; + case eSIGNAL : + value = QString("%1").arg(field).toInt(); + if ( data.mSIGNAL_Max < value ) { data.mSIGNAL_Max = value; } break; + case eIN_USE : data.mIN_USE = field.contains("*"); break; + default: break; + } + } + else { // else add the previous one and continue to the next. + if ( ! mSSID.trimmed().isEmpty() ) { + data.mSSID = mSSID; + data.mFREQ_Max += QString::number(mFREQ_Value) + mFREQ_Unit; + data.mRATE_Max += QString::number(mRATE_Value) + mRATE_Unit; + mSSIDInfoList[mSSID] = data; + qDebug() << data.toString(); + } + // clean up / reset + data.mFREQ_Max = ""; + data.mRATE_Max = ""; + data.mFLAGS = ""; + } + } + + switch (index) { // DO NOT USE default in this switch + case eSSID : mSSID = field; break; + case eBSSID :/* data.mBSSID = field; */ break; // not directly used for now + case eFREQ : mFREQ_Value = QString("%1").arg(field).toInt(); break; + case eRATE : mRATE_Value = QString("%1").arg(field).toInt(); break; + case eSIGNAL : data.mSIGNAL_Max = QString("%1").arg(field).toInt(); break; + case eIN_USE : data.mIN_USE = field.contains("*"); break; + + case eSECURITY : + data.mSECURITY = field; + if ( field.isEmpty() ) { + data.mSupported = false; + } else { + data.mSupported = field.remove(QRegExp("(WPA[23])")).trimmed().isEmpty(); + } + break; + + case eWPA_FLAGS : + if ( field.contains("tkip") ) { mWPA_FLAGS += " TKIP" ; data.mSupported = false; } + if ( field.contains("ccmp") ) { mWPA_FLAGS += " AES" ; } + if ( ! mWPA_FLAGS.isEmpty() ) { data.mFLAGS = mWPA_FLAGS.trimmed(); } + break; + + case eRSN_FLAGS : + if ( field.contains("tkip") ) { mRSN_FLAGS += " TKIP" ; data.mSupported = false; } + if ( field.contains("ccmp") ) { mRSN_FLAGS += " AES" ; } + if ( field.contains("sae" ) ) { mRSN_FLAGS += " SAE" ; } + if ( ! mRSN_FLAGS.isEmpty() ) { data.mFLAGS = mRSN_FLAGS.trimmed(); } + break; + } + } + } + return {}; }