diff --git a/ChangeLog b/ChangeLog index abf621f2f..cd7869210 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2004-08-05 Dan Williams + + * An assload of changes + 2004-08-02 Dan Williams * TODO diff --git a/configure.in b/configure.in index 34d136556..58ef7f707 100644 --- a/configure.in +++ b/configure.in @@ -15,6 +15,14 @@ PKG_CHECK_MODULES(NM, dbus-glib-1 >= 0.20 hal >= 0.2.91 gthread-2.0) AC_SUBST(NM_CFLAGS) AC_SUBST(NM_LIBS) +PKG_CHECK_MODULES(GTK, gtk+-2.0) +AC_SUBST(GTK_CFLAGS) +AC_SUBST(GTK_LIBS) + +PKG_CHECK_MODULES(GDK_PIXBUF, gdk-pixbuf-2.0) +AC_SUBST(GDK_PIXBUF_CFLAGS) +AC_SUBST(GDK_PIXBUF_LIBS) + PKG_CHECK_MODULES(GLADE, libglade-2.0) AC_SUBST(GLADE_CFLAGS) AC_SUBST(GLADE_LIBS) diff --git a/info-daemon/Makefile.am b/info-daemon/Makefile.am index 4aad3bc99..f9bb9ddc2 100644 --- a/info-daemon/Makefile.am +++ b/info-daemon/Makefile.am @@ -1,12 +1,14 @@ -INCLUDES = \ - $(NM_CFLAGS) \ +INCLUDES = \ + $(NM_CFLAGS) \ + $(GTK_CFLAGS) \ + $(GDK_PIXBUF_CFLAGS) \ $(GLADE_CFLAGS) \ $(GCONF_CFLAGS) \ - -Wall \ + -Wall \ -DDBUS_API_SUBJECT_TO_CHANGE \ -DG_DISABLE_DEPRECATED \ - -DGTK_DISABLE_DEPRECATED \ + -DGTK_DISABLE_DEPRECATED \ -DGLADEDIR=\""$(datadir)/NetworkManagerInfo/glade"\" \ -DBINDIR=\"$(bindir)\" \ -DDATADIR=\"$(datadir)\" @@ -14,11 +16,13 @@ INCLUDES = \ bin_PROGRAMS = NetworkManagerInfo NetworkManagerInfo_SOURCES = NetworkManagerInfo.h \ - NetworkManagerInfo.c \ - NetworkManagerInfoDbus.h \ - NetworkManagerInfoDbus.c + NetworkManagerInfo.c \ + NetworkManagerInfoDbus.h \ + NetworkManagerInfoDbus.c \ + NetworkManagerInfoPassphraseDialog.c \ + NetworkManagerInfoPassphraseDialog.h -NetworkManagerInfo_LDADD = $(NM_LIBS) $(GLADE_LIBS) $(GCONF_LIBS) +NetworkManagerInfo_LDADD = $(NM_LIBS) $(GLADE_LIBS) $(GCONF_LIBS) $(GTK_LIBS) $(GDK_PIXBUF_LIBS) gladedir = $(datadir)/NetworkManagerInfo/glade glade_DATA = passphrase.glade keyring.png diff --git a/info-daemon/NetworkManagerInfo.c b/info-daemon/NetworkManagerInfo.c index cc188f894..2286bc367 100644 --- a/info-daemon/NetworkManagerInfo.c +++ b/info-daemon/NetworkManagerInfo.c @@ -36,197 +36,47 @@ #include "NetworkManagerInfoDbus.h" #include "NetworkManagerInfo.h" +#include "NetworkManagerInfoPassphraseDialog.h" /* - * nmi_clear_dialog + * nmi_get_next_priority * - * Return dialog to its original state; clear out any network or device qdatas, - * clear the passphrase entry, and hide the dialog. + * Gets the next available worse priority * */ -static void nmi_clear_dialog (GtkWidget *dialog, GtkWidget *entry) +int nmi_get_next_priority (NMIAppInfo *info) { - char *data; + GSList *dir_list = NULL; + GSList *element = NULL; + int worst_prio = 0; - g_return_if_fail (dialog != NULL); - g_return_if_fail (entry != NULL); + g_return_val_if_fail (info != NULL, 999); - data = g_object_get_data (G_OBJECT (dialog), "device"); - if (data) + /* List all allowed access points that gconf knows about */ + element = dir_list = gconf_client_all_dirs (info->gconf_client, NMI_GCONF_TRUSTED_NETWORKS_PATH, NULL); + if (!dir_list) + return (10); + + while (element) { - g_free (data); - g_object_set_data (G_OBJECT (dialog), "device", NULL); - } + gchar key[100]; + GConfValue *value; - data = g_object_get_data (G_OBJECT (dialog), "network"); - if (data) - { - g_free (data); - g_object_set_data (G_OBJECT (dialog), "network", NULL); - } - - gtk_entry_set_text (GTK_ENTRY (entry), ""); - gtk_widget_hide (dialog); -} - - -/* - * ok_button_clicked - * - * OK button handler; grab the passphrase and send it back - * to NetworkManager. Get rid of the dialog. - * - */ -static void ok_button_clicked (GtkWidget *ok_button, gpointer user_data) -{ - GtkWidget *dialog = gtk_widget_get_toplevel (ok_button); - NMIAppInfo *info = (NMIAppInfo *)user_data; - - g_return_if_fail (info != NULL); - - if (GTK_WIDGET_TOPLEVEL (dialog)) - { - GtkWidget *entry = glade_xml_get_widget (info->xml, "passphrase_entry"); - const char *passphrase = gtk_entry_get_text (GTK_ENTRY (entry)); - const char *device = g_object_get_data (G_OBJECT (dialog), "device"); - const char *network = g_object_get_data (G_OBJECT (dialog), "network"); - gchar *key = NULL; - GConfEntry *gconf_entry; - - /* Tell NetworkManager about the key the user typed in */ - nmi_dbus_return_user_key (info->connection, device, network, passphrase); - - /* Update GConf with the new user key */ - key = g_strdup_printf ("%s/%s", NMI_GCONF_ALLOWED_NETWORKS_PATH, network); - gconf_entry = gconf_client_get_entry (info->gconf_client, key, NULL, TRUE, NULL); - g_free (key); - if (gconf_entry) + g_snprintf (&key[0], 99, "%s/priority", (char *)(element->data)); + if ((value = gconf_client_get (info->gconf_client, key, NULL))) { - gconf_entry_unref (gconf_entry); - key = g_strdup_printf ("%s/%s/key", NMI_GCONF_ALLOWED_NETWORKS_PATH, network); - gconf_client_set_string (info->gconf_client, key, passphrase, NULL); - g_free (key); + if (worst_prio < gconf_value_get_int (value)) + worst_prio = gconf_value_get_int (value); + gconf_value_free (value); } - nmi_clear_dialog (dialog, entry); + g_free (element->data); + element = g_slist_next (element); } -} + g_slist_free (dir_list); - -/* - * cancel_button_clicked - * - * Cancel button handler; return a cancellation message to NetworkManager - * and get rid of the dialog. - * - */ -static void cancel_button_clicked (GtkWidget *cancel_button, gpointer user_data) -{ - GtkWidget *dialog = gtk_widget_get_toplevel (cancel_button); - NMIAppInfo *info = (NMIAppInfo *)user_data; - - g_return_if_fail (info != NULL); - - if (GTK_WIDGET_TOPLEVEL (dialog)) - { - const char *device = g_object_get_data (G_OBJECT (dialog), "device"); - const char *network = g_object_get_data (G_OBJECT (dialog), "network"); - - nmi_dbus_return_user_key (info->connection, device, network, "***canceled***"); - nmi_clear_dialog (dialog, glade_xml_get_widget (info->xml, "passphrase_entry")); - } -} - - -/* - * nmi_show_user_key_dialog - * - * Pop up the user key dialog in response to a dbus message - * - */ -void nmi_show_user_key_dialog (const char *device, const char *network, NMIAppInfo *info) -{ - GtkWidget *dialog; - GtkWidget *label; - const gchar *label_text; - - g_return_if_fail (info != NULL); - g_return_if_fail (device != NULL); - g_return_if_fail (network != NULL); - - dialog = glade_xml_get_widget (info->xml, "passphrase_dialog"); - nmi_clear_dialog (dialog, glade_xml_get_widget (info->xml, "passphrase_entry")); - - /* Insert the Network name into the dialog text */ - label = glade_xml_get_widget (info->xml, "label1"); - label_text = gtk_label_get_label (GTK_LABEL (label)); - if (label_text) - { - gchar *new_label_text = g_strdup_printf (label_text, network); - gtk_label_set_label (GTK_LABEL (label), new_label_text); - } - - g_object_set_data (G_OBJECT (dialog), "device", g_strdup (device)); - g_object_set_data (G_OBJECT (dialog), "network", g_strdup (network)); - - gtk_widget_show (dialog); -} - - -/* - * nmi_cancel_user_key_dialog - * - * Cancel and hide any user key dialog that might be up - * - */ -void nmi_cancel_user_key_dialog (NMIAppInfo *info) -{ - GtkWidget *dialog; - GtkWidget *entry; - - g_return_if_fail (info != NULL); - - dialog = glade_xml_get_widget (info->xml, "passphrase_dialog"); - entry = glade_xml_get_widget (info->xml, "passphrase_entry"); - nmi_clear_dialog (dialog, entry); -} - - -/* - * nmi_interface_init - * - * Initialize the UI pieces of NMI. - * - */ -static void nmi_interface_init (NMIAppInfo *info) -{ - GtkWidget *dialog; - GtkButton *ok_button; - GtkButton *cancel_button; - GtkEntry *entry; - - info->xml = glade_xml_new(GLADEDIR"/passphrase.glade", NULL, NULL); - if (!info->xml) - { - fprintf (stderr, "Could not open glade file!\n"); - exit (1); - } - - dialog = glade_xml_get_widget (info->xml, "passphrase_dialog"); - gtk_widget_hide (dialog); - - ok_button = GTK_BUTTON (glade_xml_get_widget (info->xml, "login_button")); - g_signal_connect (G_OBJECT (ok_button), "clicked", GTK_SIGNAL_FUNC (ok_button_clicked), info); - gtk_widget_grab_default (GTK_WIDGET (ok_button)); - cancel_button = GTK_BUTTON (glade_xml_get_widget (info->xml, "cancel_button")); - g_signal_connect (G_OBJECT (cancel_button), "clicked", GTK_SIGNAL_FUNC (cancel_button_clicked), info); - - entry = GTK_ENTRY (glade_xml_get_widget (info->xml, "passphrase_entry")); - gtk_entry_set_visibility (entry, FALSE); - gtk_entry_set_invisible_char (entry, '*'); - - nmi_clear_dialog (dialog, GTK_WIDGET (entry)); + return (worst_prio + 10); } @@ -245,18 +95,28 @@ void nmi_gconf_notify_callback (GConfClient *client, guint connection_id, GConfE g_return_if_fail (entry != NULL); g_return_if_fail (info != NULL); - key = gconf_entry_get_key (entry); - if (key) + if ((key = gconf_entry_get_key (entry))) { - static int gconf_path_len = 0; - - if (!gconf_path_len) - gconf_path_len = strlen (NMI_GCONF_ALLOWED_NETWORKS_PATH) + 1; + NMINetworkType type = NETWORK_TYPE_UNKNOWN; + int trusted_path_len = strlen (NMI_GCONF_TRUSTED_NETWORKS_PATH) + 1; + int preferred_path_len = strlen (NMI_GCONF_PREFERRED_NETWORKS_PATH) + 1; + int len; /* Extract the network name from the key */ - if (strncmp (NMI_GCONF_ALLOWED_NETWORKS_PATH"/", key, gconf_path_len) == 0) + if (strncmp (NMI_GCONF_TRUSTED_NETWORKS_PATH"/", key, trusted_path_len) == 0) { - char *network = g_strdup ((key + gconf_path_len)); + type = NETWORK_TYPE_TRUSTED; + len = trusted_path_len; + } + else if (strncmp (NMI_GCONF_PREFERRED_NETWORKS_PATH"/", key, preferred_path_len) == 0) + { + type = NETWORK_TYPE_PREFERRED; + len = preferred_path_len; + } + + if (type != NETWORK_TYPE_UNKNOWN) + { + char *network = g_strdup ((key + len)); char *slash_pos; /* If its a key under the network name, zero out the slash so we @@ -265,7 +125,7 @@ void nmi_gconf_notify_callback (GConfClient *client, guint connection_id, GConfE if ((slash_pos = strchr (network, '/'))) *slash_pos = '\0'; - nmi_dbus_signal_update_allowed_network (info->connection, network); + nmi_dbus_signal_update_network (info->connection, network, type); g_free (network); } } @@ -420,7 +280,8 @@ int main( int argc, char *argv[] ) gtk_init (&argc, &argv); - nmi_interface_init (app_info); + if (nmi_passphrase_dialog_init (app_info) != 0) + exit (1); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); diff --git a/info-daemon/NetworkManagerInfo.h b/info-daemon/NetworkManagerInfo.h index 7d1e69e03..628872009 100644 --- a/info-daemon/NetworkManagerInfo.h +++ b/info-daemon/NetworkManagerInfo.h @@ -24,6 +24,7 @@ #define NETWORK_MANAGER_INFO_H #include +#include #include #include #include @@ -32,18 +33,20 @@ struct NMIAppInfo { - GladeXML *xml; + GladeXML *passphrase_dialog; DBusConnection *connection; GConfClient *gconf_client; + + GladeXML *new_networks_dialog; + GtkListStore *nnd_list_store; + GdkPixbuf *padlock_pixbuf; }; typedef struct NMIAppInfo NMIAppInfo; - #define NMI_GCONF_WIRELESS_NETWORKING_PATH "/system/networking/wireless" -#define NMI_GCONF_ALLOWED_NETWORKS_PATH "/system/networking/wireless/allowed_networks" +#define NMI_GCONF_TRUSTED_NETWORKS_PATH "/system/networking/wireless/trusted_networks" +#define NMI_GCONF_PREFERRED_NETWORKS_PATH "/system/networking/wireless/preferred_networks" - -void nmi_show_user_key_dialog (const char *device, const char *network, NMIAppInfo *info); -void nmi_cancel_user_key_dialog (NMIAppInfo *info); +int nmi_get_next_priority (NMIAppInfo *info); #endif diff --git a/info-daemon/NetworkManagerInfoDbus.c b/info-daemon/NetworkManagerInfoDbus.c index 8534e862f..30df4f31f 100644 --- a/info-daemon/NetworkManagerInfoDbus.c +++ b/info-daemon/NetworkManagerInfoDbus.c @@ -28,11 +28,14 @@ #include "NetworkManagerInfo.h" #include "NetworkManagerInfoDbus.h" +#include "NetworkManagerInfoPassphraseDialog.h" #define NMI_DBUS_NMI_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManagerInfo" #define NMI_DBUS_NMI_NAMESPACE "org.freedesktop.NetworkManagerInfo" #define NM_DBUS_NM_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager" #define NM_DBUS_NM_NAMESPACE "org.freedesktop.NetworkManager" +#define NM_DBUS_NM_DEVICES_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager/Devices" +#define NM_DBUS_NM_DEVICES_NAMESPACE "org.freedesktop.NetworkManager.Devices" /* * nmi_dbus_create_error_message @@ -60,6 +63,102 @@ static DBusMessage *nmi_dbus_create_error_message (DBusMessage *message, const c } +/* + * nmi_dbus_nm_get_network_essid + * + * Get the essid of a particular wireless network from NetworkManager. + * + */ +const char * nmi_dbus_nm_get_network_essid (DBusConnection *connection, const char *ap_path) +{ + DBusMessage *message; + DBusMessage *reply_message; + DBusError error; + char *essid; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (ap_path != NULL, NULL); + + message = dbus_message_new_method_call (NM_DBUS_NM_NAMESPACE, + ap_path, + NM_DBUS_NM_NAMESPACE, + "getName"); + if (!message) + { + fprintf (stderr, "nmi_dbus_nm_get_network_essid(): couldn't allocate the dbus message\n"); + return (NULL); + } + + dbus_error_init (&error); + reply_message = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); + dbus_message_unref (message); + if (dbus_error_is_set (&error)) + { + fprintf (stderr, "nmi_dbus_nm_get_network_essid(): %s raised:\n %s\n\n", error.name, error.message); + return (NULL); + } + + if (!reply_message) + return (NULL); + + /* now analyze reply */ + dbus_error_init (&error); + if (!dbus_message_get_args (reply_message, &error, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID)) + essid = NULL; + + dbus_message_unref (reply_message); + return (essid); +} + + +/* + * nmi_dbus_nm_get_network_encrypted + * + * Get whether or not a particular wireless network uses encryption from NetworkManager. + * + */ +gboolean nmi_dbus_nm_get_network_encrypted (DBusConnection *connection, const char *ap_path) +{ + DBusMessage *message; + DBusMessage *reply_message; + DBusError error; + gboolean encrypted = FALSE; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (ap_path != NULL, FALSE); + + message = dbus_message_new_method_call (NM_DBUS_NM_NAMESPACE, + ap_path, + NM_DBUS_NM_NAMESPACE, + "getEncrypted"); + if (!message) + { + fprintf (stderr, "nmi_dbus_get_network_encrypted(): couldn't allocate the dbus message\n"); + return (FALSE); + } + + dbus_error_init (&error); + reply_message = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); + dbus_message_unref (message); + if (dbus_error_is_set (&error)) + { + fprintf (stderr, "nmi_dbus_get_network_encrypted(): %s raised:\n %s\n\n", error.name, error.message); + return (FALSE); + } + + if (!reply_message) + return (FALSE); + + /* now analyze reply */ + dbus_error_init (&error); + if (!dbus_message_get_args (reply_message, &error, DBUS_TYPE_BOOLEAN, &encrypted, DBUS_TYPE_INVALID)) + encrypted = FALSE; + + dbus_message_unref (reply_message); + return (encrypted); +} + + /* * nmi_dbus_get_key_for_network * @@ -78,7 +177,7 @@ static void nmi_dbus_get_key_for_network (NMIAppInfo *info, DBusMessage *message DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) { - nmi_show_user_key_dialog (device, network, info); + nmi_passphrase_dialog_show (device, network, info); dbus_free (device); dbus_free (network); @@ -127,55 +226,72 @@ void nmi_dbus_return_user_key (DBusConnection *connection, const char *device, /* - * nmi_dbus_signal_update_allowed_network + * nmi_dbus_signal_update_network * * Signal NetworkManager that it needs to update info associated with a particular - * allowed network. + * allowed/ignored network. * */ -void nmi_dbus_signal_update_allowed_network (DBusConnection *connection, const char *network) +void nmi_dbus_signal_update_network (DBusConnection *connection, const char *network, NMINetworkType type) { DBusMessage *message; + const char *ignored_signal = "IgnoredNetworkUpdate"; + const char *allowed_signal = "AllowedNetworkUpdate"; + const char *signal; g_return_if_fail (connection != NULL); g_return_if_fail (network != NULL); - message = dbus_message_new_signal (NMI_DBUS_NMI_OBJECT_PATH_PREFIX, NMI_DBUS_NMI_NAMESPACE, - "AllowedNetworkUpdate"); + switch (type) + { + case (NETWORK_TYPE_TRUSTED): signal = allowed_signal; break; + case (NETWORK_TYPE_PREFERRED): signal = ignored_signal; break; + default: return; + } + + message = dbus_message_new_signal (NMI_DBUS_NMI_OBJECT_PATH_PREFIX, NMI_DBUS_NMI_NAMESPACE, signal); if (!message) { - fprintf (stderr, "nmi_dbus_signal_update_allowed_network(): Not enough memory for new dbus message!\n"); + fprintf (stderr, "nmi_dbus_signal_update_network(): Not enough memory for new dbus message!\n"); return; } dbus_message_append_args (message, DBUS_TYPE_STRING, network, DBUS_TYPE_INVALID); if (!dbus_connection_send (connection, message, NULL)) - fprintf (stderr, "nmi_dbus_signal_update_allowed_network(): Could not raise the AllowedNetworkUpdate signal!\n"); + fprintf (stderr, "nmi_dbus_signal_update_network(): Could not raise the '%s' signal!\n", signal); dbus_message_unref (message); } /* - * nmi_dbus_get_allowed_networks + * nmi_dbus_get_networks * - * Grab a list of allowed access points from GConf and return it in the form + * Grab a list of allowed or ignored access points from GConf and return it in the form * of a string array in a dbus message. * */ -static DBusMessage *nmi_dbus_get_allowed_networks (NMIAppInfo *info, DBusMessage *message) +static DBusMessage *nmi_dbus_get_networks (NMIAppInfo *info, DBusMessage *message, NMINetworkType type) { GSList *dir_list = NULL; GSList *element = NULL; DBusMessage *reply_message = NULL; DBusMessageIter iter; DBusMessageIter iter_array; + const char *path; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (message != NULL, NULL); + switch (type) + { + case (NETWORK_TYPE_TRUSTED): path = NMI_GCONF_TRUSTED_NETWORKS_PATH; break; + case (NETWORK_TYPE_PREFERRED): path = NMI_GCONF_PREFERRED_NETWORKS_PATH; break; + default: return (NULL); + } + /* List all allowed access points that gconf knows about */ - element = dir_list = gconf_client_all_dirs (info->gconf_client, NMI_GCONF_ALLOWED_NETWORKS_PATH, NULL); + element = dir_list = gconf_client_all_dirs (info->gconf_client, path, NULL); reply_message = dbus_message_new_method_return (message); dbus_message_iter_init (reply_message, &iter); @@ -187,7 +303,7 @@ static DBusMessage *nmi_dbus_get_allowed_networks (NMIAppInfo *info, DBusMessage { gboolean value_added = FALSE; - /* Append the essid of every allowed access point we know of + /* Append the essid of every allowed or ignored access point we know of * to a string array in the dbus message. */ while (element) @@ -219,34 +335,42 @@ static DBusMessage *nmi_dbus_get_allowed_networks (NMIAppInfo *info, DBusMessage /* - * nmi_dbus_get_allowed_network_prio + * nmi_dbus_get_network_prio * * If the specified allowed network exists, get its priority from gconf * and pass it back as a dbus message. * */ -static DBusMessage *nmi_dbus_get_allowed_network_prio (NMIAppInfo *info, DBusMessage *message) +static DBusMessage *nmi_dbus_get_network_prio (NMIAppInfo *info, DBusMessage *message, NMINetworkType type) { DBusMessage *reply_message = NULL; gchar *key = NULL; char *network = NULL; GConfValue *value; DBusError error; + const char *path; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (message != NULL, NULL); + switch (type) + { + case (NETWORK_TYPE_TRUSTED): path = NMI_GCONF_TRUSTED_NETWORKS_PATH; break; + case (NETWORK_TYPE_PREFERRED): path = NMI_GCONF_PREFERRED_NETWORKS_PATH; break; + default: return (NULL); + } + dbus_error_init (&error); if ( !dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID) || (strlen (network) <= 0)) { reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_NMI_NAMESPACE, "InvalidNetwork", - "NetworkManagerInfo::getAllowedNetworkPriority called with invalid network."); + "NetworkManagerInfo::get*NetworkPriority called with invalid network."); return (reply_message); } /* Grab priority key for our access point from GConf */ - key = g_strdup_printf ("%s/%s/priority", NMI_GCONF_ALLOWED_NETWORKS_PATH, network); + key = g_strdup_printf ("%s/%s/priority", path, network); value = gconf_client_get (info->gconf_client, key, NULL); g_free (key); @@ -259,7 +383,7 @@ static DBusMessage *nmi_dbus_get_allowed_network_prio (NMIAppInfo *info, DBusMes else { reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_NMI_NAMESPACE, "BadNetworkData", - "NetworkManagerInfo::getAllowedNetworkPriority could not access data for network '%s'", network); + "NetworkManagerInfo::get*NetworkPriority could not access data for network '%s'", network); } dbus_free (network); @@ -268,34 +392,42 @@ static DBusMessage *nmi_dbus_get_allowed_network_prio (NMIAppInfo *info, DBusMes /* - * nmi_dbus_get_allowed_network_essid + * nmi_dbus_get_network_essid * - * If the specified allowed network exists, get its essid from gconf + * If the specified allowed/ignored network exists, get its essid from gconf * and pass it back as a dbus message. * */ -static DBusMessage *nmi_dbus_get_allowed_network_essid (NMIAppInfo *info, DBusMessage *message) +static DBusMessage *nmi_dbus_get_network_essid (NMIAppInfo *info, DBusMessage *message, NMINetworkType type) { DBusMessage *reply_message = NULL; gchar *key = NULL; char *network = NULL; GConfValue *value; DBusError error; + const char *path; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (message != NULL, NULL); + switch (type) + { + case (NETWORK_TYPE_TRUSTED): path = NMI_GCONF_TRUSTED_NETWORKS_PATH; break; + case (NETWORK_TYPE_PREFERRED): path = NMI_GCONF_PREFERRED_NETWORKS_PATH; break; + default: return (NULL); + } + dbus_error_init (&error); if ( !dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID) || (strlen (network) <= 0)) { reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_NMI_NAMESPACE, "InvalidNetwork", - "NetworkManagerInfo::getAllowedNetworkEssid called with invalid network."); + "NetworkManagerInfo::get*NetworkEssid called with invalid network."); return (reply_message); } /* Grab essid key for our access point from GConf */ - key = g_strdup_printf ("%s/%s/essid", NMI_GCONF_ALLOWED_NETWORKS_PATH, network); + key = g_strdup_printf ("%s/%s/essid", path, network); value = gconf_client_get (info->gconf_client, key, NULL); g_free (key); @@ -308,7 +440,7 @@ static DBusMessage *nmi_dbus_get_allowed_network_essid (NMIAppInfo *info, DBusMe else { reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_NMI_NAMESPACE, "BadNetworkData", - "NetworkManagerInfo::getAllowedNetworkEssid could not access data for network '%s'", network); + "NetworkManagerInfo::get*NetworkEssid could not access data for network '%s'", network); } dbus_free (network); @@ -317,34 +449,42 @@ static DBusMessage *nmi_dbus_get_allowed_network_essid (NMIAppInfo *info, DBusMe /* - * nmi_dbus_get_allowed_network_key + * nmi_dbus_get_network_key * - * If the specified allowed network exists, get its key from gconf + * If the specified allowed/ignored network exists, get its key from gconf * and pass it back as a dbus message. * */ -static DBusMessage *nmi_dbus_get_allowed_network_key (NMIAppInfo *info, DBusMessage *message) +static DBusMessage *nmi_dbus_get_network_key (NMIAppInfo *info, DBusMessage *message, NMINetworkType type) { DBusMessage *reply_message = NULL; gchar *key = NULL; char *network = NULL; GConfValue *value; DBusError error; + const char *path; g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (message != NULL, NULL); + switch (type) + { + case (NETWORK_TYPE_TRUSTED): path = NMI_GCONF_TRUSTED_NETWORKS_PATH; break; + case (NETWORK_TYPE_PREFERRED): path = NMI_GCONF_PREFERRED_NETWORKS_PATH; break; + default: return (NULL); + } + dbus_error_init (&error); if ( !dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID) || (strlen (network) <= 0)) { reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_NMI_NAMESPACE, "InvalidNetwork", - "NetworkManagerInfo::getAllowedNetworkKey called with invalid network."); + "NetworkManagerInfo::get*NetworkKey called with invalid network."); return (reply_message); } /* Grab user-key key for our access point from GConf */ - key = g_strdup_printf ("%s/%s/key", NMI_GCONF_ALLOWED_NETWORKS_PATH, network); + key = g_strdup_printf ("%s/%s/key", path, network); value = gconf_client_get (info->gconf_client, key, NULL); g_free (key); @@ -384,24 +524,32 @@ static DBusHandlerResult nmi_dbus_nmi_message_handler (DBusConnection *connectio if (strcmp ("getKeyForNetwork", method) == 0) { - GtkWidget *dialog = glade_xml_get_widget (info->xml, "passphrase_dialog"); + GtkWidget *dialog = glade_xml_get_widget (info->passphrase_dialog, "passphrase_dialog"); if (!GTK_WIDGET_VISIBLE (dialog)) nmi_dbus_get_key_for_network (info, message); } else if (strcmp ("cancelGetKeyForNetwork", method) == 0) { - GtkWidget *dialog = glade_xml_get_widget (info->xml, "passphrase_dialog"); + GtkWidget *dialog = glade_xml_get_widget (info->passphrase_dialog, "passphrase_dialog"); if (GTK_WIDGET_VISIBLE (dialog)) - nmi_cancel_user_key_dialog (info); + nmi_passphrase_dialog_cancel (info); } else if (strcmp ("getAllowedNetworks", method) == 0) - reply_message = nmi_dbus_get_allowed_networks (info, message); + reply_message = nmi_dbus_get_networks (info, message, NETWORK_TYPE_TRUSTED); else if (strcmp ("getAllowedNetworkPriority", method) == 0) - reply_message = nmi_dbus_get_allowed_network_prio (info, message); + reply_message = nmi_dbus_get_network_prio (info, message, NETWORK_TYPE_TRUSTED); else if (strcmp ("getAllowedNetworkEssid", method) == 0) - reply_message = nmi_dbus_get_allowed_network_essid (info, message); + reply_message = nmi_dbus_get_network_essid (info, message,NETWORK_TYPE_TRUSTED); else if (strcmp ("getAllowedNetworkKey", method) == 0) - reply_message = nmi_dbus_get_allowed_network_key (info, message); + reply_message = nmi_dbus_get_network_key (info, message, NETWORK_TYPE_TRUSTED); + else if (strcmp ("getIgnoredNetworks", method) == 0) + reply_message = nmi_dbus_get_networks (info, message, NETWORK_TYPE_PREFERRED); + else if (strcmp ("getIgnoredNetworkPriority", method) == 0) + reply_message = nmi_dbus_get_network_prio (info, message, NETWORK_TYPE_PREFERRED); + else if (strcmp ("getIgnoredNetworkEssid", method) == 0) + reply_message = nmi_dbus_get_network_essid (info, message,NETWORK_TYPE_PREFERRED); + else if (strcmp ("getIgnoredNetworkKey", method) == 0) + reply_message = nmi_dbus_get_network_key (info, message, NETWORK_TYPE_PREFERRED); else { reply_message = nmi_dbus_create_error_message (message, NMI_DBUS_NMI_NAMESPACE, "UnknownMethod", @@ -433,7 +581,8 @@ void nmi_dbus_nmi_unregister_handler (DBusConnection *connection, void *user_dat static DBusHandlerResult nmi_dbus_filter (DBusConnection *connection, DBusMessage *message, void *user_data) { - char *ap_object_path; + char *ap_path; + char *dev_path; DBusError error; gboolean handled = FALSE; NMIAppInfo *info = (NMIAppInfo *) user_data; @@ -450,9 +599,20 @@ static DBusHandlerResult nmi_dbus_filter (DBusConnection *connection, DBusMessag if (appeared || disappeared) { dbus_error_init (&error); - if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &ap_object_path, DBUS_TYPE_INVALID)) + if (dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &dev_path, + DBUS_TYPE_STRING, &ap_path, + DBUS_TYPE_INVALID)) { - dbus_free (ap_object_path); +#if 0 + if (appeared) + nmi_new_networks_dialog_add_network (ap_path, info); + else if (disappeared) + nmi_new_networks_dialog_add_network (ap_path, info); +#endif + + dbus_free (dev_path); + dbus_free (ap_path); handled = TRUE; } } diff --git a/info-daemon/NetworkManagerInfoDbus.h b/info-daemon/NetworkManagerInfoDbus.h index 472419d93..ecdffd966 100644 --- a/info-daemon/NetworkManagerInfoDbus.h +++ b/info-daemon/NetworkManagerInfoDbus.h @@ -28,11 +28,26 @@ #include #include "NetworkManagerInfo.h" -int nmi_dbus_service_init (DBusConnection *dbus_connection, NMIAppInfo *info); +/* MUST match MetworkManager NMNetworkType */ +typedef enum +{ + NETWORK_TYPE_UNKNOWN = 0, + NETWORK_TYPE_TRUSTED, + NETWORK_TYPE_PREFERRED, + NETWORK_TYPE_INVALID, + NETWORK_TYPE_DEVICE +} NMINetworkType; -void nmi_dbus_return_user_key (DBusConnection *connection, const char *device, - const char *network, const char *passphrase); -void nmi_dbus_signal_update_allowed_network (DBusConnection *connection, const char *network); +int nmi_dbus_service_init (DBusConnection *dbus_connection, NMIAppInfo *info); + +const char * nmi_dbus_nm_get_network_essid (DBusConnection *connection, const char *ap_path); + +gboolean nmi_dbus_nm_get_network_encrypted (DBusConnection *connection, const char *ap_path); + +void nmi_dbus_return_user_key (DBusConnection *connection, const char *device, + const char *network, const char *passphrase); + +void nmi_dbus_signal_update_network (DBusConnection *connection, const char *network, NMINetworkType type); #endif diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 928f6b16b..53ac12dfe 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -312,9 +312,9 @@ gboolean nm_link_state_monitor (gpointer user_data) * device, since we only do scanning and link detection on the active device * anyway. */ - switch (nm_device_get_iface_type (dev)) + switch (nm_device_get_type (dev)) { - case NM_IFACE_TYPE_WIRELESS_ETHERNET: + case DEVICE_TYPE_WIRELESS_ETHERNET: if (dev != data->active_device) { if (nm_device_is_up (dev)) @@ -324,7 +324,7 @@ gboolean nm_link_state_monitor (gpointer user_data) nm_device_update_link_active (dev, FALSE); break; - case NM_IFACE_TYPE_WIRED_ETHERNET: + case DEVICE_TYPE_WIRED_ETHERNET: if (!nm_device_is_up (dev)) nm_device_bring_up (dev); nm_device_update_link_active (dev, FALSE); @@ -399,19 +399,22 @@ static NMData *nm_data_new (void) if (!data->state_modified_mutex) { nm_data_free (data); - NM_DEBUG_PRINT("Could not create state_modified mutex. Whacky shit going on?\n"); + NM_DEBUG_PRINT("Could not create state_modified mutex. Whacky stuff going on?\n"); return (NULL); } - /* Initialize the allowed access point list mutex */ - data->allowed_ap_list_mutex = g_mutex_new (); - if (!data->allowed_ap_list_mutex) + /* Initialize the allowed access point list */ + 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); + + if (!data->trusted_ap_list || !data->preferred_ap_list || !data->invalid_ap_list) { nm_data_free (data); - NM_DEBUG_PRINT("Could not create state_modified mutex. Whacky shit going on?\n"); + NM_DEBUG_PRINT("Could not create trusted ap list mutex. Whacky stuff going on?\n"); return (NULL); } - + data->state_modified = TRUE; return (data); @@ -448,8 +451,9 @@ static void nm_data_free (NMData *data) g_slist_free (data->dev_list); g_mutex_free (data->dev_list_mutex); - nm_ap_list_free (data->allowed_ap_list); - g_mutex_free (data->allowed_ap_list_mutex); + nm_ap_list_unref (data->trusted_ap_list); + nm_ap_list_unref (data->preferred_ap_list); + nm_ap_list_unref (data->invalid_ap_list); memset (data, 0, sizeof (NMData)); } @@ -609,8 +613,9 @@ int main( int argc, char *argv[] ) nm_data->hal_ctx = ctx; hal_ctx_set_user_data (nm_data->hal_ctx, nm_data); - /* Initialize our list of allowed access points */ - nm_ap_list_populate (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); diff --git a/src/NetworkManager.h b/src/NetworkManager.h index cda767be8..2b8ea2eb0 100644 --- a/src/NetworkManager.h +++ b/src/NetworkManager.h @@ -30,16 +30,17 @@ struct NMData { - LibHalContext *hal_ctx; - GSList *dev_list; - GMutex *dev_list_mutex; - struct NMDevice *active_device; - struct NMDevice *pending_device; - gboolean state_modified; - GMutex *state_modified_mutex; - GSList *allowed_ap_list; - GMutex *allowed_ap_list_mutex; - DBusConnection *dbus_connection; + LibHalContext *hal_ctx; + GSList *dev_list; + GMutex *dev_list_mutex; + struct NMDevice *active_device; + struct NMDevice *pending_device; + gboolean state_modified; + GMutex *state_modified_mutex; + 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 5f5d29fed..fcc7bbfa3 100644 --- a/src/NetworkManagerAPList.c +++ b/src/NetworkManagerAPList.c @@ -28,22 +28,143 @@ extern gboolean debug; +struct NMAccessPointList +{ + guint refcount; + NMNetworkType type; + GSList *ap_list; + GMutex *mutex; +}; + + +struct NMAPListIter +{ + NMAccessPointList *list; + GSList *cur_pos; + gboolean valid; +}; /* - * nm_ap_list_find_ap_in_list + * nm_ap_list_new * - * Helper routine to find an AP in a list. + * Creates a new empty access point list * */ -static NMAccessPoint * nm_ap_list_find_ap_in_list (GSList *list, const char *network) +NMAccessPointList *nm_ap_list_new (NMNetworkType type) +{ + NMAccessPointList *list = g_new0 (NMAccessPointList, 1); + + g_return_val_if_fail (list != NULL, NULL); + + nm_ap_list_ref (list); + list->type = type; + + return (list); +} + + +/* + * nm_ap_list_ref + * + * Increases the refcount of the ap list + * + */ +void nm_ap_list_ref (NMAccessPointList *list) +{ + g_return_if_fail (list != NULL); + + list->refcount++; +} + + +/* + * nm_ap_list_element_free + * + * Frees each member of an access point list before the list is + * disposed of. + * + */ +static void nm_ap_list_element_free (void *element, void *user_data) +{ + nm_ap_unref (element); +} + + +/* + * nm_ap_list_unref + * + * Decreases the refcount of the ap list, and if it reaches + * 0 frees the structure. + * + */ +void nm_ap_list_unref (NMAccessPointList *list) +{ + g_return_if_fail (list != NULL); + + list->refcount--; + if (list->refcount <= 0) + { + gboolean acquired = nm_try_acquire_mutex (list->mutex, __FUNCTION__); + + g_slist_foreach (list->ap_list, nm_ap_list_element_free, NULL); + g_slist_free (list->ap_list); + + if (acquired) + nm_unlock_mutex (list->mutex, __FUNCTION__); + + g_mutex_free (list->mutex); + } +} + + +/* + * nm_ap_list_append_ap + * + * Helper to append an AP to an ap list of a certain type. + * + */ +void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap) +{ + g_return_if_fail (list != NULL); + g_return_if_fail (ap != NULL); + + if (!nm_try_acquire_mutex (list->mutex, __FUNCTION__)) + { + NM_DEBUG_PRINT( "nm_ap_list_append_ap() could not acquire AP list mutex.\n" ); + return; + } + + nm_ap_ref (ap); + list->ap_list = g_slist_append (list->ap_list, ap); + + nm_unlock_mutex (list->mutex, __FUNCTION__); +} + + + +/* + * nm_ap_list_get_ap_by_essid + * + * Search through an access point list and return the access point + * that has a given essid. + * + */ +NMAccessPoint *nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network) { NMAccessPoint *found_ap = NULL; - GSList *element = list; + GSList *element; + g_return_val_if_fail (list != NULL, NULL); g_return_val_if_fail (network != NULL, NULL); - if (!list) - return (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" ); + return (NULL); + } + + /* Find the ap in the list */ + element = list->ap_list; while (element) { NMAccessPoint *ap = (NMAccessPoint *)(element->data); @@ -56,31 +177,7 @@ static NMAccessPoint * nm_ap_list_find_ap_in_list (GSList *list, const char *net element = g_slist_next (element); } - return (found_ap); -} - - -/* - * nm_ap_list_get_ap_by_essid - * - * Search through an allowed access point list and return the access point - * that has a given essid. - * - */ -NMAccessPoint *nm_ap_list_get_ap_by_essid (NMData *data, const char *network) -{ - NMAccessPoint *found_ap = NULL; - - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (network != NULL, NULL); - - if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__)) - { - found_ap = nm_ap_list_find_ap_in_list (data->allowed_ap_list, network); - nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__); - } - else - NM_DEBUG_PRINT( "nm_ap_list_get_ap_by_essid() could not acquire allowed access point mutex.\n" ); + nm_unlock_mutex (list->mutex, __FUNCTION__); return (found_ap); } @@ -89,29 +186,27 @@ NMAccessPoint *nm_ap_list_get_ap_by_essid (NMData *data, const char *network) /* * nm_ap_list_update_network * - * Given a network ID, + * Given a network ID, get its information from NetworkManagerInfo * */ -void nm_ap_list_update_network (NMData *data, const char *network) +void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NMData *data) { NMAccessPoint *ap = NULL; char *essid = NULL; - g_return_if_fail (data != NULL); + g_return_if_fail (list != NULL); g_return_if_fail (network != NULL); + g_return_if_fail (((list->type == NETWORK_TYPE_TRUSTED) || (list->type == NETWORK_TYPE_PREFERRED))); - /* Find access point in list */ - if (!(ap = nm_ap_list_get_ap_by_essid (data, network))) - { - ap = nm_ap_new (); - data->allowed_ap_list = g_slist_append (data->allowed_ap_list, ap); - } + /* Find access point in list, if not found create a new AP and add it to the list */ + if (!(ap = nm_ap_list_get_ap_by_essid (list, network))) + nm_ap_list_append_ap (list, (ap = nm_ap_new ())); /* Get the allowed access point's details from NetworkManagerInfo */ - if ((essid = nm_dbus_get_allowed_network_essid (data->dbus_connection, network))) + if ((essid = nm_dbus_get_network_essid (data->dbus_connection, list->type, network))) { - char *key = nm_dbus_get_allowed_network_key (data->dbus_connection, network); - guint priority = nm_dbus_get_allowed_network_priority (data->dbus_connection, network); + char *key = nm_dbus_get_network_key (data->dbus_connection, list->type, network); + guint priority = nm_dbus_get_network_priority (data->dbus_connection, list->type, network); nm_ap_set_essid (ap, essid); nm_ap_set_wep_key (ap, key); @@ -126,56 +221,30 @@ void nm_ap_list_update_network (NMData *data, const char *network) /* * nm_ap_list_populate * - * Populate the initial list of allowed access points + * Populate an initial list of allowed access points * */ -void nm_ap_list_populate (NMData *data) +void nm_ap_list_populate (NMAccessPointList *list, NMData *data) { char **networks; int num_networks; + g_return_if_fail (list != NULL); g_return_if_fail (data != NULL); + g_return_if_fail (((list->type == NETWORK_TYPE_TRUSTED) || (list->type == NETWORK_TYPE_PREFERRED))); - networks = nm_dbus_get_allowed_networks (data->dbus_connection, &num_networks); + networks = nm_dbus_get_networks (data->dbus_connection, list->type, &num_networks); if (networks && (num_networks > 0)) { int i; for (i = 0; i < num_networks; i++) { if (networks[i] && (strlen (networks[i]) > 0)) - nm_ap_list_update_network (data, networks[i]); + nm_ap_list_update_network (list, networks[i], data); } dbus_free_string_array (networks); } - else - fprintf( stderr, "nm_ap_list_populate(): networks 0x%X, num_networks %d\n", networks, num_networks); -} - - -/* - * nm_ap_list_element_free - * - * Frees each member of the allowed access point list before the list is - * disposed of. - * - */ -static void nm_ap_list_element_free (void *element, void *user_data) -{ - nm_ap_unref (element); -} - - -/* - * nm_ap_list_free - * - * Free all access points in an allowed access point list - * - */ -void nm_ap_list_free (GSList *ap_list) -{ - g_slist_foreach (ap_list, nm_ap_list_element_free, NULL); - g_slist_free (ap_list); } @@ -195,9 +264,9 @@ void nm_ap_list_free (GSList *ap_list) * may result in undesired behavior. * */ -void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new) +void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAccessPointList *new) { - GSList *element = old; + GSList *element = old->ap_list; g_return_if_fail (data != NULL); g_return_if_fail (dev != NULL); @@ -210,7 +279,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new) if (old_ap) { - if ((new_ap = nm_ap_list_find_ap_in_list (new, nm_ap_get_essid (old_ap)))) + if ((new_ap = nm_ap_list_get_ap_by_essid (new, nm_ap_get_essid (old_ap)))) { nm_ap_set_matched (old_ap, TRUE); nm_ap_set_matched (new_ap, TRUE); @@ -226,7 +295,7 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new) /* Iterate over the new list and compare to the old list. Items that aren't already * matched are by definition new networks. */ - element = new; + element = new->ap_list; while (element) { NMAccessPoint *new_ap = (NMAccessPoint *)(element->data); @@ -237,3 +306,76 @@ void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new) } } +gboolean nm_ap_list_lock (NMAccessPointList *list) +{ + g_return_val_if_fail (list != NULL, FALSE); + + return (nm_try_acquire_mutex (list->mutex, __FUNCTION__)); +} + + +void nm_ap_list_unlock (NMAccessPointList *list) +{ + g_return_if_fail (list != NULL); + + nm_unlock_mutex (list->mutex, __FUNCTION__); +} + + +NMAPListIter * nm_ap_list_iter_new (NMAccessPointList *list) +{ + NMAPListIter *iter; + + g_return_val_if_fail (list != NULL, NULL); + + if (!(iter = g_new0 (NMAPListIter, 1))) + return (NULL); + + if (!nm_ap_list_lock (list)) + { + g_free (iter); + return (NULL); + } + + iter->list = list; + iter->cur_pos = list->ap_list; + iter->valid = FALSE; + + return (iter); +} + + +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); + + return ((NMAccessPoint *)(iter->cur_pos->data)); +} + + +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); + else + { + iter->valid = TRUE; + iter->cur_pos = iter->list->ap_list; + } + + return (nm_ap_list_iter_get_ap (iter)); +} + + +void nm_ap_list_iter_free (NMAPListIter *iter) +{ + g_return_if_fail (iter != NULL); + + nm_ap_list_unlock (iter->list); + g_free (iter); +} diff --git a/src/NetworkManagerAPList.h b/src/NetworkManagerAPList.h index 735ac9d40..4aeb50d71 100644 --- a/src/NetworkManagerAPList.h +++ b/src/NetworkManagerAPList.h @@ -26,14 +26,38 @@ #include "NetworkManager.h" #include "NetworkManagerDevice.h" -NMAccessPoint *nm_ap_list_get_ap_by_essid (NMData *data, const char *network); +typedef enum +{ + NETWORK_TYPE_UNKNOWN = 0, + NETWORK_TYPE_TRUSTED, + NETWORK_TYPE_PREFERRED, + NETWORK_TYPE_INVALID, + NETWORK_TYPE_DEVICE +} NMNetworkType; -void nm_ap_list_update_network (NMData *data, const char *network); +typedef struct NMAccessPointList NMAccessPointList; +typedef struct NMAPListIter NMAPListIter; -void nm_ap_list_populate (NMData *data); +NMAccessPointList * nm_ap_list_new (NMNetworkType type); +void nm_ap_list_ref (NMAccessPointList *list); +void nm_ap_list_unref (NMAccessPointList *list); -void nm_ap_list_free (GSList *ap_list); +void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap); -void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new); +NMAccessPoint * nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network); + +void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NMData *data); + +void nm_ap_list_populate (NMAccessPointList *list, NMData *data); + +void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAccessPointList *new); + +gboolean nm_ap_list_lock (NMAccessPointList *list); +void nm_ap_list_unlock (NMAccessPointList *list); + +NMAPListIter * nm_ap_list_iter_new (NMAccessPointList *list); +NMAccessPoint * nm_ap_list_iter_get_ap (NMAPListIter *iter); +NMAccessPoint * nm_ap_list_iter_next (NMAPListIter *iter); +void nm_ap_list_iter_free (NMAPListIter *iter); #endif diff --git a/src/NetworkManagerDbus.c b/src/NetworkManagerDbus.c index 44f3777f8..2bfde3d1d 100644 --- a/src/NetworkManagerDbus.c +++ b/src/NetworkManagerDbus.c @@ -66,18 +66,14 @@ static DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const ch /* * nm_dbus_get_object_path_from_device * - * Copies the object path for a device object into a provided buffer + * Copies the object path for a device object. Caller must free returned string. * */ -static void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, unsigned int buf_len) +static unsigned char * nm_dbus_get_object_path_from_device (NMDevice *dev) { - g_return_if_fail (buf != NULL); - g_return_if_fail (buf_len > 0); - memset (buf, 0, buf_len); + g_return_val_if_fail (dev != NULL, NULL); - g_return_if_fail (dev != NULL); - - snprintf (buf, buf_len-1, "%s/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev)); + return (g_strdup_printf ("%s/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev))); } @@ -126,26 +122,6 @@ static NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char * } -/* - * nm_dbus_get_object_path_from_ap - * - * Copies the object path for a wireless network into a provided buffer - * - */ -static void nm_dbus_get_object_path_from_ap (NMDevice *dev, NMAccessPoint *ap, unsigned char *buf, unsigned int buf_len) -{ - g_return_if_fail (buf != NULL); - g_return_if_fail (buf_len > 0); - memset (buf, 0, buf_len); - - g_return_if_fail (dev != NULL); - g_return_if_fail (ap != NULL); - - /* FIXME: check to make sure the AP is actually in the device's ap_list */ - snprintf (buf, buf_len-1, "%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev), nm_ap_get_essid (ap)); -} - - /* * nm_dbus_get_ap_from_object_path * @@ -154,23 +130,30 @@ static void nm_dbus_get_object_path_from_ap (NMDevice *dev, NMAccessPoint *ap, u */ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevice *dev) { - NMAccessPoint *ap = NULL; - int i = 0; - char compare_path[100]; + NMAccessPoint *ap = NULL; + NMAccessPointList *ap_list; + NMAPListIter *iter; + char compare_path[100]; g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (dev != NULL, NULL); - while ((ap = nm_device_ap_list_get_ap_by_index (dev, i)) != NULL) + ap_list = nm_device_ap_list_get (dev); + if (!ap_list) + return (NULL); + + if (!(iter = nm_ap_list_iter_new (ap_list))) + return (NULL); + + while ((ap = nm_ap_list_iter_next (iter))) { snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev), nm_ap_get_essid (ap)); if (strncmp (path, compare_path, strlen (compare_path)) == 0) break; - ap = NULL; - i++; } - + + nm_ap_list_iter_free (iter); return (ap); } @@ -291,22 +274,24 @@ static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMess void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev) { DBusMessage *message; - unsigned char *object_path = g_new0 (unsigned char, 100); + unsigned char *dev_path; g_return_if_fail (connection != NULL); g_return_if_fail (dev != NULL); - g_return_if_fail (object_path != NULL); + + 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"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_device_no_longer_active(): Not enough memory for new dbus message!\n"); + g_free (dev_path); return; } - nm_dbus_get_object_path_from_device (dev, object_path, 100); - dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); + dbus_message_append_args (message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID); + g_free (dev_path); if (!dbus_connection_send (connection, message, NULL)) NM_DEBUG_PRINT ("nm_dbus_signal_device_no_longer_active(): Could not raise the DeviceNoLongerActive signal!\n"); @@ -324,21 +309,24 @@ void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevic void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev) { DBusMessage *message; - unsigned char *object_path = g_new0 (unsigned char, 100); + unsigned char *dev_path; g_return_if_fail (connection != NULL); g_return_if_fail (dev != NULL); + 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"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_device_now_active(): Not enough memory for new dbus message!\n"); + g_free (dev_path); return; } - nm_dbus_get_object_path_from_device (dev, object_path, 100); - dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); + dbus_message_append_args (message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID); + g_free (dev_path); if (!dbus_connection_send (connection, message, NULL)) NM_DEBUG_PRINT ("nm_dbus_signal_device_now_active(): Could not raise the DeviceNowActive signal!\n"); @@ -356,21 +344,24 @@ void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDevice *dev) { DBusMessage *message; - unsigned char *object_path = g_new0 (unsigned char, 100); + unsigned char *dev_path; g_return_if_fail (connection != NULL); g_return_if_fail (dev != NULL); + 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"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_device_ip4_address_change(): Not enough memory for new dbus message!\n"); + g_free (dev_path); return; } - nm_dbus_get_object_path_from_device (dev, object_path, 100); - dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); + dbus_message_append_args (message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID); + g_free (dev_path); if (!dbus_connection_send (connection, message, NULL)) NM_DEBUG_PRINT ("nm_dbus_signal_device_ip4_address_change(): Could not raise the IP4AddressChange signal!\n"); @@ -387,23 +378,38 @@ void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDev */ void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap) { - DBusMessage *message; - unsigned char *object_path = g_new0 (unsigned char, 100); + DBusMessage *message; + char *dev_path; + char *ap_path; g_return_if_fail (connection != NULL); g_return_if_fail (dev != NULL); g_return_if_fail (ap != NULL); + if (!(dev_path = nm_dbus_get_object_path_from_device (dev))) + return; + + if (!(ap_path = nm_device_get_path_for_ap (dev, ap))) + { + g_free (dev_path); + return; + } + message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "WirelessNetworkAppeared"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!\n"); + g_free (dev_path); + g_free (ap_path); return; } - nm_dbus_get_object_path_from_ap (dev, ap, object_path, 100); - dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); + dbus_message_append_args (message, + DBUS_TYPE_STRING, dev_path, + DBUS_TYPE_STRING, ap_path, + DBUS_TYPE_INVALID); + g_free (ap_path); + g_free (dev_path); if (!dbus_connection_send (connection, message, NULL)) NM_DEBUG_PRINT ("nnm_dbus_signal_wireless_network_appeared(): Could not raise the WirelessNetworkAppeared signal!\n"); @@ -421,22 +427,37 @@ void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDev void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap) { DBusMessage *message; - unsigned char *object_path = g_new0 (unsigned char, 100); + unsigned char *dev_path; + unsigned char *ap_path; g_return_if_fail (connection != NULL); g_return_if_fail (dev != NULL); g_return_if_fail (ap != NULL); + if (!(dev_path = nm_dbus_get_object_path_from_device (dev))) + return; + + if (!(ap_path = nm_device_get_path_for_ap (dev, ap))) + { + g_free (dev_path); + return; + } + message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "WirelessNetworkDisappeared"); if (!message) { NM_DEBUG_PRINT ("nm_dbus_signal_wireless_network_disappeared(): Not enough memory for new dbus message!\n"); + g_free (dev_path); + g_free (ap_path); return; } - nm_dbus_get_object_path_from_ap (dev, ap, object_path, 100); - dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); + dbus_message_append_args (message, + DBUS_TYPE_STRING, dev_path, + DBUS_TYPE_STRING, ap_path, + DBUS_TYPE_INVALID); + g_free (ap_path); + g_free (dev_path); if (!dbus_connection_send (connection, message, NULL)) NM_DEBUG_PRINT ("nnm_dbus_signal_wireless_network_disappeared(): Could not raise the WirelessNetworkDisappeared signal!\n"); @@ -573,12 +594,18 @@ static void nm_dbus_set_user_key_for_network (DBusConnection *connection, DBusMe if ((dev = nm_get_device_by_iface (data, device))) { /* If the user canceled, mark the ap as invalid */ - if (strncmp (passphrase, cancel_message, strlen (cancel_message))) + if (strncmp (passphrase, cancel_message, strlen (cancel_message)) == 0) { - NMAccessPoint *ap = nm_device_ap_list_get_ap_by_essid (dev, network); + NMAccessPoint *ap; - if (ap) - nm_ap_set_invalid (ap, TRUE); + if ((ap = nm_device_ap_list_get_ap_by_essid (dev, network))) + { + NMAccessPoint *invalid_ap = nm_ap_new_from_ap (ap); + nm_ap_list_append_ap (data->invalid_ap_list, invalid_ap); + + nm_device_pending_action_cancel (dev); + nm_device_update_best_ap (dev); + } } else nm_device_pending_action_set_user_key (dev, passphrase); @@ -621,14 +648,14 @@ void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection) /* - * nm_dbus_get_allowed_network_essid + * nm_dbus_get_network_essid * - * Get an allowed network's essid from NetworkManagerInfo + * Get a network's essid from NetworkManagerInfo * * NOTE: caller MUST free returned value * */ -char * nm_dbus_get_allowed_network_essid (DBusConnection *connection, const char *network) +char * nm_dbus_get_network_essid (DBusConnection *connection, NMNetworkType type, const char *network) { DBusMessage *message; DBusError error; @@ -637,24 +664,27 @@ char * nm_dbus_get_allowed_network_essid (DBusConnection *connection, const char g_return_val_if_fail (connection != NULL, NULL); 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, "getAllowedNetworkEssid"); + NM_DBUS_NMI_NAMESPACE, "getNetworkEssid"); if (!message) { - NM_DEBUG_PRINT ("nm_dbus_get_allowed_network_essid(): Couldn't allocate the dbus message\n"); + NM_DEBUG_PRINT ("nm_dbus_get_network_essid(): Couldn't allocate the dbus message\n"); return (NULL); } - dbus_message_append_args (message, DBUS_TYPE_STRING, network, DBUS_TYPE_INVALID); + dbus_message_append_args (message, DBUS_TYPE_STRING, network, + DBUS_TYPE_INT32, (int)type, + DBUS_TYPE_INVALID); /* Send message and get essid back from NetworkManagerInfo */ dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); if (dbus_error_is_set (&error)) - NM_DEBUG_PRINT_2 ("nm_dbus_get_allowed_network_essid(): error during getAllowedNetworkEssid. %s raised %s\n", error.name, error.message) + NM_DEBUG_PRINT_2 ("nm_dbus_get_network_essid(): %s raised %s\n", error.name, error.message) else if (!reply) - NM_DEBUG_PRINT ("nm_dbus_get_allowed_network_essid(): reply for getAllowedNetworkEssid was NULL.\n") + NM_DEBUG_PRINT ("nm_dbus_get_network_essid(): reply was NULL.\n") else { char *dbus_string; @@ -669,21 +699,21 @@ char * nm_dbus_get_allowed_network_essid (DBusConnection *connection, const char dbus_message_unref (message); if (reply) - dbus_message_unref (reply); + dbus_message_unref (reply); return (essid); } /* - * nm_dbus_get_allowed_network_key + * nm_dbus_get_network_key * - * Get an allowed network's key from NetworkManagerInfo. + * Get a network's key from NetworkManagerInfo. * * NOTE: caller MUST free returned value * */ -char * nm_dbus_get_allowed_network_key (DBusConnection *connection, const char *network) +char * nm_dbus_get_network_key (DBusConnection *connection, NMNetworkType type, const char *network) { DBusMessage *message; DBusError error; @@ -692,24 +722,27 @@ char * nm_dbus_get_allowed_network_key (DBusConnection *connection, const char * g_return_val_if_fail (connection != NULL, NULL); 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, "getAllowedNetworkKey"); + NM_DBUS_NMI_NAMESPACE, "getNetworkKey"); if (!message) { - NM_DEBUG_PRINT ("nm_dbus_get_allowed_network_key(): Couldn't allocate the dbus message\n"); + NM_DEBUG_PRINT ("nm_dbus_get_network_key(): Couldn't allocate the dbus message\n"); return (NULL); } - dbus_message_append_args (message, DBUS_TYPE_STRING, network, DBUS_TYPE_INVALID); + dbus_message_append_args (message, DBUS_TYPE_STRING, network, + DBUS_TYPE_INT32, (int)type, + DBUS_TYPE_INVALID); - /* Send message and get essid back from NetworkManagerInfo */ + /* Send message and get key back from NetworkManagerInfo */ dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); if (dbus_error_is_set (&error)) - NM_DEBUG_PRINT_2 ("nm_dbus_get_allowed_network_key(): error during getAllowedNetworkKey %s raised %s\n", error.name, error.message) + NM_DEBUG_PRINT_2 ("nm_dbus_get_network_key(): %s raised %s\n", error.name, error.message) else if (!reply) - NM_DEBUG_PRINT ("nm_dbus_get_allowed_network_key(): reply for getAllowedNetworkKey was NULL.\n") + NM_DEBUG_PRINT ("nm_dbus_get_network_key(): reply was NULL.\n") else { char *dbus_string; @@ -724,19 +757,19 @@ char * nm_dbus_get_allowed_network_key (DBusConnection *connection, const char * dbus_message_unref (message); if (reply) - dbus_message_unref (reply); + dbus_message_unref (reply); return (key); } /* - * nm_dbus_get_allowed_network_priority + * nm_dbus_get_network_priority * - * Get an allowed network's priority from NetworkManagerInfo + * Get a network's priority from NetworkManagerInfo * */ -guint nm_dbus_get_allowed_network_priority (DBusConnection *connection, const char *network) +guint nm_dbus_get_network_priority (DBusConnection *connection, NMNetworkType type, const char *network) { DBusMessage *message; DBusError error; @@ -745,24 +778,27 @@ guint nm_dbus_get_allowed_network_priority (DBusConnection *connection, const ch g_return_val_if_fail (connection != NULL, NM_AP_PRIORITY_WORST); 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, "getAllowedNetworkPriority"); + NM_DBUS_NMI_NAMESPACE, "getNetworkPriority"); if (!message) { - NM_DEBUG_PRINT ("nm_dbus_get_allowed_network_priority(): Couldn't allocate the dbus message\n"); + NM_DEBUG_PRINT ("nm_dbus_get_network_priority(): Couldn't allocate the dbus message\n"); return (NM_AP_PRIORITY_WORST); } - dbus_message_append_args (message, DBUS_TYPE_STRING, network, DBUS_TYPE_INVALID); + dbus_message_append_args (message, DBUS_TYPE_STRING, network, + DBUS_TYPE_INT32, (int)type, + DBUS_TYPE_INVALID); - /* Send message and get essid back from NetworkManagerInfo */ + /* Send message and get prio back from NetworkManagerInfo */ dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); if (dbus_error_is_set (&error)) - NM_DEBUG_PRINT_2 ("nm_dbus_get_allowed_network_priority(): error during getAllowedNetworkPriority. %s raised %s\n", error.name, error.message) + NM_DEBUG_PRINT_2 ("nm_dbus_get_network_priority(): %s raised %s\n", error.name, error.message) else if (!reply) - NM_DEBUG_PRINT ("nm_dbus_get_allowed_network_priority(): reply for getAllowedNetworkPriority was NULL.\n") + NM_DEBUG_PRINT ("nm_dbus_get_network_priority(): reply was NULL.\n") else { dbus_error_init (&error); @@ -772,21 +808,21 @@ guint nm_dbus_get_allowed_network_priority (DBusConnection *connection, const ch dbus_message_unref (message); if (reply) - dbus_message_unref (reply); + dbus_message_unref (reply); return (priority); } /* - * nm_dbus_get_allowed_networks + * nm_dbus_get_networks * - * Get all allowed networks from NetworkManagerInfo + * Get all networks of a specific type from NetworkManagerInfo * * NOTE: caller MUST free returned value using dbus_free_string_array() * */ -char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_networks) +char ** nm_dbus_get_networks (DBusConnection *connection, NMNetworkType type, int *num_networks) { DBusMessage *message; DBusError error; @@ -795,22 +831,25 @@ char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_netwo *num_networks = 0; 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, "getAllowedNetworks"); + NM_DBUS_NMI_NAMESPACE, "getNetworks"); if (!message) { - NM_DEBUG_PRINT ("nm_dbus_get_allowed_networks(): Couldn't allocate the dbus message\n"); + NM_DEBUG_PRINT ("nm_dbus_get_networks(): Couldn't allocate the dbus message\n"); return (NULL); } + dbus_message_append_args (message, DBUS_TYPE_INT32, (int)type, DBUS_TYPE_INVALID); + /* Send message and get essid back from NetworkManagerInfo */ dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error); if (dbus_error_is_set (&error)) - NM_DEBUG_PRINT_2 ("nm_dbus_get_allowed_networks(): error during getAllowedNetworks. %s raised %s\n", error.name, error.message) + NM_DEBUG_PRINT_2 ("nm_dbus_get_networks(): %s raised %s\n", error.name, error.message) else if (!reply) - NM_DEBUG_PRINT ("nm_dbus_get_allowed_networks(): reply for getAllowedNetworks was NULL.\n") + NM_DEBUG_PRINT ("nm_dbus_get_networks(): reply was NULL.\n") else { DBusMessageIter iter; @@ -821,7 +860,7 @@ char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_netwo dbus_message_unref (message); if (reply) - dbus_message_unref (reply); + dbus_message_unref (reply); return (networks); } @@ -835,8 +874,9 @@ char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_netwo */ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMessage *message, void *user_data) { - NMData *data = (NMData *)user_data; - const char *object_path; + NMData *data = (NMData *)user_data; + const char *object_path; + NMAccessPointList *list = NULL; g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); @@ -847,7 +887,12 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes if (!object_path || (strcmp (object_path, NM_DBUS_NMI_OBJECT_PATH) != 0)) return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); - if (dbus_message_is_signal (message, NM_DBUS_NMI_NAMESPACE, "AllowedNetworkUpdate")) + if (dbus_message_is_signal (message, NM_DBUS_NMI_NAMESPACE, "TrustedNetworkUpdate")) + list = data->trusted_ap_list; + else if (dbus_message_is_signal (message, NM_DBUS_NMI_NAMESPACE, "PreferredNetworkUpdate")) + list = data->preferred_ap_list; + + if (list) { char *network = NULL; DBusError error; @@ -856,7 +901,7 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED); - nm_ap_list_update_network (data, network); + nm_ap_list_update_network (list, network, data); dbus_free (network); } @@ -890,7 +935,7 @@ static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *con return (reply_message); } - if (!(reply_message = dbus_message_new_method_return (message))); + if (!(reply_message = dbus_message_new_method_return (message))) return (NULL); if (strcmp ("getName", request) == 0) @@ -909,6 +954,8 @@ static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *con dbus_message_append_args (reply_message, DBUS_TYPE_DOUBLE, nm_ap_get_freq (ap), DBUS_TYPE_INVALID); else if (strcmp ("getRate", request) == 0) dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_ap_get_rate (ap), DBUS_TYPE_INVALID); + else if (strcmp ("getEncrypted", request) == 0) + dbus_message_append_args (reply_message, DBUS_TYPE_BOOLEAN, nm_ap_get_encrypted (ap), DBUS_TYPE_INVALID); else { /* Must destroy the allocated message */ @@ -964,20 +1011,25 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection, if (strcmp ("getName", request) == 0) dbus_message_append_args (reply_message, DBUS_TYPE_STRING, nm_device_get_iface (dev), DBUS_TYPE_INVALID); else if (strcmp ("getType", request) == 0) - dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_device_get_iface_type (dev), DBUS_TYPE_INVALID); + dbus_message_append_args (reply_message, DBUS_TYPE_INT32, nm_device_get_type (dev), DBUS_TYPE_INVALID); else if (strcmp ("getIP4Address", request) == 0) dbus_message_append_args (reply_message, DBUS_TYPE_UINT32, nm_device_get_ip4_address (dev), DBUS_TYPE_INVALID); else if (strcmp ("getActiveNetwork", request) == 0) { NMAccessPoint *ap; + gboolean success = FALSE; + if ((ap = nm_device_ap_list_get_ap_by_essid (dev, nm_device_get_essid (dev)))) { - object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, - nm_device_get_iface (dev), nm_ap_get_essid (ap)); - dbus_message_append_args (reply_message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); - g_free (object_path); + if ((object_path = nm_device_get_path_for_ap (dev, ap))) + { + dbus_message_append_args (reply_message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID); + g_free (object_path); + success = TRUE; + } } - else + + if (!success) dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "", DBUS_TYPE_INVALID); } else if (strcmp ("getNetworks", request) == 0) @@ -985,19 +1037,31 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection, DBusMessageIter iter; DBusMessageIter iter_array; NMAccessPoint *ap = NULL; - int i = 0; + gboolean success = FALSE; + NMAccessPointList *ap_list; + NMAPListIter *list_iter; dbus_message_iter_init (reply_message, &iter); dbus_message_iter_append_array (&iter, &iter_array, DBUS_TYPE_STRING); - while ((ap = nm_device_ap_list_get_ap_by_index (dev, i)) != NULL) + + if ((ap_list = nm_device_ap_list_get (dev))) { - object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, - nm_device_get_iface (dev), nm_ap_get_essid (ap)); - dbus_message_iter_append_string (&iter_array, object_path); - g_free (object_path); - - i++; + if ((list_iter = nm_ap_list_iter_new (ap_list))) + { + while ((ap = nm_ap_list_iter_next (list_iter))) + { + object_path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, + nm_device_get_iface (dev), nm_ap_get_essid (ap)); + dbus_message_iter_append_string (&iter_array, object_path); + g_free (object_path); + success = TRUE; + } + nm_ap_list_iter_free (list_iter); + } } + + if (!success) + dbus_message_iter_append_string (&iter_array, ""); } else { @@ -1031,7 +1095,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); @@ -1085,6 +1149,8 @@ static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connec method = dbus_message_get_member (message); path = dbus_message_get_path (message); + /*NM_DEBUG_PRINT_2 ("nm_dbus_devices_message_handler() got method %s for path %s\n", method, path);*/ + if ((reply_message = nm_dbus_devices_handle_request (connection, data, message, path, method))) { dbus_connection_send (connection, reply_message, NULL); diff --git a/src/NetworkManagerDbus.h b/src/NetworkManagerDbus.h index 86c6b6b7e..9128a5c83 100644 --- a/src/NetworkManagerDbus.h +++ b/src/NetworkManagerDbus.h @@ -25,6 +25,7 @@ #include #include #include +#include "NetworkManagerAPList.h" #define NM_DBUS_NM_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager" @@ -51,12 +52,12 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice * void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection); -char * nm_dbus_get_allowed_network_essid (DBusConnection *connection, const char *network); +char * nm_dbus_get_network_essid (DBusConnection *connection, NMNetworkType type, const char *network); -char * nm_dbus_get_allowed_network_key (DBusConnection *connection, const char *network); +char * nm_dbus_get_network_key (DBusConnection *connection, NMNetworkType type, const char *network); -guint nm_dbus_get_allowed_network_priority (DBusConnection *connection, const char *network); +guint nm_dbus_get_network_priority (DBusConnection *connection, NMNetworkType type, const char *network); -char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_networks); +char ** nm_dbus_get_networks (DBusConnection *connection, NMNetworkType type, int *num_networks); #endif diff --git a/src/NetworkManagerDevice.c b/src/NetworkManagerDevice.c index 6bf2d1cb5..28f5c61ce 100644 --- a/src/NetworkManagerDevice.c +++ b/src/NetworkManagerDevice.c @@ -170,11 +170,10 @@ typedef enum NMPendingAction NMPendingAction; typedef struct NMDeviceWirelessOptions { - gchar *cur_essid; - gboolean supports_wireless_scan; - GMutex *ap_list_mutex; - GSList *ap_list; - NMAccessPoint *best_ap; + gchar *cur_essid; + gboolean supports_wireless_scan; + NMAccessPointList *ap_list; + NMAccessPoint *best_ap; } NMDeviceWirelessOptions; typedef struct NMDeviceWiredOptions @@ -206,14 +205,14 @@ struct NMDevice guint refcount; gchar *udi; gchar *iface; - NMIfaceType iface_type; + NMDeviceType type; gboolean link_active; NMPendingAction pending_action; NMPendingActionOptions pending_action_options; guint32 ip4_address; - NMData *app_data; /* FIXME: ipv6 address too */ - NMDeviceOptions dev_options; + NMData *app_data; + NMDeviceOptions options; }; @@ -239,19 +238,18 @@ NMDevice *nm_device_new (const char *iface, NMData *app_data) dev->refcount = 1; dev->app_data = app_data; dev->iface = g_strdup (iface); - dev->iface_type = nm_device_test_wireless_extensions (dev) ? - NM_IFACE_TYPE_WIRELESS_ETHERNET : NM_IFACE_TYPE_WIRED_ETHERNET; + dev->type = nm_device_test_wireless_extensions (dev) ? + DEVICE_TYPE_WIRELESS_ETHERNET : DEVICE_TYPE_WIRED_ETHERNET; - if (dev->iface_type == NM_IFACE_TYPE_WIRELESS_ETHERNET) + if (nm_device_is_wireless (dev)) { - dev->dev_options.wireless.supports_wireless_scan = nm_device_supports_wireless_scan (dev); - - dev->dev_options.wireless.ap_list_mutex = g_mutex_new(); - if (!dev->dev_options.wireless.ap_list_mutex) + if (!(dev->options.wireless.ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE))) { g_free (dev->iface); + g_free (dev); return (NULL); } + dev->options.wireless.supports_wireless_scan = nm_device_supports_wireless_scan (dev); } /* Have to bring the device up before checking link status. */ @@ -278,22 +276,22 @@ void nm_device_unref (NMDevice *dev) g_return_if_fail (dev != NULL); dev->refcount--; - if (dev->refcount == 0) + if (dev->refcount <= 0) { nm_device_ap_list_clear (dev); - dev->dev_options.wireless.ap_list = NULL; + dev->options.wireless.ap_list = NULL; g_free (dev->udi); g_free (dev->iface); - if (dev->iface_type == NM_IFACE_TYPE_WIRELESS_ETHERNET) + if (nm_device_is_wireless (dev)) { - g_free (dev->dev_options.wireless.cur_essid); - g_mutex_free (dev->dev_options.wireless.ap_list_mutex); - nm_ap_unref (dev->dev_options.wireless.best_ap); + nm_ap_list_unref (dev->options.wireless.ap_list); + nm_ap_unref (dev->options.wireless.best_ap); } dev->udi = NULL; dev->iface = NULL; + g_free (dev); } } @@ -332,27 +330,27 @@ char * nm_device_get_iface (NMDevice *dev) /* - * Get/set functions for iface_type + * Get/set functions for type */ -guint nm_device_get_iface_type (NMDevice *dev) +guint nm_device_get_type (NMDevice *dev) { - g_return_val_if_fail (dev != NULL, NM_IFACE_TYPE_DONT_KNOW); + g_return_val_if_fail (dev != NULL, DEVICE_TYPE_DONT_KNOW); - return (dev->iface_type); + return (dev->type); } gboolean nm_device_is_wireless (NMDevice *dev) { g_return_val_if_fail (dev != NULL, FALSE); - return (dev->iface_type == NM_IFACE_TYPE_WIRELESS_ETHERNET); + return (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET); } gboolean nm_device_is_wired (NMDevice *dev) { g_return_val_if_fail (dev != NULL, FALSE); - return (dev->iface_type == NM_IFACE_TYPE_WIRED_ETHERNET); + return (dev->type == DEVICE_TYPE_WIRED_ETHERNET); } @@ -384,7 +382,7 @@ gboolean nm_device_get_supports_wireless_scan (NMDevice *dev) if (!nm_device_is_wireless (dev)) return (FALSE); - return (dev->dev_options.wireless.supports_wireless_scan); + return (dev->options.wireless.supports_wireless_scan); } @@ -406,27 +404,39 @@ void nm_device_update_link_active (NMDevice *dev, gboolean check_mii) * seems to be whether the card has a valid access point MAC address. * Is there a better way? */ - switch (nm_device_get_iface_type (dev)) + switch (nm_device_get_type (dev)) { - case NM_IFACE_TYPE_WIRELESS_ETHERNET: + case DEVICE_TYPE_WIRELESS_ETHERNET: { - struct iwreq wrq; - int iwlib_socket; + struct iwreq wrq; + int iwlib_socket; + NMData *data = (NMData *)dev->app_data; - /* Update the "best" ap for the card */ - nm_device_do_wireless_scan (dev); - - iwlib_socket = iw_sockets_open (); - if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0) + /* Since non-active wireless cards are supposed to be powered off anyway, + * only scan for active/pending device and clear ap_list and best_ap for + * devices that aren't active/pending. + */ + if ((dev == data->active_device) || (dev == data->pending_device)) { - if (nm_ethernet_address_is_valid ((struct ether_addr *)(&(wrq.u.ap_addr.sa_data)))) - link_active = TRUE; + iwlib_socket = iw_sockets_open (); + if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0) + { + if (nm_ethernet_address_is_valid ((struct ether_addr *)(&(wrq.u.ap_addr.sa_data)))) + if (nm_device_get_best_ap (dev) && !nm_device_need_ap_switch (dev)) + link_active = TRUE; + } + close (iwlib_socket); + } + else + { + nm_ap_list_unref (dev->options.wireless.ap_list); + dev->options.wireless.ap_list = NULL; + nm_ap_unref (dev->options.wireless.best_ap); } - close (iwlib_socket); break; } - case NM_IFACE_TYPE_WIRED_ETHERNET: + case DEVICE_TYPE_WIRED_ETHERNET: { if (check_mii) link_active = mii_get_link (dev); @@ -478,9 +488,9 @@ char * nm_device_get_essid (NMDevice *dev) err = iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWESSID, &wreq); if (err >= 0) { - if (dev->dev_options.wireless.cur_essid) - g_free (dev->dev_options.wireless.cur_essid); - dev->dev_options.wireless.cur_essid = g_strdup (essid); + if (dev->options.wireless.cur_essid) + g_free (dev->options.wireless.cur_essid); + dev->options.wireless.cur_essid = g_strdup (essid); } else NM_DEBUG_PRINT_2 ("nm_device_get_essid(): error setting ESSID for device %s. errno = %d\n", nm_device_get_iface (dev), errno); @@ -488,7 +498,7 @@ char * nm_device_get_essid (NMDevice *dev) close (iwlib_socket); } - return (dev->dev_options.wireless.cur_essid); + return (dev->options.wireless.cur_essid); } @@ -802,7 +812,6 @@ gboolean nm_device_activate (NMDevice *dev) if (best_ap && nm_ap_get_essid (best_ap)) { nm_device_bring_down (dev); - nm_device_set_essid (dev, nm_ap_get_essid (best_ap)); /* Disable WEP */ @@ -815,11 +824,15 @@ gboolean nm_device_activate (NMDevice *dev) /* Bring the device up */ if (!nm_device_is_up (dev)); nm_device_bring_up (dev); + g_usleep (G_USEC_PER_SEC / 2); /* Pause to allow card to associate */ /* If we don't have a link, it probably means the access point has * encryption enabled and we don't have the right WEP key. */ nm_device_update_link_active (dev, FALSE); + best_ap = nm_device_get_best_ap (dev); + if (!best_ap) + return (FALSE); if ( !nm_device_get_link_active (dev) && !nm_device_need_ap_switch (dev) && nm_ap_get_encrypted (best_ap)) @@ -1077,13 +1090,9 @@ void nm_device_ap_list_add (NMDevice *dev, NMAccessPoint *ap) g_return_if_fail (ap != NULL); g_return_if_fail (nm_device_is_wireless (dev)); - if (nm_try_acquire_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__)) - { - nm_ap_ref (ap); - dev->dev_options.wireless.ap_list = g_slist_append (dev->dev_options.wireless.ap_list, ap); - - nm_unlock_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__); - } + nm_ap_list_append_ap (dev->options.wireless.ap_list, ap); + /* Transfer ownership of ap to the list by unrefing it here */ + nm_ap_unref (ap); } @@ -1098,55 +1107,11 @@ void nm_device_ap_list_clear (NMDevice *dev) g_return_if_fail (dev != NULL); g_return_if_fail (nm_device_is_wireless (dev)); - if (!dev->dev_options.wireless.ap_list) + if (!dev->options.wireless.ap_list) return; - if (nm_try_acquire_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__)) - { - nm_ap_list_free (dev->dev_options.wireless.ap_list); - dev->dev_options.wireless.ap_list = NULL; - - nm_unlock_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__); - } -} - - -/* - * nm_device_ap_list_get_ap_by_index - * - * Get the access point at a specified index in the list - * - */ -NMAccessPoint *nm_device_ap_list_get_ap_by_index (NMDevice *dev, int index) -{ - NMAccessPoint *ap = NULL; - - g_return_val_if_fail (dev != NULL, NULL); - g_return_val_if_fail (nm_device_is_wireless (dev), NULL); - - if (!dev->dev_options.wireless.ap_list) - return (NULL); - - if (nm_try_acquire_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__)) - { - GSList *element = dev->dev_options.wireless.ap_list; - int i = 0; - - while (element) - { - if (element->data && (index == i)) - { - ap = (NMAccessPoint *)(element->data); - break; - } - - i++; - element = g_slist_next (element); - } - nm_unlock_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__); - } - - return (ap); + nm_ap_list_unref (dev->options.wireless.ap_list); + dev->options.wireless.ap_list = NULL; } @@ -1164,24 +1129,10 @@ NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *ess g_return_val_if_fail (nm_device_is_wireless (dev), NULL); g_return_val_if_fail (essid != NULL, NULL); - if (!dev->dev_options.wireless.ap_list) + if (!dev->options.wireless.ap_list) return (NULL); - if (nm_try_acquire_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__)) - { - GSList *element = dev->dev_options.wireless.ap_list; - while (element) - { - NMAccessPoint *ap = (NMAccessPoint *)(element->data); - if (ap && nm_ap_get_essid (ap) && (strcmp (nm_ap_get_essid (ap), essid) == 0)) - { - ret_ap = ap; - break; - } - element = g_slist_next (element); - } - nm_unlock_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__); - } + ret_ap = nm_ap_list_get_ap_by_essid (dev->options.wireless.ap_list, essid); return (ret_ap); } @@ -1193,12 +1144,12 @@ NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *ess * Return a pointer to the AP list * */ -static const GSList *nm_device_ap_list_get (NMDevice *dev) +NMAccessPointList *nm_device_ap_list_get (NMDevice *dev) { g_return_val_if_fail (dev != NULL, NULL); g_return_val_if_fail (nm_device_is_wireless (dev), NULL); - return (dev->dev_options.wireless.ap_list); + return (dev->options.wireless.ap_list); } /* @@ -1210,22 +1161,63 @@ NMAccessPoint *nm_device_get_best_ap (NMDevice *dev) g_return_val_if_fail (dev != NULL, NULL); g_return_val_if_fail (nm_device_is_wireless (dev), NULL); - return (dev->dev_options.wireless.best_ap); + return (dev->options.wireless.best_ap); } void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap) { g_return_if_fail (dev != NULL); - g_return_if_fail (ap != NULL); g_return_if_fail (nm_device_is_wireless (dev)); - if (dev->dev_options.wireless.best_ap) - nm_ap_unref (dev->dev_options.wireless.best_ap); + if (dev->options.wireless.best_ap) + nm_ap_unref (dev->options.wireless.best_ap); - nm_ap_ref (ap); - dev->dev_options.wireless.best_ap = ap; + if (ap) + nm_ap_ref (ap); + + dev->options.wireless.best_ap = ap; } + +char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap) +{ + NMAccessPointList *list; + NMAPListIter *iter; + NMAccessPoint *list_ap; + char *path = NULL; + + g_return_val_if_fail (dev != NULL, NULL); + g_return_val_if_fail (ap != NULL, NULL); + + if (!(list = nm_device_ap_list_get (dev))) + return (NULL); + + if (!(iter = nm_ap_list_iter_new (list))) + return (NULL); + + while ((list_ap = nm_ap_list_iter_next (iter))) + { + if (list_ap == ap) + { + path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, + nm_device_get_iface (dev), nm_ap_get_essid (ap)); + break; + } + } + + nm_ap_list_iter_free (iter); + + return (path); +} + + +/* + * nm_device_need_ap_switch + * + * Returns TRUE if the essid of the card does not match the essid + * of the "best" access point it should be associating with. + * + */ gboolean nm_device_need_ap_switch (NMDevice *dev) { NMAccessPoint *ap; @@ -1241,6 +1233,42 @@ gboolean nm_device_need_ap_switch (NMDevice *dev) return (need_switch); } + +/* + * nm_device_update_best_ap + * + * Recalculate the "best" access point we should be associating with. + * + */ +void nm_device_update_best_ap (NMDevice *dev) +{ + int highest_priority = NM_AP_PRIORITY_WORST; + NMAccessPointList *ap_list; + NMAPListIter *iter; + NMAccessPoint *ap = NULL; + NMAccessPoint *best_ap = NULL; + + g_return_if_fail (dev != NULL); + g_return_if_fail (dev->app_data != NULL); + g_return_if_fail (nm_device_is_wireless (dev)); + + if (!(ap_list = nm_device_ap_list_get (dev))) + return; + + 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; + } + + nm_ap_list_iter_free (iter); + nm_device_set_best_ap (dev, best_ap); +} + + /* * nm_device_do_normal_scan * @@ -1249,14 +1277,17 @@ gboolean nm_device_need_ap_switch (NMDevice *dev) */ static void nm_device_do_normal_scan (NMDevice *dev) { - int iwlib_socket; + int iwlib_socket; + NMData *data; g_return_if_fail (dev != NULL); g_return_if_fail (dev->app_data != NULL); + data = (NMData *)dev->app_data; /* Device must be up before we can scan */ if (!nm_device_is_up (dev)) nm_device_bring_up (dev); + g_usleep (G_USEC_PER_SEC); iwlib_socket = iw_sockets_open (); if (iwlib_socket >= 0) @@ -1264,9 +1295,7 @@ static void nm_device_do_normal_scan (NMDevice *dev) wireless_scan_head scan_results = { NULL, 0 }; wireless_scan *tmp_ap; int err; - NMAccessPoint *highest_priority_ap = NULL; - int highest_priority = NM_AP_PRIORITY_WORST; - GSList *old_ap_list = nm_device_ap_list_get (dev); + NMAccessPointList *old_ap_list = nm_device_ap_list_get (dev); err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results); if ((err == -1) && (errno == ENODATA)) @@ -1285,7 +1314,7 @@ static void nm_device_do_normal_scan (NMDevice *dev) } /* Clear out the ap list for this device in preparation for any new ones */ - dev->dev_options.wireless.ap_list = NULL; + dev->options.wireless.ap_list = NULL; /* Iterate over scan results and pick a "most" preferred access point. */ tmp_ap = scan_results.result; @@ -1300,7 +1329,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 @@ -1314,41 +1343,26 @@ static void nm_device_do_normal_scan (NMDevice *dev) if (tmp_ap->b.has_freq) nm_ap_set_freq (nm_ap, tmp_ap->b.freq); - /* Add the AP to the device's AP list, no matter if its allowed or not */ + /* Add the AP to the device's AP list */ nm_device_ap_list_add (dev, nm_ap); - if (nm_wireless_is_most_prefered_ap (dev->app_data, nm_ap, &highest_priority)) - { - if (highest_priority_ap) - nm_ap_unref (highest_priority_ap); - - highest_priority_ap = nm_ap; - } - else - nm_ap_unref (nm_ap); + nm_ap_unref (nm_ap); } tmp_ap = tmp_ap->next; } nm_dispose_scan_results (scan_results.result); - - /* If we have the "most" preferred access point, and its different than the current - * access point, switch to it during the next cycle. - */ - if ( highest_priority_ap - && (!nm_device_get_best_ap (dev) || (nm_null_safe_strcmp (nm_device_get_essid (dev), nm_ap_get_essid (highest_priority_ap)) != 0))) - { - nm_device_set_best_ap (dev, highest_priority_ap); - nm_data_set_state_modified (dev->app_data, TRUE); - - nm_ap_unref (highest_priority_ap); - } close (iwlib_socket); /* Now do a diff of the old and new networks that we can see, and - * signal any changes over dbus. + * signal any changes over dbus, but only if we are the pending or active device. + * Users shouldn't get notification of new wireless networks if the device isn't the + * one that will provide their network connection. */ - nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev)); - nm_ap_list_free (old_ap_list); + 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); + + nm_device_update_best_ap (dev); } else NM_DEBUG_PRINT_1 ("nm_device_do_normal_scan() could not get a control socket for the wireless card %s.\n", nm_device_get_iface (dev) ); @@ -1367,78 +1381,67 @@ static void nm_device_do_normal_scan (NMDevice *dev) */ static void nm_device_do_pseudo_scan (NMDevice *dev) { + NMAccessPointList *list; + NMAPListIter *iter; + NMAccessPoint *ap; + g_return_if_fail (dev != NULL); g_return_if_fail (dev->app_data != NULL); nm_device_ref (dev); - /* Acquire allowed AP list mutex, silently fail if we cannot */ - if (nm_try_acquire_mutex (dev->app_data->allowed_ap_list_mutex, __FUNCTION__)) + if (!(list = nm_device_ap_list_get (dev))) + return; + + if (!(iter = nm_ap_list_iter_new (list))) + return; + + nm_device_set_essid (dev, ""); + while ((ap = nm_ap_list_iter_next (iter))) { - GSList *element = dev->app_data->allowed_ap_list; - - /* Turn off the essid so we can tell if its changed when - * we set it below. + gboolean valid = FALSE; + struct ether_addr save_ap_addr; + struct ether_addr cur_ap_addr; + + if (!nm_device_is_up (dev)); + nm_device_bring_up (dev); + + /* Save the MAC address */ + nm_device_get_ap_address (dev, &save_ap_addr); + + nm_device_set_essid (dev, nm_ap_get_essid (ap)); + if (nm_ap_get_wep_key (ap)) + nm_device_set_wep_key (dev, nm_ap_get_wep_key (ap)); + else + nm_device_set_wep_key (dev, NULL); + + /* Wait a bit for association */ + g_usleep (G_USEC_PER_SEC); + + /* Do we have a valid MAC address? */ + nm_device_get_ap_address (dev, &cur_ap_addr); + valid = nm_ethernet_address_is_valid (&cur_ap_addr); + + /* If the ap address we had before, and the ap address we + * have now, are the same, AP is invalid. Certain cards (orinoco) + * will let the essid change, but the the card won't actually de-associate + * from the previous access point if it can't associate with the new one + * (ie signal too weak, etc). */ - nm_device_set_essid (dev, ""); + if (valid && (memcmp (&save_ap_addr, &cur_ap_addr, sizeof (struct ether_addr)) == 0)) + valid = FALSE; - while (element) + if (valid) { - NMAccessPoint *ap = (NMAccessPoint *)(element->data); + NM_DEBUG_PRINT_2("%s: setting AP '%s' best\n", nm_device_get_iface (dev), nm_ap_get_essid (ap)); - /* Attempt to associate with this access point */ - if (ap) - { - gboolean valid = FALSE; - struct ether_addr save_ap_addr; - struct ether_addr cur_ap_addr; - - if (!nm_device_is_up (dev)); - nm_device_bring_up (dev); - - /* Save the MAC address */ - nm_device_get_ap_address (dev, &save_ap_addr); - - nm_device_set_essid (dev, nm_ap_get_essid (ap)); - if (nm_ap_get_wep_key (ap)) - nm_device_set_wep_key (dev, nm_ap_get_wep_key (ap)); - else - nm_device_set_wep_key (dev, NULL); - - /* Wait a bit for association */ - g_usleep (G_USEC_PER_SEC); - - /* Do we have a valid MAC address? */ - nm_device_get_ap_address (dev, &cur_ap_addr); - valid = nm_ethernet_address_is_valid (&cur_ap_addr); - - /* If the ap address we had before, and the ap address we - * have now, are the same, AP is invalid. Certain cards (orinoco) - * will let the essid change, but the the card won't actually de-associate - * from the previous access point if it can't associate with the new one - * (ie signal too weak, etc). - */ - if (valid && (memcmp (&save_ap_addr, &cur_ap_addr, sizeof (struct ether_addr)) == 0)) - valid = FALSE; - - /* FIXME - * We should probably lock access to data->desired_ap - */ - if (valid) - { - NM_DEBUG_PRINT_1 ("AP %s looks good, setting to desired\n", nm_ap_get_essid (ap)); - - nm_device_set_best_ap (dev, ap); - nm_data_set_state_modified (dev->app_data, TRUE); - break; - } - } - element = g_slist_next (element); + nm_device_set_best_ap (dev, ap); + nm_data_set_state_modified (dev->app_data, TRUE); + break; } - - nm_unlock_mutex (dev->app_data->allowed_ap_list_mutex, __FUNCTION__); } + nm_ap_list_iter_free (iter); nm_device_unref (dev); } @@ -1451,7 +1454,8 @@ static void nm_device_do_pseudo_scan (NMDevice *dev) */ void nm_device_do_wireless_scan (NMDevice *dev) { - g_return_if_fail (dev != NULL); + g_return_if_fail (dev != NULL); + g_return_if_fail (dev->app_data != NULL); g_return_if_fail (nm_device_is_wireless (dev)); if (nm_device_get_supports_wireless_scan (dev)) @@ -1466,7 +1470,8 @@ void nm_device_do_wireless_scan (NMDevice *dev) */ nm_device_get_ap_address (dev, &ap_addr); if ( !nm_ethernet_address_is_valid (&ap_addr) - || !nm_policy_essid_is_allowed (dev->app_data, nm_device_get_essid (dev)) + || !nm_ap_list_get_ap_by_essid (dev->app_data->trusted_ap_list, nm_device_get_essid (dev)) + || !nm_ap_list_get_ap_by_essid (dev->app_data->preferred_ap_list, nm_device_get_essid (dev)) || !nm_device_get_best_ap (dev)) { nm_device_do_pseudo_scan (dev); diff --git a/src/NetworkManagerDevice.h b/src/NetworkManagerDevice.h index f1c0f518e..d5cba30d4 100644 --- a/src/NetworkManagerDevice.h +++ b/src/NetworkManagerDevice.h @@ -22,21 +22,21 @@ #ifndef NETWORK_MANAGER_DEVICE_H #define NETWORK_MANAGER_DEVICE_H -#include "NetworkManager.h" #include +#include "NetworkManager.h" /* * Types of NetworkManager devices */ -enum NMIfaceType +enum NMDeviceType { - NM_IFACE_TYPE_DONT_KNOW = 0, - NM_IFACE_TYPE_WIRED_ETHERNET, - NM_IFACE_TYPE_WIRELESS_ETHERNET + DEVICE_TYPE_DONT_KNOW = 0, + DEVICE_TYPE_WIRED_ETHERNET, + DEVICE_TYPE_WIRELESS_ETHERNET }; typedef struct NMDevice NMDevice; -typedef enum NMIfaceType NMIfaceType; +typedef enum NMDeviceType NMDeviceType; NMDevice * nm_device_new (const char *iface, NMData *app_data); @@ -49,7 +49,7 @@ void nm_device_set_udi (NMDevice *dev, const char *udi); char * nm_device_get_iface (NMDevice *dev); -NMIfaceType nm_device_get_iface_type (NMDevice *dev); +NMDeviceType nm_device_get_type (NMDevice *dev); gboolean nm_device_is_wireless (NMDevice *dev); gboolean nm_device_is_wired (NMDevice *dev); /* There is no nm_device_set_iface_type() because that's determined when you set the device's iface */ @@ -70,10 +70,14 @@ void nm_device_get_ip6_address (NMDevice *dev); gboolean nm_device_get_supports_wireless_scan (NMDevice *dev); void nm_device_do_wireless_scan (NMDevice *dev); + NMAccessPoint *nm_device_get_best_ap (NMDevice *dev); void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap); +void nm_device_update_best_ap (NMDevice *dev); gboolean nm_device_need_ap_switch (NMDevice *dev); +char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap); + /* There is no function to get the WEP key since that's a slight security risk */ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key); @@ -91,7 +95,7 @@ void nm_device_pending_action_set_user_key (NMDevice *dev, unsigned char *key) void nm_device_ap_list_add (NMDevice *dev, NMAccessPoint *ap); void nm_device_ap_list_clear (NMDevice *dev); -NMAccessPoint *nm_device_ap_list_get_ap_by_index (NMDevice *dev, int index); +struct NMAccessPointList *nm_device_ap_list_get (NMDevice *dev); NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *essid); NMDevice * nm_get_device_by_udi (NMData *data, const char *udi); diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index b81f73a12..33a74a496 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -59,16 +59,16 @@ NMDevice * nm_policy_get_best_device (NMData *data) while (element) { NMDevice *dev = NULL; - guint iface_type; + guint dev_type; gboolean link_active; guint prio = 0; dev = (NMDevice *)(element->data); - iface_type = nm_device_get_iface_type (dev); + dev_type = nm_device_get_type (dev); link_active = nm_device_get_link_active (dev); - if (iface_type == NM_IFACE_TYPE_WIRED_ETHERNET) + if (dev_type == DEVICE_TYPE_WIRED_ETHERNET) { if (link_active) prio += 1; @@ -84,7 +84,7 @@ NMDevice * nm_policy_get_best_device (NMData *data) best_wired_prio = prio; } } - else if (iface_type == NM_IFACE_TYPE_WIRELESS_ETHERNET) + else if (dev_type == DEVICE_TYPE_WIRELESS_ETHERNET) { NMAccessPoint *best_ap = nm_device_get_best_ap (dev); @@ -239,7 +239,7 @@ gboolean nm_state_modification_monitor (gpointer user_data) return (TRUE); } - +#if 0 /* * nm_policy_allowed_ap_refresh_worker * @@ -383,42 +383,4 @@ void nm_policy_update_allowed_access_points (NMData *data) else NM_DEBUG_PRINT( "nm_policy_update_allowed_access_points() could not lock allowed ap list mutex\n" ); } - - -/* - * nm_policy_essid_is_allowed - * - * Searches for a specific essid in the list of allowed access points. - */ -gboolean nm_policy_essid_is_allowed (NMData *data, const unsigned char *essid) -{ - gboolean allowed = FALSE; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (essid != NULL, FALSE); - - if (strlen (essid) <= 0) - return FALSE; - - /* Acquire allowed AP list mutex, silently fail if we cannot */ - if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__)) - { - GSList *element = data->allowed_ap_list; - - while (element) - { - NMAccessPoint *ap = (NMAccessPoint *)(element->data); - - if (ap && (nm_null_safe_strcmp (nm_ap_get_essid (ap), essid) == 0)) - { - allowed = TRUE; - break; - } - element = g_slist_next (element); - } - - nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__); - } - - return (allowed); -} +#endif diff --git a/src/NetworkManagerPolicy.h b/src/NetworkManagerPolicy.h index bd99d0a99..84ecb1f66 100644 --- a/src/NetworkManagerPolicy.h +++ b/src/NetworkManagerPolicy.h @@ -29,8 +29,6 @@ gboolean nm_state_modification_monitor (gpointer user_data); void nm_policy_update_allowed_access_points (NMData *data); -gboolean nm_policy_essid_is_allowed (NMData *data, const unsigned char *essid); - gpointer nm_policy_allowed_ap_refresh_worker (gpointer user_data); #endif diff --git a/src/NetworkManagerWireless.c b/src/NetworkManagerWireless.c index 355ee597e..964c98d11 100644 --- a/src/NetworkManagerWireless.c +++ b/src/NetworkManagerWireless.c @@ -75,56 +75,45 @@ char *nm_wireless_128bit_key_from_passphrase (char *passphrase) /* - * nm_wireless_is_most_prefered_ap + * nm_wireless_is_ap_better * * For a given AP, filter it through the allowed list and return TRUE if its * both allowed _and_ has a better priority than highest_priority. * */ -gboolean nm_wireless_is_most_prefered_ap (NMData *data, NMAccessPoint *ap, int *highest_priority) +gboolean nm_wireless_is_ap_better (NMAccessPointList *list, NMAccessPoint *ap, int *highest_priority) { - GSList *element; - gboolean is_most_preferred = FALSE; + NMAPListIter *iter; + NMAccessPoint *list_ap; + gboolean better = FALSE; - g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (list != NULL, FALSE); g_return_val_if_fail (ap != NULL, FALSE); g_return_val_if_fail (highest_priority != NULL, FALSE); - /* If the AP is marked as invalid, of course its not prefered */ + /* If the AP is marked as invalid, of course its not preferred */ if (nm_ap_get_invalid (ap)) return (FALSE); - /* Attempt to acquire mutex for device list iteration. - * If the acquire fails, just ignore the scan completely. - */ - if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__)) + if (!(iter = nm_ap_list_iter_new (list))) + return (FALSE); + + while ((list_ap = nm_ap_list_iter_next (iter))) { - element = data->allowed_ap_list; - - while (element) + /* If the essid of the scanned ap matches one in our allowed list, and this AP is + * a higher priority than one we may possibly have already found. + */ + if ( (nm_null_safe_strcmp (nm_ap_get_essid (list_ap), nm_ap_get_essid (ap)) == 0) + && (nm_ap_get_priority (list_ap) < *highest_priority)) { - NMAccessPoint *allowed_ap = (NMAccessPoint *)(element->data); - - /* If the essid of the scanned ap matches one in our allowed list, and this AP is - * a higher priority than one we may possibly have already found. - */ - if ( allowed_ap - && (nm_null_safe_strcmp (nm_ap_get_essid (allowed_ap), nm_ap_get_essid (ap)) == 0) - && (nm_ap_get_priority (allowed_ap) < *highest_priority)) - { - *highest_priority = nm_ap_get_priority (allowed_ap); - is_most_preferred = TRUE; - break; - } - - element = g_slist_next (element); + *highest_priority = nm_ap_get_priority (list_ap); + better = TRUE; + break; } - nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__); } - else - NM_DEBUG_PRINT( "nm_wireless_is_most_prefered_ap() could not acquire allowed access point mutex.\n" ); - - return (is_most_preferred); + + nm_ap_list_iter_free (iter); + return (better); } @@ -148,7 +137,7 @@ gboolean nm_wireless_scan_monitor (gpointer user_data) */ if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) { - if (data->active_device && (nm_device_get_iface_type (data->active_device) == NM_IFACE_TYPE_WIRELESS_ETHERNET)) + if (data->active_device && nm_device_is_wireless (data->active_device)) nm_device_do_wireless_scan (data->active_device); nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); diff --git a/src/NetworkManagerWireless.h b/src/NetworkManagerWireless.h index 0ba11557c..73ff51d01 100644 --- a/src/NetworkManagerWireless.h +++ b/src/NetworkManagerWireless.h @@ -24,10 +24,11 @@ #include "NetworkManager.h" #include "NetworkManagerDevice.h" +#include "NetworkManagerAPList.h" char * nm_wireless_128bit_key_from_passphrase (char *passphrase); -gboolean nm_wireless_is_most_prefered_ap (NMData *data, NMAccessPoint *ap, int *highest_priority); +gboolean nm_wireless_is_ap_better (NMAccessPointList *list, NMAccessPoint *ap, int *highest_priority); gboolean nm_wireless_scan_monitor (gpointer user_data);