#include "dhcpcd-about.h"
#include "dhcpcd-preferences.h"
#include "dhcpcd-wi.h"
+#include "dhcpcd-ifmenu.h"
#include "dhcpcd-ssidmenu.h"
+#ifdef NOTIFY
+#include <knotification.h>
+#endif
+
DhcpcdQt::DhcpcdQt()
{
exit(EXIT_FAILURE);
return;
}
+ dhcpcd_set_progname(con, "dhcpcd-qt");
dhcpcd_set_status_callback(con, dhcpcd_status_cb, this);
dhcpcd_set_if_callback(con, dhcpcd_if_cb, this);
dhcpcd_wpa_set_scan_callback(con, dhcpcd_wpa_scan_cb, this);
+ dhcpcd_wpa_set_status_callback(con, dhcpcd_wpa_status_cb, this);
tryOpen();
-
}
DhcpcdQt::~DhcpcdQt()
{
- qDeleteAll(*wis);
- delete wis;
-
- free(lastStatus);
+ if (ssidMenu) {
+ ssidMenu->setVisible(false);
+ ssidMenu->deleteLater();
+ }
if (con != NULL) {
dhcpcd_close(con);
dhcpcd_free(con);
}
+
+ free(lastStatus);
+
+ for (auto &wi : *wis)
+ wi->deleteLater();
+ delete wis;
+}
+
+DHCPCD_CONNECTION *DhcpcdQt::getConnection()
+{
+
+ return con;
+}
+
+QList<DhcpcdWi *> *DhcpcdQt::getWis()
+{
+
+ return wis;
+}
+
+const char * DhcpcdQt::signalStrengthIcon(DHCPCD_WI_SCAN *scan)
+{
+
+ if (scan->strength.value > 80)
+ return "network-wireless-connected-100";
+ else if (scan->strength.value > 55)
+ return "network-wireless-connected-75";
+ else if (scan->strength.value > 30)
+ return "network-wireless-connected-50";
+ else if (scan->strength.value > 5)
+ return "network-wireless-connected-25";
+ else
+ return "network-wireless-connected-00";
+}
+
+DHCPCD_WI_SCAN * DhcpcdQt::getStrongestSignal()
+{
+ DHCPCD_WI_SCAN *scan, *scans, *s;
+ DHCPCD_WPA *wpa;
+ DHCPCD_IF *i;
+
+ scan = NULL;
+ for (auto &wi : *wis) {
+ wpa = wi->getWpa();
+ i = dhcpcd_wpa_if(wpa);
+ scans = wi->getScans();
+ for (s = scans; s; s = s->next) {
+ if (dhcpcd_wi_associated(i, s) &&
+ (scan == NULL ||
+ s->strength.value > scan->strength.value))
+ scan = s;
+ }
+ }
+ return scan;
}
void DhcpcdQt::animate()
{
const char *icon;
+ DHCPCD_WI_SCAN *scan;
+
+ scan = getStrongestSignal();
if (onLine) {
if (aniCounter++ > 6) {
}
if (aniCounter % 2 == 0)
- icon = "network-idle";
+ icon = scan ? "network-wireless-connected-00" :
+ "network-idle";
else
- icon = "network-transmit-receive";
+ icon = scan ? DhcpcdQt::signalStrengthIcon(scan) :
+ "network-transmit-receive";
} else {
- switch(aniCounter++) {
- case 0:
- icon = "network-transmit";
- break;
- case 1:
- icon = "network-receive";
- break;
- default:
- icon = "network-idle";
- aniCounter = 0;
+ if (scan) {
+ switch(aniCounter++) {
+ case 0:
+ icon = "network-wireless-connected-00";
+ break;
+ case 1:
+ icon = "network-wireless-connected-25";
+ break;
+ case 2:
+ icon = "network-wireless-connected-50";
+ break;
+ case 3:
+ icon = "network-wireless-connected-75";
+ break;
+ default:
+ icon = "network-wireless-connected-100";
+ aniCounter = 0;
+ }
+ } else {
+ switch(aniCounter++) {
+ case 0:
+ icon = "network-transmit";
+ break;
+ case 1:
+ icon = "network-receive";
+ break;
+ default:
+ icon = "network-idle";
+ aniCounter = 0;
+ }
}
}
if (onLine != isOn || carrier != isCarrier) {
onLine = isOn;
+ carrier = isCarrier;
aniTimer->stop();
aniCounter = 0;
if (isOn) {
if (strcmp(status, "down") == 0) {
aniTimer->stop();
aniCounter = 0;
+ onLine = carrier = false;
setIcon("status", "network-offline");
+ trayIcon->setToolTip(tr("Not connected to dhcpcd"));
+ /* Close down everything */
if (notifier) {
- delete notifier;
+ notifier->setEnabled(false);
+ notifier->deleteLater();
notifier = NULL;
}
- trayIcon->setToolTip(tr("Not connected to dhcpcd"));
+ if (ssidMenu) {
+ ssidMenu->deleteLater();
+ ssidMenu = NULL;
+ }
+ preferencesAction->setEnabled(false);
+ if (preferences) {
+ preferences->deleteLater();
+ preferences = NULL;
+ }
} else {
bool refresh;
refresh = true;
} else
refresh = strcmp(lastStatus, "opened") ? false : true;
- printf ("refresh %d\n", refresh);
updateOnline(refresh);
- printf ("updated\n");
}
free(lastStatus);
char *msg;
bool new_msg;
+ if (strcmp(i->reason, "RENEW") &&
+ strcmp(i->reason, "STOP") &&
+ strcmp(i->reason, "STOPPED"))
+ {
+ msg = dhcpcd_if_message(i, &new_msg);
+ if (msg) {
+ qDebug("%s", msg);
+ if (new_msg) {
+ QSystemTrayIcon::MessageIcon icon =
+ i->up ? QSystemTrayIcon::Information :
+ QSystemTrayIcon::Warning;
+ QString t = tr("Network Event");
+ QString m = msg;
+ notify(t, m, icon);
+ }
+ free(msg);
+ }
+ }
+
updateOnline(false);
- if (strcmp(i->reason, "RENEW") == 0 ||
- strcmp(i->reason, "STOP") == 0 ||
- strcmp(i->reason, "STOPPED") == 0)
- return;
+ if (i->wireless) {
+ for (auto &wi : *wis) {
+ DHCPCD_WPA *wpa = wi->getWpa();
+ if (dhcpcd_wpa_if(wpa) == i) {
+ DHCPCD_WI_SCAN *scans;
- msg = dhcpcd_if_message(i, &new_msg);
- if (msg) {
- qDebug("%s", msg);
- if (new_msg) {
- QSystemTrayIcon::MessageIcon icon =
- i->up ? QSystemTrayIcon::Information :
- QSystemTrayIcon::Warning;
- trayIcon->showMessage(tr("Network Event"), msg, icon);
+ scans = dhcpcd_wi_scans(i);
+ processScans(wi, scans);
+ }
}
- free(msg);
}
}
return NULL;
}
+void DhcpcdQt::processScans(DhcpcdWi *wi, DHCPCD_WI_SCAN *scans)
+{
+ DHCPCD_WI_SCAN *s1, *s2;
+
+ QString title = tr("New Access Point");
+ QString txt;
+ for (s1 = scans; s1; s1 = s1->next) {
+ for (s2 = wi->getScans(); s2; s2 = s2->next) {
+ if (strcmp(s1->ssid, s2->ssid) == 0)
+ break;
+ }
+ if (s2 == NULL) {
+ if (!txt.isEmpty()) {
+ title = tr("New Access Points");
+ txt += '\n';
+ }
+ txt += s1->ssid;
+ }
+ }
+ if (!txt.isEmpty() &&
+ (ssidMenu == NULL || !ssidMenu->isVisible()))
+ notify(title, txt);
+
+ if (wi->setScans(scans) && ssidMenu && ssidMenu->isVisible())
+ ssidMenu->popup(ssidMenuPos);
+}
+
void DhcpcdQt::scanCallback(DHCPCD_WPA *wpa)
{
- DHCPCD_WI_SCAN *scans, *s1, *s2;
+ DHCPCD_WI_SCAN *scans;
int fd = dhcpcd_wpa_get_fd(wpa);
DhcpcdWi *wi;
qCritical("No fd for WPA");
if (wi) {
wis->removeOne(wi);
- delete wi;
+ wi->deleteLater();
}
return;
}
qCritical("No interface for WPA");
if (wi) {
wis->removeOne(wi);
- delete wi;
+ wi->deleteLater();
}
return;
}
scans = dhcpcd_wi_scans(i);
if (wi == NULL) {
wi = new DhcpcdWi(this, wpa);
- wis->append(wi);
- } else {
- QString title = tr("New Access Point");
- QString txt;
- for (s1 = scans; s1; s1 = s1->next) {
- for (s2 = wi->getScans(); s2; s2 = s2->next) {
- if (strcmp(s1->ssid, s2->ssid) == 0)
- break;
- if (s2 == NULL) {
- if (!txt.isEmpty()) {
- title = tr("New Access Points");
- txt += '\n';
- }
- txt += s1->ssid;
- }
- }
- }
- if (!txt.isEmpty())
- notify(title, txt);
+ if (wi->open()) {
+ wis->append(wi);
+ wi->setScans(scans);
+ } else
+ wi->deleteLater();
+ } else
+ processScans(wi, scans);
+
+ if (!aniTimer->isActive()) {
+ DHCPCD_WI_SCAN *scan;
+
+ scan = getStrongestSignal();
+ if (scan)
+ setIcon("status", DhcpcdQt::signalStrengthIcon(scan));
}
- wi->setScans(scans);
}
void DhcpcdQt::dhcpcd_wpa_scan_cb(DHCPCD_WPA *wpa, void *d)
dhcpcdQt->scanCallback(wpa);
}
+void DhcpcdQt::wpaStatusCallback(DHCPCD_WPA *wpa, const char *status)
+{
+ DHCPCD_IF *i;
+
+ i = dhcpcd_wpa_if(wpa);
+ qDebug("%s: WPA status %s", i->ifname, status);
+ if (strcmp(status, "down") == 0) {
+ DhcpcdWi *wi = findWi(wpa);
+ if (wi) {
+ wis->removeOne(wi);
+ wi->deleteLater();
+ }
+ }
+}
+
+void DhcpcdQt::dhcpcd_wpa_status_cb(DHCPCD_WPA *wpa, const char *status,
+ void *d)
+{
+ DhcpcdQt *dhcpcdQt = (DhcpcdQt *)d;
+
+ dhcpcdQt->wpaStatusCallback(wpa, status);
+}
+
void DhcpcdQt::tryOpen() {
- int fd = dhcpcd_open(con);
+ int fd = dhcpcd_open(con, true);
static int last_error;
if (fd == -1) {
+ if (errno == EACCES || errno == EPERM) {
+ if ((fd = dhcpcd_open(con, false)) != -1)
+ goto unprived;
+ }
if (errno != last_error) {
last_error = errno;
- qCritical("dhcpcd_open: %s", strerror(errno));
+ const char *errt = strerror(errno);
+ qCritical("dhcpcd_open: %s", errt);
+ trayIcon->setToolTip(
+ tr("Error connecting to dhcpcd: %1").arg(errt));
}
if (retryOpenTimer == NULL) {
retryOpenTimer = new QTimer(this);
return;
}
+unprived:
/* Start listening to WPA events */
dhcpcd_wpa_start(con);
if (retryOpenTimer) {
- delete retryOpenTimer;
+ retryOpenTimer->stop();
+ retryOpenTimer->deleteLater();
retryOpenTimer = NULL;
}
notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
-}
-void DhcpcdQt::dispatch() {
+ preferencesAction->setEnabled(dhcpcd_privileged(con));
+}
- if (dhcpcd_get_fd(con) == -1) {
- qWarning("dhcpcd connection lost");
- return;
- }
+void DhcpcdQt::dispatch()
+{
dhcpcd_dispatch(con);
}
void DhcpcdQt::notify(QString &title, QString &msg,
- QSystemTrayIcon::MessageIcon icon)
+#ifdef NOTIFY
+ QSystemTrayIcon::MessageIcon
+#else
+ QSystemTrayIcon::MessageIcon icon
+#endif
+ )
{
- qDebug("%s", qPrintable(msg));
- trayIcon->showMessage(title, msg, icon);
+#ifdef NOTIFY
+ KNotification *n = new KNotification("event", this);
+ n->setTitle(title);
+ n->setText(msg);
+ n->sendEvent();
+#else
+ //trayIcon->showMessage(title, msg, icon);
+#endif
}
-
void DhcpcdQt::closeEvent(QCloseEvent *event)
{
icon = QIcon::fromTheme(name);
else
icon = QIcon(ICONDIR "/hicolor/scalable/" + category + "/" + name + ".svg");
+
return icon;
}
return getIcon("status", "network-transmit-receive");
}
-void DhcpcdQt::addSsidMenu(QMenu *&menu, DHCPCD_IF *ifp, DhcpcdWi *&wi)
+void DhcpcdQt::menuDeleted(QMenu *menu)
{
- DHCPCD_WI_SCAN *scan;
- for (scan = wi->getScans(); scan; scan = scan->next) {
- QWidgetAction *wa = new QWidgetAction(menu);
- DhcpcdSsidMenu *ssidMenu = new DhcpcdSsidMenu(menu, ifp, scan);
- wa->setDefaultWidget(ssidMenu);
- menu->addAction(wa);
- connect(ssidMenu, SIGNAL(selected(DHCPCD_IF *, DHCPCD_WI_SCAN *)),
- this, SLOT(connectSsid(DHCPCD_IF *, DHCPCD_WI_SCAN *)));
- }
-}
-
-void DhcpcdQt::connectSsid(DHCPCD_IF *, DHCPCD_WI_SCAN *)
-{
-
- QMessageBox::information(this, "Not implemented",
- "SSID selection is not yet implemented");
+ if (ssidMenu == menu)
+ ssidMenu = NULL;
}
void DhcpcdQt::createSsidMenu()
{
- DHCPCD_WPA *wpa;
- DHCPCD_IF *ifp;
if (ssidMenu) {
- delete ssidMenu;
+ ssidMenu->deleteLater();
ssidMenu = NULL;
}
if (wis->size() == 0)
return;
ssidMenu = new QMenu(this);
- if (wis->size() == 1) {
- DhcpcdWi *wi = wis->first();
- wpa = wi->getWpa();
- ifp = dhcpcd_wpa_if(wpa);
- addSsidMenu(ssidMenu, ifp, wi);
- } else {
- for (auto &wi : *wis) {
- wpa = wi->getWpa();
- ifp = dhcpcd_wpa_if(wpa);
- if (ifp) {
- QMenu *ifmenu = ssidMenu->addMenu(ifp->ifname);
- addSsidMenu(ifmenu, ifp, wi);
- }
- }
+ if (wis->size() == 1)
+ wis->first()->createMenu(ssidMenu);
+ else {
+ for (auto &wi : *wis)
+ ssidMenu->addMenu(wi->createIfMenu(ssidMenu));
}
- ssidMenu->popup(QCursor::pos());
+ ssidMenuPos = QCursor::pos();
+ ssidMenu->popup(ssidMenuPos);
}
void DhcpcdQt::iconActivated(QSystemTrayIcon::ActivationReason reason)
preferencesAction = new QAction(tr("&Preferences"), this);
preferencesAction->setIcon(QIcon::fromTheme("preferences-system-network"));
+ preferencesAction->setEnabled(false);
connect(preferencesAction, SIGNAL(triggered()),
this, SLOT(showPreferences()));