2004-08-02 Dan Williams <dcbw@redhat.com>
authorDan Williams <dcbw@redhat.com>
Mon, 2 Aug 2004 21:12:40 +0000 (21:12 +0000)
committerDan Williams <dcbw@redhat.com>
Mon, 2 Aug 2004 21:12:40 +0000 (21:12 +0000)
* TODO
- new task: proper logging support

* info-daemon/NetworkManagerInfo.c
- Correct spelling of "canceled"
- Correct casting of objects for g_signal_connect()

* info-daemon/NetworkManagerInfoDbus.c
- Add defines for NetworkManager namespace and object path, and use them
- Add filter function to trap new signals from NetworkManager:
WirelessNetworkAppeared, WirelessNetworkDisappeared

* info-daemon/passphrase.glade
- Change name of "ok" button to "Login to Network..."
- Mark invisible

* src/NetworkManager.c
- Code and debug message cleanups
- Rename "nm_add_current_devices"->"nm_add_initial_devices"
- (nm_add_initial_devices) Check returned string array of devices
and don't try to add devices if array is NULL
- (main) Initialize libhal a bit later, make code a bit clearer

* src/NetworkManagerAP.[ch]
- New accessor and data member "matched": used to speed up AP list
diffing
- New accessor and data member "enc_method": will be used during key
fallback to cache which passphrase->key conversion actually works
so we don't have to do it every time

* src/NetworkManagerAPList.[ch]
- (nm_ap_list_find_ap_in_list) New: find an AP by essid in an AP list
- (nm_ap_list_diff) New: given two lists of access points, find the differences
between them, and send WirelessNetworkAppeared/Disappeared signals over
dbus in response to those differences

* src/NetworkManagerDbus.[ch]
- (nm_dbus_get_object_path_from_ap) New: given a device and an access point,
make an object path for that access point (NOTE that we don't yet check to
make sure that access point is actually in the device's AP list yet)
- (nm_dbus_get_ap_from_object_path) Renamed from nm_dbus_get_network_from_object_path
- (nm_dbus_signal_wireless_network_appeared, nm_dbus_signal_wireless_network_disappeared)
New: signal appearance/disappearance of wireless networks
- (nm_dbus_set_user_key_for_network) Mark the network/ap as invalid if the user cancelled
key entry

* src/NetworkManagerDevice.[ch]
- (nm_device_ap_list_clear) Use nm_ap_list_free rather than doing it ourselves
- (nm_device_ap_list_get) New: return the AP list (static function)
- (nm_device_do_normal_scan) Destroy old AP list later, so that we can diff the
new one resulting from the scan with the old one

* src/NetworkManagerWireless.c
- (nm_wireless_is_most_prefered_ap) "invalid" access points cannot be "best" access points

* test/nminfotest.c
- #define object paths and namespaces and use the #defines rather than static strings
- Test out user-key functionality of NetworkManagerInfo too

git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@33 4912f4e0-d625-0410-9fb7-b9a5a253dbdc

16 files changed:
ChangeLog
TODO
info-daemon/NetworkManagerInfo.c
info-daemon/NetworkManagerInfoDbus.c
info-daemon/passphrase.glade
src/NetworkManager.c
src/NetworkManagerAP.c
src/NetworkManagerAP.h
src/NetworkManagerAPList.c
src/NetworkManagerAPList.h
src/NetworkManagerDbus.c
src/NetworkManagerDbus.h
src/NetworkManagerDevice.c
src/NetworkManagerDevice.h
src/NetworkManagerWireless.c
test/nminfotest.c

index 5e28427..abf621f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,64 @@
+2004-08-02  Dan Williams <dcbw@redhat.com>
+
+       * TODO
+               - new task: proper logging support
+
+       * info-daemon/NetworkManagerInfo.c
+               - Correct spelling of "canceled"
+               - Correct casting of objects for g_signal_connect()
+
+       * info-daemon/NetworkManagerInfoDbus.c
+               - Add defines for NetworkManager namespace and object path, and use them
+               - Add filter function to trap new signals from NetworkManager:
+                       WirelessNetworkAppeared, WirelessNetworkDisappeared
+
+       * info-daemon/passphrase.glade
+               - Change name of "ok" button to "Login to Network..."
+               - Mark invisible
+
+       * src/NetworkManager.c
+               - Code and debug message cleanups
+               - Rename "nm_add_current_devices"->"nm_add_initial_devices"
+               - (nm_add_initial_devices) Check returned string array of devices
+                       and don't try to add devices if array is NULL
+               - (main) Initialize libhal a bit later, make code a bit clearer
+
+       * src/NetworkManagerAP.[ch]
+               - New accessor and data member "matched": used to speed up AP list
+                       diffing
+               - New accessor and data member "enc_method": will be used during key
+                       fallback to cache which passphrase->key conversion actually works
+                       so we don't have to do it every time
+
+       * src/NetworkManagerAPList.[ch]
+               - (nm_ap_list_find_ap_in_list) New: find an AP by essid in an AP list
+               - (nm_ap_list_diff) New: given two lists of access points, find the differences
+                       between them, and send WirelessNetworkAppeared/Disappeared signals over
+                       dbus in response to those differences
+
+       * src/NetworkManagerDbus.[ch]
+               - (nm_dbus_get_object_path_from_ap) New: given a device and an access point,
+                       make an object path for that access point (NOTE that we don't yet check to
+                       make sure that access point is actually in the device's AP list yet)
+               - (nm_dbus_get_ap_from_object_path) Renamed from nm_dbus_get_network_from_object_path
+               - (nm_dbus_signal_wireless_network_appeared, nm_dbus_signal_wireless_network_disappeared)
+                       New: signal appearance/disappearance of wireless networks
+               - (nm_dbus_set_user_key_for_network) Mark the network/ap as invalid if the user cancelled
+                       key entry
+
+       * src/NetworkManagerDevice.[ch]
+               - (nm_device_ap_list_clear) Use nm_ap_list_free rather than doing it ourselves
+               - (nm_device_ap_list_get) New: return the AP list (static function)
+               - (nm_device_do_normal_scan) Destroy old AP list later, so that we can diff the
+                       new one resulting from the scan with the old one
+
+       * src/NetworkManagerWireless.c
+               - (nm_wireless_is_most_prefered_ap) "invalid" access points cannot be "best" access points
+
+       * test/nminfotest.c
+               - #define object paths and namespaces and use the #defines rather than static strings
+               - Test out user-key functionality of NetworkManagerInfo too
+
 2004-07-29  Dan Williams <dcbw@redhat.com>
 
        * info-daemon/NetworkManagerInfoDbus.c
diff --git a/TODO b/TODO
index 2a7cbd8..805fa45 100644 (file)
--- a/TODO
+++ b/TODO
@@ -28,6 +28,10 @@ Wireless link checking could be enhanced to check the signal strength of an acce
 There is currently no logic to gracefully recover from a crashed/killed dbus or hal.  While we don't depend as heavily on NetworkManagerInfo, we need to make sure that we can operate effectively when it's not there.  There are dbus functions for notification when services come up and go away which could be used here.  Remeber that when dbus dies, hal also dies at the moment.
 
 
+- Proper logging support
+
+We need to replace NM_DEBUG_PRINT with proper logging support to syslog or something.
+
 - Deal with blank ESSIDs
 
 Access points can be set not to broadcast their ESSIDs, which the client must know.  These appear as blank ESSIDs to cards doing wireless scanning, even though the rest of the AP's information is known (channel, rate, etc).  There has to be a way to deal with this as many companies do not broadcast ESSIDs for security measures.  Workarounds for this practice could include brute-forcing the Allowed Networks list if no suitable wireless network is found to begin with.  Obviously, there would be no way to detect if a WEP key was wrong, because unless the ESSID and WEP key are both correct, we cannot associate with the access point to see if we have a link.  Code exists to do this for wireless cards that do not support wireless scanning, and this code could be adapted.
index 4388991..cc188f8 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <glib.h>
 #include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
 #include <getopt.h>
 #include <errno.h>
@@ -132,7 +133,7 @@ static void cancel_button_clicked (GtkWidget *cancel_button, gpointer user_data)
                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, "***cancelled***");
+               nmi_dbus_return_user_key (info->connection, device, network, "***canceled***");
                nmi_clear_dialog (dialog, glade_xml_get_widget (info->xml, "passphrase_entry"));
        }
 }
