diff --git a/ChangeLog b/ChangeLog index afa71af36..8618e60af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2004-08-06 Dan Williams + + * panel-applet/* + - Add panel applet + + * src/NetworkManagerPolicy.c + src/NetworkManager.c + - Get access point lists from NetworkManagerInfo on-demand, + and look for ServiceCreate/ServiceDeleted signals to see when + we should query NMI for lists + * src/NetworkManagerAPList.c + - Make sure to init the list's mutex + - Convert traversals of the list over to the list iter functions + + * src/NetworkManagerDbus.[ch] + - Use more aptly-named path/service/interface constants + - Treat both active and pending devices the same for "getActiveDevice" + - Add a "status" method returning "connected", "connecting", or "disconnected" + + * src/NetworkManagerDevice.c + - Honor "ignored" network list when picking best ap to use + + 2004-08-06 Seth Nickell * aclocal.m4: diff --git a/Makefile.am b/Makefile.am index 9be2645c2..89e2c5237 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS = src dispatcher-daemon info-daemon initscript test +SUBDIRS = src dispatcher-daemon info-daemon panel-applet initscript test diff --git a/configure.in b/configure.in index 0fb467a96..b07dd7859 100644 --- a/configure.in +++ b/configure.in @@ -35,6 +35,10 @@ PKG_CHECK_MODULES(OPENSSL, openssl) AC_SUBST(OPENSSL_CFLAGS) AC_SUBST(0PENSSL_LIBS) +PKG_CHECK_MODULES(PANEL_APPLET, libpanelapplet-2.0) +AC_SUBST(PANEL_APPLET_CFLAGS) +AC_SUBST(PANEL_APPLET_LIBS) + PKG_CHECK_MODULES(LIBGNOMEUI, libgnomeui-2.0) AC_SUBST(LIBGNOMEUI_CFLAFS) AC_SUBST(LIBGNOMEUI_LIBS) @@ -55,6 +59,7 @@ Makefile src/Makefile dispatcher-daemon/Makefile info-daemon/Makefile +panel-applet/Makefile test/Makefile initscript/Makefile ]) diff --git a/panel-applet/Makefile.am b/panel-applet/Makefile.am new file mode 100644 index 000000000..25adc0abd --- /dev/null +++ b/panel-applet/Makefile.am @@ -0,0 +1,65 @@ +## Process this file with automake to produce Makefile.in + +NULL= + +INCLUDES = \ + $(NM_CFLAGS) \ + $(GLADE_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) \ + $(PANEL_APPLET_CFLAGS) \ + -DICONDIR=\""$(datadir)/pixmaps"\" \ + -DG_DISABLE_DEPRECATED \ + -DGDK_DISABLE_DEPRECATED \ + -DGNOME_DISABLE_DEPRECATED \ + $(NULL) + +libexec_PROGRAMS = NMWirelessApplet + +NMWirelessApplet_SOURCES = \ + NMWirelessApplet.c \ + NMWirelessApplet.h \ + NMWirelessAppletDbus.c \ + NMWirelessAppletDbus.h \ + $(NULL) + +NMWirelessApplet_LDADD = \ + $(NM_LIBS) \ + $(LIBGLADE_LIBS) \ + $(DBUS_LIBS) \ + $(DBUS_GLIB_LIBS) \ + $(PANEL_APPLET_LIBS) \ + $(NULL) + +serverdir = $(libdir)/bonobo/servers +server_in_files = NMWirelessApplet.server.in +server_DATA = $(server_in_files:.server.in=.server) + +$(server_in_files:.server.in=.server): $(server_in_files) + sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ + +uidir = $(datadir)/gnome-2.0/ui +ui_DATA = NMWirelessApplet.xml + +pixmapdir = $(datadir)/pixmaps/NMWirelessApplet/ +pixmap_DATA = no-link-0.png \ + broken-0.png \ + signal-1-40.png \ + signal-41-60.png \ + signal-61-80.png \ + signal-81-100.png \ + wireless-applet.png \ + connect-0.png \ + connect-1.png \ + connect-2.png \ + connect-3.png \ + $(NULL) + +CLEANFILES = $(server_in_files) $(server_DATA) *.bak *.gladep + +EXTRA_DIST = \ + $(server_DATA) \ + $(pixmap_DATA) \ + $(ui_DATA) \ + $(NULL) + diff --git a/panel-applet/NMWirelessApplet.c b/panel-applet/NMWirelessApplet.c new file mode 100644 index 000000000..aa7fbbd3b --- /dev/null +++ b/panel-applet/NMWirelessApplet.c @@ -0,0 +1,549 @@ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "NMWirelessApplet.h" +#include "NMWirelessAppletDbus.h" + +#define CFG_UPDATE_INTERVAL 2 + +static char * pixmap_names[] = +{ + "broken-0.png", + "no-link-0.png", + "signal-1-40.png", + "signal-41-60.png", + "signal-61-80.png", + "signal-81-100.png", + "connect-0.png", + "connect-1.png", + "connect-2.png", + "connect-3.png", +}; + + +/* Represents an access point */ +typedef struct +{ + char * essid; + gboolean encrypted; +} AccessPoint; + +static GladeXML *xml = NULL; +static gchar *glade_file = NULL; + +static int nmwa_timeout_handler (NMWirelessApplet *applet); +static void nmwa_about_cb (BonoboUIComponent *uic, NMWirelessApplet *applet); +static GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet); + +static const BonoboUIVerb nmwa_context_menu_verbs [] = +{ + BONOBO_UI_UNSAFE_VERB ("NMWirelessAbout", nmwa_about_cb), + BONOBO_UI_VERB_END +}; + + +static GType nmwa_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GTypeInfo info = + { + sizeof (PanelAppletClass), + NULL, NULL, NULL, NULL, NULL, + sizeof (NMWirelessApplet), + 0, NULL, NULL + }; + + type = g_type_register_static (PANEL_TYPE_APPLET, "NMWirelessApplet", &info, 0); + } + + return (type); +} + +static void nmwa_draw (NMWirelessApplet *applet) +{ + const char *label_text; + char *tmp; + PixmapState state = PIX_BROKEN; + + if (applet->have_active_device) + state = PIX_SIGNAL_4; + + if (applet->pixmaps[state] != applet->current_pixbuf) + { + applet->current_pixbuf = (GdkPixbuf *)applet->pixmaps[state]; + gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), applet->current_pixbuf); + } +} + +static void nmwa_update_state (NMWirelessApplet *applet) +{ + nmwa_draw (applet); +} + +static void nmwa_start_timeout (NMWirelessApplet *applet) +{ + applet->timeout_handler_id = g_timeout_add (CFG_UPDATE_INTERVAL * 1000, + (GtkFunction)nmwa_timeout_handler, applet); +} + +static void nmwa_cancel_timeout (NMWirelessApplet *applet) +{ + g_source_remove (applet->timeout_handler_id); + applet->timeout_handler_id = -1; + nmwa_update_state (applet); +} + + +static void nmwa_load_theme (NMWirelessApplet *applet) +{ + char *pixmapdir; + char *pixmapname; + int i; + + pixmapdir = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_PIXMAP, + "NMWirelessApplet/", FALSE, NULL); + + for (i = 0; i < PIX_NUMBER; i++) + { + pixmapname = g_build_filename (G_DIR_SEPARATOR_S, + pixmapdir, pixmap_names[i], NULL); + applet->pixmaps[i] = gdk_pixbuf_new_from_file (pixmapname, NULL); + g_free (pixmapname); + } + + g_free (pixmapdir); +} + + +static int nmwa_timeout_handler (NMWirelessApplet *applet) +{ + char *active_device; + + /* Try to get a connection to dbus if we don't already have one */ + if (!applet->connection) + applet->connection = nmwa_dbus_init (applet); + + if (applet->nm_active) + { + if (active_device = nmwa_dbus_get_active_wireless_device (applet->connection)) + { + applet->have_active_device = TRUE; + nmwa_update_state (applet); + gtk_widget_show (GTK_WIDGET (applet)); + show_warning_dialog ("showing... %s", active_device); + dbus_free (active_device); + } + else + show_warning_dialog ("didn't get good active device\n"); + } + else + { + show_warning_dialog ("hiding..."); + gtk_widget_hide (GTK_WIDGET (applet)); + } + + return (TRUE); +} + +void show_error_dialog (gchar *mesg, ...) +{ + GtkWidget *dialog; + char *tmp; + va_list ap; + + va_start (ap,mesg); + tmp = g_strdup_vprintf (mesg,ap); + dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, mesg, NULL); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (tmp); + va_end (ap); +} + +void show_warning_dialog (gchar *mesg, ...) +{ + GtkWidget *dialog; + char *tmp; + va_list ap; + + va_start (ap,mesg); + tmp = g_strdup_vprintf (mesg,ap); + dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, mesg, NULL); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + g_free (tmp); + va_end (ap); +} + + +static void nmwa_about_cb (BonoboUIComponent *uic, NMWirelessApplet *applet) +{ + GdkPixbuf *pixbuf; + char *file; + + const gchar *authors[] = + { + "Dan Williams ", + NULL + }; + + if (applet->about_dialog != NULL) + { + gtk_window_set_screen (GTK_WINDOW (applet->about_dialog), gtk_widget_get_screen (GTK_WIDGET (&applet->base))); + gtk_window_present (GTK_WINDOW (applet->about_dialog)); + return; + } + + file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_PIXMAP, "NMWirelessApplet/wireless-applet.png", FALSE, NULL); + pixbuf = gdk_pixbuf_new_from_file (file, NULL); + g_free (file); + + applet->about_dialog = gnome_about_new ( + "Wireless Network Applet", + VERSION, + "(C) 2004 Red Hat, Inc.", + "This utility shows the status of a wireless link.", + authors, + NULL, + NULL, + pixbuf); + + g_object_unref (pixbuf); + + gtk_window_set_screen (GTK_WINDOW (applet->about_dialog), gtk_widget_get_screen (GTK_WIDGET (applet))); + g_signal_connect (applet->about_dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &applet->about_dialog); + gtk_widget_show (applet->about_dialog); + + return; +} + + +static void nmwa_destroy (NMWirelessApplet *applet, gpointer user_data) +{ + int i; + + if (applet->menu) + gtk_widget_destroy (applet->menu); + + if (applet->timeout_handler_id > 0) + { + gtk_timeout_remove (applet->timeout_handler_id); + applet->timeout_handler_id = 0; + } + + for (i = 0; i < PIX_NUMBER; i++) + g_object_unref (applet->pixmaps[i]); + + if (applet->about_dialog) + { + gtk_widget_destroy (applet->about_dialog); + applet->about_dialog = NULL; + } +} + + +static void nmwa_get_menu_pos (GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data) +{ + NMWirelessApplet *applet = data; + GtkRequisition reqmenu, reqapplet; + gint tempx, tempy, width, height; + gint screen_width, screen_height; + + gtk_widget_size_request (GTK_WIDGET (menu), &reqmenu); + gdk_window_get_origin (GTK_WIDGET (applet)->window, &tempx, &tempy); + gdk_window_get_geometry (GTK_WIDGET (applet)->window, NULL, NULL, &width, &height, NULL); + + switch (panel_applet_get_orient (PANEL_APPLET (applet))) + { + case PANEL_APPLET_ORIENT_DOWN: + tempy += height; + break; + case PANEL_APPLET_ORIENT_UP: + tempy -= reqmenu.height; + break; + case PANEL_APPLET_ORIENT_LEFT: + tempx -= reqmenu.width; + break; + case PANEL_APPLET_ORIENT_RIGHT: + tempx += width; + break; + } + screen_width = gdk_screen_width (); + screen_height = gdk_screen_height (); + *x = CLAMP (tempx, 0, MAX (0, screen_width - reqmenu.width)); + *y = CLAMP (tempy, 0, MAX (0, screen_height - reqmenu.height)); +} + + +static void nmwa_button_clicked (GtkWidget *button, NMWirelessApplet *applet) +{ + if (GTK_WIDGET_VISIBLE (applet->menu)) + gtk_menu_popdown (GTK_MENU (applet->menu)); + else + { + applet->menu = nmwa_populate_menu (applet); + gtk_menu_popup (GTK_MENU (applet->menu), NULL, NULL, nmwa_get_menu_pos, applet, 0, gtk_get_current_event_time()); + } +} + + +/* + * nmwa_add_menu_item + * + * Callback from nmwa_dbus_add_networks_to_menu() during network enumeration. + * Given a network, add it to our networks menu. + * + */ +void nmwa_add_menu_item (char *network, gboolean current, gpointer user_data) +{ + GtkWidget *menu = (GtkWidget *)user_data; + GtkWidget *menu_item; + + g_return_if_fail (network != NULL); + g_return_if_fail (menu != NULL); + + menu_item = gtk_check_menu_item_new_with_label (network); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), current); + gtk_widget_show (menu_item); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); +} + + +/* + * nmwa_populate_menu + * + * Set up our networks menu from scratch + * + */ +static GtkWidget * nmwa_populate_menu (NMWirelessApplet *applet) +{ + GtkWidget *menu; + GtkWidget *menu_item; + int num_networks; + char **networks; + + g_return_if_fail (applet != NULL); + + menu = gtk_menu_new (); + if (applet->nm_active) + nmwa_dbus_add_networks_to_menu (applet->connection, menu); + else + nmwa_add_menu_item ("No Wireless Networks found...", FALSE, menu); + + return (menu); +} + + +static void nmwa_setup_widgets (NMWirelessApplet *applet) +{ + GtkRequisition req; + gint total_size = 0; + gboolean horizontal = FALSE; + gint panel_size; + GtkWidget *menu_item; + + panel_size = panel_applet_get_size (PANEL_APPLET (applet)); + switch (panel_applet_get_orient(PANEL_APPLET (applet))) + { + case PANEL_APPLET_ORIENT_LEFT: + case PANEL_APPLET_ORIENT_RIGHT: + horizontal = FALSE; + break; + case PANEL_APPLET_ORIENT_UP: + case PANEL_APPLET_ORIENT_DOWN: + horizontal = TRUE; + break; + } + + /* construct pixmap widget */ + applet->pixmap = gtk_image_new (); + gtk_image_set_from_pixbuf (GTK_IMAGE (applet->pixmap), applet->pixmaps[PIX_BROKEN]); + gtk_widget_size_request (applet->pixmap, &req); + gtk_widget_show (applet->pixmap); + + if (horizontal) + total_size += req.height; + else + total_size += req.width; + + /* pack */ + if (applet->button) + gtk_widget_destroy (applet->button); + + if (horizontal && (total_size <= panel_size)) + applet->box = gtk_vbox_new (FALSE, 0); + else if (horizontal && (total_size > panel_size)) + applet->box = gtk_hbox_new (FALSE, 0); + else if (!horizontal && (total_size <= panel_size)) + applet->box = gtk_hbox_new (FALSE, 0); + else + applet->box = gtk_vbox_new (FALSE, 0); + + applet->button = gtk_button_new (); + g_signal_connect(applet->button, "clicked", G_CALLBACK(nmwa_button_clicked), applet); + gtk_button_set_relief (GTK_BUTTON (applet->button), GTK_RELIEF_NONE); + gtk_container_add (GTK_CONTAINER(applet->button), applet->box); + + gtk_box_pack_start (GTK_BOX (applet->box), applet->pixmap, TRUE, TRUE, 0); + gtk_widget_show (applet->button); + gtk_widget_show (applet->box); + gtk_container_add (GTK_CONTAINER (applet), applet->button); + + applet->current_pixbuf = NULL; + applet->about_dialog = NULL; + + if (applet->menu) + gtk_widget_destroy (applet->menu); + applet->menu = nmwa_populate_menu (applet); +} + +static void change_size_cb(PanelApplet *pa, gint s, NMWirelessApplet *applet) +{ + nmwa_setup_widgets (applet); + nmwa_timeout_handler (applet); +} + +static void change_orient_cb(PanelApplet *pa, gint s, NMWirelessApplet *applet) +{ + nmwa_setup_widgets (applet); + nmwa_timeout_handler (applet); +} + +static gboolean do_not_eat_button_press (GtkWidget *widget, GdkEventButton *event) +{ + if (event->button != 1) + g_signal_stop_emission_by_name (widget, "button_press_event"); + + return (FALSE); +} + +static void change_background_cb(PanelApplet *a, PanelAppletBackgroundType type, + GdkColor *color, GdkPixmap *pixmap, NMWirelessApplet *applet) +{ + GtkRcStyle *rc_style = gtk_rc_style_new (); + + switch (type) + { + case PANEL_PIXMAP_BACKGROUND: + gtk_widget_modify_style (GTK_WIDGET (applet), rc_style); + break; + + case PANEL_COLOR_BACKGROUND: + gtk_widget_modify_bg (GTK_WIDGET (applet), GTK_STATE_NORMAL, color); + break; + + case PANEL_NO_BACKGROUND: + gtk_widget_modify_style (GTK_WIDGET (applet), rc_style); + break; + + default: + gtk_widget_modify_style (GTK_WIDGET (applet), rc_style); + break; + } + + gtk_rc_style_unref (rc_style); +} + +static GtkWidget * nmwa_new (NMWirelessApplet *applet) +{ + panel_applet_set_flags (PANEL_APPLET (applet), PANEL_APPLET_EXPAND_MINOR); + + applet->connection = nmwa_dbus_init(applet); + applet->have_active_device = FALSE; + applet->nm_active = FALSE; + + nmwa_load_theme (applet); + nmwa_setup_widgets (applet); + + g_signal_connect (applet,"destroy", G_CALLBACK (nmwa_destroy),NULL); + g_signal_connect (applet->button, "button_press_event", G_CALLBACK (do_not_eat_button_press), NULL); + + nmwa_timeout_handler (applet); + nmwa_start_timeout (applet); + + panel_applet_setup_menu_from_file (PANEL_APPLET (applet), NULL, "NMWirelessApplet.xml", NULL, + nmwa_context_menu_verbs, applet); + + if (panel_applet_get_locked_down (PANEL_APPLET (applet))) + { + BonoboUIComponent *popup_component; + + popup_component = panel_applet_get_popup_component (PANEL_APPLET (applet)); + bonobo_ui_component_set_prop (popup_component, "/commands/NMWirelessApplet", "hidden", "1", NULL); + } + + g_signal_connect (G_OBJECT (applet), "change_size", G_CALLBACK (change_size_cb), applet); + g_signal_connect (G_OBJECT (applet), "change_orient", G_CALLBACK (change_orient_cb), applet); + g_signal_connect (G_OBJECT (applet), "change_background", G_CALLBACK (change_background_cb), applet); + + return (GTK_WIDGET (applet)); +} + +static gboolean nmwa_fill (NMWirelessApplet *applet) +{ + gnome_window_icon_set_default_from_file (ICONDIR"/NMWirelessApplet/wireless-applet.png"); + + glade_gnome_init (); + glade_file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_DATADIR, + "NMWirelessApplet/wireless-applet.glade", FALSE, NULL); + + nmwa_new (applet); + return (TRUE); +} + +static gboolean nmwa_factory (NMWirelessApplet *applet, const gchar *iid, gpointer data) +{ + gboolean retval = FALSE; + + if (!strcmp (iid, "OAFIID:NMWirelessApplet")) + retval = nmwa_fill (applet); + + return (retval); +} + +PANEL_APPLET_BONOBO_FACTORY ("OAFIID:NMWirelessApplet_Factory", + nmwa_get_type (), + "wireless", + "0", + (PanelAppletFactoryCallback) nmwa_factory, + NULL) + diff --git a/panel-applet/NMWirelessApplet.h b/panel-applet/NMWirelessApplet.h new file mode 100644 index 000000000..64518a02b --- /dev/null +++ b/panel-applet/NMWirelessApplet.h @@ -0,0 +1,76 @@ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + */ + +#ifndef NM_WIRELESS_APPLET_H +#define NM_WIRELESS_APPLET_H + +#include +#include +#include + +typedef enum +{ + PIX_BROKEN, + PIX_NO_LINK, + PIX_SIGNAL_1, + PIX_SIGNAL_2, + PIX_SIGNAL_3, + PIX_SIGNAL_4, + PIX_CONNECT_0, + PIX_CONNECT_1, + PIX_CONNECT_2, + PIX_CONNECT_3, + PIX_NUMBER, +} PixmapState; + + +typedef struct +{ + PanelApplet base; + + DBusConnection *connection; + gboolean nm_active; + gboolean have_active_device; + + /* contains pointers into the images GList. + * 0-100 are for link */ + GdkPixbuf *pixmaps[PIX_NUMBER]; + /* pointer to the current used file name */ + GdkPixbuf *current_pixbuf; + + GtkWidget *pixmap; + GtkWidget *button; + GtkWidget *box; + GtkWidget *about_dialog; + GtkWidget *menu; + + guint timeout_handler_id; +} NMWirelessApplet; + + +void nmwa_add_menu_item (char *network, gboolean current, gpointer user_data); + +void show_warning_dialog (gchar *mesg, ...); + +void show_warning_dialog (gchar *mesg, ...); + + +#endif diff --git a/panel-applet/NMWirelessApplet.server.in b/panel-applet/NMWirelessApplet.server.in new file mode 100644 index 000000000..d389ed2f4 --- /dev/null +++ b/panel-applet/NMWirelessApplet.server.in @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/panel-applet/NMWirelessApplet.xml b/panel-applet/NMWirelessApplet.xml new file mode 100644 index 000000000..1efd885d9 --- /dev/null +++ b/panel-applet/NMWirelessApplet.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/panel-applet/NMWirelessAppletDbus.c b/panel-applet/NMWirelessAppletDbus.c new file mode 100644 index 000000000..3eed70a86 --- /dev/null +++ b/panel-applet/NMWirelessAppletDbus.c @@ -0,0 +1,421 @@ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + */ + +#include +#include +#include "NMWirelessAppletDbus.h" +#include "NMWirelessApplet.h" + +#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" + +#define NM_DBUS_PATH "/org/freedesktop/NetworkManager" +#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" +#define NM_DBUS_PATH_DEVICES "/org/freedesktop/NetworkManager/Devices" +#define NM_DBUS_INTERFACE_DEVICES "org.freedesktop.NetworkManager.Devices" + +#define NMI_DBUS_SERVICE "org.freedesktop.NetworkManagerInfo" +#define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo" +#define NMI_DBUS_INTERFACE "org.freedesktop.NetworkManagerInfo" + + +/* + * nmwa_dbus_get_string + * + * NOTE: caller MUST free the returned string + * + */ +char * nmwa_dbus_get_string (DBusConnection *connection, const char *path, const char *method) +{ + DBusMessage *message; + DBusMessage *reply; + DBusError error; + char *string = NULL; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (method != NULL, NULL); + + if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE, method))) + { + show_warning_dialog ("Couldn't allocate the dbus message\n"); + return (NULL); + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); + if (dbus_error_is_set (&error)) + { + show_warning_dialog ("aaa %s raised:\n %s\n\n", error.name, error.message); + dbus_message_unref (message); + return (NULL); + } + + if (reply == NULL) + { + show_warning_dialog ("dbus reply message was NULL\n" ); + dbus_message_unref (message); + return (NULL); + } + + dbus_error_init (&error); + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &string, DBUS_TYPE_INVALID)) + { + show_warning_dialog ("bbb %s raised:\n %s\n\n", error.name, error.message); + string = NULL; + } + + dbus_message_unref (reply); + dbus_message_unref (message); + + return (string); +} + + +/* + * nmwa_dbus_get_int + * + */ +gint32 nmwa_dbus_get_int (DBusConnection *connection, const char *path, const char *method) +{ + DBusMessage *message; + DBusMessage *reply; + DBusError error; + gint32 num; + + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (path != NULL, 0); + g_return_val_if_fail (method != NULL, 0); + + if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE, method))) + { + fprintf (stderr, "Couldn't allocate the dbus message\n"); + return (0); + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); + if (dbus_error_is_set (&error)) + { + fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message); + dbus_message_unref (message); + return (0); + } + + if (reply == NULL) + { + fprintf( stderr, "dbus reply message was NULL\n" ); + dbus_message_unref (message); + return (0); + } + + dbus_error_init (&error); + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_INT32, &num, DBUS_TYPE_INVALID)) + num = 0; + + dbus_message_unref (reply); + dbus_message_unref (message); + + return (num); +} + + +/* + * nmwa_dbus_get_double + * + */ +double nmwa_dbus_get_double (DBusConnection *connection, const char *path, const char *method) +{ + DBusMessage *message; + DBusMessage *reply; + DBusError error; + double num; + + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (path != NULL, 0); + g_return_val_if_fail (method != NULL, 0); + + if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE, method))) + { + fprintf (stderr, "Couldn't allocate the dbus message\n"); + return (0); + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); + if (dbus_error_is_set (&error)) + { + fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message); + dbus_message_unref (message); + return (0); + } + + if (reply == NULL) + { + fprintf( stderr, "dbus reply message was NULL\n" ); + dbus_message_unref (message); + return (0); + } + + dbus_error_init (&error); + if (!dbus_message_get_args (reply, &error, DBUS_TYPE_DOUBLE, &num, DBUS_TYPE_INVALID)) + num = 0; + + dbus_message_unref (reply); + dbus_message_unref (message); + + return (num); +} + + +/* + * nmwa_dbus_get_string_array + * + * NOTE: caller MUST free the returned string array + * + */ +char **nmwa_dbus_get_string_array (DBusConnection *connection, const char *path, const char *method, int *num_items) +{ + DBusMessage *message; + DBusMessage *reply; + DBusMessageIter iter; + DBusError error; + char **array; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (method != NULL, NULL); + g_return_val_if_fail (num_items != NULL, NULL); + + if (!(message = dbus_message_new_method_call (NM_DBUS_SERVICE, path, NM_DBUS_INTERFACE, method))) + { + fprintf (stderr, "Couldn't allocate the dbus message\n"); + return (NULL); + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); + if (dbus_error_is_set (&error)) + { + fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message); + dbus_message_unref (message); + return (NULL); + } + + if (reply == NULL) + { + fprintf( stderr, "dbus reply message was NULL\n" ); + dbus_message_unref (message); + return (NULL); + } + + /* now analyze reply */ + dbus_message_iter_init (reply, &iter); + if (!dbus_message_iter_get_string_array (&iter, &array, num_items)) + array = NULL; + + dbus_message_unref (reply); + dbus_message_unref (message); + + return (array); +} + + +/* + * nmwa_dbus_get_active_wireless_device + * + * Returns the object_path of the currently active wireless device, if any. + * + */ +char * nmwa_dbus_get_active_wireless_device (DBusConnection *connection) +{ + char *active_device; + + if (!connection) + return (NULL); + + if ((active_device = active_device = nmwa_dbus_get_string (connection, NM_DBUS_PATH, "getActiveDevice"))) + { + int type; + + type = nmwa_dbus_get_int (connection, active_device, "getType"); + if (type != 2) /* wireless */ + { +show_warning_dialog ("nmwa_dbus_get_active_wireless_device(): device was not wireless\n"); + dbus_free (active_device); + active_device = NULL; + } +else +show_warning_dialog ("nmwa_dbus_get_active_wireless_device(): device GOOD\n"); + } +else +show_warning_dialog ("nmwa_dbus_get_active_wireless_device(): could not get string from dbus\n"); + + return (active_device); +} + + +/* + * nmwa_dbus_add_networks_to_menu + * + * Query NetworkManager for networks and add any to the networks menu + * + */ +void nmwa_dbus_add_networks_to_menu (DBusConnection *connection, gpointer user_data) +{ + char *active_device; + char *active_network; + char **networks; + int num_items = 0; + + if (!connection) + { + nmwa_add_menu_item ("No wireless networks found...", FALSE, user_data); + return; + } + + if (!(active_device = nmwa_dbus_get_active_wireless_device (connection))) + { + nmwa_add_menu_item ("No wireless networks found...", FALSE, user_data); + return; + } + + if (!(active_network = nmwa_dbus_get_string (connection, active_device, "getActiveNetwork"))) + { + nmwa_add_menu_item ("No wireless networks found...", FALSE, user_data); + return; + } + + /* Get each of the networks in turn and add them to the menu */ + if ((networks = nmwa_dbus_get_string_array (connection, active_device, "getNetworks", &num_items))) + { + if (strlen (networks[0]) == 0) + nmwa_add_menu_item ("No wireless networks found...", FALSE, user_data); + else + { + int i; + for (i = 0; i < num_items; i++) + { + char *name = nmwa_dbus_get_string (connection, networks[i], "getName"); + nmwa_add_menu_item (name, (strcmp (networks[i], active_network) == 0), user_data); + dbus_free (name); + } + } + dbus_free_string_array (networks); + } + + dbus_free (active_device); +} + + +/* + * nmwa_dbus_nm_is_running + * + * Ask dbus whether or not NetworkManager is running + * + */ +gboolean nmwa_dbus_nm_is_running (DBusConnection *connection) +{ + DBusError error; + gboolean exists; + + g_return_val_if_fail (connection != NULL, FALSE); + + dbus_error_init (&error); + exists = dbus_bus_service_exists (connection, NM_DBUS_SERVICE, &error); + return (exists); +} + + +/* + * nmwa_dbus_filter + * + */ +static DBusHandlerResult nmwa_dbus_filter (DBusConnection *connection, DBusMessage *message, void *user_data) +{ + NMWirelessApplet *applet = (NMWirelessApplet *)user_data; + gboolean handled = TRUE; + + g_return_val_if_fail (applet != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); + + if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceCreated")) + { + char *service; + DBusError error; + + dbus_error_init (&error); + if ( dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID) + && (strcmp (service, NM_DBUS_SERVICE) == 0)) + applet->nm_active = TRUE; + } + else if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceDeleted")) + { + char *service; + DBusError error; + + dbus_error_init (&error); + if ( dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID) + && (strcmp (service, NM_DBUS_SERVICE) == 0)) + applet->nm_active = FALSE; + } + else + handled = FALSE; + + return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED); +} + + +/* + * nmwa_dbus_init + * + * Initialize a connection to NetworkManager if we can get one + * + */ +DBusConnection * nmwa_dbus_init (gpointer user_data) +{ + DBusConnection *connection; + DBusError error; + + dbus_error_init (&error); + connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (!connection) + return (NULL); + + if (!dbus_connection_add_filter (connection, nmwa_dbus_filter, user_data, NULL)) + return (NULL); + + dbus_connection_set_exit_on_disconnect (connection, FALSE); + dbus_connection_setup_with_g_main (connection, NULL); + + dbus_bus_add_match(connection, + "type='signal'," + "interface='" DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "'," + "sender='" DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "'", + &error); + if (dbus_error_is_set (&error)) + { + show_warning_dialog ("Could not add match, error: '%s'", error.message); + } + + return (connection); +} + diff --git a/panel-applet/NMWirelessAppletDbus.h b/panel-applet/NMWirelessAppletDbus.h new file mode 100644 index 000000000..31e44be16 --- /dev/null +++ b/panel-applet/NMWirelessAppletDbus.h @@ -0,0 +1,36 @@ +/* NetworkManager Wireless Applet -- Display wireless access points and allow user control + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2004 Red Hat, Inc. + */ + +#ifndef NM_WIRELESS_APPLET_DBUS_H +#define NM_WIRELESS_APPLET_DBUS_H + +#include +#include + +DBusConnection * nmwa_dbus_init (gpointer user_data); + +gboolean nmwa_dbus_nm_is_running (DBusConnection *connection); + +void nmwa_dbus_add_networks_to_menu (DBusConnection *connection, gpointer user_data); + +char * nmwa_dbus_get_active_wireless_device (DBusConnection *connection); + +#endif diff --git a/panel-applet/broken-0.png b/panel-applet/broken-0.png new file mode 100644 index 000000000..6a2996491 Binary files /dev/null and b/panel-applet/broken-0.png differ diff --git a/panel-applet/connect-0.png b/panel-applet/connect-0.png new file mode 100644 index 000000000..6e051dd13 Binary files /dev/null and b/panel-applet/connect-0.png differ diff --git a/panel-applet/connect-1.png b/panel-applet/connect-1.png new file mode 100644 index 000000000..3ba69e527 Binary files /dev/null and b/panel-applet/connect-1.png differ diff --git a/panel-applet/connect-2.png b/panel-applet/connect-2.png new file mode 100644 index 000000000..eddad5e25 Binary files /dev/null and b/panel-applet/connect-2.png differ diff --git a/panel-applet/connect-3.png b/panel-applet/connect-3.png new file mode 100644 index 000000000..7d7691529 Binary files /dev/null and b/panel-applet/connect-3.png differ diff --git a/panel-applet/no-link-0.png b/panel-applet/no-link-0.png new file mode 100644 index 000000000..3b35f7591 Binary files /dev/null and b/panel-applet/no-link-0.png differ diff --git a/panel-applet/signal-1-40.png b/panel-applet/signal-1-40.png new file mode 100644 index 000000000..25ecd555a Binary files /dev/null and b/panel-applet/signal-1-40.png differ diff --git a/panel-applet/signal-41-60.png b/panel-applet/signal-41-60.png new file mode 100644 index 000000000..eb862f046 Binary files /dev/null and b/panel-applet/signal-41-60.png differ diff --git a/panel-applet/signal-61-80.png b/panel-applet/signal-61-80.png new file mode 100644 index 000000000..be6920467 Binary files /dev/null and b/panel-applet/signal-61-80.png differ diff --git a/panel-applet/signal-81-100.png b/panel-applet/signal-81-100.png new file mode 100644 index 000000000..0c9ccad55 Binary files /dev/null and b/panel-applet/signal-81-100.png differ diff --git a/panel-applet/wireless-applet.png b/panel-applet/wireless-applet.png new file mode 100644 index 000000000..a3e9e26f6 Binary files /dev/null and b/panel-applet/wireless-applet.png differ diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 53ac12dfe..ead5e050d 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -403,7 +403,7 @@ static NMData *nm_data_new (void) return (NULL); } - /* Initialize the allowed access point list */ + /* Initialize the access point lists */ data->trusted_ap_list = nm_ap_list_new (NETWORK_TYPE_TRUSTED); data->preferred_ap_list = nm_ap_list_new (NETWORK_TYPE_PREFERRED); data->invalid_ap_list = nm_ap_list_new (NETWORK_TYPE_INVALID); @@ -411,7 +411,7 @@ static NMData *nm_data_new (void) if (!data->trusted_ap_list || !data->preferred_ap_list || !data->invalid_ap_list) { nm_data_free (data); - NM_DEBUG_PRINT("Could not create trusted ap list mutex. Whacky stuff going on?\n"); + NM_DEBUG_PRINT("Could not create access point lists. Whacky stuff going on?\n"); return (NULL); } @@ -603,6 +603,8 @@ int main( int argc, char *argv[] ) nm_data_free (nm_data); exit (EXIT_FAILURE); } + nm_data->info_daemon_avail = nm_dbus_is_info_daemon_running (nm_data->dbus_connection); + nm_data->update_ap_lists = TRUE; /* Initialize libhal. We get a connection to the hal daemon here. */ if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL) @@ -613,10 +615,6 @@ int main( int argc, char *argv[] ) nm_data->hal_ctx = ctx; hal_ctx_set_user_data (nm_data->hal_ctx, nm_data); - /* Initialize our lists of allowed and ignored access points */ - nm_ap_list_populate (nm_data->trusted_ap_list, nm_data); - nm_ap_list_populate (nm_data->preferred_ap_list, nm_data); - /* Grab network devices that are already present and add them to our list */ nm_add_initial_devices (nm_data); @@ -628,11 +626,9 @@ int main( int argc, char *argv[] ) /* Another watch function which handles networking state changes and applies * the correct policy on a change. */ - policy_source = g_timeout_add (3000, nm_state_modification_monitor, nm_data); + policy_source = g_timeout_add (500, nm_state_modification_monitor, nm_data); - /* Yet another watch function which scans for access points and - * attempts to associate with approved ones in a users' list. - */ + /* Keep a current list of access points */ wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data); /* Watch all devices that HAL knows about for state changes */ diff --git a/src/NetworkManager.h b/src/NetworkManager.h index 2b8ea2eb0..129f41e89 100644 --- a/src/NetworkManager.h +++ b/src/NetworkManager.h @@ -31,16 +31,22 @@ struct NMData { LibHalContext *hal_ctx; + DBusConnection *dbus_connection; + gboolean info_daemon_avail; + GSList *dev_list; GMutex *dev_list_mutex; + struct NMDevice *active_device; struct NMDevice *pending_device; + gboolean state_modified; GMutex *state_modified_mutex; + + gboolean update_ap_lists; struct NMAccessPointList *trusted_ap_list; struct NMAccessPointList *preferred_ap_list; struct NMAccessPointList *invalid_ap_list; - DBusConnection *dbus_connection; }; typedef struct NMData NMData; diff --git a/src/NetworkManagerAPList.c b/src/NetworkManagerAPList.c index fcc7bbfa3..ffff98be2 100644 --- a/src/NetworkManagerAPList.c +++ b/src/NetworkManagerAPList.c @@ -58,6 +58,13 @@ NMAccessPointList *nm_ap_list_new (NMNetworkType type) nm_ap_list_ref (list); list->type = type; + list->mutex = g_mutex_new (); + if (!list->mutex) + { + g_free (list); + NM_DEBUG_PRINT ("nm_ap_list_new() could not create list mutex\n"); + return (NULL); + } return (list); } @@ -151,34 +158,28 @@ void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap) */ NMAccessPoint *nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network) { + NMAccessPoint *ap; NMAccessPoint *found_ap = NULL; - GSList *element; + NMAPListIter *iter; - g_return_val_if_fail (list != NULL, NULL); g_return_val_if_fail (network != NULL, NULL); - if (!nm_try_acquire_mutex (list->mutex, __FUNCTION__)) - { - NM_DEBUG_PRINT( "nm_ap_list_get_ap_by_essid() could not acquire AP list mutex.\n" ); + if (!list) return (NULL); - } - /* Find the ap in the list */ - element = list->ap_list; - while (element) + if (!(iter = nm_ap_list_iter_new (list))) + return (NULL); + + while ((ap = nm_ap_list_iter_next (iter))) { - NMAccessPoint *ap = (NMAccessPoint *)(element->data); - - if (ap && (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0)) + if (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0) { found_ap = ap; break; } - element = g_slist_next (element); } - nm_unlock_mutex (list->mutex, __FUNCTION__); - + nm_ap_list_iter_free (iter); return (found_ap); } @@ -266,11 +267,14 @@ void nm_ap_list_populate (NMAccessPointList *list, NMData *data) */ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAccessPointList *new) { - GSList *element = old->ap_list; + GSList *element = NULL; g_return_if_fail (data != NULL); g_return_if_fail (dev != NULL); + if (old) + element = old->ap_list; + /* Iterate over each item in the old list and find it in the new list */ while (element) { @@ -295,7 +299,11 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAcc /* Iterate over the new list and compare to the old list. Items that aren't already * matched are by definition new networks. */ - element = new->ap_list; + if (new) + element = new->ap_list; + else + element = NULL; + while (element) { NMAccessPoint *new_ap = (NMAccessPoint *)(element->data); @@ -349,7 +357,9 @@ NMAccessPoint * nm_ap_list_iter_get_ap (NMAPListIter *iter) { g_return_val_if_fail (iter != NULL, NULL); g_return_val_if_fail (iter->valid, NULL); - g_return_val_if_fail (iter->cur_pos != NULL, NULL); + + if (!iter->cur_pos) + return (NULL); return ((NMAccessPoint *)(iter->cur_pos->data)); } @@ -358,7 +368,6 @@ NMAccessPoint * nm_ap_list_iter_get_ap (NMAPListIter *iter) NMAccessPoint * nm_ap_list_iter_next (NMAPListIter *iter) { g_return_val_if_fail (iter != NULL, NULL); - g_return_val_if_fail (iter->cur_pos != NULL, NULL); if (iter->valid) iter->cur_pos = g_slist_next (iter->cur_pos); @@ -367,7 +376,6 @@ NMAccessPoint * nm_ap_list_iter_next (NMAPListIter *iter) iter->valid = TRUE; iter->cur_pos = iter->list->ap_list; } - return (nm_ap_list_iter_get_ap (iter)); } diff --git a/src/NetworkManagerDbus.c b/src/NetworkManagerDbus.c index 2bfde3d1d..cada341ff 100644 --- a/src/NetworkManagerDbus.c +++ b/src/NetworkManagerDbus.c @@ -73,7 +73,7 @@ static unsigned char * nm_dbus_get_object_path_from_device (NMDevice *dev) { g_return_val_if_fail (dev != NULL, NULL); - return (g_strdup_printf ("%s/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev))); + return (g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev))); } @@ -107,7 +107,7 @@ static NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char * { if ((dev = (NMDevice *)(element->data))) { - snprintf (compare_path, 100, "%s/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev)); + snprintf (compare_path, 100, "%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); /* Compare against our constructed path, but ignore any trailing elements */ if (strncmp (path, compare_path, strlen (compare_path)) == 0) break; @@ -147,7 +147,7 @@ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevic while ((ap = nm_ap_list_iter_next (iter))) { - snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, + snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap)); if (strncmp (path, compare_path, strlen (compare_path)) == 0) break; @@ -166,25 +166,35 @@ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevic */ static DBusMessage *nm_dbus_nm_get_active_device (DBusConnection *connection, DBusMessage *message, NMData *data) { - DBusMessage *reply_message = NULL; + DBusMessage *reply_message = NULL; + NMDevice *dev = NULL; g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (message != NULL, NULL); + if (data->active_device) + dev = data->active_device; + else if (data->pending_device) + dev = data->pending_device; + reply_message = dbus_message_new_method_return (message); if (!reply_message) return (NULL); /* Construct object path of "active" device and return it */ - if (data->active_device) + if (dev) { - char *object_path = g_strdup_printf ("%s/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (data->active_device)); + char *object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); +fprintf( stderr, "nm_dbus_nm_get_active_device() appending device '%s'\n", object_path); dbus_message_append_args (reply_message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); g_free (object_path); } else + { +fprintf( stderr, "nm_dbus_nm_get_active_device() appending device none\n"); dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "", DBUS_TYPE_INVALID); + } return (reply_message); } @@ -233,7 +243,7 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess if (dev) { - char *object_path = g_strdup_printf ("%s/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev)); + char *object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); dbus_message_iter_append_string (&iter_array, object_path); g_free (object_path); appended = TRUE; @@ -252,7 +262,7 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess } else { - reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "Retry", + reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "Retry", "NetworkManager could not lock device list, try again."); } @@ -282,7 +292,7 @@ void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevic if (!(dev_path = nm_dbus_get_object_path_from_device (dev))) return; - message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "DeviceNoLongerActive"); + message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceNoLongerActive"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_device_no_longer_active(): Not enough memory for new dbus message!\n"); @@ -317,7 +327,7 @@ void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev if (!(dev_path = nm_dbus_get_object_path_from_device (dev))) return; - message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "DeviceNowActive"); + message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceNowActive"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_device_now_active(): Not enough memory for new dbus message!\n"); @@ -352,7 +362,7 @@ void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDev if (!(dev_path = nm_dbus_get_object_path_from_device (dev))) return; - message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "DeviceIP4AddressChange"); + message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceIP4AddressChange"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_device_ip4_address_change(): Not enough memory for new dbus message!\n"); @@ -395,7 +405,7 @@ void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDev return; } - message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "WirelessNetworkAppeared"); + message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkAppeared"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!\n"); @@ -443,7 +453,7 @@ void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NM return; } - message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "WirelessNetworkDisappeared"); + message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_wireless_network_disappeared(): Not enough memory for new dbus message!\n"); @@ -529,8 +539,8 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev g_return_if_fail (ap != NULL); g_return_if_fail (nm_ap_get_essid (ap) != NULL); - message = dbus_message_new_method_call (NM_DBUS_NMI_NAMESPACE, NM_DBUS_NMI_OBJECT_PATH, - NM_DBUS_NMI_NAMESPACE, "getKeyForNetwork"); + message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, + NMI_DBUS_INTERFACE, "getKeyForNetwork"); if (message == NULL) { NM_DEBUG_PRINT ("nm_dbus_get_user_key_for_network(): Couldn't allocate the dbus message\n"); @@ -632,8 +642,8 @@ void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection) g_return_if_fail (connection != NULL); - message = dbus_message_new_method_call (NM_DBUS_NMI_NAMESPACE, NM_DBUS_NMI_OBJECT_PATH, - NM_DBUS_NMI_NAMESPACE, "cancelGetKeyForNetwork"); + message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, + NMI_DBUS_INTERFACE, "cancelGetKeyForNetwork"); if (message == NULL) { NM_DEBUG_PRINT ("nm_dbus_cancel_get_user_key_for_network(): Couldn't allocate the dbus message\n"); @@ -666,8 +676,8 @@ char * nm_dbus_get_network_essid (DBusConnection *connection, NMNetworkType type g_return_val_if_fail (network != NULL, NULL); g_return_val_if_fail (type != NETWORK_TYPE_UNKNOWN, NULL); - message = dbus_message_new_method_call (NM_DBUS_NMI_NAMESPACE, NM_DBUS_NMI_OBJECT_PATH, - NM_DBUS_NMI_NAMESPACE, "getNetworkEssid"); + message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, + NMI_DBUS_INTERFACE, "getNetworkEssid"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_get_network_essid(): Couldn't allocate the dbus message\n"); @@ -724,8 +734,8 @@ char * nm_dbus_get_network_key (DBusConnection *connection, NMNetworkType type, g_return_val_if_fail (network != NULL, NULL); g_return_val_if_fail (type != NETWORK_TYPE_UNKNOWN, NULL); - message = dbus_message_new_method_call (NM_DBUS_NMI_NAMESPACE, NM_DBUS_NMI_OBJECT_PATH, - NM_DBUS_NMI_NAMESPACE, "getNetworkKey"); + message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, + NMI_DBUS_INTERFACE, "getNetworkKey"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_get_network_key(): Couldn't allocate the dbus message\n"); @@ -780,8 +790,8 @@ guint nm_dbus_get_network_priority (DBusConnection *connection, NMNetworkType ty g_return_val_if_fail (network != NULL, NM_AP_PRIORITY_WORST); g_return_val_if_fail (type != NETWORK_TYPE_UNKNOWN, NM_AP_PRIORITY_WORST); - message = dbus_message_new_method_call (NM_DBUS_NMI_NAMESPACE, NM_DBUS_NMI_OBJECT_PATH, - NM_DBUS_NMI_NAMESPACE, "getNetworkPriority"); + message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, + NMI_DBUS_INTERFACE, "getNetworkPriority"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_get_network_priority(): Couldn't allocate the dbus message\n"); @@ -833,8 +843,8 @@ char ** nm_dbus_get_networks (DBusConnection *connection, NMNetworkType type, in g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (type != NETWORK_TYPE_UNKNOWN, NULL); - message = dbus_message_new_method_call (NM_DBUS_NMI_NAMESPACE, NM_DBUS_NMI_OBJECT_PATH, - NM_DBUS_NMI_NAMESPACE, "getNetworks"); + message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, + NMI_DBUS_INTERFACE, "getNetworks"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_get_networks(): Couldn't allocate the dbus message\n"); @@ -882,15 +892,43 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); - object_path = dbus_message_get_path (message); - - if (!object_path || (strcmp (object_path, NM_DBUS_NMI_OBJECT_PATH) != 0)) + if (!(object_path = dbus_message_get_path (message))) return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); - if (dbus_message_is_signal (message, NM_DBUS_NMI_NAMESPACE, "TrustedNetworkUpdate")) + if ( (strcmp (object_path, NMI_DBUS_PATH) != 0) + && dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "TrustedNetworkUpdate")) list = data->trusted_ap_list; - else if (dbus_message_is_signal (message, NM_DBUS_NMI_NAMESPACE, "PreferredNetworkUpdate")) + else if ( (strcmp (object_path, NMI_DBUS_PATH) != 0) + && dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "PreferredNetworkUpdate")) list = data->preferred_ap_list; + else if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceCreated")) + { + char *service; + DBusError error; + + dbus_error_init (&error); + if ( dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID) + && (strcmp (service, NMI_DBUS_SERVICE) == 0)) + { + data->update_ap_lists = TRUE; + data->info_daemon_avail = TRUE; + nm_data_set_state_modified (data, TRUE); + } + } + else if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceDeleted")) + { + char *service; + DBusError error; + + dbus_error_init (&error); + if ( dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_INVALID) + && (strcmp (service, NMI_DBUS_SERVICE) == 0)) + { + data->update_ap_lists = TRUE; + data->info_daemon_avail = FALSE; + nm_data_set_state_modified (data, TRUE); + } + } if (list) { @@ -930,7 +968,7 @@ static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *con if (!(ap = nm_dbus_get_ap_from_object_path (path, dev))) { - reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "NetworkNotFound", + reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NetworkNotFound", "The requested network does not exist for this device."); return (reply_message); } @@ -961,7 +999,7 @@ static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *con /* Must destroy the allocated message */ dbus_message_unref (reply_message); - reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "UnknownMethod", + reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "UnknownMethod", "NetworkManager knows nothing about the method %s for object %s", request, path); } @@ -990,13 +1028,13 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection, if (!(dev = nm_dbus_get_device_from_object_path (data, path))) { - reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "DeviceNotFound", + reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", "The requested network device does not exist."); return (reply_message); } /* Test whether or not the _networks_ of a device were queried instead of the device itself */ - object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev)); + object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); if (strncmp (path, object_path, strlen (object_path)) == 0) { free (object_path); @@ -1050,7 +1088,7 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection, { while ((ap = nm_ap_list_iter_next (list_iter))) { - object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, + object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap)); dbus_message_iter_append_string (&iter_array, object_path); g_free (object_path); @@ -1095,7 +1133,7 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection, method = dbus_message_get_member (message); path = dbus_message_get_path (message); - /*NM_DEBUG_PRINT_2 ("nm_dbus_nm_message_handler() got method %s for path %s\n", method, path);*/ + NM_DEBUG_PRINT_2 ("nm_dbus_nm_message_handler() got method %s for path %s\n", method, path); if (strcmp ("getActiveDevice", method) == 0) reply_message = nm_dbus_nm_get_active_device (connection, message, data); @@ -1103,6 +1141,19 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection, reply_message = nm_dbus_nm_get_devices (connection, message, data); else if (strcmp ("setKeyForNetwork", method) == 0) nm_dbus_set_user_key_for_network (connection, message, data); + else if (strcmp ("status", method) == 0) + { + reply_message = dbus_message_new_method_return (message); + if (reply_message) + { + if (data->active_device) + dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "connected", DBUS_TYPE_INVALID); + else if (!data->active_device && data->pending_device) + dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "connecting", DBUS_TYPE_INVALID); + else + dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "disconnected", DBUS_TYPE_INVALID); + } + } else handled = FALSE; @@ -1174,6 +1225,23 @@ void nm_dbus_devices_unregister_handler (DBusConnection *connection, void *user_ } +/* + * nm_dbus_is_info_daemon_running + * + * Ask dbus whether or not the info daemon is providing its dbus service + * + */ +gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection) +{ + DBusError error; + + g_return_val_if_fail (connection != NULL, FALSE); + + dbus_error_init (&error); + return (dbus_bus_service_exists (connection, NMI_DBUS_SERVICE, &error)); +} + + /* * nm_dbus_init * @@ -1200,21 +1268,21 @@ DBusConnection *nm_dbus_init (NMData *data) dbus_connection_set_exit_on_disconnect (connection, FALSE); dbus_connection_setup_with_g_main (connection, NULL); - dbus_bus_acquire_service (connection, NM_DBUS_NM_NAMESPACE, 0, &dbus_error); + dbus_bus_acquire_service (connection, NM_DBUS_SERVICE, 0, &dbus_error); if (dbus_error_is_set (&dbus_error)) { NM_DEBUG_PRINT_1 ("nm_dbus_init() could not acquire its service. dbus_bus_acquire_service() says: '%s'\n", dbus_error.message); return (NULL); } - success = dbus_connection_register_object_path (connection, NM_DBUS_NM_OBJECT_PATH_PREFIX, &nm_vtable, data); + success = dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data); if (!success) { NM_DEBUG_PRINT ("nm_dbus_init() could not register a handler for NetworkManager. Not enough memory?\n"); return (NULL); } - success = dbus_connection_register_fallback (connection, NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, &devices_vtable, data); + success = dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data); if (!success) { NM_DEBUG_PRINT ("nm_dbus_init() could not register a handler for NetworkManager devices. Not enough memory?\n"); @@ -1226,9 +1294,16 @@ DBusConnection *nm_dbus_init (NMData *data) dbus_bus_add_match (connection, "type='signal'," - "interface='"NM_DBUS_NMI_NAMESPACE"'," - "sender='"NM_DBUS_NMI_NAMESPACE"'," - "path='"NM_DBUS_NMI_OBJECT_PATH"'", &dbus_error); + "interface='" NMI_DBUS_INTERFACE "'," + "sender='" NMI_DBUS_SERVICE "'," + "path='" NMI_DBUS_PATH "'", + &dbus_error); + + dbus_bus_add_match(connection, + "type='signal'," + "interface='" DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS "'," + "sender='" DBUS_SERVICE_ORG_FREEDESKTOP_DBUS "'", + &dbus_error); return (connection); } diff --git a/src/NetworkManagerDbus.h b/src/NetworkManagerDbus.h index 9128a5c83..d4ac6c59c 100644 --- a/src/NetworkManagerDbus.h +++ b/src/NetworkManagerDbus.h @@ -27,17 +27,22 @@ #include #include "NetworkManagerAPList.h" +#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager" -#define NM_DBUS_NM_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager" -#define NM_DBUS_NM_NAMESPACE "org.freedesktop.NetworkManager" -#define NM_DBUS_DEVICES_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager/Devices" -#define NM_DBUS_DEVICES_NAMESPACE "org.freedesktop.NetworkManager.Devices" -#define NM_DBUS_NMI_OBJECT_PATH "/org/freedesktop/NetworkManagerInfo" -#define NM_DBUS_NMI_NAMESPACE "org.freedesktop.NetworkManagerInfo" +#define NM_DBUS_PATH "/org/freedesktop/NetworkManager" +#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager" +#define NM_DBUS_PATH_DEVICES "/org/freedesktop/NetworkManager/Devices" +#define NM_DBUS_INTERFACE_DEVICES "org.freedesktop.NetworkManager.Devices" + +#define NMI_DBUS_SERVICE "org.freedesktop.NetworkManagerInfo" +#define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo" +#define NMI_DBUS_INTERFACE "org.freedesktop.NetworkManagerInfo" DBusConnection *nm_dbus_init (NMData *data); +gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection); + void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev); void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev); diff --git a/src/NetworkManagerDevice.c b/src/NetworkManagerDevice.c index 28f5c61ce..677475e15 100644 --- a/src/NetworkManagerDevice.c +++ b/src/NetworkManagerDevice.c @@ -174,6 +174,7 @@ typedef struct NMDeviceWirelessOptions gboolean supports_wireless_scan; NMAccessPointList *ap_list; NMAccessPoint *best_ap; + gboolean freeze_best_ap; } NMDeviceWirelessOptions; typedef struct NMDeviceWiredOptions @@ -431,7 +432,8 @@ void nm_device_update_link_active (NMDevice *dev, gboolean check_mii) { nm_ap_list_unref (dev->options.wireless.ap_list); dev->options.wireless.ap_list = NULL; - nm_ap_unref (dev->options.wireless.best_ap); + if (dev->options.wireless.best_ap) + nm_ap_unref (dev->options.wireless.best_ap); } break; } @@ -1199,7 +1201,7 @@ char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap) { if (list_ap == ap) { - path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, + path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap)); break; } @@ -1255,16 +1257,35 @@ void nm_device_update_best_ap (NMDevice *dev) if (!(ap_list = nm_device_ap_list_get (dev))) return; + /* Check the trusted list first */ if (!(iter = nm_ap_list_iter_new (ap_list))) return; - while ((ap = nm_ap_list_iter_next (iter))) { - if (nm_wireless_is_ap_better (dev->app_data->trusted_ap_list, ap, &highest_priority)) - best_ap = ap; + /* Access points in the "invalid" list cannot be used */ + if (!nm_ap_list_get_ap_by_essid (dev->app_data->invalid_ap_list, nm_ap_get_essid (ap))) + if (nm_wireless_is_ap_better (dev->app_data->trusted_ap_list, ap, &highest_priority)) + best_ap = ap; + } + nm_ap_list_iter_free (iter); + + /* If its not in the trusted list, check the preferred list */ + if (!best_ap) + { + highest_priority = NM_AP_PRIORITY_WORST; + + if (!(iter = nm_ap_list_iter_new (ap_list))) + return; + while ((ap = nm_ap_list_iter_next (iter))) + { + /* Access points in the "invalid" list cannot be used */ + if (!nm_ap_list_get_ap_by_essid (dev->app_data->invalid_ap_list, nm_ap_get_essid (ap))) + if (nm_wireless_is_ap_better (dev->app_data->preferred_ap_list, ap, &highest_priority)) + best_ap = ap; + } + nm_ap_list_iter_free (iter); } - nm_ap_list_iter_free (iter); nm_device_set_best_ap (dev, best_ap); } @@ -1314,7 +1335,13 @@ static void nm_device_do_normal_scan (NMDevice *dev) } /* Clear out the ap list for this device in preparation for any new ones */ - dev->options.wireless.ap_list = NULL; + dev->options.wireless.ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE); + if (!(dev->options.wireless.ap_list)) + { + nm_dispose_scan_results (scan_results.result); + close (iwlib_socket); + return; + } /* Iterate over scan results and pick a "most" preferred access point. */ tmp_ap = scan_results.result; @@ -1329,7 +1356,7 @@ static void nm_device_do_normal_scan (NMDevice *dev) /* Copy over info from scan to local structure */ nm_ap_set_essid (nm_ap, tmp_ap->b.essid); -fprintf( stderr, "SCAN: found ap '%s'\n", tmp_ap->b.essid); + if (tmp_ap->b.has_key && (tmp_ap->b.key_flags & IW_ENCODE_DISABLED)) nm_ap_set_encrypted (nm_ap, FALSE); else @@ -1345,8 +1372,6 @@ fprintf( stderr, "SCAN: found ap '%s'\n", tmp_ap->b.essid); /* Add the AP to the device's AP list */ nm_device_ap_list_add (dev, nm_ap); - - nm_ap_unref (nm_ap); } tmp_ap = tmp_ap->next; } @@ -1360,7 +1385,8 @@ fprintf( stderr, "SCAN: found ap '%s'\n", tmp_ap->b.essid); */ if ((dev == data->active_device) || (dev == data->pending_device)) nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev)); - nm_ap_list_unref (old_ap_list); + if (old_ap_list) + nm_ap_list_unref (old_ap_list); nm_device_update_best_ap (dev); } diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 33a74a496..c903918e6 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -32,6 +32,8 @@ #include "NetworkManagerPolicy.h" #include "NetworkManagerUtils.h" #include "NetworkManagerAP.h" +#include "NetworkManagerAPList.h" +#include "NetworkManagerDbus.h" gboolean allowed_ap_worker_exit = FALSE; extern gboolean debug; @@ -158,6 +160,26 @@ gboolean nm_state_modification_monitor (gpointer user_data) g_return_val_if_fail (data != NULL, TRUE); + /* If the info daemon is now running, get our trusted/preferred ap lists from it */ + if (data->info_daemon_avail && data->update_ap_lists) + { +fprintf( stderr, "getting lists from NetworkManagerInfo\n"); + /* Query info daemon for network lists if its now running */ + if (data->trusted_ap_list) + nm_ap_list_unref (data->trusted_ap_list); + data->trusted_ap_list = nm_ap_list_new (NETWORK_TYPE_TRUSTED); + if (data->trusted_ap_list) + nm_ap_list_populate (data->trusted_ap_list, data); + + if (data->preferred_ap_list) + nm_ap_list_unref (data->preferred_ap_list); + data->preferred_ap_list = nm_ap_list_new (NETWORK_TYPE_PREFERRED); + if (data->preferred_ap_list) + nm_ap_list_populate (data->preferred_ap_list, data); + + data->update_ap_lists = FALSE; + } + /* Check global state modified variable, and reset it with * appropriate locking. */