Disconnect when same SSID selected (#1)
[dhcpcd-ui] / src / dhcpcd-qt / dhcpcd-wi.cpp
index 260938bcbe0fe3264ae148c694401857b515e0a5..4e4d86a8a5fbeaa2a11a77f28d95a4cd0376c802 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * dhcpcd-qt
- * Copyright 2014 Roy Marples <roy@marples.name>
+ * Copyright 2014-2017 Roy Marples <roy@marples.name>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,48 +54,38 @@ DhcpcdWi::DhcpcdWi(DhcpcdQt *parent, DHCPCD_WPA *wpa)
 
        notifier = NULL;
        pingTimer = NULL;
-#ifdef BG_SCAN
        scanTimer = NULL;
-#endif
 }
 
 DhcpcdWi::~DhcpcdWi()
 {
 
+       close();
        if (menu) {
                dhcpcdQt->menuDeleted(menu);
-               menu->setVisible(false);
                menu->deleteLater();
                menu = NULL;
        }
 
        if (notifier) {
-               notifier->setEnabled(false);
                notifier->deleteLater();
                notifier = NULL;
        }
 
        if (pingTimer) {
-               pingTimer->stop();
                pingTimer->deleteLater();
                pingTimer = NULL;
        }
 
        if (ssid) {
-               ssid->reject();
                ssid->deleteLater();
                ssid = NULL;
        }
 
-#ifdef BG_SCAN
        if (scanTimer) {
-               scanTimer->stop();
                scanTimer->deleteLater();
                scanTimer = NULL;
        }
-#endif
-
-       dhcpcd_wi_scans_free(scans);
 }
 
 DHCPCD_WPA *DhcpcdWi::getWpa()
@@ -197,10 +187,8 @@ void DhcpcdWi::createMenu1(QMenu *menu)
        DHCPCD_WI_SCAN *scan;
        QAction *before;
 
-#ifdef BG_SCAN
        connect(menu, SIGNAL(aboutToShow()), this, SLOT(menuShown()));
        connect(menu, SIGNAL(aboutToHide()), this, SLOT(menuHidden()));
-#endif
 
        i = dhcpcd_wpa_if(wpa);
        for (scan = scans; scan; scan = scan->next) {
@@ -257,14 +245,40 @@ bool DhcpcdWi::open()
        pingTimer = new QTimer(this);
        connect(pingTimer, SIGNAL(timeout()), this, SLOT(ping()));
        pingTimer->start(DHCPCD_WPA_PING);
-#ifdef BG_SCAN
        scanTimer = new QTimer(this);
        connect(scanTimer, SIGNAL(timeout()), this, SLOT(scan()));
        scanTimer->start(DHCPCD_WPA_SCAN_LONG);
-#endif
        return true;
 }
 
+void DhcpcdWi::close()
+{
+
+       if (menu)
+               menu->setVisible(false);
+
+       if (notifier)
+               notifier->setEnabled(false);
+
+       if (pingTimer)
+               pingTimer->stop();
+
+       if (ssid)
+               ssid->reject();
+
+       if (scanTimer)
+               scanTimer->stop();
+
+       if (scans) {
+               dhcpcd_wi_scans_free(scans);
+               scans = NULL;
+       }
+       if (wpa) {
+               dhcpcd_wpa_close(wpa);
+               wpa = NULL;
+       }
+}
+
 void DhcpcdWi::dispatch()
 {
 
@@ -281,13 +295,23 @@ void DhcpcdWi::ping()
 void DhcpcdWi::connectSsid(DHCPCD_WI_SCAN *scan)
 {
        DHCPCD_WI_SCAN s;
+       DHCPCD_IF *i;
        int err;
 
        /* Take a copy of scan incase it's destroyed by a scan update */
        memcpy(&s, scan, sizeof(s));
        s.next = NULL;
 
-       if (s.flags & WSF_PSK) {
+       i = dhcpcd_wpa_if(wpa);
+       if (i == NULL)
+               err = DHCPCD_WPA_ERR;
+       else if (dhcpcd_wi_associated(i, &s)) {
+               /* Disconnect if same interface selected */
+               if (!dhcpcd_wpa_disconnect(wpa))
+                       err = DHCPCD_WPA_ERR_DISCONN;
+               else
+                       err = DHCPCD_WPA_SUCCESS;
+       } else if (s.flags & WSF_PSK) {
                bool ok;
                QString pwd;
 
@@ -300,7 +324,7 @@ void DhcpcdWi::connectSsid(DHCPCD_WI_SCAN *scan)
                if (pwd.isNull() || pwd.isEmpty())
                        err = dhcpcd_wpa_select(wpa, &s);
                else
-                       err = dhcpcd_wpa_configure(wpa, &s, pwd.toAscii());
+                       err = dhcpcd_wpa_configure(wpa, &s, pwd.toLatin1());
        } else
                err = dhcpcd_wpa_configure(wpa, &s, NULL);
 
@@ -308,11 +332,14 @@ void DhcpcdWi::connectSsid(DHCPCD_WI_SCAN *scan)
        switch (err) {
        case DHCPCD_WPA_SUCCESS:
                return;
+       case DHCPCD_WPA_ERR:
+               errt = tr("Failed.");
+               break;
        case DHCPCD_WPA_ERR_DISCONN:
                errt = tr("Failed to disconnect.");
                break;
        case DHCPCD_WPA_ERR_RECONF:
-               errt = tr("Faile to reconfigure.");
+               errt = tr("Failed to reconfigure.");
                break;
        case DHCPCD_WPA_ERR_SET:
                errt = tr("Failed to set key management.");
@@ -341,11 +368,13 @@ void DhcpcdWi::connectSsid(DHCPCD_WI_SCAN *scan)
            errt);
 }
 
-#ifdef BG_SCAN
 void DhcpcdWi::scan()
 {
+       DHCPCD_IF *i;
 
-       dhcpcd_wpa_scan(wpa);
+       i = dhcpcd_wpa_if(wpa);
+       if (!i->up || dhcpcd_wpa_can_background_scan(wpa))
+               dhcpcd_wpa_scan(wpa);
 }
 
 void DhcpcdWi::menuHidden()
@@ -365,4 +394,3 @@ void DhcpcdWi::menuShown()
                scanTimer->start(DHCPCD_WPA_SCAN_SHORT);
        }
 }
-#endif