@@ -216,10 +217,10 @@ static void nmi_interface_init (NMIAppInfo *info)
        gtk_widget_hide (dialog);
 
        ok_button = GTK_BUTTON (glade_xml_get_widget (info->xml, "login_button"));
-       g_signal_connect (GTK_OBJECT (ok_button), "clicked", GTK_SIGNAL_FUNC (ok_button_clicked), info);
+       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 (GTK_OBJECT (cancel_button), "clicked", GTK_SIGNAL_FUNC (cancel_button_clicked), info);
+       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);
index 836a6aa..8534e86 100644 (file)
@@ -31,6 +31,8 @@
 
 #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"
 
 /*
  * nmi_dbus_create_error_message
@@ -100,9 +102,9 @@ void nmi_dbus_return_user_key (DBusConnection *connection, const char *device,
        g_return_if_fail (network != NULL);
        g_return_if_fail (passphrase != NULL);
 
-       message = dbus_message_new_method_call ("org.freedesktop.NetworkManager",
-                                                                       "/org/freedesktop/NetworkManager",
-                                                                       "org.freedesktop.NetworkManager",
+       message = dbus_message_new_method_call (NM_DBUS_NM_NAMESPACE,
+                                                                       NM_DBUS_NM_OBJECT_PATH_PREFIX,
+                                                                       NM_DBUS_NM_NAMESPACE,
                                                                        "setKeyForNetwork");
        if (message == NULL)
        {
@@ -138,7 +140,7 @@ void nmi_dbus_signal_update_allowed_network (DBusConnection *connection, const c
        g_return_if_fail (connection != NULL);
        g_return_if_fail (network != NULL);
 
-       message = dbus_message_new_signal ("/org/freedesktop/NetworkManagerInfo", "org.freedesktop.NetworkManagerInfo",
+       message = dbus_message_new_signal (NMI_DBUS_NMI_OBJECT_PATH_PREFIX, NMI_DBUS_NMI_NAMESPACE,
                                                                        "AllowedNetworkUpdate");
        if (!message)
        {
@@ -428,6 +430,37 @@ 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;
+       DBusError                error;
+       gboolean                 handled = FALSE;
+       NMIAppInfo      *info = (NMIAppInfo *) user_data;
+       gboolean                 appeared = FALSE;
+       gboolean                 disappeared = FALSE;
+
+       g_return_val_if_fail (info != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+       if (dbus_message_is_signal (message, NM_DBUS_NM_NAMESPACE, "WirelessNetworkAppeared"))
+               appeared = TRUE;
+       else if (dbus_message_is_signal (message, NM_DBUS_NM_NAMESPACE, "WirelessNetworkDisappeared"))
+               disappeared = TRUE;
+
+       if (appeared || disappeared)
+       {
+               dbus_error_init (&error);
+               if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &ap_object_path, DBUS_TYPE_INVALID))
+               {
+                       dbus_free (ap_object_path);
+                       handled = TRUE;
+               }
+       }
+
+       return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+}
+
+
 /*
  * nmi_dbus_service_init
  *
@@ -453,5 +486,17 @@ int nmi_dbus_service_init (DBusConnection *dbus_connection, NMIAppInfo *info)
                return (-1);
        }
 
+       if (!dbus_connection_add_filter (dbus_connection, nmi_dbus_filter, info, NULL))
+               return (-1);
+
+       dbus_error_init (&dbus_error);
+       dbus_bus_add_match (dbus_connection,
+                               "type='signal',"
+                               "interface='"NM_DBUS_NM_NAMESPACE"',"
+                               "sender='"NM_DBUS_NM_NAMESPACE"',"
+                               "path='"NM_DBUS_NM_OBJECT_PATH_PREFIX"'", &dbus_error);
+       if (dbus_error_is_set (&dbus_error))
+               return (-1);
+
        return (0);
 }
index 6217635..273dd0c 100644 (file)
@@ -5,7 +5,6 @@
 
 <widget class="GtkDialog" id="passphrase_dialog">
   <property name="border_width">6</property>
-  <property name="visible">True</property>
   <property name="title" translatable="yes"></property>
   <property name="type">GTK_WINDOW_TOPLEVEL</property>
   <property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
@@ -47,8 +46,9 @@
            <widget class="GtkButton" id="login_button">
              <property name="visible">True</property>
              <property name="can_default">True</property>
+             <property name="has_default">True</property>
              <property name="can_focus">True</property>
-             <property name="label" translatable="yes">_Login to AP</property>
+             <property name="label" translatable="yes">_Login to Network</property>
              <property name="use_underline">True</property>
              <property name="relief">GTK_RELIEF_NORMAL</property>
              <property name="focus_on_click">True</property>
@@ -147,6 +147,7 @@ A passphrase or WEP key is required to access the wireless network '%s'.</proper
                    <widget class="GtkEntry" id="passphrase_entry">
                      <property name="visible">True</property>
                      <property name="can_focus">True</property>
+                     <property name="has_focus">True</property>
                      <property name="editable">True</property>
                      <property name="visibility">True</property>
                      <property name="max_length">0</property>
index fb0f54f..928f6b1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <glib.h>
 #include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
 #include <hal/libhal.h>
 #include <getopt.h>
@@ -36,6 +37,7 @@
 #include "NetworkManagerPolicy.h"
 #include "NetworkManagerWireless.h"
 #include "NetworkManagerDbus.h"
+#include "NetworkManagerAP.h"
 #include "NetworkManagerAPList.h"
 
 
@@ -72,16 +74,13 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
                gchar   *iface_name = hal_device_get_property_string (data->hal_ctx, udi, "net.interface");
 
                /* Make sure the device is not already in the device list */
