Move saving WPA configuration to libdhcpcd.
authorRoy Marples <roy@marples.name>
Thu, 11 Sep 2014 23:00:33 +0000 (23:00 +0000)
committerRoy Marples <roy@marples.name>
Thu, 11 Sep 2014 23:00:33 +0000 (23:00 +0000)
When we get scan results, update menu items with new information.

13 files changed:
src/dhcpcd-gtk/dhcpcd-gtk.h
src/dhcpcd-gtk/main.c
src/dhcpcd-gtk/menu.c
src/dhcpcd-gtk/wpa.c
src/dhcpcd-qt/dhcpcd-qt.cpp
src/dhcpcd-qt/dhcpcd-qt.h
src/dhcpcd-qt/dhcpcd-qt.pro
src/dhcpcd-qt/dhcpcd-ssidmenu.cpp
src/dhcpcd-qt/dhcpcd-ssidmenu.h
src/dhcpcd-qt/dhcpcd-wi.cpp
src/dhcpcd-qt/dhcpcd-wi.h
src/libdhcpcd/dhcpcd.h
src/libdhcpcd/wpa.c

index 3ab2980ee84f724c76d64250032ccf014ad5264e..8f771b94c77408cf4334d387967a12bfbae05024 100644 (file)
@@ -57,6 +57,7 @@ extern WI_SCAN *wi_scans;
 WI_SCAN * wi_scan_find(DHCPCD_WI_SCAN *);
 
 void menu_init(GtkStatusIcon *, DHCPCD_CONNECTION *);
+void menu_update_scans(DHCPCD_IF *, DHCPCD_WI_SCAN *);
 
 void notify_close(void);
 
index 54090fe18e731b4a0bfd488e7828e79b1278bbbc..3389263821095b3560b22516969bd7e191a887f5 100644 (file)
@@ -553,6 +553,7 @@ dhcpcd_wpa_scan_cb(DHCPCD_WPA *wpa, _unused void *data)
                        notify(msg, txt, "network-wireless");
                        g_free(txt);
                }
+               menu_update_scans(w->interface, scans);
                dhcpcd_wi_scans_free(w->scans);
        }
        w->scans = scans;
index f2c7bc9fbbaccbba91197b95a08748342e5eaf95..2216ca01748b77c3573925eab80f8b19a0a1a319 100644 (file)
@@ -30,6 +30,8 @@
 static const char *copyright = "Copyright (c) 2009-2014 Roy Marples";
 static const char *authors[] = { "Roy Marples <roy@marples.name>", NULL };
 
+static GtkWidget *menu;
+
 static void
 on_pref(_unused GObject *o, gpointer data)
 {
@@ -73,12 +75,12 @@ url_hook(GtkAboutDialog *dialog, const char *url, _unused gpointer data)
 #endif
 
 static void
-ssid_hook(_unused GtkMenuItem *item, gpointer data)
+ssid_hook(GtkMenuItem *item, _unused gpointer data)
 {
        DHCPCD_WI_SCAN *scan;
        WI_SCAN *wi;
 
-       scan = (DHCPCD_WI_SCAN *)data;
+       scan = g_object_get_data(G_OBJECT(item), "dhcpcd_wi_scan");
        wi = wi_scan_find(scan);
        if (wi) {
                DHCPCD_CONNECTION *con;
@@ -114,11 +116,36 @@ on_about(_unused GtkMenuItem *item)
            NULL);
 }
 
+void
+menu_update_scans(DHCPCD_IF *i, DHCPCD_WI_SCAN *scan)
+{
+       GList *lst, *l;
+       DHCPCD_WI_SCAN *s, *wis;
+
+       if (menu == NULL)
+               return;
+       lst = gtk_container_get_children(GTK_CONTAINER(menu));
+       for (s = scan; s; s = s->next) {
+               for (l = lst; l; l = l->next) {
+                       wis = g_object_get_data(G_OBJECT(l->data), "dhcpcd_wi_scan");
+                       if (wis) {
+                               if (memcmp(wis->bssid, s->bssid,
+                                   sizeof(s->bssid)) == 0)
+                               {
+                                       g_object_set_data(G_OBJECT(l->data),
+                                           "dhcpcd_wi_scan", s);
+                                       break;
+                               }
+                       }
+               }
+       }
+}
+
 static GtkWidget *
 add_scans(WI_SCAN *scan)
 {
        DHCPCD_WI_SCAN *wis;
-       GtkWidget *menu, *item, *image, *box, *label, *bar;
+       GtkWidget *item, *image, *box, *label, *bar;
        double perc;
        const char *icon;
        char *tip;
@@ -165,7 +192,8 @@ add_scans(WI_SCAN *scan)
                gtk_widget_show(image);
                gtk_widget_show(box);
                g_signal_connect(G_OBJECT(item), "activate",
-                   G_CALLBACK(ssid_hook), wis);
+                   G_CALLBACK(ssid_hook), NULL);
+               g_object_set_data(G_OBJECT(item), "dhcpcd_wi_scan", wis);
                gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
        }
        return menu;
