+ add CurrentWiFi method

+ add support of pid files with interface name to provide compability
with netctl module
* change default wpa_sup ctrl paths
* optimization of wifi calls
This commit is contained in:
arcan1s
2015-03-10 00:52:45 +03:00
parent 362a11f0bc
commit 19976819a1
16 changed files with 183 additions and 76 deletions

View File

@ -196,6 +196,11 @@ small {
<td>yes</td>
</tr>
<!-- wpa_supplicant actions -->
<tr>
<td>QStringList CurrentWiFi()</td>
<td>returns current WiFi point in format <code>NAME|SECURITY|TYPE|FREQS|MACS|SIGNAL|ACTIVE|EXISTS</code></td>
<td>yes</td>
</tr>
<tr>
<td>QStringList VerboseWiFi()</td>
<td>returns available WiFi points in format <code>NAME|SECURITY|TYPE|FREQS|MACS|SIGNAL|ACTIVE|EXISTS</code></td>
@ -238,7 +243,7 @@ small {
</tr>
<tr>
<td>QStringList netctlVerboseProfileList()</td>
<td>returns available profiles in format <code>NAME|DESCRIPTION|ESSID|ACTIVE|ENABLED</code> from netctl even if netctl-auto is running</td>
<td>returns available profiles in format <code>NAME|DESCRIPTION|TYPE|INTERFACE|ESSID|ACTIVE|ENABLED</code> from netctl even if netctl-auto is running</td>
<td>no</td>
</tr>
<tr>
@ -248,7 +253,7 @@ small {
</tr>
<tr>
<td>QStringList VerboseProfileList()</td>
<td>returns available profiles in format <code>NAME|DESCRIPTION|ESSID|ACTIVE|ENABLED</code></td>
<td>returns available profiles in format <code>NAME|DESCRIPTION|TYPE|INTERFACE|ESSID|ACTIVE|ENABLED</code></td>
<td>no</td>
</tr>
<tr>

View File

@ -33,13 +33,15 @@ QList<netctlProfileInfo> parseOutputNetctl(const QList<QVariant> raw)
QStringList list = raw[0].toStringList();
for (int i=0; i<list.count(); i++) {
QStringList info = list[i].split(QChar('|'));
if (info.count() != 5) continue;
if (info.count() != 7) continue;
netctlProfileInfo profile;
profile.name = info[0];
profile.description = info[1];
profile.essid = info[2];
profile.active = info[3].toInt();
profile.enabled = info[4].toInt();
profile.type = info[2];
profile.interface = info[3];
profile.essid = info[4];
profile.active = info[5].toInt();
profile.enabled = info[6].toInt();
profileInfo.append(profile);
}

View File

@ -181,9 +181,14 @@ void MainWindow::updateMainTab()
font.setItalic(profiles[i].enabled);
// tooltip
QString toolTip = QString("");
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Active")).arg(checkStatus(profiles[i].active));
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Enabled")).arg(checkStatus(profiles[i].enabled));
toolTip += QString("%1: %2").arg(QApplication::translate("MainWindow", "Is wireless")).arg(checkStatus(!profiles[i].essid.isEmpty()));
toolTip += QString("%1: %2@%3\n").arg(QApplication::translate("MainWindow", "Type"))
.arg(profiles[i].type).arg(profiles[i].interface);
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Active"))
.arg(checkStatus(profiles[i].active));
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Enabled"))
.arg(checkStatus(profiles[i].enabled));
toolTip += QString("%1: %2").arg(QApplication::translate("MainWindow", "Is wireless"))
.arg(checkStatus(!profiles[i].essid.isEmpty()));
// name
ui->tableWidget_main->setItem(i, 0, new QTableWidgetItem(profiles[i].name));
ui->tableWidget_main->item(i, 0)->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
@ -296,9 +301,12 @@ void MainWindow::updateWifiTab()
.arg(scanResults[i].macs[j])
.arg(scanResults[i].frequencies[j])
.arg(QApplication::translate("MainWindow", "MHz"));
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Type")).arg(type);
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Active")).arg(checkStatus(scanResults[i].active));
toolTip += QString("%1: %2").arg(QApplication::translate("MainWindow", "Exists")).arg(checkStatus(scanResults[i].exists));
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Type"))
.arg(type);
toolTip += QString("%1: %2\n").arg(QApplication::translate("MainWindow", "Active"))
.arg(checkStatus(scanResults[i].active));
toolTip += QString("%1: %2").arg(QApplication::translate("MainWindow", "Exists"))
.arg(checkStatus(scanResults[i].exists));
// name
ui->tableWidget_wifi->setItem(i, 0, new QTableWidgetItem(scanResults[i].name));
ui->tableWidget_wifi->item(i, 0)->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);

View File

@ -435,9 +435,9 @@ QMap<QString, QString> SettingsWindow::getSettings(QString fileName)
settings.beginGroup(QString("wpa_supplicant"));
config[QString("WPASUP_PATH")] = settings.value(QString("WPASUP_PATH"), QString("/usr/bin/wpa_supplicant")).toString();
config[QString("WPACLI_PATH")] = settings.value(QString("WPACLI_PATH"), QString("/usr/bin/wpa_cli")).toString();
config[QString("PID_FILE")] = settings.value(QString("PID_FILE"), QString("/run/wpa_supplicant_netctl-gui.pid")).toString();
config[QString("PID_FILE")] = settings.value(QString("PID_FILE"), QString("/run/wpa_supplicant_$i.pid")).toString();
config[QString("WPA_DRIVERS")] = settings.value(QString("WPA_DRIVERS"), QString("nl80211,wext")).toString();
config[QString("CTRL_DIR")] = settings.value(QString("CTRL_DIR"), QString("/run/wpa_supplicant_netctl-gui")).toString();
config[QString("CTRL_DIR")] = settings.value(QString("CTRL_DIR"), QString("/run/wpa_supplicant")).toString();
config[QString("CTRL_GROUP")] = settings.value(QString("CTRL_GROUP"), QString("users")).toString();
settings.endGroup();

View File

@ -60,11 +60,12 @@ WPASUP_PATH=/usr/bin/wpa_supplicant
# path to wpa_cli
WPACLI_PATH=/usr/bin/wpa_cli
# wpa_supplicant PID file
PID_FILE=/run/wpa_supplicant_netctl-gui.pid
# $i is interface
PID_FILE=/run/wpa_supplicant_$i.pid
# wpa_supplicant drivers for wireless interface comma separated
WPA_DRIVERS=nl80211,wext
# path to control directory which is required by wpa_supplicant
CTRL_DIR=/run/wpa_supplicant_netctl-gui
CTRL_DIR=/run/wpa_supplicant
# group which is owner of CTRL_DIR
CTRL_GROUP=users

View File

@ -20,7 +20,7 @@ close helper after GUI application quit. This option is not recognized by
.IP "CLOSETOTRAY=true"
hide application to tray on exit if tray is available. This option is not recognized by
.BR netctlgui-helper (1)
.IP "CTRL_DIR=/run/wpa_supplicant_netctl-gui"
.IP "CTRL_DIR=/run/wpa_supplicant"
path to control directory which is required by
.BR wpa_supplicant (8)
.IP "CTRL_GROUP=users"
@ -56,7 +56,7 @@ path to
service name without
.I .service
suffix
.IP "PID_FILE=/run/wpa_supplicant_netctl-gui.pid"
.IP "PID_FILE=/run/wpa_supplicant_$i.pid"
.BR wpa_supplicant (8)
PID file
.IP "PREFERED_IFACE="

View File

@ -90,7 +90,7 @@ QStringList ControlAdaptor::FindSettings()
QString ControlAdaptor::LibraryDocs()
{
return (QString("html/index.html").arg(QString(DOCS_PATH)));
return (QString("%1html/index.html").arg(QString(DOCS_PATH)));
}
@ -249,6 +249,26 @@ bool ControlAdaptor::Remove(const QString profile)
// wpaCommand
QString ControlAdaptor::CurrentWiFi()
{
netctlWifiInfo wifiPoint = wpaCommand->current();
QStringList point;
point.append(wifiPoint.name);
point.append(wifiPoint.security);
point.append(QString::number(wifiPoint.type));
QStringList freqList;
for (int j=0; j<wifiPoint.frequencies.count(); j++)
freqList.append(QString::number(wifiPoint.frequencies[j]));
point.append(freqList.join(QChar(',')));
point.append(wifiPoint.macs.join(QChar(',')));
point.append(QString::number(wifiPoint.signal));
point.append(QString::number(wifiPoint.active));
point.append(QString::number(wifiPoint.exists));
return point.join(QChar('|'));
}
QStringList ControlAdaptor::VerboseWiFi()
{
QList<netctlWifiInfo> wifiPoints = wpaCommand->scanWifi();

View File

@ -68,6 +68,7 @@ public slots:
bool Create(const QString profile, const QStringList settingsList);
bool Remove(const QString profile);
// wpaCommand
QString CurrentWiFi();
QStringList VerboseWiFi();
QStringList WiFi();

View File

@ -137,6 +137,8 @@ QStringList NetctlAdaptor::netctlVerboseProfileList()
QStringList profileInfo;
profileInfo.append(profilesInfo[i].name);
profileInfo.append(profilesInfo[i].description);
profileInfo.append(profilesInfo[i].type);
profileInfo.append(profilesInfo[i].interface);
profileInfo.append(profilesInfo[i].essid);
profileInfo.append(QString::number(profilesInfo[i].active));
profileInfo.append(QString::number(profilesInfo[i].enabled));

View File

@ -164,9 +164,9 @@ QMap<QString, QString> NetctlHelper::getSettings(const QString file)
settings.beginGroup(QString("wpa_supplicant"));
config[QString("WPASUP_PATH")] = settings.value(QString("WPASUP_PATH"), QString("/usr/bin/wpa_supplicant")).toString();
config[QString("WPACLI_PATH")] = settings.value(QString("WPACLI_PATH"), QString("/usr/bin/wpa_cli")).toString();
config[QString("PID_FILE")] = settings.value(QString("PID_FILE"), QString("/run/wpa_supplicant_netctl-gui.pid")).toString();
config[QString("PID_FILE")] = settings.value(QString("PID_FILE"), QString("/run/wpa_supplicant_$i.pid")).toString();
config[QString("WPA_DRIVERS")] = settings.value(QString("WPA_DRIVERS"), QString("nl80211,wext")).toString();
config[QString("CTRL_DIR")] = settings.value(QString("CTRL_DIR"), QString("/run/wpa_supplicant_netctl-gui")).toString();
config[QString("CTRL_DIR")] = settings.value(QString("CTRL_DIR"), QString("/run/wpa_supplicant")).toString();
config[QString("CTRL_GROUP")] = settings.value(QString("CTRL_GROUP"), QString("users")).toString();
settings.endGroup();

View File

@ -42,6 +42,10 @@ class NetctlProfile;
* profile description
* @var netctlProfileInfo::essid
* ESSID if any
* @var netctlProfileInfo::interface
* profile interface
* @var netctlProfileInfo::type
* profile type
* @var netctlProfileInfo::active
* whether profile is active
* @var netctlProfileInfo::enabled
@ -52,8 +56,10 @@ typedef struct
QString name;
QString description;
QString essid;
bool active;
bool enabled;
QString interface;
QString type;
bool active = false;
bool enabled = false;
} netctlProfileInfo;
/**

View File

@ -81,8 +81,8 @@ typedef struct
QString security;
int signal;
PointType type = PointType::None;
bool active;
bool exists;
bool active = false;
bool exists = false;
} netctlWifiInfo;
/**
@ -141,6 +141,11 @@ public:
public slots:
// functions
/**
* @brief method which returns active point information
* @return current point information
*/
netctlWifiInfo current();
/**
* @brief method which scans WiFi networks
* @return list of essids
@ -177,17 +182,17 @@ private:
*/
bool useSuid = true;
/**
* @brief path to ctrl_directory. Defaults is "/run/wpa_supplicant_netctl-gui"
* @brief path to ctrl_directory. Defaults is "/run/wpa_supplicant"
*/
QString ctrlDir = QString("/run/wpa_supplicant_netctl-gui");
QString ctrlDir = QString("/run/wpa_supplicant");
/**
* @brief group which is owner of CTRL_DIR. Default is "users"
*/
QString ctrlGroup = QString("users");
/**
* @brief wpa_supplicant PID file. Default is "/run/wpa_supplicant_netctl-gui.pid"
* @brief wpa_supplicant PID file. $i is interface. Default is "/run/wpa_supplicant_$i.pid"
*/
QString pidFile = QString("/run/wpa_supplicant_netctl-gui.pid");
QString pidFile = QString("/run/wpa_supplicant_$i.pid");
/**
* @brief path to sudo command. Default is "/usr/bin/kdesu"
*/

View File

@ -193,12 +193,16 @@ QList<netctlProfileInfo> Netctl::getProfileList()
profileInfo.enabled = isProfileEnabled(profileInfo.name);
// external
QStringList keys;
keys.append(QString("Connection"));
keys.append(QString("Description"));
keys.append(QString("ESSID"));
keys.append(QString("Interface"));
QStringList profileValues = netctlProfile->getValuesFromProfile(profileInfo.name,
keys);
profileInfo.description = profileValues[0];
profileInfo.essid = profileValues[1];
profileInfo.description = profileValues[1];
profileInfo.essid = profileValues[2];
profileInfo.interface = profileValues[3];
profileInfo.type = profileValues[0];
fullProfilesInfo.append(profileInfo);
}

View File

@ -245,9 +245,7 @@ QString NetctlProfile::getValueFromProfile(const QString profile, const QString
if (debug) qDebug() << PDEBUG << ":" << "Profile" << profile;
if (debug) qDebug() << PDEBUG << ":" << "Key" << key;
QMap<QString, QString> settings = getSettingsFromProfile(profile);
return settings[key];
return getValuesFromProfile(profile, QStringList() << key)[0];
}

View File

@ -115,7 +115,7 @@ QMap<QString, QString> WpaSup::getRecommendedConfiguration()
QStringList recommended;
// ctrl directory
// nothing to do
settings[QString("CTRL_DIR")] = QString("/run/wpa_supplicant_netctl-gui");
settings[QString("CTRL_DIR")] = QString("/run/wpa_supplicant");
// ctrl group
// check group list and find out 'network', 'users', 'root'
settings[QString("CTRL_GROUP")] = QString("");
@ -148,7 +148,7 @@ QMap<QString, QString> WpaSup::getRecommendedConfiguration()
}
// pid file
// nothing to do
settings[QString("PID_FILE")] = QString("/run/wpa_supplicant_netctl-gui.pid");
settings[QString("PID_FILE")] = QString("/run/wpa_supplicant_$i.pid");
// sudo path
// find out sudo, kdesu, gksu exes
settings[QString("SUDO_PATH")] = QString("");
@ -251,20 +251,102 @@ bool WpaSup::isProfileExists(const QString essid)
}
/**
* @fn current
*/
netctlWifiInfo WpaSup::current()
{
if (debug) qDebug() << PDEBUG;
if (pidFile.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find PID file";
return netctlWifiInfo();
}
QStringList interfaces = netctlCommand->getWirelessInterfaceList();
if (interfaces.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find interfaces";
return netctlWifiInfo();
}
QString _pidFile = pidFile;
_pidFile.replace(QString("$i"), interfaces[0]);
if (debug) qDebug() << PDEBUG << ":" << "PID file" << _pidFile << QFile(_pidFile).exists();
bool terminateOnExit = (!QFile(_pidFile).exists());
netctlWifiInfo current;
if (!startWpaSupplicant()) {
if (terminateOnExit) stopWpaSupplicant();
return current;
}
QStringList rawList = getWpaCliOutput(QString("status")).split(QChar('\n'), QString::SkipEmptyParts);
for (int i=0; i<rawList.count(); i++) {
QStringList line = rawList[i].split(QChar('='));
if (line.count() != 2) continue;
if (line[0] == QString("bssid"))
current.macs.append(line[1]);
else if (line[0] == QString("freq")) {
if ((line[1].toInt() >= 5000) && (line[1].toInt() < 6000))
current.type = PointType::FiveG;
else if ((line[1].toInt() < 5000) && (line[1].toInt() > 2000))
current.type = PointType::TwoG;
current.frequencies.append(line[1].toInt());
} else if (line[0] == QString("ssid"))
current.name = line[1];
else if (line[0] == QString("key_mgmt")) {
QString security = line[1];
if (security.contains(QString("WPA2")))
security = QString("WPA2");
else if (security.contains(QString("WPA")))
security = QString("WPA");
else if (security.contains(QString("WEP")))
security = QString("WEP");
else
security = QString("none");
current.security = security;
}
}
current.signal = 0;
if (terminateOnExit) stopWpaSupplicant();
// status
current.active = true;
QList<netctlProfileInfo> profiles = netctlCommand->getProfileList();
for (int j=0; j<profiles.count(); j++) {
if (current.name != profiles[j].essid) continue;
current.exists = true;
break;
}
return current;
}
/**
* @fn scanWifi
*/
QList<netctlWifiInfo> WpaSup::scanWifi()
{
if (debug) qDebug() << PDEBUG;
if (pidFile.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find PID file";
return QList<netctlWifiInfo>();
}
QStringList interfaces = netctlCommand->getWirelessInterfaceList();
if (interfaces.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find interfaces";
return QList<netctlWifiInfo>();
}
QString _pidFile = pidFile;
_pidFile.replace(QString("$i"), interfaces[0]);
if (debug) qDebug() << PDEBUG << ":" << "PID file" << _pidFile << QFile(_pidFile).exists();
bool terminateOnExit = (!QFile(_pidFile).exists());
QList<netctlWifiInfo> scanResults;
if (!startWpaSupplicant()) {
stopWpaSupplicant();
if (terminateOnExit) stopWpaSupplicant();
return scanResults;
}
if (!wpaCliCall(QString("scan"))) return scanResults;
waitForProcess(1);
waitForProcess(3);
QStringList rawList = getWpaCliOutput(QString("scan_results")).split(QChar('\n'), QString::SkipEmptyParts);
// remove table header
@ -343,7 +425,7 @@ QList<netctlWifiInfo> WpaSup::scanWifi()
names.append(name);
scanResults.append(wifiPoint);
}
stopWpaSupplicant();
if (terminateOnExit) stopWpaSupplicant();
return scanResults;
}
@ -384,10 +466,13 @@ bool WpaSup::startWpaSupplicant()
if (debug) qDebug() << PDEBUG << ":" << "Could not find interfaces";
return false;
}
QString _pidFile = pidFile;
_pidFile.replace(QString("$i"), interfaces[0]);
if (debug) qDebug() << PDEBUG << ":" << "PID file" << _pidFile << QFile(_pidFile).exists();
if (QFile(pidFile).exists()) return true;
if (QFile(_pidFile).exists()) return true;
QString cmd = QString("%1 %2 -B -P \"%3\" -i %4 -D %5 -C \"DIR=%6 GROUP=%7\"")
.arg(sudoCommand).arg(wpaSupPath).arg(pidFile).arg(interfaces[0])
.arg(sudoCommand).arg(wpaSupPath).arg(_pidFile).arg(interfaces[0])
.arg(wpaDrivers).arg(ctrlDir).arg(ctrlGroup);
if (debug) qDebug() << PDEBUG << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd, useSuid);
@ -423,27 +508,12 @@ QString WpaSup::getWpaCliOutput(const QString commandLine)
if (debug) qDebug() << PDEBUG << ":" << "Could not find directory";
return QString();
}
if (pidFile.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find PID file";
return QString();
}
if (wpaCliPath.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find wpa_cli";
return QString();
}
if (netctlCommand == nullptr) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find library";
return QString();
}
QStringList interfaces = netctlCommand->getWirelessInterfaceList();
if (interfaces.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find interfaces";
return QString();
}
QString interface = interfaces[0];
QString cmd = QString("%1 -i %2 -p %3 -P %4 %5").arg(wpaCliPath).arg(interface)
.arg(ctrlDir).arg(pidFile).arg(commandLine);
QString cmd = QString("%1 -p %2 %3").arg(wpaCliPath).arg(ctrlDir).arg(commandLine);
if (debug) qDebug() << PDEBUG << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd);
if (debug) qDebug() << PDEBUG << ":" << "Cmd returns" << process.exitCode;
@ -462,7 +532,7 @@ bool WpaSup::waitForProcess(const int sec)
if (debug) qDebug() << PDEBUG;
if (debug) qDebug() << PDEBUG << ":" << "Interval" << sec;
QString cmd = QString("sleep %1").arg(QString::number(sec));
QString cmd = QString("sleep %1").arg(sec);
runTask(cmd);
return true;
@ -480,27 +550,12 @@ bool WpaSup::wpaCliCall(const QString commandLine)
if (debug) qDebug() << PDEBUG << ":" << "Could not find directory";
return false;
}
if (pidFile.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find PID file";
return false;
}
if (wpaCliPath.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find wpa_cli";
return false;
}
if (netctlCommand == nullptr) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find library";
return false;
}
QStringList interfaces = netctlCommand->getWirelessInterfaceList();
if (interfaces.isEmpty()) {
if (debug) qDebug() << PDEBUG << ":" << "Could not find interfaces";
return false;
}
QString interface = interfaces[0];
QString cmd = QString("%1 -i %2 -p %3 -P %4 %5").arg(wpaCliPath).arg(interface)
.arg(ctrlDir).arg(pidFile).arg(commandLine);
QString cmd = QString("%1 -p %2 %3").arg(wpaCliPath).arg(ctrlDir).arg(commandLine);
if (debug) qDebug() << PDEBUG << ":" << "Run cmd" << cmd;
TaskResult process = runTask(cmd);
waitForProcess(1);

View File

@ -74,10 +74,10 @@ void TestWpaSup::cleanupTestCase()
void TestWpaSup::test_getRecommendedConfiguration()
{
QStringList original;
original.append(QString("CTRL_DIR==/run/wpa_supplicant_netctl-gui"));
original.append(QString("CTRL_DIR==/run/wpa_supplicant"));
original.append(QString("CTRL_GROUP==network"));
original.append(QString("FORCE_SUDO==false"));
original.append(QString("PID_FILE==/run/wpa_supplicant_netctl-gui.pid"));
original.append(QString("PID_FILE==/run/wpa_supplicant_$i.pid"));
original.append(QString("SUDO_PATH==/usr/bin/sudo"));
original.append(QString("WPACLI_PATH==/usr/bin/wpa_cli"));
original.append(QString("WPASUP_PATH==/usr/bin/wpa_supplicant"));