-               dev = nm_get_device_by_iface (data, iface_name);
-               if (dev)
+               if ((dev = nm_get_device_by_iface (data, iface_name)))
                {
-                       NM_DEBUG_PRINT_1 ("nm_create_device_and_add_to_list() device %s was already in the list\n", iface_name);
                        hal_free_string (iface_name);
                        return (NULL);
                }
 
-               dev = nm_device_new (iface_name, data);
-               if (dev)
+               if ((dev = nm_device_new (iface_name, data)))
                {
 
                        /* Build up the device structure */
@@ -92,8 +91,8 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
                         */
                        if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
                        {
-                               NM_DEBUG_PRINT_3( "nm_create_device_and_add_to_list() adding udi='%s', iface='%s', iface_type=%s\n",
-                                       nm_device_get_udi (dev), nm_device_get_iface (dev), nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET ? "wireless" : "wired" );
+                               NM_DEBUG_PRINT_2( "nm_create_device_and_add_to_list(): adding device '%s' (%s)\n",
+                                       nm_device_get_iface (dev), nm_device_is_wireless (dev) ? "wireless" : "wired" );
 
                                data->dev_list = g_slist_append (data->dev_list, dev);
                                nm_device_deactivate (dev, TRUE);
@@ -113,7 +112,7 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
                        nm_device_unref (dev);
                        dev = NULL;
                }
-       } else NM_DEBUG_PRINT_1( "nm_create_device_and_add_to_list(): device %s does not have 'net.interface' property\n", udi );
+       }
 
        return (dev);
 }
@@ -257,12 +256,12 @@ static void nm_hal_device_property_modified (LibHalContext *ctx, const char *udi
 
 
 /*
- * nm_add_current_devices
+ * nm_add_initial_devices
  *
  * Add all devices that hal knows about right now (ie not hotplug devices)
  *
  */
-static void nm_add_current_devices (NMData *data)
+static void nm_add_initial_devices (NMData *data)
 {
        char            **net_devices;
        int               num_net_devices;
@@ -272,8 +271,11 @@ static void nm_add_current_devices (NMData *data)
        
        /* Grab a list of network devices */
        net_devices = hal_find_device_by_capability (data->hal_ctx, "net.ethernet", &num_net_devices);
-       for (i = 0; i < num_net_devices; i++)
-               nm_create_device_and_add_to_list (data, net_devices[i]);
+       if (net_devices)
+       {
+               for (i = 0; i < num_net_devices; i++)
+                       nm_create_device_and_add_to_list (data, net_devices[i]);
+       }
 
        hal_free_string_array (net_devices);
 }
@@ -527,7 +529,7 @@ int main( int argc, char *argv[] )
                                if (strcmp (opt, "help") == 0)
                                {
                                        nm_print_usage ();
-                                       return 0;
+                                       exit (EXIT_SUCCESS);
                                }
                                else if (strcmp (opt, "daemon") == 0)
                                {
@@ -538,14 +540,14 @@ int main( int argc, char *argv[] )
                                        else
                                        {
                                                nm_print_usage ();
-                                               return 1;
+                                               exit (EXIT_FAILURE);
                                        }
                                }
                                break;
 
                        default:
                                nm_print_usage ();
-                               return 1;
+                               exit (EXIT_FAILURE);
                                break;
                }
        }
