Fix wpa stopping and describe DEPARTED a bit better.
[dhcpcd-ui] / src / dhcpcd-qt / dhcpcd-qt.cpp
index c77ec41c196eab733d708077174af509db01f896..2561e25160edc3a3b1aa91668a3413535ef51794 100644 (file)
@@ -37,6 +37,7 @@
 #include "dhcpcd-about.h"
 #include "dhcpcd-preferences.h"
 #include "dhcpcd-wi.h"
+#include "dhcpcd-ifmenu.h"
 #include "dhcpcd-ssidmenu.h"
 
 DhcpcdQt::DhcpcdQt()
@@ -49,6 +50,7 @@ DhcpcdQt::DhcpcdQt()
        lastStatus = NULL;
        aniTimer = new QTimer(this);
        connect(aniTimer, SIGNAL(timeout()), this, SLOT(animate()));
+       notifier = NULL;
        retryOpenTimer = NULL;
 
        about = NULL;
@@ -67,8 +69,8 @@ DhcpcdQt::DhcpcdQt()
        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()
@@ -77,12 +79,12 @@ DhcpcdQt::~DhcpcdQt()
        qDeleteAll(*wis);
        delete wis;
 
-       free(lastStatus);
-
        if (con != NULL) {
                dhcpcd_close(con);
                dhcpcd_free(con);
        }
+
+       free(lastStatus);
 }
 
 void DhcpcdQt::animate()
@@ -149,6 +151,7 @@ void DhcpcdQt::updateOnline(bool showIf)
 
        if (onLine != isOn || carrier != isCarrier) {
                onLine = isOn;
+               carrier = isCarrier;
                aniTimer->stop();
                aniCounter = 0;
                if (isOn) {
@@ -169,27 +172,37 @@ void DhcpcdQt::statusCallback(const char *status)
 
        qDebug("Status changed to %s", status);
        if (strcmp(status, "down") == 0) {
-               QString msg;
-               if (lastStatus)
-                       msg = tr("Connection to dhcpcd lost");
-               else
-                       msg = tr("dhcpcd not running");
                aniTimer->stop();
                aniCounter = 0;
+               onLine = carrier = false;
                setIcon("status", "network-offline");
+               if (notifier) {
+                       delete notifier;
+                       notifier = NULL;
+               }
+               trayIcon->setToolTip(tr("Not connected to dhcpcd"));
        } else {
                bool refresh;
 
-               if ((lastStatus == NULL || strcmp(lastStatus, "down") == 0)) {
+               if (lastStatus == NULL || strcmp(lastStatus, "down") == 0) {
                        qDebug("Connected to dhcpcd-%s", dhcpcd_version(con));
                        refresh = true;
                } else
-                       refresh = false;
+                       refresh = strcmp(lastStatus, "opened") ? false : true;
                updateOnline(refresh);
        }
 
        free(lastStatus);
        lastStatus = strdup(status);
+
+       if (strcmp(status, "down") == 0) {
+               if (retryOpenTimer == NULL) {
+                       retryOpenTimer = new QTimer(this);
+                       connect(retryOpenTimer, SIGNAL(timeout()),
+                           this, SLOT(tryOpen()));
+                       retryOpenTimer->start(DHCPCD_RETRYOPEN);
+               }
+       }
 }
 
 void DhcpcdQt::dhcpcd_status_cb(_unused DHCPCD_CONNECTION *con,
@@ -205,24 +218,25 @@ void DhcpcdQt::ifCallback(DHCPCD_IF *i)
        char *msg;
        bool new_msg;
 
-       updateOnline(false);
-
-       if (strcmp(i->reason, "RENEW") == 0 ||
-           strcmp(i->reason, "STOP") == 0 ||
-           strcmp(i->reason, "STOPPED") == 0)
-               return;
-
-       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);
+       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;
+                               trayIcon->showMessage(tr("Network Event"),
+                                   msg, icon);
+                       }
+                       free(msg);
                }
-               free(msg);
        }
+
+       updateOnline(false);
 }
 
 void DhcpcdQt::dhcpcd_if_cb(DHCPCD_IF *i, void *d)
@@ -280,19 +294,22 @@ void DhcpcdQt::scanCallback(DHCPCD_WPA *wpa)
                        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 (s2 == NULL) {
+                               if (!txt.isEmpty()) {
+                                       title = tr("New Access Points");
+                                       txt += '\n';
                                }
+                               txt += s1->ssid;
                        }
                }
-               if (!txt.isEmpty())
+               if (!txt.isEmpty() &&
+                   (ssidMenu == NULL || !ssidMenu->isVisible()))
                        notify(title, txt);
        }
-       wi->setScans(scans);
+
+       if (wi->setScans(scans) && ssidMenu->isVisible())
+               ssidMenu->popup(ssidMenuPos);
 }
 
 void DhcpcdQt::dhcpcd_wpa_scan_cb(DHCPCD_WPA *wpa, void *d)
@@ -302,7 +319,30 @@ void DhcpcdQt::dhcpcd_wpa_scan_cb(DHCPCD_WPA *wpa, void *d)
        dhcpcdQt->scanCallback(wpa);
 }
 
-bool DhcpcdQt::tryOpen() {
+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);
+                       delete wi;
+               }
+       }
+}
+
+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);
        static int last_error;
 
@@ -317,9 +357,12 @@ bool DhcpcdQt::tryOpen() {
                            this, SLOT(tryOpen()));
                        retryOpenTimer->start(DHCPCD_RETRYOPEN);
                }
-               return false;
+               return;
        }
 
+       /* Start listening to WPA events */
+       dhcpcd_wpa_start(con);
+
        if (retryOpenTimer) {
                delete retryOpenTimer;
                retryOpenTimer = NULL;
@@ -327,8 +370,6 @@ bool DhcpcdQt::tryOpen() {
 
        notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
        connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
-
-       return true;
 }
 
 void DhcpcdQt::dispatch() {
@@ -383,31 +424,8 @@ QIcon DhcpcdQt::icon()
        return getIcon("status", "network-transmit-receive");
 }
 
-void DhcpcdQt::addSsidMenu(QMenu *&menu, DHCPCD_IF *ifp, DhcpcdWi *&wi)
-{
-       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");
-}
-
 void DhcpcdQt::createSsidMenu()
 {
-       DHCPCD_WPA *wpa;
-       DHCPCD_IF *ifp;
 
        if (ssidMenu) {
                delete ssidMenu;
@@ -417,22 +435,14 @@ void DhcpcdQt::createSsidMenu()
                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)