wpa_gui: Add tray icon based signal strength meter
System tray icon can be set to 5 different pictographs according to the connection status. One for disconnected state (not associated with the network, or not connected with the wpa_supplicant service), and four for connected status (showing the signal strength on the receiver). By default this functionality is disabled. The reason for this, is the fact, that the underlaying approach of this functionality is poll based, which might be considered as a non-efficient one. Update interval has to be set explicitly by the user with '-m<seconds>' command line argument. Status icon names are based on various Gnome icon packs (e.g., Faba). When icon can not be found, default one is shown (wpa_gui logo). Signed-off-by: Arkadiusz Bokowy <arkadiusz.bokowy@gmail.com>
This commit is contained in:
parent
54d3dc9184
commit
e7b4cd0c55
3 changed files with 162 additions and 5 deletions
|
@ -16,6 +16,7 @@
|
||||||
<command>wpa_gui</command>
|
<command>wpa_gui</command>
|
||||||
<arg>-p <replaceable>path to ctrl sockets</replaceable></arg>
|
<arg>-p <replaceable>path to ctrl sockets</replaceable></arg>
|
||||||
<arg>-i <replaceable>ifname</replaceable></arg>
|
<arg>-i <replaceable>ifname</replaceable></arg>
|
||||||
|
<arg>-m <replaceable>seconds</replaceable></arg>
|
||||||
<arg>-t</arg>
|
<arg>-t</arg>
|
||||||
<arg>-q</arg>
|
<arg>-q</arg>
|
||||||
</cmdsynopsis>
|
</cmdsynopsis>
|
||||||
|
@ -51,6 +52,14 @@
|
||||||
a control socket in the socket path.</para></listitem>
|
a control socket in the socket path.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>-m seconds</term>
|
||||||
|
|
||||||
|
<listitem><para>Set the update interval in seconds for the signal
|
||||||
|
strength meter. This value must be a positive integer, otherwise
|
||||||
|
meter is not enabled (default behavior).</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term>-t</term>
|
<term>-t</term>
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,7 @@ WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *, Qt::WFlags)
|
||||||
monitor_conn = NULL;
|
monitor_conn = NULL;
|
||||||
msgNotifier = NULL;
|
msgNotifier = NULL;
|
||||||
ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
|
ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
|
||||||
|
signalMeterInterval = 0;
|
||||||
|
|
||||||
parse_argv();
|
parse_argv();
|
||||||
|
|
||||||
|
@ -161,6 +162,10 @@ WpaGui::WpaGui(QApplication *_app, QWidget *parent, const char *, Qt::WFlags)
|
||||||
timer->setSingleShot(FALSE);
|
timer->setSingleShot(FALSE);
|
||||||
timer->start(1000);
|
timer->start(1000);
|
||||||
|
|
||||||
|
signalMeterTimer = new QTimer(this);
|
||||||
|
signalMeterTimer->setInterval(signalMeterInterval);
|
||||||
|
connect(signalMeterTimer, SIGNAL(timeout()), SLOT(signalMeterUpdate()));
|
||||||
|
|
||||||
if (openCtrlConnection(ctrl_iface) < 0) {
|
if (openCtrlConnection(ctrl_iface) < 0) {
|
||||||
debug("Failed to open control connection to "
|
debug("Failed to open control connection to "
|
||||||
"wpa_supplicant.");
|
"wpa_supplicant.");
|
||||||
|
@ -234,7 +239,7 @@ void WpaGui::parse_argv()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
c = getopt(qApp->argc(), qApp->argv(), "i:p:tq");
|
c = getopt(qApp->argc(), qApp->argv(), "i:m:p:tq");
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
break;
|
break;
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -242,6 +247,9 @@ void WpaGui::parse_argv()
|
||||||
free(ctrl_iface);
|
free(ctrl_iface);
|
||||||
ctrl_iface = strdup(optarg);
|
ctrl_iface = strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
signalMeterInterval = atoi(optarg) * 1000;
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
free(ctrl_iface_dir);
|
free(ctrl_iface_dir);
|
||||||
ctrl_iface_dir = strdup(optarg);
|
ctrl_iface_dir = strdup(optarg);
|
||||||
|
@ -496,6 +504,8 @@ void WpaGui::updateStatus()
|
||||||
textBssid->clear();
|
textBssid->clear();
|
||||||
textIpAddress->clear();
|
textIpAddress->clear();
|
||||||
updateTrayToolTip(tr("no status information"));
|
updateTrayToolTip(tr("no status information"));
|
||||||
|
updateTrayIcon(TrayIconOffline);
|
||||||
|
signalMeterTimer->stop();
|
||||||
|
|
||||||
#ifdef CONFIG_NATIVE_WINDOWS
|
#ifdef CONFIG_NATIVE_WINDOWS
|
||||||
static bool first = true;
|
static bool first = true;
|
||||||
|
@ -544,6 +554,11 @@ void WpaGui::updateStatus()
|
||||||
ssid_updated = true;
|
ssid_updated = true;
|
||||||
textSsid->setText(pos);
|
textSsid->setText(pos);
|
||||||
updateTrayToolTip(pos + tr(" (associated)"));
|
updateTrayToolTip(pos + tr(" (associated)"));
|
||||||
|
if (!signalMeterInterval) {
|
||||||
|
/* if signal meter is not enabled show
|
||||||
|
* full signal strength */
|
||||||
|
updateTrayIcon(TrayIconSignalExcellent);
|
||||||
|
}
|
||||||
} else if (strcmp(start, "ip_address") == 0) {
|
} else if (strcmp(start, "ip_address") == 0) {
|
||||||
ipaddr_updated = true;
|
ipaddr_updated = true;
|
||||||
textIpAddress->setText(pos);
|
textIpAddress->setText(pos);
|
||||||
|
@ -587,6 +602,23 @@ void WpaGui::updateStatus()
|
||||||
} else
|
} else
|
||||||
textEncryption->clear();
|
textEncryption->clear();
|
||||||
|
|
||||||
|
if (signalMeterInterval) {
|
||||||
|
/*
|
||||||
|
* Handle signal meter service. When network is not associated,
|
||||||
|
* deactivate timer, otherwise keep it going. Tray icon has to
|
||||||
|
* be initialized here, because of the initial delay of the
|
||||||
|
* timer.
|
||||||
|
*/
|
||||||
|
if (ssid_updated) {
|
||||||
|
if (!signalMeterTimer->isActive()) {
|
||||||
|
updateTrayIcon(TrayIconConnected);
|
||||||
|
signalMeterTimer->start();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
signalMeterTimer->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!status_updated)
|
if (!status_updated)
|
||||||
textStatus->clear();
|
textStatus->clear();
|
||||||
if (!auth_updated)
|
if (!auth_updated)
|
||||||
|
@ -594,6 +626,7 @@ void WpaGui::updateStatus()
|
||||||
if (!ssid_updated) {
|
if (!ssid_updated) {
|
||||||
textSsid->clear();
|
textSsid->clear();
|
||||||
updateTrayToolTip(tr("(not-associated)"));
|
updateTrayToolTip(tr("(not-associated)"));
|
||||||
|
updateTrayIcon(TrayIconOffline);
|
||||||
}
|
}
|
||||||
if (!bssid_updated)
|
if (!bssid_updated)
|
||||||
textBssid->clear();
|
textBssid->clear();
|
||||||
|
@ -828,6 +861,53 @@ void WpaGui::ping()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WpaGui::signalMeterUpdate()
|
||||||
|
{
|
||||||
|
char reply[128];
|
||||||
|
size_t reply_len = sizeof(reply);
|
||||||
|
char *rssi;
|
||||||
|
int rssi_value;
|
||||||
|
|
||||||
|
ctrlRequest("SIGNAL_POLL", reply, &reply_len);
|
||||||
|
|
||||||
|
/* In order to eliminate signal strength fluctuations, try
|
||||||
|
* to obtain averaged RSSI value in the first place. */
|
||||||
|
if ((rssi = strstr(reply, "AVG_RSSI=")) != NULL)
|
||||||
|
rssi_value = atoi(&rssi[sizeof("AVG_RSSI")]);
|
||||||
|
else if ((rssi = strstr(reply, "RSSI=")) != NULL)
|
||||||
|
rssi_value = atoi(&rssi[sizeof("RSSI")]);
|
||||||
|
else {
|
||||||
|
debug("Failed to get RSSI value");
|
||||||
|
updateTrayIcon(TrayIconSignalNone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("RSSI value: %d", rssi_value);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: The code below assumes, that the unit of the value returned
|
||||||
|
* by the SIGNAL POLL request is dBm. It might not be true for all
|
||||||
|
* wpa_supplicant drivers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calibration is based on "various Internet sources". Nonetheless,
|
||||||
|
* it seems to be compatible with the Windows 8.1 strength meter -
|
||||||
|
* tested on Intel Centrino Advanced-N 6235.
|
||||||
|
*/
|
||||||
|
if (rssi_value >= -60)
|
||||||
|
updateTrayIcon(TrayIconSignalExcellent);
|
||||||
|
else if (rssi_value >= -68)
|
||||||
|
updateTrayIcon(TrayIconSignalGood);
|
||||||
|
else if (rssi_value >= -76)
|
||||||
|
updateTrayIcon(TrayIconSignalOk);
|
||||||
|
else if (rssi_value >= -84)
|
||||||
|
updateTrayIcon(TrayIconSignalWeak);
|
||||||
|
else
|
||||||
|
updateTrayIcon(TrayIconSignalNone);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int str_match(const char *a, const char *b)
|
static int str_match(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
return strncmp(a, b, strlen(b)) == 0;
|
return strncmp(a, b, strlen(b)) == 0;
|
||||||
|
@ -1278,10 +1358,7 @@ void WpaGui::createTrayIcon(bool trayOnly)
|
||||||
QApplication::setQuitOnLastWindowClosed(false);
|
QApplication::setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
tray_icon = new QSystemTrayIcon(this);
|
tray_icon = new QSystemTrayIcon(this);
|
||||||
if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
|
updateTrayIcon(TrayIconOffline);
|
||||||
tray_icon->setIcon(QIcon(":/icons/wpa_gui.svg"));
|
|
||||||
else
|
|
||||||
tray_icon->setIcon(QIcon(":/icons/wpa_gui.png"));
|
|
||||||
|
|
||||||
connect(tray_icon,
|
connect(tray_icon,
|
||||||
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
|
||||||
|
@ -1421,6 +1498,59 @@ void WpaGui::updateTrayToolTip(const QString &msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WpaGui::updateTrayIcon(TrayIconType type)
|
||||||
|
{
|
||||||
|
if (!tray_icon || currentIconType == type)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QIcon icon;
|
||||||
|
QIcon fallback_icon;
|
||||||
|
|
||||||
|
if (QImageReader::supportedImageFormats().contains(QByteArray("svg")))
|
||||||
|
fallback_icon = QIcon(":/icons/wpa_gui.svg");
|
||||||
|
else
|
||||||
|
fallback_icon = QIcon(":/icons/wpa_gui.png");
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case TrayIconOffline:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-offline",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconAcquiring:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-acquiring",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconConnected:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-connected",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconSignalNone:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-signal-none",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconSignalWeak:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-signal-weak",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconSignalOk:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-signal-ok",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconSignalGood:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-signal-good",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
case TrayIconSignalExcellent:
|
||||||
|
icon = QIcon::fromTheme("network-wireless-signal-excellent",
|
||||||
|
fallback_icon);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIconType = type;
|
||||||
|
tray_icon->setIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WpaGui::closeEvent(QCloseEvent *event)
|
void WpaGui::closeEvent(QCloseEvent *event)
|
||||||
{
|
{
|
||||||
if (eh) {
|
if (eh) {
|
||||||
|
|
|
@ -22,6 +22,18 @@ class WpaGui : public QMainWindow, public Ui::WpaGui
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum TrayIconType {
|
||||||
|
TrayIconOffline = 0,
|
||||||
|
TrayIconAcquiring,
|
||||||
|
TrayIconConnected,
|
||||||
|
TrayIconSignalNone,
|
||||||
|
TrayIconSignalWeak,
|
||||||
|
TrayIconSignalOk,
|
||||||
|
TrayIconSignalGood,
|
||||||
|
TrayIconSignalExcellent,
|
||||||
|
};
|
||||||
|
|
||||||
WpaGui(QApplication *app, QWidget *parent = 0, const char *name = 0,
|
WpaGui(QApplication *app, QWidget *parent = 0, const char *name = 0,
|
||||||
Qt::WFlags fl = 0);
|
Qt::WFlags fl = 0);
|
||||||
~WpaGui();
|
~WpaGui();
|
||||||
|
@ -49,6 +61,7 @@ public slots:
|
||||||
virtual void scan();
|
virtual void scan();
|
||||||
virtual void eventHistory();
|
virtual void eventHistory();
|
||||||
virtual void ping();
|
virtual void ping();
|
||||||
|
virtual void signalMeterUpdate();
|
||||||
virtual void processMsg(char *msg);
|
virtual void processMsg(char *msg);
|
||||||
virtual void processCtrlReq(const char *req);
|
virtual void processCtrlReq(const char *req);
|
||||||
virtual void receiveMsgs();
|
virtual void receiveMsgs();
|
||||||
|
@ -70,6 +83,7 @@ public slots:
|
||||||
virtual void showTrayMessage(QSystemTrayIcon::MessageIcon type,
|
virtual void showTrayMessage(QSystemTrayIcon::MessageIcon type,
|
||||||
int sec, const QString &msg);
|
int sec, const QString &msg);
|
||||||
virtual void showTrayStatus();
|
virtual void showTrayStatus();
|
||||||
|
virtual void updateTrayIcon(TrayIconType type);
|
||||||
virtual void updateTrayToolTip(const QString &msg);
|
virtual void updateTrayToolTip(const QString &msg);
|
||||||
virtual void wpsDialog();
|
virtual void wpsDialog();
|
||||||
virtual void peersDialog();
|
virtual void peersDialog();
|
||||||
|
@ -113,6 +127,7 @@ private:
|
||||||
QAction *quitAction;
|
QAction *quitAction;
|
||||||
QMenu *tray_menu;
|
QMenu *tray_menu;
|
||||||
QSystemTrayIcon *tray_icon;
|
QSystemTrayIcon *tray_icon;
|
||||||
|
TrayIconType currentIconType;
|
||||||
QString wpaStateTranslate(char *state);
|
QString wpaStateTranslate(char *state);
|
||||||
void createTrayIcon(bool);
|
void createTrayIcon(bool);
|
||||||
bool ackTrayIcon;
|
bool ackTrayIcon;
|
||||||
|
@ -127,6 +142,9 @@ private:
|
||||||
|
|
||||||
void stopWpsRun(bool success);
|
void stopWpsRun(bool success);
|
||||||
|
|
||||||
|
QTimer *signalMeterTimer;
|
||||||
|
int signalMeterInterval;
|
||||||
|
|
||||||
#ifdef CONFIG_NATIVE_WINDOWS
|
#ifdef CONFIG_NATIVE_WINDOWS
|
||||||
QAction *fileStartServiceAction;
|
QAction *fileStartServiceAction;
|
||||||
QAction *fileStopServiceAction;
|
QAction *fileStopServiceAction;
|
||||||
|
|
Loading…
Reference in a new issue