@@ -557,7 +559,7 @@ int main( int argc, char *argv[] )
                if (chdir ("/") < 0)
                {
                        fprintf( stderr, "NetworkManager could not chdir to /.  errno=%d", errno);
-                       return 1;
+                       return (1);
                }
 
                child_pid = fork ();
@@ -572,7 +574,7 @@ int main( int argc, char *argv[] )
                                break;
 
                        default:
-                               exit (0);
+                               exit (EXIT_SUCCESS);
                                break;
                }
        }
@@ -581,72 +583,75 @@ int main( int argc, char *argv[] )
        if (!g_thread_supported ())
                g_thread_init (NULL);
 
-       /* Initialize libhal.  We get a connection to the hal daemon here. */
-       if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL)
-       {
-               NM_DEBUG_PRINT("hal_initialize() failed, exiting...  Make sure the hal daemon is running?\n");
-               exit (1);
-       }
-
        /* Initialize our instance data */
        nm_data = nm_data_new ();
        if (!nm_data)
        {
                NM_DEBUG_PRINT("nm_data_new() failed... Not enough memory?\n");
-               exit (1);
+               exit (EXIT_FAILURE);
        }       
 
-       nm_data->hal_ctx = ctx;
-       hal_ctx_set_user_data (nm_data->hal_ctx, nm_data);
-
        /* Create our dbus service */
        nm_data->dbus_connection = nm_dbus_init (nm_data);
-       if (nm_data->dbus_connection)
+       if (!nm_data->dbus_connection)
        {
-               /* Initialize our list of allowed access points */
-               nm_ap_list_populate (nm_data);
-
-               /* Grab network devices that are already present and add them to our list */
-               nm_add_current_devices (nm_data);
-
-               /* Create a watch function that monitors cards for link status (hal doesn't do
-                * this for wireless cards yet).
-                */
-               link_source = g_timeout_add (5000, nm_link_state_monitor, nm_data);
-
-               /* Another watch function which handles networking state changes and applies
-                * the correct policy on a change.
-                */
-               policy_source = g_timeout_add (3000, nm_state_modification_monitor, nm_data);
-
-               /* Yet another watch function which scans for access points and
-                * attempts to associate with approved ones in a users' list.
-                */
-               wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data);
-
-               /* Watch all devices that HAL knows about for state changes */
-               hal_device_property_watch_all (nm_data->hal_ctx);
-
-               /* We run dhclient when we need to, and we don't want any stray ones
-                * lying around upon launch.
-                */
-               system ("killall dhclient");
-
-               /* Wheeee!!! */
-               loop = g_main_loop_new (NULL, FALSE);
-               g_main_loop_run (loop);
-
-               /* Kill the watch functions */
-               g_source_remove (link_source);
-               g_source_remove (policy_source);
-               g_source_remove (wireless_scan_source);
+               hal_shutdown (nm_data->hal_ctx);
+               nm_data_free (nm_data);
+               exit (EXIT_FAILURE);
        }
 
+       /* Initialize libhal.  We get a connection to the hal daemon here. */
+       if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL)
+       {
+               NM_DEBUG_PRINT("hal_initialize() failed, exiting...  Make sure the hal daemon is running?\n");
+               exit (EXIT_FAILURE);
+       }
+       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);
+
+       /* Grab network devices that are already present and add them to our list */
+       nm_add_initial_devices (nm_data);
+
+       /* Create a watch function that monitors cards for link status (hal doesn't do
+        * this for wireless cards yet).
+        */
+       link_source = g_timeout_add (5000, nm_link_state_monitor, nm_data);
+
+       /* Another watch function which handles networking state changes and applies
+        * the correct policy on a change.
+        */
+       policy_source = g_timeout_add (3000, nm_state_modification_monitor, nm_data);
+
+       /* Yet another watch function which scans for access points and
+        * attempts to associate with approved ones in a users' list.
+        */
+       wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data);
+
+       /* Watch all devices that HAL knows about for state changes */
+       hal_device_property_watch_all (nm_data->hal_ctx);
+
+       /* We run dhclient when we need to, and we don't want any stray ones
+        * lying around upon launch.
+        */
+       system ("killall dhclient");
+
+       /* Wheeee!!! */
+       loop = g_main_loop_new (NULL, FALSE);
+       g_main_loop_run (loop);
+
+       /* Kill the watch functions */
+       g_source_remove (link_source);
+       g_source_remove (policy_source);
+       g_source_remove (wireless_scan_source);
+
        /* Cleanup */
        if (hal_shutdown (nm_data->hal_ctx) != 0)
                g_warning ("hal_shutdown() failed\n");
 
        nm_data_free (nm_data);
 
-       return 0;
+       return (0);
 }
index efc0ab0..4d7d9eb 100644 (file)
@@ -38,6 +38,8 @@ struct NMAccessPoint
        guint16                  rate;
        gboolean                         encrypted;
        gboolean                         invalid;
+       NMAPEncMethod            enc_method;
+       gboolean                         matched;       // used in ap list diffing
 
        /* Things from user prefs */
        gchar                   *wep_key;
@@ -323,3 +325,46 @@ void nm_ap_set_invalid (NMAccessPoint *ap, gboolean invalid)
 
        ap->invalid = invalid;
 }