@@ -175,7 +203,7 @@ static void
 on_activate(GtkStatusIcon *icon)
 {
        WI_SCAN *w;
-       GtkWidget *menu, *item, *image;
+       GtkWidget *item, *image;
 
        notify_close();
        if (wi_scans == NULL)
@@ -208,13 +236,13 @@ static void
 on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
 {
        DHCPCD_CONNECTION *con;
-       GtkMenu *menu;
+       GtkMenu *mnu;
        GtkWidget *item, *image;
 
        notify_close();
 
        con = (DHCPCD_CONNECTION *)data;
-       menu = (GtkMenu *)gtk_menu_new();
+       mnu = (GtkMenu *)gtk_menu_new();
 
        item = gtk_image_menu_item_new_with_mnemonic(_("_Preferences"));
        image = gtk_image_new_from_icon_name(GTK_STOCK_PREFERENCES,
@@ -225,10 +253,10 @@ on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
        else
                g_signal_connect(G_OBJECT(item), "activate",
                    G_CALLBACK(on_pref), data);
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_menu_shell_append(GTK_MENU_SHELL(mnu), item);
 
        item = gtk_separator_menu_item_new();
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_menu_shell_append(GTK_MENU_SHELL(mnu), item);
 
        item = gtk_image_menu_item_new_with_mnemonic(_("_About"));
        image = gtk_image_new_from_icon_name(GTK_STOCK_ABOUT,
@@ -236,7 +264,7 @@ on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
        g_signal_connect(G_OBJECT(item), "activate",
            G_CALLBACK(on_about), icon);
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_menu_shell_append(GTK_MENU_SHELL(mnu), item);
 
        item = gtk_image_menu_item_new_with_mnemonic(_("_Quit"));
        image = gtk_image_new_from_icon_name(GTK_STOCK_QUIT,
@@ -244,13 +272,13 @@ on_popup(GtkStatusIcon *icon, guint button, guint32 atime, gpointer data)
        gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), image);
        g_signal_connect(G_OBJECT(item), "activate",
            G_CALLBACK(on_quit), icon);
-       gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+       gtk_menu_shell_append(GTK_MENU_SHELL(mnu), item);
 
-       gtk_widget_show_all(GTK_WIDGET(menu));
-       gtk_menu_popup(GTK_MENU(menu), NULL, NULL,
+       gtk_widget_show_all(GTK_WIDGET(mnu));
+       gtk_menu_popup(GTK_MENU(mnu), NULL, NULL,
            gtk_status_icon_position_menu, icon, button, atime);
        if (button == 0)
-               gtk_menu_shell_select_first(GTK_MENU_SHELL(menu), FALSE);
+               gtk_menu_shell_select_first(GTK_MENU_SHELL(mnu), FALSE);
 }
 
 void
index 2965326125d737baa6fb1c402353caa45efe29d3..58feda10b3e4b38a85c7d1dde7a5a4798a0e34ba 100644 (file)
@@ -40,47 +40,6 @@ wpa_dialog(const char *title, const char *txt)
        gtk_widget_destroy(dialog);
 }
 
-static bool
-configure_network(DHCPCD_WPA *wpa,
-    int id, const char *mgmt, const char *var, const char *val, bool quote)
-{
-       char *str;
-       static bool warned = false;
-
-       if (!dhcpcd_wpa_network_set(wpa, id, "key_mgmt", mgmt)) {
-               g_warning("libdhcpcd: %s", strerror(errno));
-               wpa_dialog(_("Error"),
-                   _("Failed to set key management"));
-               return false;
-       }
-       if (quote)
-               str = g_strconcat("\"", val, "\"", NULL);
-       else
-               str = NULL;
-       if (!dhcpcd_wpa_network_set(wpa, id, var, quote ? str : val)) {
-               g_warning("libdhcpcd: %s", strerror(errno));
-               g_free(str);
-               wpa_dialog(_("Error setting password"),
-                   _("Failed to set password, probably too short."));
-               return false;
-       }
-       g_free(str);
-       if (!dhcpcd_wpa_network_enable(wpa, id)) {
-               wpa_dialog(_("Error enabling network"), strerror(errno));
-               return false;
-       }
-       if (!dhcpcd_wpa_config_write(wpa)) {
-               g_warning("libdhcpcd: %s", strerror(errno));
-               if (!warned) {
-                       warned = true;
-                       wpa_dialog(_("Error saving configuration"),
-                           _("Failed to save wpa_supplicant configuration.\n\nYou should add update_config=1 to /etc/wpa_supplicant.conf.\nThis warning will not appear again until program restarted."));
-               }
-               return false;
-       }
-       return dhcpcd_wpa_reassociate(wpa);
-}
-
 static void
 onEnter(_unused GtkWidget *widget, gpointer *data)
 {
@@ -88,14 +47,19 @@ onEnter(_unused GtkWidget *widget, gpointer *data)
 }
 
 bool
-wpa_configure(DHCPCD_WPA *wpa, DHCPCD_WI_SCAN *s)
+wpa_configure(DHCPCD_WPA *wpa, DHCPCD_WI_SCAN *scan)
 {
+       DHCPCD_WI_SCAN s;
        GtkWidget *dialog, *label, *psk, *vbox, *hbox;
-       const char *var, *mgt;
-       int result, id;
+       const char *var, *errt;
+       int result;
        bool retval;
 
-       dialog = gtk_dialog_new_with_buttons(s->ssid,
+       /* Take a copy of scan incase it's destroyed by a scan update */
+       memcpy(&s, scan, sizeof(s));
+       s.next = NULL;
+
+       dialog = gtk_dialog_new_with_buttons(s.ssid,
            NULL,
            GTK_DIALOG_MODAL,
            GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
@@ -122,23 +86,36 @@ wpa_configure(DHCPCD_WPA *wpa, DHCPCD_WI_SCAN *s)
 again:
        result = gtk_dialog_run(GTK_DIALOG(dialog));
 
-       id = -1;
        retval = false;
        if (result == GTK_RESPONSE_ACCEPT) {
-               id = dhcpcd_wpa_network_find_new(wpa, s->ssid);
-               if (g_strcmp0(s->flags, "[WEP]") == 0) {
-                       mgt = "NONE";
-                       var = "wep_key0";
-               } else {
-                       mgt = "WPA-PSK";
-                       var = "psk";
-               }
-               if (id != -1) {
-                       configure_network(wpa, id, mgt, var,
-                           gtk_entry_get_text(GTK_ENTRY(psk)), true);
+               var = gtk_entry_get_text(GTK_ENTRY(psk));
+               switch (dhcpcd_wpa_configure_psk(wpa, &s, var)) {
+               case DHCPCD_WPA_SUCCESS:
+                       retval = true;
+                       break;
+               case DHCPCD_WPA_ERR_SET:
+                       errt = _("Failed to set key management.");
+                       break;
+               case DHCPCD_WPA_ERR_SET_PSK:
+                       errt = _("Failed to set password, probably too short.");
+                       break;
+               case DHCPCD_WPA_ERR_ENABLE:
+                       errt = _("Failed to enable the network.");
+                       break;
+               case DHCPCD_WPA_ERR_ASSOC:
+                       errt = _("Failed to start association.");
+                       break;
+               case DHCPCD_WPA_ERR_WRITE:
+                       errt =_("Failed to save wpa_supplicant configuration.\n\nYou should add update_config=1 to /etc/wpa_supplicant.conf.");
+                       break;
+               default:
+                       errt = strerror(errno);
+                       break;
                }
-               if (!retval)
+               if (!retval) {
+                       wpa_dialog(_("Error enabling network"), errt);
                        goto again;
+               }
        }
        gtk_widget_destroy(dialog);
        return retval;
index 9a9169373e0cada629917b4c3d2e918403c5ac3c..d40ce4023632059630c039be27e17a317f2b0c1e 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()
@@ -290,18 +291,19 @@ 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())
                        notify(title, txt);
        }
+
        wi->setScans(scans);
 }
 
@@ -394,31 +396,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;
@@ -428,20 +407,11 @@ 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());
 }
index 6ea55bcc21306f9895a65ac9f5799663f7879d13..1ab7aa3517efe9d89c9aae59dd1fa7d6e7013ff6 100644 (file)
@@ -81,8 +81,6 @@ private slots:
        void showPreferences();
        void iconActivated(QSystemTrayIcon::ActivationReason reason);
 
-       void connectSsid(DHCPCD_IF *ifp, DHCPCD_WI_SCAN *scan);
-
 private:
        DHCPCD_CONNECTION *con;
        QSocketNotifier *notifier;
index 536cb19ee9395e3087c5ffb2ec1825416aeeda8c..171a6ec2f5af1b6cadd51c86dbad32d793f80b96 100644 (file)
@@ -1,10 +1,11 @@
 CONFIG+=               qt gui c++11 debug
-QMAKE_CXXFLAGS+=       -std=c++11
+QMAKE_CXXFLAGS+=       -std=c++11 -O2
 
 HEADERS=               dhcpcd-qt.h dhcpcd-about.h dhcpcd-preferences.h \
-                       dhcpcd-wi.h dhcpcd-ssidmenu.h
+                       dhcpcd-wi.h dhcpcd-ifmenu.h dhcpcd-ssidmenu.h
 SOURCES=               main.cpp dhcpcd-qt.cpp dhcpcd-about.cpp \
-                       dhcpcd-preferences.cpp dhcpcd-wi.cpp dhcpcd-ssidmenu.cpp
+                       dhcpcd-preferences.cpp dhcpcd-wi.cpp \
+                       dhcpcd-ifmenu.cpp dhcpcd-ssidmenu.cpp
 
 INCLUDEPATH+=          ../../
 INCLUDEPATH+=          ../libdhcpcd/
index ed7f5ca6dcc1979771b5c9b85898549bee3ebacc..855b289aa0bfd26d87430225b7ab672a55217a23 100644 (file)
 #include "dhcpcd-qt.h"
 #include "dhcpcd-ssidmenu.h"
 
-DhcpcdSsidMenu::DhcpcdSsidMenu(QWidget *parent, DHCPCD_IF *ifp, DHCPCD_WI_SCAN *scan)
+DhcpcdSsidMenu::DhcpcdSsidMenu(QWidget *parent, DhcpcdWi *wi, DHCPCD_WI_SCAN *scan)
     : QWidget(parent, NULL)
 {
-       int strength;
+
+       this->wi = wi;
+
+       QHBoxLayout *layout = new QHBoxLayout(this);
+       button = new QRadioButton(this);
+       layout->addWidget(button);
+       licon = new QLabel(this);
+       layout->addWidget(licon);
+       bar = new QProgressBar(this);
+       layout->addWidget(bar);
+       setScan(scan);
+
+       button->installEventFilter(this);
+       licon->installEventFilter(this);
+       bar->installEventFilter(this);
+}
+
+DHCPCD_WI_SCAN *DhcpcdSsidMenu::getScan()
+{
+
+       return scan;
+}
+
+void DhcpcdSsidMenu::setScan(DHCPCD_WI_SCAN *scan)
+{
+       DHCPCD_WPA *wpa;
+       DHCPCD_IF *ifp;
        QIcon icon;
 
-       this->ifp = ifp;
        this->scan = scan;
+       wpa = wi->getWpa();
+       ifp = dhcpcd_wpa_if(wpa);
 
-       QHBoxLayout *layout = new QHBoxLayout(this);
-       button = new QRadioButton(scan->ssid, this);
        button->setChecked(strcmp(scan->ssid, ifp->ssid) == 0);
-       layout->addWidget(button);
+       button->setText(scan->ssid);
        if (scan->flags[0] == '\0') {
                icon = DhcpcdQt::getIcon("devices", "network-wireless");
                setToolTip(scan->bssid);
@@ -60,22 +85,14 @@ DhcpcdSsidMenu::DhcpcdSsidMenu(QWidget *parent, DHCPCD_IF *ifp, DHCPCD_WI_SCAN *
                setToolTip(tip);
        }
        QPixmap picon = icon.pixmap(22, 22);
-       licon = new QLabel(this);
        licon->setPixmap(picon);
-       layout->addWidget(licon);
-       bar = new QProgressBar(this);
        bar->setValue(scan->strength.value);
-       layout->addWidget(bar);
-
-       button->installEventFilter(this);
-       licon->installEventFilter(this);
-       bar->installEventFilter(this);
 }
 
 bool DhcpcdSsidMenu::eventFilter(QObject *, QEvent *event)
 {
 
        if (event->type() == QEvent::MouseButtonPress)
-               emit selected(ifp, scan);
+               emit selected(scan);
        return false;
 }
index 75a27eb26f6588afb0df62adc7cf64c945033f26..a9c9ec1cb323cadb86b5b508f9602e8336770c20 100644 (file)
@@ -32,22 +32,27 @@ class QRadioButton;
 class QLabel;
 class QProgressBar;
 
+class DhcpcdWi;
+
 class DhcpcdSsidMenu : public QWidget
 {
        Q_OBJECT
 
 public:
-       DhcpcdSsidMenu(QWidget *parent, DHCPCD_IF *ifp, DHCPCD_WI_SCAN *scan);
+       DhcpcdSsidMenu(QWidget *parent, DhcpcdWi *wi, DHCPCD_WI_SCAN *scan);
        ~DhcpcdSsidMenu() {};
 
+       DHCPCD_WI_SCAN *getScan();
+       void setScan(DHCPCD_WI_SCAN *scan);
+
 signals:
-       void selected(DHCPCD_IF *ifp, DHCPCD_WI_SCAN *scan);
+       void selected(DHCPCD_WI_SCAN *scan);
 
 private slots:
        bool eventFilter(QObject *obj, QEvent *event);
 
 private:
-       DHCPCD_IF *ifp;
+       DhcpcdWi *wi;
        DHCPCD_WI_SCAN *scan;
 
        QRadioButton *button;
index e8b3ab015271aa4cc69d040db0109605457b0ef8..a02907911657bfe5ccfe714d9c1e9d6ad223a928 100644 (file)
  */
 
 #include <QObject>
+#include <QInputDialog>
+#include <QLineEdit>
+#include <QMenu>
+#include <QMessageBox>
 #include <QSocketNotifier>
 #include <QTimer>
+#include <QWidgetAction>
 
 #include <cerrno>
 
 #include "config.h"
 #include "dhcpcd-wi.h"
+#include "dhcpcd-qt.h"
+#include "dhcpcd-ifmenu.h"
+#include "dhcpcd-ssidmenu.h"
 
 DhcpcdWi::DhcpcdWi(DhcpcdQt *parent, DHCPCD_WPA *wpa)
 {
 
        this->dhcpcdQt = parent;
        this->wpa = wpa;
+       menu = NULL;
        scans = NULL;
 
        int fd = dhcpcd_wpa_get_fd(wpa);
@@ -54,7 +63,7 @@ DhcpcdWi::~DhcpcdWi()
                delete notifier;
 }
 
-DHCPCD_WPA * DhcpcdWi::getWpa()
+DHCPCD_WPA *DhcpcdWi::getWpa()
 {
 
        return wpa;
@@ -65,13 +74,64 @@ DHCPCD_WI_SCAN *DhcpcdWi::getScans()
 
        return scans;
 }
+
 void DhcpcdWi::setScans(DHCPCD_WI_SCAN *scans)
 {
 
+       if (menu) {
+               QList<DhcpcdSsidMenu*> lst;
+               DHCPCD_WI_SCAN *scan;
+
+               lst = menu->findChildren<DhcpcdSsidMenu*>();
+               for (scan = scans; scan; scan = scan->next) {
+                       foreach(DhcpcdSsidMenu *sm, lst) {
+                               DHCPCD_WI_SCAN *s = sm->getScan();
+                               if (memcmp(scan->bssid, s->bssid,
+                                   sizeof(scan->bssid)) == 0)
+                               {
+                                       sm->setScan(scan);
+                                       break;
+                               }
+                       }
+               }
+       }
+               
        dhcpcd_wi_scans_free(this->scans);
        this->scans = scans;
 }
 
+void DhcpcdWi::createMenu1(QMenu *menu)
+{
+       DHCPCD_WI_SCAN *scan;
+
+       for (scan = scans; scan; scan = scan->next) {
+               QWidgetAction *wa = new QWidgetAction(menu);
+               DhcpcdSsidMenu *ssidMenu = new DhcpcdSsidMenu(menu, this, scan);
+               wa->setDefaultWidget(ssidMenu);
+               menu->addAction(wa);
+               connect(ssidMenu, SIGNAL(selected(DHCPCD_WI_SCAN *)),
+                   this, SLOT(connectSsid(DHCPCD_WI_SCAN *)));
+       }
+}
+
+void DhcpcdWi::createMenu(QMenu *menu)
+{
+
+       this->menu = menu;
+       createMenu1(menu);
+}
+
+QMenu *DhcpcdWi::createIfMenu(QMenu *parent)
+{
+       DHCPCD_IF *ifp;
+
+       ifp = dhcpcd_wpa_if(wpa);
+       menu = new DhcpcdIfMenu(ifp, parent);
+       menu->setIcon(QIcon::fromTheme("network-wireless"));
+       createMenu1(menu);
+       return menu;
+}
+
 void DhcpcdWi::wpaOpen()
 {
        int fd = dhcpcd_wpa_open(wpa);
@@ -120,3 +180,47 @@ void DhcpcdWi::dispatch()
 
        dhcpcd_wpa_dispatch(wpa);
 }
+
+void DhcpcdWi::connectSsid(DHCPCD_WI_SCAN *scan)
+{
+       bool ok;
+       DHCPCD_WI_SCAN s;
+
+       /* Take a copy of scan incase it's destroyed by a scan update */
+       memcpy(&s, scan, sizeof(s));
+       s.next = NULL;
+
+       QString psk = QInputDialog::getText(dhcpcdQt, s.ssid,
+           tr("Pre Shared key"), QLineEdit::Normal, NULL, &ok);
+
+       if (!ok)
+               return;
+
+       QString errt;
+
+       switch (dhcpcd_wpa_configure_psk(wpa, &s, psk.toAscii())) {
+       case DHCPCD_WPA_SUCCESS:
+               return;
+       case DHCPCD_WPA_ERR_SET:
+               errt = tr("Failed to set key management.");
+               break;
+       case DHCPCD_WPA_ERR_SET_PSK:
+               errt = tr("Failed to set password, probably too short.");
+               break;
+       case DHCPCD_WPA_ERR_ENABLE:
+               errt = tr("Failed to enable the network.");
+               break;
+       case DHCPCD_WPA_ERR_ASSOC:
+               errt = tr("Failed to start association.");
+               break;
+       case DHCPCD_WPA_ERR_WRITE:
+               errt = tr("Failed to save wpa_supplicant configuration.\n\nYou should add update_config=1 to /etc/wpa_supplicant.conf.");
+               break;
+       default:
+               errt = strerror(errno);
+               break;
+       }
+
+       QMessageBox::critical(dhcpcdQt, tr("Error setting wireless properties"),
+           errt);
+}
index d46c0b3fef0d2300d2e5d5e637a6b3b2c657833d..6ec15e0ed2928cf9ca06f3d8d1ed58dcda7654f3 100644 (file)
@@ -32,6 +32,7 @@
 #include "dhcpcd.h"
 
 class DhcpcdQt;
+class QMenu;
 class QSocketNotifier;
 class QTimer;
 
@@ -47,9 +48,13 @@ public:
        DHCPCD_WI_SCAN *getScans();
        void setScans(DHCPCD_WI_SCAN *scans);
 
+       void createMenu(QMenu *parent);
+       QMenu *createIfMenu(QMenu *parent);
+
 private slots:
        void dispatch();
        void wpaOpen();
+       void connectSsid(DHCPCD_WI_SCAN *scan);
 
 private:
        DhcpcdQt *dhcpcdQt;
@@ -58,6 +63,9 @@ private:
 
        QSocketNotifier *notifier;
        QTimer *retryOpenTimer;
+
+       QMenu *menu;
+       void createMenu1(QMenu *parent);
 };
 
 #endif
index 4b6fecb2812b11137bedab2fc5a84f3d8f9d444a..337dbfd1223b8eb3e4f5f0c97c75a2daef536bd2 100644 (file)
@@ -232,6 +232,15 @@ bool dhcpcd_wpa_network_remove(DHCPCD_WPA *, int);
 char * dhcpcd_wpa_network_get(DHCPCD_WPA *, int, const char *);
 bool dhcpcd_wpa_network_set(DHCPCD_WPA *, int, const char *, const char *);
 
+#define DHCPCD_WPA_SUCCESS      0
+#define DHCPCD_WPA_ERR         -1
+#define DHCPCD_WPA_ERR_SET     -2
+#define DHCPCD_WPA_ERR_SET_PSK -3
+#define DHCPCD_WPA_ERR_ENABLE  -4
+#define DHCPCD_WPA_ERR_WRITE   -5
+#define DHCPCD_WPA_ERR_ASSOC   -6
+int dhcpcd_wpa_configure_psk(DHCPCD_WPA *w, DHCPCD_WI_SCAN *s, const char *p);
+
 char ** dhcpcd_config_blocks(DHCPCD_CONNECTION *, const char *);
 DHCPCD_OPTION *dhcpcd_config_read(DHCPCD_CONNECTION *,
     const char *, const char *);
index 92a690696e951f1fc43b62f1aa9e9d01bc713584..472b2659d2d9b3fb3c235c031c1b2652954cc992 100644 (file)
@@ -688,3 +688,56 @@ dhcpcd_wpa_start(DHCPCD_CONNECTION *con)
        for (i = con->interfaces; i; i = i->next)
                dhcpcd_wpa_if_event(i);
 }
+
+int
+dhcpcd_wpa_configure_psk(DHCPCD_WPA *wpa, DHCPCD_WI_SCAN *s, const char *psk)
+{
+       const char *mgmt, *var;
+       int id;
+       char *npsk;
+       size_t psk_len;
+       bool r;
+
+       assert(wpa);
+       assert(s);
+
+       id = dhcpcd_wpa_network_find_new(wpa, s->ssid);
+       if (id == -1)
+               return DHCPCD_WPA_ERR;
+
+       if (strcmp(s->flags, "[WEP]") == 0) {
+               mgmt = "NONE";
+               var = "wep_key0";
+       } else {
+               mgmt = "WPA-PSK";
+               var = "psk";
+       }
+
+       if (!dhcpcd_wpa_network_set(wpa, id, "key_mgmt", mgmt))
+               return DHCPCD_WPA_ERR_SET;
+
+       if (psk)
+               psk_len = strlen(psk);
+       else
+               psk_len = 0;
+       npsk = malloc(psk_len + 3);
+       if (npsk == NULL)
+               return DHCPCD_WPA_ERR;
+       npsk[0] = '"';
+       if (psk_len)
+               memcpy(npsk + 1, psk, psk_len);
+       npsk[psk_len + 1] = '"';
+       npsk[psk_len + 2] = '\0';
+       r = dhcpcd_wpa_network_set(wpa, id, var, npsk);
+       free(npsk);
+       if (!r)
+               return DHCPCD_WPA_ERR_SET_PSK;
+
+       if (!dhcpcd_wpa_network_enable(wpa, id))
+               return DHCPCD_WPA_ERR_ENABLE;
+       if (!dhcpcd_wpa_reassociate(wpa))
+               return DHCPCD_WPA_ERR_ASSOC;
+       if (!dhcpcd_wpa_config_write(wpa))
+               return DHCPCD_WPA_ERR_WRITE;
+       return DHCPCD_WPA_SUCCESS;
+}