+
+
+/*
+ * Get/set functions for "matched", which is used by
+ * the ap list diffing functions to speed up the diff
+ *
+ */
+gboolean nm_ap_get_matched (NMAccessPoint *ap)
+{
+       g_return_val_if_fail (ap != NULL, TRUE);
+
+       return (ap->matched);
+}
+
+void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched)
+{
+       g_return_if_fail (ap != NULL);
+
+       ap->matched = matched;
+}
+
+
+/*
+ * Get/set functions for encryption method
+ * Given some sort of passphrase/wep key from the user, we try it first
+ * as a 104-bit passphrase->key conversion, and fall back from there.  These
+ * functions are meant to cache which fallback succeeds so we don't have to
+ * do it every time.
+ *
+ */
+NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap)
+{
+       g_return_val_if_fail (ap != NULL, TRUE);
+
+       return (ap->enc_method);
+}
+
+void nm_ap_set_enc_method (NMAccessPoint *ap, NMAPEncMethod enc_method)
+{
+       g_return_if_fail (ap != NULL);
+
+       ap->enc_method = enc_method;
+}
index 0ebf110..beb09b8 100644 (file)
@@ -29,6 +29,14 @@ typedef struct NMAccessPoint NMAccessPoint;
 
 #define        NM_AP_PRIORITY_WORST            1000
 
+typedef enum NMAPEncMethod
+{
+       NM_AP_ENC_METHOD_NONE = 0,
+       NM_AP_ENC_METHOD_HEX_KEY,
+       NM_AP_ENC_METHOD_40_BIT_PASSPHRASE,
+       NM_AP_ENC_METHOD_104_BIT_PASSPHRASE
+} NMAPEncMethod;
+
 
 NMAccessPoint          *nm_ap_new                              (void);
 NMAccessPoint          *nm_ap_new_from_ap                      (NMAccessPoint *ap);
@@ -63,4 +71,10 @@ void                          nm_ap_set_rate                 (NMAccessPoint *ap, guint16 rate);
 gboolean                        nm_ap_get_invalid                      (NMAccessPoint *ap);
 void                            nm_ap_set_invalid                      (NMAccessPoint *ap, gboolean invalid);
 
+gboolean                        nm_ap_get_matched                      (NMAccessPoint *ap);
+void                            nm_ap_set_matched                      (NMAccessPoint *ap, gboolean matched);
+
+NMAPEncMethod           nm_ap_get_enc_method           (NMAccessPoint *ap);
+void                            nm_ap_set_enc_method           (NMAccessPoint *ap, NMAPEncMethod enc_method);
+
 #endif
index cd16558..5f5d29f 100644 (file)
 
 extern gboolean        debug;
 
+
+/*
+ * nm_ap_list_find_ap_in_list
+ *
+ * Helper routine to find an AP in a list.
+ *
+ */
+static NMAccessPoint * nm_ap_list_find_ap_in_list (GSList *list, const char *network)
+{
+       NMAccessPoint   *found_ap = NULL;
+       GSList          *element = list;
+
+       g_return_val_if_fail (network != NULL, NULL);
+       if (!list)
+               return (NULL);
+
+       while (element)
+       {
+               NMAccessPoint   *ap = (NMAccessPoint *)(element->data);
+
+               if (ap && (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0))
+               {
+                       found_ap = ap;
+                       break;
+               }
+               element = g_slist_next (element);
+       }
+
+       return (found_ap);
+}
+
+
 /*
  * nm_ap_list_get_ap_by_essid
  *
@@ -44,19 +76,7 @@ NMAccessPoint *nm_ap_list_get_ap_by_essid (NMData *data, const char *network)
 
        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), network) == 0))
-                       {
-                               found_ap = ap;
-                               break;
-                       }
-                       element = g_slist_next (element);
-               }
+               found_ap = nm_ap_list_find_ap_in_list (data->allowed_ap_list, network);
                nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__);
        }
        else
@@ -158,3 +178,62 @@ void nm_ap_list_free (GSList *ap_list)
        g_slist_free (ap_list);
 }
 
+
+/*
+ * nm_ap_list_diff
+ *
+ * Takes two ap lists and determines the differences.  For each ap that is present
+ * in the original list, but not in the new list, a WirelessNetworkDisappeared signal is emitted
+ * over DBus.  For each ap in the new list but not in the original, a WirelessNetworkAppeared
+ * signal is emitted.  For each ap that is the same between the lists, the "invalid" flag is copied
+ * over from the old ap to the new ap to preserve "invalid" ap status (ie, user cancelled entering
+ * a WEP key so we cannot connect to it anyway, so why try).
+ *
+ * NOTE: it is assumed that this function is called only ONCE for each list passed into it,
+ *       since the "matched" value on access points in the list are never cleared after the
+ *       ap is initially created.  Therefore, calling this function twice for any given ap list
+ *       may result in undesired behavior.
+ *
+ */
+void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new)
+{
+       GSList          *element = old;
+
+       g_return_if_fail (data != NULL);
+       g_return_if_fail (dev  != NULL);
+
+       /* Iterate over each item in the old list and find it in the new list */
+       while (element)
+       {
+               NMAccessPoint   *old_ap = (NMAccessPoint *)(element->data);
+               NMAccessPoint   *new_ap = NULL;
+
+               if (old_ap)
+               {
+                       if ((new_ap = nm_ap_list_find_ap_in_list (new, nm_ap_get_essid (old_ap))))
+                       {
+                               nm_ap_set_matched (old_ap, TRUE);
+                               nm_ap_set_matched (new_ap, TRUE);
+                               nm_ap_set_invalid (new_ap, nm_ap_get_invalid (old_ap));
+                               nm_ap_set_enc_method (new_ap, nm_ap_get_enc_method (old_ap));
+                       }
+                       else
+                               nm_dbus_signal_wireless_network_disappeared (data->dbus_connection, dev, old_ap);
+               }
+               element = g_slist_next (element);
+       }
+
+       /* Iterate over the new list and compare to the old list.  Items that aren't already
+        * matched are by definition new networks.
+        */
+       element = new;
+       while (element)
+       {
+               NMAccessPoint   *new_ap = (NMAccessPoint *)(element->data);
+
+               if (new_ap && !nm_ap_get_matched (new_ap))
+                       nm_dbus_signal_wireless_network_appeared (data->dbus_connection, dev, new_ap);
+               element = g_slist_next (element);
+       }
+}
+
index 0711bdd..735ac9d 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <glib.h>
 #include "NetworkManager.h"
+#include "NetworkManagerDevice.h"
 
 NMAccessPoint *nm_ap_list_get_ap_by_essid      (NMData *data, const char *network);
 
@@ -33,4 +34,6 @@ void                  nm_ap_list_populate                     (NMData *data);
 
 void                   nm_ap_list_free                 (GSList *ap_list);
 
+void                   nm_ap_list_diff                 (NMData *data, NMDevice *dev, GSList *old, GSList *new);
+
 #endif
index 916a109..44f3777 100644 (file)
@@ -20,6 +20,8 @@
  */
 
 #include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
 #include <stdarg.h>
 #include <iwlib.h>
@@ -67,7 +69,7 @@ static DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const ch
  * Copies the object path for a device object into a provided buffer
  *
  */
-void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, unsigned int buf_len)
+static void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, unsigned int buf_len)
 {
        g_return_if_fail (buf != NULL);
        g_return_if_fail (buf_len > 0);
@@ -85,7 +87,7 @@ void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, uns
  * Returns the device associated with a dbus object path
  *
  */
-NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char *path)
+static NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char *path)
 {
        NMDevice        *dev = NULL;
 
@@ -125,12 +127,32 @@ NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char *path)
 
 
 /*
- * nm_dbus_get_network_from_object_path
+ * 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
  *
  * Returns the network (ap) associated with a dbus object path
  *
  */
-NMAccessPoint *nm_dbus_get_network_from_object_path (const char *path, NMDevice *dev)
+static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevice *dev)
 {
        NMAccessPoint   *ap = NULL;
        int                      i = 0;
@@ -356,6 +378,73 @@ void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDev
        dbus_message_unref (message);
 }
 
+
+/*
+ * nm_dbus_signal_wireless_network_appeared
+ *
+ * Notifies the bus that a new wireless network has come into range
+ *
+ */
+void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap)
+{
+       DBusMessage             *message;
+       unsigned char           *object_path = g_new0 (unsigned char, 100);
+
+       g_return_if_fail (connection != NULL);
+       g_return_if_fail (dev != NULL);
+       g_return_if_fail (ap != NULL);
+
+       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");
+               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);
+
+       if (!dbus_connection_send (connection, message, NULL))
+               NM_DEBUG_PRINT ("nnm_dbus_signal_wireless_network_appeared(): Could not raise the WirelessNetworkAppeared signal!\n");
+
+       dbus_message_unref (message);
+}
+
+
+/*
+ * nm_dbus_signal_wireless_network_disappeared
+ *
+ * Notifies the bus that a new wireless network is no longer in range
+ *
+ */
+void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap)
+{
+       DBusMessage             *message;
+       unsigned char           *object_path = g_new0 (unsigned char, 100);
+
+       g_return_if_fail (connection != NULL);
+       g_return_if_fail (dev != NULL);
+       g_return_if_fail (ap != NULL);
+
+       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");
+               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);
+
+       if (!dbus_connection_send (connection, message, NULL))
+               NM_DEBUG_PRINT ("nnm_dbus_signal_wireless_network_disappeared(): Could not raise the WirelessNetworkDisappeared signal!\n");
+
+       dbus_message_unref (message);
+}
+
+
 #if 0
 /*
  * nm_dbus_get_user_key_for_network_callback
@@ -479,8 +568,21 @@ static void nm_dbus_set_user_key_for_network (DBusConnection *connection, DBusMe
                                                        DBUS_TYPE_INVALID))
        {
                NMDevice                *dev;
+               const char      *cancel_message = "***canceled***";
+
                if ((dev = nm_get_device_by_iface (data, device)))
-                       nm_device_pending_action_set_user_key (dev, passphrase);
+               {
+                       /* If the user canceled, mark the ap as invalid */
+                       if (strncmp (passphrase, cancel_message, strlen (cancel_message)))
+                       {
+                               NMAccessPoint   *ap = nm_device_ap_list_get_ap_by_essid (dev, network);
+
+                               if (ap)
+                                       nm_ap_set_invalid (ap, TRUE);
+                       }
+                       else
+                               nm_device_pending_action_set_user_key (dev, passphrase);
+               }
 
                char *key = nm_wireless_128bit_key_from_passphrase (passphrase);
                g_free (key);
@@ -741,6 +843,7 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes
        g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
 
        object_path = dbus_message_get_path (message);
+
        if (!object_path || (strcmp (object_path, NM_DBUS_NMI_OBJECT_PATH) != 0))
                return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
 
@@ -780,7 +883,7 @@ static DBusMessage *nm_dbus_devices_handle_networks_request (DBusConnection *con
        g_return_val_if_fail (request != NULL, NULL);
        g_return_val_if_fail (dev != NULL, NULL);
 
-       if (!(ap = nm_dbus_get_network_from_object_path (path, dev)))
+       if (!(ap = nm_dbus_get_ap_from_object_path (path, dev)))
        {
                reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "NetworkNotFound",
                                                "The requested network does not exist for this device.");
index 3cb4df1..86c6b6b 100644 (file)
 #define        NM_DBUS_NMI_NAMESPACE                           "org.freedesktop.NetworkManagerInfo"
 
 
-DBusConnection *       nm_dbus_init                                            (NMData *data);
+DBusConnection *nm_dbus_init                                           (NMData *data);
 
-void                           nm_dbus_signal_device_no_longer_active  (DBusConnection *connection, NMDevice *dev);
+void                   nm_dbus_signal_device_no_longer_active  (DBusConnection *connection, NMDevice *dev);
 
-void                           nm_dbus_signal_device_now_active                (DBusConnection *connection, NMDevice *dev);
+void                   nm_dbus_signal_device_now_active                (DBusConnection *connection, NMDevice *dev);
 
-void                           nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
+void                   nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
 
-void                           nm_dbus_get_user_key_for_network                (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, DBusPendingCall **pending);
+void                   nm_dbus_signal_wireless_network_appeared        (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);
 
-void                           nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection);
+void                   nm_dbus_signal_wireless_network_disappeared     (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);
 
-char *                 nm_dbus_get_allowed_network_essid               (DBusConnection *connection, const char *network);
+void                   nm_dbus_get_user_key_for_network                (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, DBusPendingCall **pending);
 
-char *                 nm_dbus_get_allowed_network_key         (DBusConnection *connection, const char *network);
+void                   nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection);
 
-guint                  nm_dbus_get_allowed_network_priority    (DBusConnection *connection, const char *network);
+char *         nm_dbus_get_allowed_network_essid               (DBusConnection *connection, const char *network);
 
-char **                        nm_dbus_get_allowed_networks                    (DBusConnection *connection, int *num_networks);
+char *         nm_dbus_get_allowed_network_key         (DBusConnection *connection, const char *network);
+
+guint          nm_dbus_get_allowed_network_priority    (DBusConnection *connection, const char *network);
+
+char **                nm_dbus_get_allowed_networks                    (DBusConnection *connection, int *num_networks);
 
 #endif
index 1ed1844..6bf2d1c 100644 (file)
@@ -33,7 +33,7 @@
 #include "NetworkManagerDbus.h"
 #include "NetworkManagerWireless.h"
 #include "NetworkManagerPolicy.h"
-
+#include "NetworkManagerAPList.h"
 
 extern gboolean        debug;
 
@@ -1095,8 +1095,6 @@ void      nm_device_ap_list_add (NMDevice *dev, NMAccessPoint *ap)
  */
 void   nm_device_ap_list_clear (NMDevice *dev)
 {
-       GSList  *element;
-
        g_return_if_fail (dev != NULL);
        g_return_if_fail (nm_device_is_wireless (dev));
 
@@ -1105,19 +1103,7 @@ void     nm_device_ap_list_clear (NMDevice *dev)
 
        if (nm_try_acquire_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__))
        {
-               element = dev->dev_options.wireless.ap_list;
-               while (element)
-               {
-                       if (element->data)
-                       {
-                               nm_ap_unref (element->data);
-                               element->data = NULL;
-                       }
-
-                       element = g_slist_next (element);
-               }
-
-               g_slist_free (dev->dev_options.wireless.ap_list);
+               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__);
@@ -1201,6 +1187,20 @@ NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *ess
 }
 
 
+/*
+ * nm_device_ap_list_get
+ *
+ * Return a pointer to the AP list
+ *
+ */
+static const GSList *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);
+}
+
 /*
  * Get/Set functions for "best" access point
  *
@@ -1266,9 +1266,7 @@ static void nm_device_do_normal_scan (NMDevice *dev)
                int                              err;
                NMAccessPoint           *highest_priority_ap = NULL;
                int                              highest_priority = NM_AP_PRIORITY_WORST;
-
-               /* Clear out the device's ap list */
-               nm_device_ap_list_clear (dev);
+               GSList                  *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))
@@ -1286,6 +1284,9 @@ 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;
+
                /* Iterate over scan results and pick a "most" preferred access point. */
                tmp_ap = scan_results.result;
                while (tmp_ap)
@@ -1342,6 +1343,12 @@ static void nm_device_do_normal_scan (NMDevice *dev)
                        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.
+                */
+               nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
+               nm_ap_list_free (old_ap_list);
        }
        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) );
index 944739f..f1c0f51 100644 (file)
@@ -30,7 +30,7 @@
  */
 enum NMIfaceType
 {
-       NM_IFACE_TYPE_DONT_KNOW,
+       NM_IFACE_TYPE_DONT_KNOW = 0,
        NM_IFACE_TYPE_WIRED_ETHERNET,
        NM_IFACE_TYPE_WIRELESS_ETHERNET
 };
index 94748da..355ee59 100644 (file)
@@ -90,6 +90,10 @@ gboolean nm_wireless_is_most_prefered_ap (NMData *data, NMAccessPoint *ap, int *
        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 (nm_ap_get_invalid (ap))
+               return (FALSE);
+
        /* Attempt to acquire mutex for device list iteration.
         * If the acquire fails, just ignore the scan completely.
         */
index 9dbf608..f5a6ad5 100644 (file)
 
 #include <glib.h>
 #include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
 #include <dbus/dbus-glib.h>
 #include <stdio.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"
+
 
 char * get_network_string_property (DBusConnection *connection, char *network, char *method)
 {
@@ -32,10 +38,10 @@ char * get_network_string_property (DBusConnection *connection, char *network, c
        DBusMessageIter iter;
        DBusError                error;
 
-       message = dbus_message_new_method_call ("org.freedesktop.NetworkManagerInfo",
-                                               "/org/freedesktop/NetworkManagerInfo",
-                                               "org.freedesktop.NetworkManagerInfo",
-                                               method);
+       message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE,
+                                                                       NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+                                                                       NMI_DBUS_NMI_NAMESPACE,
+                                                                       method);
        if (message == NULL)
        {
                fprintf (stderr, "Couldn't allocate the dbus message\n");
@@ -89,10 +95,10 @@ int get_network_prio (DBusConnection *connection, char *network)
        g_return_val_if_fail (connection != NULL, -1);
        g_return_val_if_fail (network != NULL, -1);
 
-       message = dbus_message_new_method_call ("org.freedesktop.NetworkManagerInfo",
-                                               "/org/freedesktop/NetworkManagerInfo",
-                                               "org.freedesktop.NetworkManagerInfo",
-                                               "getAllowedNetworkPriority");
+       message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE,
+                                                                       NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+                                                                       NMI_DBUS_NMI_NAMESPACE,
+                                                                       "getAllowedNetworkPriority");
        if (message == NULL)
        {
                fprintf (stderr, "Couldn't allocate the dbus message\n");
@@ -137,10 +143,10 @@ void get_allowed_networks (DBusConnection *connection)
        DBusMessageIter iter;
        DBusError                error;
 
-       message = dbus_message_new_method_call ("org.freedesktop.NetworkManagerInfo",
-                                               "/org/freedesktop/NetworkManagerInfo",
-                                               "org.freedesktop.NetworkManagerInfo",
-                                               "getAllowedNetworks");
+       message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE,
+                                                                       NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+                                                                       NMI_DBUS_NMI_NAMESPACE,
+                                                                       "getAllowedNetworks");
        if (message == NULL)
        {
                fprintf (stderr, "Couldn't allocate the dbus message\n");
@@ -191,13 +197,109 @@ void get_allowed_networks (DBusConnection *connection)
        dbus_free_string_array (networks);
 }
 
+void get_user_key_for_network (DBusConnection *connection)
+{
+       DBusMessage             *message;
+
+       g_return_if_fail (connection != NULL);
+
+       message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE, NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+                                               NMI_DBUS_NMI_NAMESPACE, "getKeyForNetwork");
+       if (message == NULL)
+       {
+               fprintf (stderr, "get_user_key_for_network(): Couldn't allocate the dbus message\n");
+               return;
+       }
+
+       dbus_message_append_args (message, DBUS_TYPE_STRING, "eth1",
+                                                               DBUS_TYPE_STRING, "wireless-ap",
+                                                               DBUS_TYPE_INVALID);
+
+       if (!dbus_connection_send (connection, message, NULL))
+               fprintf (stderr, "get_user_key_for_network(): could not send dbus message\n");
+
+       dbus_message_unref (message);
+}
+
+
+void set_user_key_for_network (DBusConnection *connection, DBusMessage *message, GMainLoop *loop)
+{
+       DBusError        error;
+       char            *device;
+       char            *network;
+       char            *passphrase;
+
+       g_return_if_fail (connection != NULL);
+       g_return_if_fail (message != NULL);
+
+       dbus_error_init (&error);
+       if (dbus_message_get_args (message, &error,
+                                                       DBUS_TYPE_STRING, &device,
+                                                       DBUS_TYPE_STRING, &network,
+                                                       DBUS_TYPE_STRING, &passphrase,
+                                                       DBUS_TYPE_INVALID))
+       {
+               fprintf( stderr, "Device was '%s'\nNetwork was '%s'\nPassphrase was '%s'\n", device, network, passphrase);
+
+               dbus_free (device);
+               dbus_free (network);
+               dbus_free (passphrase);
+
+               g_main_loop_quit (loop);
+       }
+}
+
+
+static DBusHandlerResult nm_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+       const char              *method;
+       const char              *path;
+       DBusMessage             *reply_message = NULL;
+       gboolean                         handled = TRUE;
+
+       g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+       g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+       method = dbus_message_get_member (message);
+       path = dbus_message_get_path (message);
+
+       fprintf (stderr, "nm_dbus_nm_message_handler() got method %s for path %s\n", method, path);
+
+       if (strcmp ("setKeyForNetwork", method) == 0)
+               set_user_key_for_network (connection, message, user_data);
+       else
+               handled = FALSE;
+
+       return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+}
+
+
+/*
+ * nm_dbus_nm_unregister_handler
+ *
+ * Nothing happens here.
+ *
+ */
+void nm_unregister_handler (DBusConnection *connection, void *user_data)
+{
+       /* do nothing */
+}
+
 
 int main( int argc, char *argv[] )
 {
-       DBusConnection *connection;
-       DBusError               error;
+       DBusConnection                  *connection;
+       DBusConnection                  *connection2;
+       DBusError                                error;
+       DBusObjectPathVTable     vtable = { &nm_unregister_handler, &nm_message_handler, NULL, NULL, NULL, NULL };
+       dbus_bool_t                      success = FALSE;
+       GMainLoop                               *loop = NULL;
+
+       loop = g_main_loop_new (NULL, FALSE);
 
        g_type_init ();
+       if (!g_thread_supported ())
+               g_thread_init (NULL);
 
        dbus_error_init (&error);
        connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
@@ -205,10 +307,29 @@ int main( int argc, char *argv[] )
        {
                fprintf (stderr, "Error connecting to system bus: %s\n", error.message);
                dbus_error_free (&error);
-               return 1;
+               exit (1);
+       }
+
+       dbus_connection_setup_with_g_main (connection, NULL);
+       dbus_error_init (&error);
+       dbus_bus_acquire_service (connection, NM_DBUS_NM_NAMESPACE, 0, &error);
+       if (dbus_error_is_set (&error))
+       {
+               fprintf (stderr, "Could not acquire its service.  dbus_bus_acquire_service() says: '%s'\n", error.message);
+               exit (1);
+       }
+
+       success = dbus_connection_register_object_path (connection, NM_DBUS_NM_OBJECT_PATH_PREFIX, &vtable, loop);
+       if (!success)
+       {
+               fprintf (stderr, "Could not register a handler for NetworkManager.  Not enough memory?\n");
+               exit (1);
        }
 
        get_allowed_networks (connection);
+       get_user_key_for_network (connection);
+
+       g_main_loop_run (loop);
 
        return 0;
 }