2007-02-05 Tambet Ingo <tambet@ximian.com>
authorTambet Ingo <tambet@ximian.com>
Mon, 5 Feb 2007 12:14:09 +0000 (12:14 +0000)
committerTambet Ingo <tambet@gmail.com>
Mon, 5 Feb 2007 12:14:09 +0000 (12:14 +0000)
Make NMDevice abstract class, remove almost all references to it's
subclasses (the last place gets removed with new policy manager). Add
NMDeviceInterface (which NMDevice implements) so that when we have
NMDevice exported over DBUS, there's a common NMDevice interface which
all instances have, plus there's a device specific interface for each
specific type.
Remove functions (nm_device_is_802_3_ethernet) and
(nm_device_is_802_11_wireless). There are already standard GObject macros
for type safe checks.
Use the updated supplican manager API.

* src/nm-device-interface.h:
* src/nm-device-interface.c:
* src/nm-call-store.h:
* src/nm-call-store.c: Implement.

* src/supplicant-manager/nm-supplicant-interface.c:
* src/supplicant-manager/nm-supplicant-interface.h:
* src/supplicant-manager/nm-supplicant-manager.c:
* src/supplicant-manager/nm-supplicant-manager.h:
- Remove all private data type references from public header files.
- Remove all references to other NM classes, this class is just a
  proxy between wpa_supplicant and NM so it doesn't have to know
  any internals.
- Convert to dbus-glib bindings.
- Type safe checks for public methods' arguments.
- Store pending DBUS call ids to NMCallStore.

* src/supplicant-manager/nm-supplicant-config.c:
- Store config values in a GHashTable instead of GSList.

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

34 files changed:
ChangeLog
include/NetworkManager.h
src/Makefile.am
src/NetworkManager.c
src/NetworkManagerAP.c
src/NetworkManagerAP.h
src/NetworkManagerAPList.c
src/NetworkManagerAPList.h
src/NetworkManagerPolicy.c
src/NetworkManagerUtils.c
src/autoip.c
src/backends/NetworkManagerGeneric.c
src/backends/NetworkManagerSuSE.c
src/nm-activation-request.c
src/nm-call-store.c [new file with mode: 0644]
src/nm-call-store.h [new file with mode: 0644]
src/nm-dbus-device.c
src/nm-dbus-nm.c
src/nm-device-802-11-wireless.c
src/nm-device-802-11-wireless.h
src/nm-device-802-3-ethernet.c
src/nm-device-802-3-ethernet.h
src/nm-device-interface.c [new file with mode: 0644]
src/nm-device-interface.h [new file with mode: 0644]
src/nm-device-private.h
src/nm-device.c
src/nm-device.h
src/supplicant-manager/nm-supplicant-config.c
src/supplicant-manager/nm-supplicant-config.h
src/supplicant-manager/nm-supplicant-interface.c
src/supplicant-manager/nm-supplicant-interface.h
src/supplicant-manager/nm-supplicant-manager.c
src/supplicant-manager/nm-supplicant-manager.h
src/supplicant-manager/nm-supplicant-marshal.list

index cfcf1d9..ec17b44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,36 @@
 2007-02-05  Tambet Ingo  <tambet@ximian.com>
 
+       Make NMDevice abstract class, remove almost all references to it's
+       subclasses (the last place gets removed with new policy manager). Add
+       NMDeviceInterface (which NMDevice implements) so that when we have
+       NMDevice exported over DBUS, there's a common NMDevice interface which
+       all instances have, plus there's a device specific interface for each
+       specific type.
+       Remove functions (nm_device_is_802_3_ethernet) and
+       (nm_device_is_802_11_wireless). There are already standard GObject macros
+       for type safe checks.
+       Use the updated supplican manager API.
+
+       * src/nm-device-interface.h: 
+       * src/nm-device-interface.c: 
+       * src/nm-call-store.h: 
+       * src/nm-call-store.c: Implement.
+
+       * src/supplicant-manager/nm-supplicant-interface.c:
+       * src/supplicant-manager/nm-supplicant-interface.h:
+       * src/supplicant-manager/nm-supplicant-manager.c:
+       * src/supplicant-manager/nm-supplicant-manager.h:
+               - Remove all private data type references from public header files.
+               - Remove all references to other NM classes, this class is just a
+                 proxy between wpa_supplicant and NM so it doesn't have to know
+                 any internals.
+               - Convert to dbus-glib bindings.
+               - Type safe checks for public methods' arguments.
+               - Store pending DBUS call ids to NMCallStore.
+
+       * src/supplicant-manager/nm-supplicant-config.c:
+               - Store config values in a GHashTable instead of GSList.
+
        * src/NetworkManagerMain.h: Remove all references to DHCP manager.
 
        * src/NetworkManager.c: Don't initialize the DHCP manager, it's a
index 2cc9d3f..e553764 100644 (file)
@@ -173,4 +173,22 @@ typedef enum NMActStage
        NM_ACT_STAGE_CANCELLED
 } NMActStage;
 
-#endif
+
+/*
+ * Device states. Will obsolete NMActStage soon.
+ */
+typedef enum
+{
+       NM_DEVICE_STATE_UNKNOWN = 0,
+       NM_DEVICE_STATE_DISCONNECTED,
+       NM_DEVICE_STATE_PREPARE,
+       NM_DEVICE_STATE_CONFIG,
+       NM_DEVICE_STATE_NEED_AUTH,
+       NM_DEVICE_STATE_IP_CONFIG,
+       NM_DEVICE_STATE_ACTIVATED,
+       NM_DEVICE_STATE_FAILED,
+       NM_DEVICE_STATE_CANCELLED,
+} NMDeviceState;
+
+
+#endif /* NETWORK_MANAGER_H */
index 53cb168..811470a 100644 (file)
@@ -12,8 +12,12 @@ INCLUDES = -I${top_srcdir}                   \
 sbin_PROGRAMS = NetworkManager
 
 NetworkManager_SOURCES =                               \
+               nm-call-store.c                         \
+               nm-call-store.h                         \
                nm-device.c                             \
                nm-device.h                             \
+               nm-device-interface.c                   \
+               nm-device-interface.h                   \
                nm-device-private.h                     \
                nm-device-802-3-ethernet.c      \
                nm-device-802-3-ethernet.h      \
index 04f224a..73fd6de 100644 (file)
@@ -104,6 +104,84 @@ static char *nm_get_device_interface_from_hal (LibHalContext *ctx, const char *u
 
 
 /*
+ * nm_device_test_wireless_extensions
+ *
+ * Test whether a given device is a wireless one or not.
+ *
+ */
+static NMDeviceType
+discover_device_type (LibHalContext *ctx, const char *udi)
+{
+       char * category = NULL;
+
+       if (libhal_device_property_exists (ctx, udi, "info.category", NULL))
+               category = libhal_device_get_property_string(ctx, udi, "info.category", NULL);
+       if (category && (!strcmp (category, "net.80211")))
+               return DEVICE_TYPE_802_11_WIRELESS;
+       else if (category && (!strcmp (category, "net.80203")))
+               return DEVICE_TYPE_802_3_ETHERNET;
+       return DEVICE_TYPE_UNKNOWN;
+}
+
+/*
+ * nm_get_device_driver_name
+ *
+ * Get the device's driver name from HAL.
+ *
+ */
+static char *
+nm_get_device_driver_name (LibHalContext *ctx, const char *udi)
+{
+       char    *       driver_name = NULL;
+       char *  physdev_udi = NULL;
+
+       g_return_val_if_fail (ctx != NULL, NULL);
+       g_return_val_if_fail (udi != NULL, NULL);
+
+       physdev_udi = libhal_device_get_property_string (ctx, udi, "net.physical_device", NULL);
+       if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL))
+       {
+               char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL);
+               driver_name = g_strdup (drv);
+               g_free (drv);
+       }
+       g_free (physdev_udi);
+
+       return driver_name;
+}
+
+
+static NMDevice *
+create_nm_device (LibHalContext *ctx,
+                                 const char *iface,
+                                 const char *udi)
+{
+       NMDevice *dev;
+       char *driver;
+       NMDeviceType type;
+
+       type = discover_device_type (ctx, udi);
+       driver = nm_get_device_driver_name (ctx, udi);
+
+       switch (type) {
+       case DEVICE_TYPE_802_11_WIRELESS:
+               dev = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, nm_data);
+               break;
+       case DEVICE_TYPE_802_3_ETHERNET:
+               dev = (NMDevice *) nm_device_802_3_ethernet_new (iface, udi, driver, FALSE, nm_data);
+               break;
+
+       default:
+               g_assert_not_reached ();
+       }
+
+       g_free (driver);
+
+       return dev;
+}
+
+
+/*
  * nm_create_device_and_add_to_list
  *
  * Create a new network device and add it to our device list.
@@ -136,16 +214,16 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons
        if ((dev = nm_get_device_by_iface (data, iface)))
                return (NULL);
 
-       if ((dev = nm_device_new (iface, udi, test_device, test_device_type, data))) {
-                       nm_info ("Now managing %s device '%s'.",
-                                nm_device_is_802_11_wireless (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)",
-                                nm_device_get_iface (dev));
+       if ((dev = create_nm_device (data->hal_ctx, iface, udi))) {
+               nm_info ("Now managing %s device '%s'.",
+                                NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)",
+                                nm_device_get_iface (dev));
 
-                       data->dev_list = g_slist_append (data->dev_list, dev);
-                       nm_device_deactivate (dev);
+               data->dev_list = g_slist_append (data->dev_list, dev);
+               nm_device_deactivate (dev);
 
-                       nm_policy_schedule_device_change_check (data);
-                       nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED);
+               nm_policy_schedule_device_change_check (data);
+               nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED);
        }
 
        return dev;
@@ -549,16 +627,15 @@ static void nm_data_free (NMData *data)
        if ((req = nm_vpn_manager_get_vpn_act_request (data->vpn_manager)))
                nm_vpn_manager_deactivate_vpn_connection (data->vpn_manager, nm_vpn_act_request_get_parent_dev (req));
 
-       if (data->netlink_monitor)
-       {
-               g_object_unref (G_OBJECT (data->netlink_monitor));
-               data->netlink_monitor = NULL;
-       }
-
        /* Stop and destroy all devices */
        g_slist_foreach (data->dev_list, (GFunc) device_stop_and_free, NULL);
        g_slist_free (data->dev_list);
 
+       if (data->netlink_monitor) {
+               g_object_unref (G_OBJECT (data->netlink_monitor));
+               data->netlink_monitor = NULL;
+       }
+
        nm_ap_list_unref (data->allowed_ap_list);
        nm_ap_list_unref (data->invalid_ap_list);
 
index 7ba16d9..6328b76 100644 (file)
@@ -133,6 +133,105 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
 }
 
 
+#define IEEE80211_CAP_ESS       0x0001
+#define IEEE80211_CAP_IBSS      0x0002
+#define IEEE80211_CAP_PRIVACY   0x0010
+
+
+static void
+foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
+{
+       GValue *variant = (GValue *) value;
+       NMAccessPoint *ap = (NMAccessPoint *) user_data;
+
+       if (G_VALUE_HOLDS_BOXED (variant)) {
+               GArray *array = g_value_get_boxed (variant);
+
+               if (!strcmp (key, "ssid")) {
+                       char ssid[33];
+                       int ssid_len = sizeof (ssid);
+
+                       if (array->len < sizeof (ssid))
+                               ssid_len = array->len;
+                       if (ssid_len <= 0)
+                               return;
+                       /* Stupid ieee80211 layer uses <hidden> */
+                       if (((ssid_len == 8) || (ssid_len == 9))
+                               && (memcmp (array->data, "<hidden>", 8) == 0))
+                               return;
+                       memset (&ssid, 0, sizeof (ssid));
+                       memcpy (&ssid, array->data, ssid_len);
+                       ssid[32] = '\0';
+                       nm_ap_set_essid (ap, ssid);
+               } else if (!strcmp (key, "bssid")) {
+                       struct ether_addr addr;
+
+                       if (array->len != ETH_ALEN)
+                               return;
+                       memset (&addr, 0, sizeof (struct ether_addr));
+                       memcpy (&addr, array->data, ETH_ALEN);
+                       nm_ap_set_address (ap, &addr);
+               } else if (!strcmp (key, "wpaie")) {
+                       guint8 * ie = (guint8 *) array->data;
+                       if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
+                               return;
+                       nm_ap_add_capabilities_from_ie (ap, ie, array->len);
+               } else if (!strcmp (key, "rsnie")) {
+                       guint8 * ie = (guint8 *) array->data;
+                       if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
+                               return;
+                       nm_ap_add_capabilities_from_ie (ap, ie, array->len);
+               }
+       } else if (G_VALUE_HOLDS_INT (variant)) {
+               gint32 int_val = g_value_get_int (variant);
+
+               if (!strcmp (key, "frequency")) {
+                       double freq = (double) int_val;
+                       nm_ap_set_freq (ap, freq);
+               } else if (!strcmp (key, "maxrate")) {
+                       nm_ap_set_rate (ap, int_val);
+               }
+       } else if (G_VALUE_HOLDS_UINT (variant)) {
+               guint32 val = g_value_get_uint (variant);
+
+               if (!strcmp (key, "capabilities")) {
+                       if (val & IEEE80211_CAP_ESS) {
+                               nm_ap_set_mode (ap, IW_MODE_INFRA);
+                       } else if (val & IEEE80211_CAP_IBSS) {
+                               nm_ap_set_mode (ap, IW_MODE_ADHOC);
+                       }
+
+                       if (val & IEEE80211_CAP_PRIVACY) {
+                               if (nm_ap_get_capabilities (ap) & NM_802_11_CAP_PROTO_NONE)
+                                       nm_ap_add_capabilities_for_wep (ap);
+                       }
+               }
+       }
+}
+
+
+NMAccessPoint *
+nm_ap_new_from_properties (GHashTable *properties)
+{
+       NMAccessPoint *ap;
+       GTimeVal cur_time;
+
+       g_return_val_if_fail (properties != NULL, NULL);
+
+       ap = nm_ap_new ();
+
+       g_hash_table_foreach (properties, foreach_property_cb, ap);
+
+       g_get_current_time (&cur_time);
+       nm_ap_set_last_seen (ap, &cur_time);
+
+       if (!nm_ap_get_essid (ap))
+               nm_ap_set_broadcast (ap, FALSE);
+
+       return ap;
+}
+
+
 /*
  * AP refcounting functions
  */
index dd2135e..7ba390d 100644 (file)
@@ -33,6 +33,7 @@ typedef struct NMAccessPoint NMAccessPoint;
 
 NMAccessPoint *        nm_ap_new                               (void);
 NMAccessPoint *        nm_ap_new_from_ap               (NMAccessPoint *ap);
+NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties);
 
 void                           nm_ap_unref                     (NMAccessPoint *ap);
 void                           nm_ap_ref                               (NMAccessPoint *ap);
index 1209f0b..c968fc4 100644 (file)
@@ -354,123 +354,6 @@ NMAccessPoint *nm_ap_list_get_ap_by_address (NMAccessPointList *list, const stru
 
 
 /*
- * nm_ap_list_merge_scanned_ap
- *
- * Given an AP list and an access point, merge the access point into the list.
- * If the AP is already in the list, merge just the /attributes/ together for that
- * AP, if its not already in the list then just add it.  This doesn't merge all
- * attributes, just ones that are likely to be new from the scan.
- *
- * Returns:    FALSE if the AP was not new and was merged
- *                     TRUE if the ap was completely new
- *
- */
-gboolean
-nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev,
-                             NMAccessPointList *list,
-                             NMAccessPoint *merge_ap)
-{
-       NMAccessPoint *                 list_ap = NULL;
-       gboolean                                        strength_changed = FALSE;
-       gboolean                                        new = FALSE;
-       const struct ether_addr *       merge_bssid;
-
-       g_return_val_if_fail (dev != NULL, FALSE);
-       g_return_val_if_fail (list != NULL, FALSE);
-       g_return_val_if_fail (merge_ap != NULL, FALSE);
-
-       merge_bssid = nm_ap_get_address (merge_ap);
-       if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid)))
-       {
-               /* First, we check for an address match.  If the merge AP has a valid
-                * BSSID and the same address as a list AP, then the merge AP and
-                * the list AP must be the same physical AP. The list AP properties must
-                * be from a previous scan so the time_last_seen's are not equal.  Update
-                * encryption, authentication method, strength, and the time_last_seen. */
-
-               const char *    devlist_essid = nm_ap_get_essid (list_ap);
-               const char *    merge_essid = nm_ap_get_essid (merge_ap);
-               const GTimeVal  *merge_ap_seen = nm_ap_get_last_seen (merge_ap);
-
-               /* Did the AP's name change? */
-               if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid))
-               {
-                       nm_dbus_signal_wireless_network_change (dev, list_ap,
-                                       NETWORK_STATUS_DISAPPEARED, -1);
-                       new = TRUE;
-               }
-
-               nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
-               if (nm_ap_get_strength (merge_ap) != nm_ap_get_strength (list_ap)) {
-                       nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap));
-                       strength_changed = TRUE;
-               }
-               nm_ap_set_last_seen (list_ap, merge_ap_seen);
-               nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap));
-
-               /* If the AP is noticed in a scan, it's automatically no longer
-                * artificial, since it clearly exists somewhere.
-                */
-               nm_ap_set_artificial (list_ap, FALSE);
-
-               /* Have to change AP's name _after_ dbus signal for old network name
-                * has gone out.
-                */
-               nm_ap_set_essid (list_ap, merge_essid);
-       }
-       else if ((list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap))))
-       {
-               /* Second, we check for an ESSID match. In this case,
-                * a list AP has the same non-NULL ESSID as the merge AP. Update the
-                * encryption and authentication method. Update the strength and address
-                * except when the time_last_seen of the list AP is the same as the
-                * time_last_seen of the merge AP and the strength of the list AP is greater
-                * than or equal to the strength of the merge AP. If the time_last_seen's are
-                * equal, the merge AP and the list AP come from the same scan.
-                * Update the time_last_seen. */
-
-               const GTimeVal *        merge_ap_seen = nm_ap_get_last_seen (merge_ap);
-               const GTimeVal *        list_ap_seen = nm_ap_get_last_seen (list_ap);
-               const int                       merge_ap_strength = nm_ap_get_strength (merge_ap);
-
-               nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
-
-               if (!((list_ap_seen->tv_sec == merge_ap_seen->tv_sec)
-                       && (nm_ap_get_strength (list_ap) >= merge_ap_strength)))
-               {
-                       nm_ap_set_strength (list_ap, merge_ap_strength);
-                       nm_ap_set_address (list_ap, nm_ap_get_address (merge_ap));
-               }
-               nm_ap_set_last_seen (list_ap, merge_ap_seen);
-               nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap));
-
-               /* If the AP is noticed in a scan, it's automatically no longer
-                * artificial, since it clearly exists somewhere.
-                */
-               nm_ap_set_artificial (list_ap, FALSE);
-       } else {
-               /* Add the merge AP to the list. */
-               nm_ap_list_append_ap (list, merge_ap);
-               list_ap = merge_ap;
-               new = TRUE;
-       }
-
-       if (list_ap && strength_changed && !new) {
-               const int new_strength = nm_ap_get_strength (list_ap);
-               nm_dbus_signal_wireless_network_change (dev, list_ap,
-                               NETWORK_STATUS_STRENGTH_CHANGED, new_strength);
-       }
-
-       if (list_ap && new) {
-               nm_dbus_signal_wireless_network_change (dev, list_ap,
-                               NETWORK_STATUS_APPEARED, -1);
-       }
-
-       return TRUE;
-}
-
-
-/*
  * nm_ap_list_copy_properties
  *
  * Update properties (like encryption keys or timestamps) in one access point list from
@@ -513,27 +396,23 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
  *
  */
 void
-nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev,
-                                      NMAccessPoint *ap,
+nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap,
                                       NMAccessPointList *search_list)
 {
-       NMAccessPoint * found_ap;
+       NMAccessPoint *found_ap;
+       const char *essid;
 
        g_return_if_fail (ap != NULL);
 
-       if (!search_list)
-               return;
-
        /* Ignore APs that already have an ESSID */
-       if (nm_ap_get_essid (ap))
+       if (!search_list || nm_ap_get_essid (ap))
                return;
 
        found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap));
-       if (!found_ap || !nm_ap_get_essid (found_ap))
-               return;
+       essid = found_ap ? nm_ap_get_essid (found_ap) : NULL; 
 
-       nm_ap_set_essid (ap, nm_ap_get_essid (found_ap));
-       nm_dbus_signal_wireless_network_change (dev, ap, NETWORK_STATUS_APPEARED, 0);
+       if (essid)
+               nm_ap_set_essid (ap, essid);
 }
 
 
@@ -546,8 +425,7 @@ nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev,
  *
  */
 void
-nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev,
-                                   NMAccessPointList *dest,
+nm_ap_list_copy_essids_by_address (NMAccessPointList *dest,
                                    NMAccessPointList *source)
 {
        NMAPListIter    *iter;
@@ -560,7 +438,7 @@ nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev,
                return;
 
        while ((dest_ap = nm_ap_list_iter_next (iter)))
-               nm_ap_list_copy_one_essid_by_address (dev, dest_ap, source);
+               nm_ap_list_copy_one_essid_by_address (dest_ap, source);
        nm_ap_list_iter_free (iter);
 }
 
index 972156b..d3b0e43 100644 (file)
@@ -26,8 +26,6 @@
 #include "NetworkManager.h"
 #include "NetworkManagerMain.h"
 #include "NetworkManagerAP.h"
-#include "nm-device.h"
-#include "nm-device-802-11-wireless.h"
 
 typedef struct NMAccessPointList       NMAccessPointList;
 typedef struct NMAPListIter            NMAPListIter;
@@ -48,10 +46,8 @@ NMAccessPoint *      nm_ap_list_get_ap_by_essid              (NMAccessPointList *list, const char
 NMAccessPoint *        nm_ap_list_get_ap_by_address            (NMAccessPointList *list, const struct ether_addr *addr);
 
 void                           nm_ap_list_copy_properties              (NMAccessPointList *dest, NMAccessPointList *source);
-void                           nm_ap_list_copy_essids_by_address       (NMDevice80211Wireless *dev, NMAccessPointList *dest, NMAccessPointList *source);
-void                           nm_ap_list_copy_one_essid_by_address    (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMAccessPointList *search_list);
-
-gboolean                       nm_ap_list_merge_scanned_ap             (NMDevice80211Wireless *dev, NMAccessPointList *list, NMAccessPoint *merge_ap);
+void                           nm_ap_list_copy_essids_by_address       (NMAccessPointList *dest, NMAccessPointList *source);
+void                           nm_ap_list_copy_one_essid_by_address    (NMAccessPoint *ap, NMAccessPointList *search_list);
 
 NMNetworkType          nm_ap_list_get_type                             (NMAccessPointList *list);
 
index 05299c3..5f8ac40 100644 (file)
@@ -63,7 +63,7 @@ static gboolean nm_policy_activation_finish (gpointer user_data)
        dev = nm_act_request_get_dev (req);
        g_assert (dev);
 
-    if (nm_device_is_802_11_wireless (dev))
+    if (NM_IS_DEVICE_802_11_WIRELESS (dev))
         ap = nm_act_request_get_ap (req);
 
        nm_device_activation_success_handler (dev, req);
@@ -126,7 +126,7 @@ static gboolean nm_policy_activation_failed (gpointer user_data)
 
        nm_device_activation_failure_handler (dev, req);
 
-    if (nm_device_is_802_11_wireless (dev))
+    if (NM_IS_DEVICE_802_11_WIRELESS (dev))
         ap = nm_act_request_get_ap (req);
 
        nm_info ("Activation (%s) failed.", nm_device_get_iface (dev));
@@ -204,7 +204,7 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint **
                if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED))
                        continue;
 
-               if (nm_device_is_802_3_ethernet (dev))
+               if (NM_IS_DEVICE_802_3_ETHERNET (dev))
                {
                        /* We never automatically choose devices that don't support carrier detect */
                        if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
@@ -222,7 +222,7 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint **
                                best_wired_prio = prio;
                        }
                }
-               else if (nm_device_is_802_11_wireless (dev) && data->wireless_enabled)
+               else if (NM_IS_DEVICE_802_11_WIRELESS (dev) && data->wireless_enabled)
                {
                        /* Don't automatically choose a device that doesn't support wireless scanning */
                        if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
@@ -309,8 +309,8 @@ nm_policy_device_change_check (gpointer user_data)
                /* Don't interrupt semi-supported devices either.  If the user chose one, they must
                 * explicitly choose to move to another device, we're not going to move for them.
                 */
-               if ((nm_device_is_802_3_ethernet (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT))
-                       || (nm_device_is_802_11_wireless (old_dev) && !(caps & NM_DEVICE_CAP_WIRELESS_SCAN))) {
+               if ((NM_IS_DEVICE_802_3_ETHERNET (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT))
+                       || (NM_IS_DEVICE_802_11_WIRELESS (old_dev) && !(caps & NM_DEVICE_CAP_WIRELESS_SCAN))) {
                        nm_info ("Old device '%s' was semi-supported and user chosen, won't change unless told to.",
                                nm_device_get_iface (old_dev));
                        goto out;
@@ -353,7 +353,7 @@ nm_policy_device_change_check (gpointer user_data)
                gboolean                old_user_requested = nm_act_request_get_user_requested (old_act_req);
                gboolean                old_has_link = nm_device_has_active_link (old_dev);
 
-               if (nm_device_is_802_3_ethernet (old_dev)) {
+               if (NM_IS_DEVICE_802_3_ETHERNET (old_dev)) {
                        /* Only switch if the old device was not user requested, and we are switching to
                         * a new device.  Note that new_dev will never be wireless since automatic device picking
                         * above will prefer a wired device to a wireless device.
@@ -365,9 +365,9 @@ nm_policy_device_change_check (gpointer user_data)
                                         nm_device_get_iface (old_dev));
                                do_switch = TRUE;
                        }
-               } else if (nm_device_is_802_11_wireless (old_dev)) {
+               } else if (NM_IS_DEVICE_802_11_WIRELESS (old_dev)) {
                        /* Only switch if the old device's wireless config is invalid */
-                       if (nm_device_is_802_11_wireless (new_dev)) {
+                       if (NM_IS_DEVICE_802_11_WIRELESS (new_dev)) {
                                NMAccessPoint *old_ap = nm_act_request_get_ap (old_act_req);
                                const char *    old_essid = nm_ap_get_essid (old_ap);
                                int                     old_mode = nm_ap_get_mode (old_ap);
@@ -398,7 +398,7 @@ nm_policy_device_change_check (gpointer user_data)
                                                 same_essid, old_has_link);
                                        do_switch = TRUE;
                                }
-                       } else if (nm_device_is_802_3_ethernet (new_dev)) {
+                       } else if (NM_IS_DEVICE_802_3_ETHERNET (new_dev)) {
                                /* Always prefer Ethernet over wireless, unless the user explicitly switched away. */
                                if (!old_user_requested)
                                        do_switch = TRUE;
@@ -406,7 +406,7 @@ nm_policy_device_change_check (gpointer user_data)
                }
        }
 
-       if (do_switch && (nm_device_is_802_3_ethernet (new_dev) || (nm_device_is_802_11_wireless (new_dev) && ap))) {
+       if (do_switch && (NM_IS_DEVICE_802_3_ETHERNET (new_dev) || (NM_IS_DEVICE_802_11_WIRELESS (new_dev) && ap))) {
                NMActRequest *  act_req = NULL;
 
                if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE))) {
@@ -582,7 +582,7 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data)
                NMDevice        *dev = (NMDevice *)(elt->data);
                NMDevice80211Wireless * wdev;
 
-               if (!nm_device_is_802_11_wireless (dev))
+               if (!NM_IS_DEVICE_802_11_WIRELESS (dev))
                        continue;
 
                wdev = NM_DEVICE_802_11_WIRELESS (dev);
@@ -592,8 +592,7 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data)
                         * broadcasting their ESSID, if we have their MAC address in our
                         * allowed list.
                         */
-                       nm_ap_list_copy_essids_by_address (wdev,
-                                                          nm_device_802_11_wireless_ap_list_get (wdev),
+                       nm_ap_list_copy_essids_by_address (nm_device_802_11_wireless_ap_list_get (wdev),
                                                           data->allowed_ap_list);
                        nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev),
                                                    data->allowed_ap_list);
index e3aabbb..3f7cfc1 100644 (file)
@@ -302,7 +302,7 @@ void nm_print_device_capabilities (NMDevice *dev)
                return;
        }
 
-       if (nm_device_is_802_3_ethernet (dev))
+       if (NM_IS_DEVICE_802_3_ETHERNET (dev))
        {
                if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
                {
@@ -312,7 +312,7 @@ void nm_print_device_capabilities (NMDevice *dev)
                        full_support = FALSE;
                }
        }
-       else if (nm_device_is_802_11_wireless (dev))
+       else if (NM_IS_DEVICE_802_11_WIRELESS (dev))
        {
                if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
                {
index 0a0a81a..3ae1b74 100644 (file)
@@ -224,9 +224,9 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip)
        memset (&saddr, 0, sizeof (saddr));
        strncpy (saddr.sa_data, nm_device_get_iface (dev), sizeof (saddr.sa_data));
 
-       if (nm_device_is_802_3_ethernet (dev))
+       if (NM_IS_DEVICE_802_3_ETHERNET (dev))
                nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &addr);
-       else if (nm_device_is_802_11_wireless (dev))
+       else if (NM_IS_DEVICE_802_11_WIRELESS (dev))
                nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &addr);
        else
                goto out;
index 1b683a7..a4201df 100644 (file)
@@ -272,9 +272,9 @@ void nm_generic_device_add_ip6_link_address (NMDevice *dev)
        struct ether_addr hw_addr;
        unsigned char eui[8];
 
-       if (nm_device_is_802_3_ethernet (dev))
+       if (NM_IS_DEVICE_802_3_ETHERNET (dev))
                nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr);
-       else if (nm_device_is_802_11_wireless (dev))
+       else if (NM_IS_DEVICE_802_11_WIRELESS (dev))
                nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr);
 
        memcpy (eui, &(hw_addr.ether_addr_octet), sizeof (hw_addr.ether_addr_octet));
index b7b3376..cae800a 100644 (file)
@@ -316,9 +316,9 @@ void *nm_system_device_get_system_config (NMDevice *dev, NMData *app_data)
        sys_data = g_malloc0 (sizeof (SuSEDeviceConfigData));
        sys_data->use_dhcp = TRUE;
 
-       if (nm_device_is_802_3_ethernet (dev))
+       if (NM_IS_DEVICE_802_3_ETHERNET (dev))
                nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr);
-       else if (nm_device_is_802_11_wireless (dev))
+       else if (NM_IS_DEVICE_802_11_WIRELESS (dev))
                nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr);
 
        sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x",
index 7d15924..ed702cd 100644 (file)
@@ -52,7 +52,7 @@ NMActRequest * nm_act_request_new (NMData *data, NMDevice *dev, NMAccessPoint *a
        g_return_val_if_fail (data != NULL, NULL);
        g_return_val_if_fail (dev != NULL, NULL);
 
-       if (nm_device_is_802_11_wireless (dev))
+       if (NM_IS_DEVICE_802_11_WIRELESS (dev))
                g_return_val_if_fail (ap != NULL, NULL);
 
        req = g_malloc0 (sizeof (NMActRequest));
diff --git a/src/nm-call-store.c b/src/nm-call-store.c
new file mode 100644 (file)
index 0000000..4019e83
--- /dev/null
@@ -0,0 +1,147 @@
+#include "nm-call-store.h"
+#include "nm-utils.h"
+
+NMCallStore *
+nm_call_store_new (void)
+{
+       return g_hash_table_new_full (NULL, NULL, NULL,
+                                                                 (GDestroyNotify) g_hash_table_destroy);
+}
+
+static void
+object_destroyed_cb (gpointer data, GObject *object)
+{
+       g_hash_table_remove ((NMCallStore *) data, object);
+}
+
+void
+nm_call_store_add (NMCallStore *store,
+                                  GObject *object,
+                                  gpointer *call_id)
+{
+       GHashTable *call_ids_hash;
+
+       g_return_if_fail (store != NULL);
+       g_return_if_fail (object != NULL);
+       g_return_if_fail (call_id != NULL);
+
+       call_ids_hash = g_hash_table_lookup (store, object);
+       if (!call_ids_hash) {
+               call_ids_hash = g_hash_table_new (NULL, NULL);
+               g_hash_table_insert (store, object, call_ids_hash);
+               g_object_weak_ref (object, object_destroyed_cb, store);
+       }
+
+       g_hash_table_insert (call_ids_hash, call_id, NULL);
+}
+
+void
+nm_call_store_remove (NMCallStore *store,
+                                         GObject *object,
+                                         gpointer call_id)
+{
+       GHashTable *call_ids_hash;
+
+       g_return_if_fail (store != NULL);
+       g_return_if_fail (object != NULL);
+       g_return_if_fail (call_id != NULL);
+
+       call_ids_hash = g_hash_table_lookup (store, object);
+       if (!call_ids_hash) {
+               nm_warning ("Trying to move a non-existant call id.");
+               return;
+       }
+
+       if (!g_hash_table_remove (call_ids_hash, call_id))
+               nm_warning ("Trying to move a non-existant call id.");
+
+       if (g_hash_table_size (call_ids_hash) == 0) {
+               g_hash_table_remove (store, object);
+               g_object_weak_unref (object, object_destroyed_cb, store);
+       }
+}
+
+typedef struct {
+       GObject *object;
+       gint count;
+       NMCallStoreFunc callback;
+       gpointer user_data;
+} StoreForeachInfo;
+
+static void
+call_callback (gpointer key, gpointer value, gpointer user_data)
+{
+       StoreForeachInfo *info = (StoreForeachInfo *) user_data;
+
+       if (info->count >= 0) {
+               if (info->callback (info->object, key, info->user_data))
+                       info->count++;
+               else
+                       info->count = -1;
+       }
+}
+
+static void
+call_all_callbacks (gpointer key, gpointer value, gpointer user_data)
+{
+       StoreForeachInfo *info = (StoreForeachInfo *) user_data;
+
+       info->object = G_OBJECT (key);
+       g_hash_table_foreach ((GHashTable *) value, call_callback, info);
+}
+
+int
+nm_call_store_foreach (NMCallStore *store,
+                                          GObject *object,
+                                          NMCallStoreFunc callback,
+                                          gpointer user_data)
+{
+       StoreForeachInfo info;
+
+       g_return_val_if_fail (store != NULL, -1);
+       g_return_val_if_fail (callback != NULL, -1);
+
+       info.object = object;
+       info.count = 0;
+       info.callback = callback;
+       info.user_data = user_data;
+
+       if (object) {
+               GHashTable *call_ids_hash;
+
+               call_ids_hash = g_hash_table_lookup (store, object);
+               if (!call_ids_hash) {
+                       nm_warning ("Object not in store");
+                       return -1;
+               }
+
+               g_hash_table_foreach (call_ids_hash, call_callback, &info);
+       } else {
+               g_hash_table_foreach (store, call_all_callbacks, &info);
+       }
+
+       return info.count;
+}
+
+static void
+remove_weakref (gpointer key, gpointer value, gpointer user_data)
+{
+       g_object_weak_unref (G_OBJECT (key), object_destroyed_cb, user_data);
+}
+
+void
+nm_call_store_clear (NMCallStore *store)
+{
+       g_return_if_fail (store);
+
+       g_hash_table_foreach (store, remove_weakref, store);
+       g_hash_table_remove_all (store);
+}
+
+void
+nm_call_store_destroy (NMCallStore *store)
+{
+       g_return_if_fail (store);
+
+       g_hash_table_destroy (store);
+}
diff --git a/src/nm-call-store.h b/src/nm-call-store.h
new file mode 100644 (file)
index 0000000..a4574cb
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef NM_CALLBACK_STORE_H
+#define NM_CALLBACK_STORE_H
+
+#include <glib-object.h>
+
+typedef GHashTable NMCallStore;
+
+typedef gboolean (*NMCallStoreFunc) (GObject *object, gpointer call_id, gpointer user_data);
+
+NMCallStore *nm_call_store_new     (void);
+void         nm_call_store_add     (NMCallStore *store,
+                                                                       GObject *object,
+                                                                       gpointer *call_id);
+
+void         nm_call_store_remove  (NMCallStore *store,
+                                                                       GObject *object,
+                                                                       gpointer call_id);
+
+int          nm_call_store_foreach (NMCallStore *store,
+                                                                       GObject *object,
+                                                                       NMCallStoreFunc callback,
+                                                                       gpointer user_data);
+
+void         nm_call_store_clear   (NMCallStore *store);
+void         nm_call_store_destroy (NMCallStore *store);
+
+#endif /* NM_CALLBACK_STORE_H */
index 896262e..98b93d1 100644 (file)
@@ -173,9 +173,9 @@ nm_dbus_device_get_hw_address (DBusConnection *connection,
        }
 
        memset (&addr, 0, sizeof (struct ether_addr));
-       if (nm_device_is_802_3_ethernet (data->dev)) {
+       if (NM_IS_DEVICE_802_3_ETHERNET (data->dev)) {
                nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (data->dev), &addr);
-       } else if (nm_device_is_802_11_wireless (data->dev)) {
+       } else if (NM_IS_DEVICE_802_11_WIRELESS (data->dev)) {
                nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (data->dev), &addr);
        }
        memset (char_addr, 0, 20);
@@ -199,7 +199,7 @@ nm_dbus_device_get_mode (DBusConnection *connection,
        g_return_val_if_fail (data != NULL, NULL);
        g_return_val_if_fail (data->dev != NULL, NULL);
 
-       if (!nm_device_is_802_11_wireless (data->dev)) {
+       if (!NM_IS_DEVICE_802_11_WIRELESS (data->dev)) {
                reply = new_invalid_device_type_error (message);
                goto out;
        }
@@ -260,7 +260,7 @@ nm_dbus_device_get_active_network (DBusConnection *connection,
 
        /* Only wireless devices have an active network */
        dev = data->dev;
-       if (!nm_device_is_802_11_wireless (dev))
+       if (!NM_IS_DEVICE_802_11_WIRELESS (dev))
        {
                reply = new_invalid_device_type_error (message);
                goto out;
@@ -318,7 +318,7 @@ nm_dbus_device_get_networks (DBusConnection *connection,
        g_return_val_if_fail (data != NULL, NULL);
        g_return_val_if_fail (data->dev != NULL, NULL);
 
-       if (!nm_device_is_802_11_wireless (data->dev)) {
+       if (!NM_IS_DEVICE_802_11_WIRELESS (data->dev)) {
                reply = new_invalid_device_type_error (message);
                goto out;
        }
@@ -516,9 +516,9 @@ nm_dbus_device_get_properties (DBusConnection *connection,
        act_stage = active ? nm_act_request_get_stage (nm_device_get_act_request (dev)) : NM_ACT_STAGE_UNKNOWN;
 
        memset (hw_addr_buf, 0, 20);
-       if (nm_device_is_802_3_ethernet (dev))
+       if (NM_IS_DEVICE_802_3_ETHERNET (dev))
                nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr);
-       else if (nm_device_is_802_11_wireless (dev))
+       else if (NM_IS_DEVICE_802_11_WIRELESS (dev))
                nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr);
        iw_ether_ntop (&hw_addr, hw_addr_buf);
 
@@ -543,7 +543,7 @@ nm_dbus_device_get_properties (DBusConnection *connection,
        primary_dns = nm_utils_inet_ip4_address_as_string (primary_dns_addr);
        secondary_dns = nm_utils_inet_ip4_address_as_string (secondary_dns_addr);
 
-       if (nm_device_is_802_11_wireless (dev)) {
+       if (NM_IS_DEVICE_802_11_WIRELESS (dev)) {
                NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev);
                NMActRequest *          req = nm_device_get_act_request (dev);
                NMAccessPoint * ap;
index 2b5dcb8..d75c6c4 100644 (file)
@@ -266,7 +266,7 @@ nm_dbus_nm_set_active_device (DBusConnection *connection,
                goto out;
        }
 
-       if (nm_device_is_802_11_wireless (dev)) {
+       if (NM_IS_DEVICE_802_11_WIRELESS (dev)) {
                NMAPSecurity *  security = NULL;
                char *                  essid = NULL;
                gboolean                        fallback = FALSE;
@@ -315,7 +315,7 @@ nm_dbus_nm_set_active_device (DBusConnection *connection,
                        g_object_unref (G_OBJECT (security));
 
                nm_info ("User Switch: %s / %s", dev_path, essid);
-       } else if (nm_device_is_802_3_ethernet (dev)) {
+       } else if (NM_IS_DEVICE_802_3_ETHERNET (dev)) {
                nm_info ("User Switch: %s", dev_path);
        }
 
@@ -382,7 +382,7 @@ nm_dbus_nm_create_wireless_network (DBusConnection *connection,
                goto out;
        }
 
-       if (   !nm_device_is_802_11_wireless (dev)
+       if (   !NM_IS_DEVICE_802_11_WIRELESS (dev)
                || !dbus_message_iter_next (&iter)
                || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) {
                reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
@@ -551,7 +551,7 @@ nm_dbus_nm_set_wireless_enabled (DBusConnection *connection,
                for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
                        NMDevice * dev = NM_DEVICE (elt->data);
 
-                       if (nm_device_is_802_11_wireless (dev)) {
+                       if (NM_IS_DEVICE_802_11_WIRELESS (dev)) {
                                nm_device_deactivate (dev);
                                nm_device_bring_down (dev);
                        }
index 19ecc77..7889c3c 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "nm-device.h"
 #include "nm-device-802-11-wireless.h"
+#include "nm-device-interface.h"
 #include "nm-device-private.h"
 #include "NetworkManagerAPList.h"
 #include "NetworkManagerDbus.h"
@@ -135,7 +136,7 @@ static void supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
                                                   NMDevice80211Wireless *self);
 
 static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
-                                            DBusMessage * message,
+                                            GHashTable *properties,
                                             NMDevice80211Wireless * self);
 
 static void supplicant_iface_scan_result_cb (NMSupplicantInterface * iface,
@@ -390,6 +391,8 @@ nm_device_802_11_wireless_init (NMDevice80211Wireless * self)
        self->priv->supplicant.iface_error_id = 0;
 
        memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr));
+
+       nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_11_WIRELESS);
 }
 
 static void
@@ -402,7 +405,8 @@ init_supplicant_interface (NMDevice80211Wireless * self)
        sup = (Supplicant *) &self->priv->supplicant;
 
        sup->iface = nm_supplicant_manager_get_iface (sup->mgr,
-                                                    NM_DEVICE (self));
+                                                                                                 nm_device_get_iface (NM_DEVICE (self)),
+                                                                                                 TRUE);
        if (sup->iface == NULL) {
                nm_warning ("Couldn't initialize supplicant interface for %s.",
                            nm_device_get_iface (NM_DEVICE (self)));
@@ -647,39 +651,6 @@ nm_device_802_11_wireless_get_address (NMDevice80211Wireless *self,
 }
 
 
-/*
- * nm_device_802_11_wireless_set_address
- *
- * Set a device's hardware address
- *
- */
-void
-nm_device_802_11_wireless_set_address (NMDevice80211Wireless *self)
-{
-       NMDevice *dev = NM_DEVICE (self);
-       struct ifreq req;
-       NMSock *sk;
-       int ret;
-
-       g_return_if_fail (self != NULL);
-
-       sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL);
-       if (!sk)
-               return;
-       memset (&req, 0, sizeof (struct ifreq));
-       strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1);
-
-       ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req);
-       if (ret)
-               goto out;
-
-       memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr));
-
-out:
-       nm_dev_sock_close (sk);
-}
-
-
 static gboolean
 link_to_specific_ap (NMDevice80211Wireless *self,
                      NMAccessPoint *ap,
@@ -1157,7 +1128,7 @@ nm_device_802_11_wireless_set_scan_interval (NMData *data,
                if (self && (NM_DEVICE (self) != d))
                        continue;
 
-               if (d && nm_device_is_802_11_wireless (d)) {
+               if (d && NM_IS_DEVICE_802_11_WIRELESS (d)) {
                        NM_DEVICE_802_11_WIRELESS (d)->priv->scan_interval = seconds;
                        if (self && (NM_DEVICE (self) == d))
                                found = TRUE;
@@ -2054,6 +2025,110 @@ ap_is_auth_required (NMAccessPoint *ap, gboolean *has_key)
  *
  */
 
+/*
+ * merge_scanned_ap
+ *
+ * Given an AP list and an access point, merge the access point into the list.
+ * If the AP is already in the list, merge just the /attributes/ together for that
+ * AP, if its not already in the list then just add it.  This doesn't merge all
+ * attributes, just ones that are likely to be new from the scan.
+ *
+ */
+static void
+merge_scanned_ap (NMDevice80211Wireless *dev,
+                                 NMAccessPoint *merge_ap)
+{
+       
+       NMAccessPointList *list;
+       NMAccessPoint *list_ap = NULL;
+       gboolean strength_changed = FALSE;
+       gboolean new = FALSE;
+       const struct ether_addr *merge_bssid;
+
+       list = nm_device_802_11_wireless_ap_list_get (dev);
+
+       merge_bssid = nm_ap_get_address (merge_ap);
+       if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid)))
+       {
+               /* First, we check for an address match.  If the merge AP has a valid
+                * BSSID and the same address as a list AP, then the merge AP and
+                * the list AP must be the same physical AP. The list AP properties must
+                * be from a previous scan so the time_last_seen's are not equal.  Update
+                * encryption, authentication method, strength, and the time_last_seen. */
+
+               const char *    devlist_essid = nm_ap_get_essid (list_ap);
+               const char *    merge_essid = nm_ap_get_essid (merge_ap);
+               const GTimeVal  *merge_ap_seen = nm_ap_get_last_seen (merge_ap);
+
+               /* Did the AP's name change? */
+               if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid)) {
+                       nm_dbus_signal_wireless_network_change (dev, list_ap,
+                                                                                                       NETWORK_STATUS_DISAPPEARED, -1);
+                       new = TRUE;
+               }
+
+               nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
+               if (nm_ap_get_strength (merge_ap) != nm_ap_get_strength (list_ap)) {
+                       nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap));
+                       strength_changed = TRUE;
+               }
+
+               nm_ap_set_last_seen (list_ap, merge_ap_seen);
+               nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap));
+
+               /* If the AP is noticed in a scan, it's automatically no longer
+                * artificial, since it clearly exists somewhere.
+                */
+               nm_ap_set_artificial (list_ap, FALSE);
+
+               /* Have to change AP's name _after_ dbus signal for old network name
+                * has gone out.
+                */
+               nm_ap_set_essid (list_ap, merge_essid);
+       }
+       else if ((list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap))))
+       {
+               /* Second, we check for an ESSID match. In this case,
+                * a list AP has the same non-NULL ESSID as the merge AP. Update the
+                * encryption and authentication method. Update the strength and address
+                * except when the time_last_seen of the list AP is the same as the
+                * time_last_seen of the merge AP and the strength of the list AP is greater
+                * than or equal to the strength of the merge AP. If the time_last_seen's are
+                * equal, the merge AP and the list AP come from the same scan.
+                * Update the time_last_seen. */
+
+               const GTimeVal *        merge_ap_seen = nm_ap_get_last_seen (merge_ap);
+               const GTimeVal *        list_ap_seen = nm_ap_get_last_seen (list_ap);
+               const int                       merge_ap_strength = nm_ap_get_strength (merge_ap);
+
+               nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
+
+               if (!((list_ap_seen->tv_sec == merge_ap_seen->tv_sec)
+                       && (nm_ap_get_strength (list_ap) >= merge_ap_strength)))
+               {
+                       nm_ap_set_strength (list_ap, merge_ap_strength);
+                       nm_ap_set_address (list_ap, nm_ap_get_address (merge_ap));
+               }
+               nm_ap_set_last_seen (list_ap, merge_ap_seen);
+               nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap));
+
+               /* If the AP is noticed in a scan, it's automatically no longer
+                * artificial, since it clearly exists somewhere.
+                */
+               nm_ap_set_artificial (list_ap, FALSE);
+       } else {
+               /* Add the merge AP to the list. */
+               nm_ap_list_append_ap (list, merge_ap);
+               list_ap = merge_ap;
+               new = TRUE;
+       }
+
+       if (list_ap && new) {
+               nm_dbus_signal_wireless_network_change (dev, list_ap,
+                                                                                               NETWORK_STATUS_APPEARED, -1);
+       }
+}
+
 static void
 cull_scan_list (NMDevice80211Wireless * self)
 {
@@ -2121,28 +2196,6 @@ out:
        nm_policy_schedule_device_change_check (app_data);
 }
 
-#define HANDLE_DICT_ITEM(in_key, in_type, op) \
-       if (!strcmp (entry.key, in_key)) { \
-               if (entry.type != in_type) { \
-                       nm_warning (in_key "had invalid type in scanned AP message."); \
-               } else { \
-                       op \
-               } \
-               goto next; \
-       }
-
-#define HANDLE_DICT_ARRAY_ITEM(in_key, in_ary_type, op) \
-       if (!strcmp (entry.key, in_key)) { \
-               if (entry.type != DBUS_TYPE_ARRAY) { \
-                       nm_warning (in_key "had invalid type in scanned AP message."); \
-               } else if (entry.array_type != in_ary_type) { \
-                       nm_warning (in_key "had invalid array type in scanned AP message."); \
-               } else { \
-                       op \
-               } \
-               goto next; \
-       }
-
 #define SET_QUALITY_MEMBER(qual_item, lc_member, uc_member) \
        if (lc_member != -1) { \
                qual_item.lc_member = lc_member; \
@@ -2151,176 +2204,80 @@ out:
                qual_item.updated |= IW_QUAL_##uc_member##_INVALID; \
        }
 
+static void
+set_ap_strength_from_properties (NMDevice80211Wireless *self,
+                                                                NMAccessPoint *ap,
+                                                                GHashTable *properties)
+{
+       int qual, level, noise;
+       struct iw_quality quality;
+       GValue *value;
+
+       value = (GValue *) g_hash_table_lookup (properties, "quality");
+       qual = value ? g_value_get_int (value) : -1;
+
+       value = (GValue *) g_hash_table_lookup (properties, "level");
+       level = value ? g_value_get_int (value) : -1;
+
+       value = (GValue *) g_hash_table_lookup (properties, "noise");
+       noise = value ? g_value_get_int (value) : -1;
+
+       /* Calculate and set the AP's signal quality */
+       memset (&quality, 0, sizeof (struct iw_quality));
+       SET_QUALITY_MEMBER (quality, qual, QUAL);
+       SET_QUALITY_MEMBER (quality, level, LEVEL);
+       SET_QUALITY_MEMBER (quality, noise, NOISE);
 
-#define IEEE80211_CAP_ESS       0x0001
-#define IEEE80211_CAP_IBSS      0x0002
-#define IEEE80211_CAP_PRIVACY   0x0010
+       nm_ap_set_strength (ap, wireless_qual_to_percent
+                                               (&quality,
+                                                (const iwqual *)(&self->priv->max_qual),
+                                                (const iwqual *)(&self->priv->avg_qual)));
+}
 
 static void
 supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
-                                DBusMessage * message,
+                                                               GHashTable *properties,
                                 NMDevice80211Wireless * self)
 {
-       DBusMessageIter iter, iter_dict;
-       NMUDictEntry        entry = { .type = DBUS_TYPE_STRING };
-       NMAccessPoint *     ap = NULL;
-       GTimeVal            cur_time;
-       NMAccessPointList * ap_list;
-       int                 qual = -1, level = -1, noise = -1;
-       NMData *            app_data;
-       struct iw_quality   quality;
+       NMAccessPoint *ap;
+       GTimeVal *last_seen;
+       NMData *app_data;
 
        g_return_if_fail (self != NULL);
-       g_return_if_fail (message != NULL);
+       g_return_if_fail (properties != NULL);
        g_return_if_fail (iface != NULL);
 
        if (!(app_data = nm_device_get_app_data (NM_DEVICE (self))))
-               goto out;
-
-       /* Convert the scanned AP into a NMAccessPoint */
-       dbus_message_iter_init (message, &iter);
-
-       if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) {
-               nm_warning ("Warning: couldn't get properties dictionary"
-                           " from scanned AP message.");
-               goto out;
-       }
-
-       /* First arg: Dict Type */
-       if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
-               nm_warning ("Error: couldn't get properties dictionary"
-                         " from scanned AP message.");
-               goto out;
-       }
-
-       ap = nm_ap_new ();
-       if (!ap) {
-               nm_warning ("could not allocate new access point.");
-               goto out;
-       }
-
-       while (nmu_dbus_dict_has_dict_entry (&iter_dict)) {
-               if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) {
-                       nm_warning ("Error: couldn't read properties dictionary entry"
-                                   " from scanned AP message.");
-                       goto out;
-               }
-
-               HANDLE_DICT_ARRAY_ITEM("ssid", DBUS_TYPE_BYTE,
-                       {
-                               char ssid[33];
-                               int ssid_len = sizeof (ssid);
-
-                               if (entry.array_len < sizeof (ssid))
-                                       ssid_len = entry.array_len;
-                               if (ssid_len <= 0)
-                                       goto next;
-                               /* Stupid ieee80211 layer uses <hidden> */
-                               if (((ssid_len == 8) || (ssid_len == 9))
-                                       && (memcmp (entry.bytearray_value, "<hidden>", 8) == 0))
-                                       goto next;
-                               memset (&ssid, 0, sizeof (ssid));
-                               memcpy (&ssid, entry.bytearray_value, ssid_len);
-                               ssid[32] = '\0';
-                               nm_ap_set_essid (ap, ssid);
-                       });
-               HANDLE_DICT_ARRAY_ITEM("bssid", DBUS_TYPE_BYTE,
-                       {
-                               struct ether_addr addr;
-                               if (entry.array_len != ETH_ALEN)
-                                       goto next;
-                               memset (&addr, 0, sizeof (struct ether_addr));
-                               memcpy (&addr, entry.bytearray_value, ETH_ALEN);
-                               nm_ap_set_address (ap, &addr);
-                       });
-
-               HANDLE_DICT_ARRAY_ITEM("wpaie", DBUS_TYPE_BYTE,
-                       {
-                               guint8 * ie = (guint8 *) entry.bytearray_value;
-                               if (entry.array_len <= 0 || entry.array_len > WPA_MAX_IE_LEN)
-                                       goto next;
-                               nm_ap_add_capabilities_from_ie (ap, ie, entry.array_len);
-                       });
-
-               HANDLE_DICT_ARRAY_ITEM("rsnie", DBUS_TYPE_BYTE,
-                       {
-                               guint8 * ie = (guint8 *) entry.bytearray_value;
-                               if (entry.array_len <= 0 || entry.array_len > WPA_MAX_IE_LEN)
-                                       goto next;
-                               nm_ap_add_capabilities_from_ie (ap, ie, entry.array_len);
-                       });
-
-               HANDLE_DICT_ITEM("frequency", DBUS_TYPE_INT32,
-                       {
-                               double freq = (double) entry.double_value;
-                               nm_ap_set_freq (ap, freq);
-                       });
-
-               HANDLE_DICT_ITEM("maxrate", DBUS_TYPE_INT32,
-                       { nm_ap_set_rate (ap, entry.int32_value); });
-
-               HANDLE_DICT_ITEM("quality", DBUS_TYPE_INT32,
-                       { qual = entry.int32_value; });
-
-               HANDLE_DICT_ITEM("level", DBUS_TYPE_INT32,
-                       { level = entry.int32_value; });
-
-               HANDLE_DICT_ITEM("noise", DBUS_TYPE_INT32,
-                       { noise = entry.int32_value; });
-
-               HANDLE_DICT_ITEM("capabilities", DBUS_TYPE_UINT16,
-                       {
-                               guint32 caps = entry.uint16_value;
-
-                               if (caps & IEEE80211_CAP_ESS)
-                                       nm_ap_set_mode (ap, IW_MODE_INFRA);
-                               else if (caps & IEEE80211_CAP_IBSS)
-                                       nm_ap_set_mode (ap, IW_MODE_ADHOC);
+               return;
 
-                               if (caps & IEEE80211_CAP_PRIVACY) {
-                                       if (nm_ap_get_capabilities (ap) & NM_802_11_CAP_PROTO_NONE)
-                                               nm_ap_add_capabilities_for_wep (ap);
-                               }
-                       });
+       ap = nm_ap_new_from_properties (properties);
+       if (!ap)
+               return;
 
-       next:
-               nmu_dbus_dict_entry_clear (&entry);
-       };
+       set_ap_strength_from_properties (self, ap, properties);
 
-       g_get_current_time (&cur_time);
-       self->priv->last_scan = cur_time.tv_sec;
-       nm_ap_set_last_seen (ap, &cur_time);
+       last_seen = (GTimeVal *) nm_ap_get_last_seen (ap);
+       self->priv->last_scan = last_seen->tv_sec;
 
        /* If the AP is not broadcasting its ESSID, try to fill it in here from our
         * allowed list where we cache known MAC->ESSID associations.
         */
        if (!nm_ap_get_essid (ap)) {
                nm_ap_set_broadcast (ap, FALSE);
-               nm_ap_list_copy_one_essid_by_address (self, ap, app_data->allowed_ap_list);
+               nm_ap_list_copy_one_essid_by_address (ap, app_data->allowed_ap_list);
        }
 
-       /* Calculate and set the AP's signal quality */
-       memset (&quality, 0, sizeof (struct iw_quality));
-       SET_QUALITY_MEMBER (quality, qual, QUAL);
-       SET_QUALITY_MEMBER (quality, level, LEVEL);
-       SET_QUALITY_MEMBER (quality, noise, NOISE);
-       nm_ap_set_strength (ap, wireless_qual_to_percent (&quality,
-                                               (const iwqual *)(&self->priv->max_qual),
-                                               (const iwqual *)(&self->priv->avg_qual)));
-
        /* Add the AP to the device's AP list */
-       ap_list = nm_device_802_11_wireless_ap_list_get (self);
-       nm_ap_list_merge_scanned_ap (self, ap_list, ap);
+       merge_scanned_ap (self, ap);
 
        /* Once we have the list, copy in any relevant information from our Allowed list. */
-       nm_ap_list_copy_properties (ap_list, app_data->allowed_ap_list);
+       nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (self),
+                                                               app_data->allowed_ap_list);
 
        /* Remove outdated access points */
        cull_scan_list (self);
 
-out:
-       if (ap)
-               nm_ap_unref (ap);
+       nm_ap_unref (ap);
 }
 
 
@@ -2389,6 +2346,7 @@ link_timeout_cb (gpointer user_data)
                nm_device_set_active_link (dev, FALSE);
                if (nm_device_is_activating (dev)) {
                        cleanup_association_attempt (self, TRUE);
+                       nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
                        nm_policy_schedule_activation_failed (req);
                }
                return FALSE;
@@ -2404,6 +2362,7 @@ link_timeout_cb (gpointer user_data)
                nm_info ("Activation (%s/wireless): disconnected during association,"
                         " asking for new key.", nm_device_get_iface (dev));
                cleanup_association_attempt (self, TRUE);
+               nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
                nm_dbus_get_user_key_for_network (req, TRUE);
        } else {
                nm_info ("%s: link timed out.", nm_device_get_iface (dev));
@@ -2659,6 +2618,7 @@ supplicant_mgr_state_cb_handler (gpointer user_data)
 
                        if (nm_device_is_activating (dev)) {
                                NMActRequest * req = nm_device_get_act_request (dev);
+                               nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
                                nm_policy_schedule_activation_failed (req);
                        } else if (nm_device_is_activated (dev)) {
                                nm_policy_schedule_device_change_check (app_data);
@@ -2718,6 +2678,7 @@ supplicant_iface_connection_error_cb_handler (gpointer user_data)
                 cb_data->message);
 
        cleanup_association_attempt (self, TRUE);
+       nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED);
        nm_policy_schedule_activation_failed (req);
 
 out:
@@ -2794,6 +2755,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
                         "asking for new key.",
                         nm_device_get_iface (dev));
 
+               nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
                nm_dbus_get_user_key_for_network (req, TRUE);
        } else {
                if (nm_device_is_activating (dev)) {
@@ -2801,6 +2763,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
                                 "failing activation.",
                                 nm_device_get_iface (dev));
 
+                       nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
                        nm_policy_schedule_activation_failed (nm_device_get_act_request (dev));
                }
        }
@@ -2812,7 +2775,6 @@ supplicant_connection_timeout_cb (gpointer user_data)
 static gboolean
 start_supplicant_connection_timeout (NMDevice80211Wireless *self)
 {
-       GMainContext * context;
        NMDevice *     dev;
        guint          id;
 
@@ -2858,7 +2820,7 @@ build_supplicant_config (NMDevice80211Wireless *self,
        ap = nm_act_request_get_ap (req);
        g_assert (ap);
 
-       config = nm_supplicant_config_new (NM_DEVICE (self));
+       config = nm_supplicant_config_new (nm_device_get_iface (NM_DEVICE (self)));
        if (config == NULL)
                goto out;
 
@@ -2900,6 +2862,28 @@ error:
 
 /****************************************************************************/
 
+static void
+real_set_hw_address (NMDevice *dev)
+{
+       NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev);
+       struct ifreq req;
+       NMSock *sk;
+       int ret;
+
+       sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL);
+       if (!sk)
+               return;
+
+       memset (&req, 0, sizeof (struct ifreq));
+       strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1);
+
+       ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req);
+       if (ret == 0)
+               memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr));
+
+       nm_dev_sock_close (sk);
+}
+
 
 static NMActStageReturn
 real_act_stage2_config (NMDevice *dev,
@@ -2919,6 +2903,7 @@ real_act_stage2_config (NMDevice *dev,
 
        /* If we need an encryption key, get one */
        if (ap_need_key (self, ap, &ask_user)) {
+               nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
                nm_dbus_get_user_key_for_network (req, ask_user);
                return NM_ACT_STAGE_RETURN_POSTPONE;
        }
@@ -3062,6 +3047,7 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
                /* Activation failed, we must have bad encryption key */
                nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.",
                                nm_device_get_iface (dev), nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)");
+               nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
                nm_dbus_get_user_key_for_network (req, TRUE);
                ret = NM_ACT_STAGE_RETURN_POSTPONE;
        }
@@ -3275,6 +3261,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass)
        parent_class->init = real_init;
        parent_class->start = real_start;
        parent_class->update_link = real_update_link;
+       parent_class->set_hw_address = real_set_hw_address;
 
        parent_class->act_stage2_config = real_act_stage2_config;
        parent_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start;
@@ -3317,3 +3304,32 @@ nm_device_802_11_wireless_get_type (void)
        return type;
 }
 
+NMDevice80211Wireless *
+nm_device_802_11_wireless_new (const char *iface,
+                                                          const char *udi,
+                                                          const char *driver,
+                                                          gboolean test_dev,
+                                                          NMData *app_data)
+{
+       GObject *obj;
+
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (udi != NULL, NULL);
+       g_return_val_if_fail (driver != NULL, NULL);
+       g_return_val_if_fail (app_data != NULL, NULL);
+
+       obj = g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS,
+                                               NM_DEVICE_INTERFACE_UDI, udi,
+                                               NM_DEVICE_INTERFACE_IFACE, iface,
+                                               NM_DEVICE_INTERFACE_DRIVER, driver,
+                                               NM_DEVICE_INTERFACE_APP_DATA, app_data,
+                                               NULL);
+
+       /* FIXME */
+/*     g_signal_connect (obj, "state-changed", */
+/*                                       (GCallback) state_changed_cb, */
+/*                                       NULL); */
+
+       return NM_DEVICE_802_11_WIRELESS (obj);
+
+}
index 70f379b..7d5dcaf 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "nm-device.h"
 #include "NetworkManagerAP.h"
+#include "NetworkManagerMain.h"
 
 struct NMAccessPointList;
 
@@ -65,14 +66,11 @@ struct _NMDevice80211WirelessClass
 
 GType nm_device_802_11_wireless_get_type (void);
 
-
-static inline gboolean nm_device_is_802_11_wireless (NMDevice *dev);
-static inline gboolean nm_device_is_802_11_wireless (NMDevice *dev)
-{
-       g_return_val_if_fail (dev != NULL, FALSE);
-
-       return (G_OBJECT_TYPE (dev) == NM_TYPE_DEVICE_802_11_WIRELESS);
-}
+NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *iface,
+                                                                                                         const char *udi,
+                                                                                                         const char *driver,
+                                                                                                         gboolean test_dev,
+                                                                                                         NMData *app_data);
 
 void                   nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self,
                                                                                  const char *essid);
@@ -80,8 +78,6 @@ void                  nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self,
 void nm_device_802_11_wireless_get_address (NMDevice80211Wireless *dev,
                                                                   struct ether_addr *addr);
 
-void nm_device_802_11_wireless_set_address (NMDevice80211Wireless *dev);
-
 void                   nm_device_802_11_wireless_get_bssid (NMDevice80211Wireless *dev,
                                                     struct ether_addr *bssid);
 
index 9b5cb65..d8ffa4d 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 
 #include "nm-device-802-3-ethernet.h"
+#include "nm-device-interface.h"
 #include "nm-device-private.h"
 #include "NetworkManagerMain.h"
 #include "nm-activation-request.h"
@@ -76,6 +77,8 @@ nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self)
        self->priv->link_source_id = 0;
 
        memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr));
+
+       nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_3_ETHERNET);
 }
 
 static void
@@ -99,7 +102,8 @@ real_init (NMDevice *dev)
 
        sup_mgr = nm_supplicant_manager_get ();
        self->priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr,
-                                                                NM_DEVICE (self));
+                                                                                                                        nm_device_get_iface (NM_DEVICE (self)),
+                                                                                                                        FALSE);
        if (self->priv->sup_iface == NULL) {
                nm_warning ("Couldn't initialize supplicant interface for %s.",
                            nm_device_get_iface (NM_DEVICE (self)));
@@ -211,6 +215,31 @@ real_start (NMDevice *dev)
 }
 
 
+NMDevice8023Ethernet *
+nm_device_802_3_ethernet_new (const char *iface,
+                                                         const char *udi,
+                                                         const char *driver,
+                                                         gboolean test_dev,
+                                                         NMData *app_data)
+{
+       GObject *obj;
+
+       g_return_val_if_fail (iface != NULL, NULL);
+       g_return_val_if_fail (udi != NULL, NULL);
+       g_return_val_if_fail (driver != NULL, NULL);
+       g_return_val_if_fail (app_data != NULL, NULL);
+
+       obj = g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET,
+                                               NM_DEVICE_INTERFACE_UDI, udi,
+                                               NM_DEVICE_INTERFACE_IFACE, iface,
+                                               NM_DEVICE_INTERFACE_DRIVER, driver,
+                                               NM_DEVICE_INTERFACE_APP_DATA, app_data,
+                                               NULL);
+
+       return NM_DEVICE_802_3_ETHERNET (obj);
+}
+
+
 /*
  * nm_device_802_3_ethernet_get_address
  *
@@ -227,35 +256,25 @@ nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *self, struct ether_a
 }
 
 
-/*
- * nm_device_802_3_ethernet_set_address
- *
- * Set a device's hardware address
- *
- */
-void
-nm_device_802_3_ethernet_set_address (NMDevice8023Ethernet *self)
+static void
+real_set_hw_address (NMDevice *dev)
 {
-       NMDevice *dev = NM_DEVICE (self);
+       NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev);
        struct ifreq req;
        NMSock *sk;
        int ret;
 
-       g_return_if_fail (self != NULL);
-
        sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL);
        if (!sk)
                return;
+
        memset (&req, 0, sizeof (struct ifreq));
        strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1);
 
        ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req);
-       if (ret)
-               goto out;
+       if (ret == 0)
+               memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr));
 
-       memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr));
-
-out:
        nm_dev_sock_close (sk);
 }
 
@@ -370,6 +389,9 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass)
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass);
 
+       g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate));
+
+       /* virtual methods */
        object_class->dispose = nm_device_802_3_ethernet_dispose;
        object_class->finalize = nm_device_802_3_ethernet_finalize;
 
@@ -378,8 +400,7 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass)
        parent_class->start = real_start;
        parent_class->update_link = real_update_link;
        parent_class->can_interrupt_activation = real_can_interrupt_activation;
-
-       g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate));
+       parent_class->set_hw_address = real_set_hw_address;
 }
 
 GType
index 5d5a70b..74fa118 100644 (file)
@@ -27,6 +27,7 @@
 #include <net/ethernet.h>
 
 #include "nm-device.h"
+#include "NetworkManagerMain.h"
 
 G_BEGIN_DECLS
 
@@ -58,19 +59,15 @@ struct _NMDevice8023EthernetClass
 GType nm_device_802_3_ethernet_get_type (void);
 
 
-static inline gboolean nm_device_is_802_3_ethernet (NMDevice *dev);
-static inline gboolean nm_device_is_802_3_ethernet (NMDevice *dev)
-{
-       g_return_val_if_fail (dev != NULL, FALSE);
-
-       return (G_OBJECT_TYPE (dev) == NM_TYPE_DEVICE_802_3_ETHERNET);
-}
+NMDevice8023Ethernet *nm_device_802_3_ethernet_new (const char *iface,
+                                                                                                       const char *udi,
+                                                                                                       const char *driver,
+                                                                                                       gboolean test_dev,
+                                                                                                       NMData *app_data);
 
 void nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *dev,
                                                                   struct ether_addr *addr);
 
-void nm_device_802_3_ethernet_set_address (NMDevice8023Ethernet *dev);
-
 int nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *self);
 
 G_END_DECLS
diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c
new file mode 100644 (file)
index 0000000..45513ff
--- /dev/null
@@ -0,0 +1,142 @@
+
+#include "nm-device-interface.h"
+
+static void
+nm_device_interface_init (gpointer g_iface)
+{
+       GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
+       static gboolean initialized = FALSE;
+
+       if (initialized)
+               return;
+
+       /* Properties */
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_string (NM_DEVICE_INTERFACE_UDI,
+                                                         "Udi",
+                                                         "HAL Udi",
+                                                         NULL,
+                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_string (NM_DEVICE_INTERFACE_IFACE,
+                                                         "Interface",
+                                                         "Interface",
+                                                         NULL,
+                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_string (NM_DEVICE_INTERFACE_DRIVER,
+                                                         "Driver",
+                                                         "Driver",
+                                                         NULL,
+                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+       
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_uint (NM_DEVICE_INTERFACE_CAPABILITIES,
+                                                       "Capabilities",
+                                                       "Capabilities",
+                                                       0, G_MAXUINT32, NM_DEVICE_CAP_NONE,
+                                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_pointer (NM_DEVICE_INTERFACE_APP_DATA,
+                                                          "AppData",
+                                                          "AppData",
+                                                          G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_uint (NM_DEVICE_INTERFACE_IP4_ADDRESS,
+                                                       "IP4 address",
+                                                       "IP4 address",
+                                                       0, G_MAXUINT32, 0, /* FIXME */
+                                                       G_PARAM_READWRITE));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_boolean (NM_DEVICE_INTERFACE_USE_DHCP,
+                                                          "Use DHCP",
+                                                          "Use DHCP",
+                                                          TRUE,
+                                                          G_PARAM_READWRITE));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_uint (NM_DEVICE_INTERFACE_STATE,
+                                                       "State",
+                                                       "State",
+                                                       0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN,
+                                                       G_PARAM_READABLE));
+
+       g_object_interface_install_property
+               (g_iface,
+                g_param_spec_uint (NM_DEVICE_INTERFACE_DEVICE_TYPE,
+                                                       "DeviceType",
+                                                       "DeviceType",
+                                                       0, G_MAXUINT32, DEVICE_TYPE_UNKNOWN,
+                                                       G_PARAM_READABLE));
+
+       /* Signals */
+       g_signal_new ("state_changed",
+                                 iface_type,
+                                 G_SIGNAL_RUN_FIRST,
+                                 G_STRUCT_OFFSET (NMDeviceInterface, state_changed),
+                                 NULL, NULL,
+                                 g_cclosure_marshal_VOID__UINT,
+                                 G_TYPE_NONE, 1,
+                                 G_TYPE_UINT);
+
+       g_signal_new ("carrier_changed",
+                                 iface_type,
+                                 G_SIGNAL_RUN_FIRST,
+                                 G_STRUCT_OFFSET (NMDeviceInterface, carrier_changed),
+                                 NULL, NULL,
+                                 g_cclosure_marshal_VOID__BOOLEAN,
+                                 G_TYPE_NONE, 1,
+                                 G_TYPE_BOOLEAN);
+
+       initialized = TRUE;
+}
+
+
+GType
+nm_device_interface_get_type (void)
+{
+       static GType device_interface_type = 0;
+
+       if (!device_interface_type) {
+               const GTypeInfo device_interface_info = {
+                       sizeof (NMDeviceInterface), /* class_size */
+                       nm_device_interface_init,   /* base_init */
+                       NULL,           /* base_finalize */
+                       NULL,
+                       NULL,           /* class_finalize */
+                       NULL,           /* class_data */
+                       0,
+                       0,              /* n_preallocs */
+                       NULL
+               };
+
+               device_interface_type = g_type_register_static (G_TYPE_INTERFACE,
+                                                                                                               "NMDeviceInterface",
+                                                                                                               &device_interface_info, 0);
+
+               g_type_interface_add_prerequisite (device_interface_type, G_TYPE_OBJECT);
+       }
+
+       return device_interface_type;
+}
+
+void
+nm_device_interface_deactivate (NMDeviceInterface *device)
+{
+       g_return_if_fail (NM_IS_DEVICE_INTERFACE (device));
+
+       NM_DEVICE_INTERFACE_GET_INTERFACE (device)->deactivate (device);
+}
diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h
new file mode 100644 (file)
index 0000000..1308346
--- /dev/null
@@ -0,0 +1,55 @@
+
+#ifndef NM_DEVICE_INTERFACE_H
+#define NM_DEVICE_INTERFACE_H
+
+#include <glib-object.h>
+#include "NetworkManager.h"
+
+#define NM_TYPE_DEVICE_INTERFACE      (nm_device_interface_get_type ())
+#define NM_DEVICE_INTERFACE(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INTERFACE, NmDeviceInterface))
+#define NM_IS_DEVICE_INTERFACE(obj)   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INTERFACE))
+#define NM_DEVICE_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_DEVICE_INTERFACE, NMDeviceInterface))
+
+
+#define NM_DEVICE_INTERFACE_UDI "udi"
+#define NM_DEVICE_INTERFACE_IFACE "interface"
+#define NM_DEVICE_INTERFACE_DRIVER "driver"
+#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities"
+#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4_address"
+#define NM_DEVICE_INTERFACE_USE_DHCP "use_dhcp"
+#define NM_DEVICE_INTERFACE_STATE "state"
+#define NM_DEVICE_INTERFACE_APP_DATA "app_data" /* Ugh */
+#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device_type" /* ugh */
+
+typedef enum {
+       NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000,
+
+       NM_DEVICE_INTERFACE_PROP_UDI = NM_DEVICE_INTERFACE_PROP_FIRST,
+       NM_DEVICE_INTERFACE_PROP_IFACE,
+       NM_DEVICE_INTERFACE_PROP_DRIVER,
+       NM_DEVICE_INTERFACE_PROP_CAPABILITIES,
+       NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS,
+       NM_DEVICE_INTERFACE_PROP_USE_DHCP,
+       NM_DEVICE_INTERFACE_PROP_STATE,
+       NM_DEVICE_INTERFACE_PROP_APP_DATA,
+       NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE
+} NMDeviceInterfaceProp;
+
+
+typedef struct _NMDeviceInterface NMDeviceInterface;
+
+struct _NMDeviceInterface {
+       GTypeInterface g_iface;
+
+       /* Methods */
+       void (*deactivate) (NMDeviceInterface *device);
+
+       /* Signals */
+       void (*state_changed) (NMDeviceInterface *device, NMDeviceState state);
+       void (*carrier_changed) (NMDeviceInterface *device, gboolean carrier_on);
+};
+
+GType nm_device_interface_get_type (void);
+
+
+#endif /* NM_DEVICE_INTERFACE_H */
index bb20028..6702bf3 100644 (file)
@@ -32,11 +32,15 @@ typedef struct NMDbusCBData {
 } NMDbusCBData;
 
 
+void                   nm_device_set_device_type (NMDevice *dev, NMDeviceType type);
+
 gboolean               nm_device_is_activated (NMDevice *dev);
 
 NMIP4Config *  nm_device_new_ip4_autoip_config (NMDevice *self);
 
 void                   nm_device_activate_schedule_stage3_ip_config_start (struct NMActRequest *req);
 
+void                   nm_device_state_changed (NMDevice *device, NMDeviceState state);
+
 
 #endif /* NM_DEVICE_PRIVATE_H */
index bc47bd0..c1211fe 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include "nm-device.h"
+#include "nm-device-interface.h"
 #include "nm-device-private.h"
 #include "nm-device-802-3-ethernet.h"
 #include "nm-device-802-11-wireless.h"
 #include "nm-utils.h"
 #include "autoip.h"
 
+static void device_interface_init (NMDeviceInterface *device_interface_class);
+
+G_DEFINE_TYPE_EXTENDED (NMDevice, nm_device, G_TYPE_OBJECT,
+                                               G_TYPE_FLAG_ABSTRACT,
+                                               G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE,
+                                                                                          device_interface_init))
+
 #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
 
 struct _NMDevicePrivate
 {
        gboolean        dispose_has_run;
 
+       NMDeviceState state;
+
        char *                  udi;
        char *                  iface;
        NMDeviceType            type;
@@ -72,89 +82,62 @@ static void         nm_device_activate_schedule_stage5_ip_config_commit (NMActRequest *
 void nm_device_bring_up (NMDevice *dev);
 gboolean nm_device_bring_up_wait (NMDevice *self, gboolean cancelable);
 
-/*
- * nm_device_test_wireless_extensions
- *
- * Test whether a given device is a wireless one or not.
- *
- */
-static NMDeviceType
-discover_device_type (LibHalContext *ctx, const char *udi)
+
+static void
+nm_device_set_address (NMDevice *device)
 {
-       char * category = NULL;
+       if (NM_DEVICE_GET_CLASS (device)->set_hw_address)
+               NM_DEVICE_GET_CLASS (device)->set_hw_address (device);
+}
 
-       if (libhal_device_property_exists (ctx, udi, "info.category", NULL))
-               category = libhal_device_get_property_string(ctx, udi, "info.category", NULL);
-       if (category && (!strcmp (category, "net.80211")))
-               return DEVICE_TYPE_802_11_WIRELESS;
-       else if (category && (!strcmp (category, "net.80203")))
-               return DEVICE_TYPE_802_3_ETHERNET;
-       return DEVICE_TYPE_UNKNOWN;
+static void
+device_interface_init (NMDeviceInterface *device_interface_class)
+{
 }
 
-/*
- * nm_get_device_driver_name
- *
- * Get the device's driver name from HAL.
- *
- */
-static char *
-nm_get_device_driver_name (LibHalContext *ctx, const char *udi)
+
+static void
+nm_device_init (NMDevice * self)
 {
-       char    *       driver_name = NULL;
-       char *  physdev_udi = NULL;
+       self->priv = NM_DEVICE_GET_PRIVATE (self);
+       self->priv->dispose_has_run = FALSE;
+       self->priv->udi = NULL;
+       self->priv->iface = NULL;
+       self->priv->type = DEVICE_TYPE_UNKNOWN;
+       self->priv->capabilities = NM_DEVICE_CAP_NONE;
+       self->priv->driver = NULL;
+       self->priv->removed = FALSE;
 
-       g_return_val_if_fail (ctx != NULL, NULL);
-       g_return_val_if_fail (udi != NULL, NULL);
+       self->priv->link_active = FALSE;
+       self->priv->ip4_address = 0;
+       memset (&self->priv->ip6_address, 0, sizeof (struct in6_addr));
+       self->priv->app_data = NULL;
 
-       physdev_udi = libhal_device_get_property_string (ctx, udi, "net.physical_device", NULL);
-       if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL))
-       {
-               char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL);
-               driver_name = g_strdup (drv);
-               g_free (drv);
-       }
-       g_free (physdev_udi);
+       self->priv->act_source_id = 0;
 
-       return driver_name;
+       self->priv->system_config_data = NULL;
+       self->priv->ip4_config = NULL;
+
+       self->priv->state = NM_DEVICE_STATE_DISCONNECTED;
 }
 
 
-NMDevice *
-nm_device_new (const char *iface, 
-               const char *udi,
-               gboolean test_dev,
-               NMDeviceType test_dev_type,
-               NMData *app_data)
+static GObject*
+constructor (GType type,
+                        guint n_construct_params,
+                        GObjectConstructParam *construct_params)
 {
-       NMDevice *      dev;
-       NMDeviceType    type;
+       GObject *object;
+       NMDevice *dev;
 
-       g_return_val_if_fail (iface != NULL, NULL);
-       g_return_val_if_fail (udi != NULL, NULL);
-       g_return_val_if_fail (strlen (iface) > 0, NULL);
-       g_return_val_if_fail (app_data != NULL, NULL);
+       object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type,
+                                                                                                                                  n_construct_params,
+                                                                                                                                  construct_params);
 
-       type = discover_device_type (app_data->hal_ctx, udi);
-       switch (type)
-       {
-               case DEVICE_TYPE_802_11_WIRELESS:
-                       dev = NM_DEVICE (g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, NULL));
-                       break;
-               case DEVICE_TYPE_802_3_ETHERNET:
-                       dev = NM_DEVICE (g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, NULL));
-                       break;
-
-               default:
-                       g_assert_not_reached ();
-       }
+       if (!object)
+               return NULL;
 
-       g_assert (dev);
-       dev->priv->iface = g_strdup (iface);
-       dev->priv->udi = g_strdup (udi);
-       dev->priv->driver = nm_get_device_driver_name (app_data->hal_ctx, udi);
-       dev->priv->app_data = app_data;
-       dev->priv->type = type;
+       dev = NM_DEVICE (object);
 
        dev->priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev);
        if (!(dev->priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED))
@@ -169,13 +152,10 @@ nm_device_new (const char *iface,
        nm_device_update_ip4_address (dev);
 
        /* Update the device's hardware address */
-       if (nm_device_is_802_3_ethernet (dev))
-               nm_device_802_3_ethernet_set_address (NM_DEVICE_802_3_ETHERNET (dev));
-       else if (nm_device_is_802_11_wireless (dev))
-               nm_device_802_11_wireless_set_address (NM_DEVICE_802_11_WIRELESS (dev));
+       nm_device_set_address (dev);
 
        /* Grab IP config data for this device from the system configuration files */
-       dev->priv->system_config_data = nm_system_device_get_system_config (dev, app_data);
+       dev->priv->system_config_data = nm_system_device_get_system_config (dev, dev->priv->app_data);
        nm_device_set_use_dhcp (dev, nm_system_device_get_use_dhcp (dev));
 
        /* Allow distributions to flag devices as disabled */
@@ -193,34 +173,10 @@ nm_device_new (const char *iface,
 
        NM_DEVICE_GET_CLASS (dev)->start (dev);
 
-       return dev;
+       return object;
 }
 
 
-static void
-nm_device_init (NMDevice * self)
-{
-       self->priv = NM_DEVICE_GET_PRIVATE (self);
-       self->priv->dispose_has_run = FALSE;
-       self->priv->udi = NULL;
-       self->priv->iface = NULL;
-       self->priv->type = DEVICE_TYPE_UNKNOWN;
-       self->priv->capabilities = NM_DEVICE_CAP_NONE;
-       self->priv->driver = NULL;
-       self->priv->removed = FALSE;
-
-       self->priv->link_active = FALSE;
-       self->priv->ip4_address = 0;
-       memset (&self->priv->ip6_address, 0, sizeof (struct in6_addr));
-       self->priv->app_data = NULL;
-
-       self->priv->act_request = NULL;
-       self->priv->act_source_id = 0;
-
-       self->priv->system_config_data = NULL;
-       self->priv->ip4_config = NULL;
-}
-
 static guint32
 real_get_generic_capabilities (NMDevice *dev)
 {
@@ -346,6 +302,16 @@ nm_device_get_device_type (NMDevice *self)
 }
 
 
+void
+nm_device_set_device_type (NMDevice *dev, NMDeviceType type)
+{
+       g_return_if_fail (NM_IS_DEVICE (dev));
+       g_return_if_fail (NM_DEVICE_GET_PRIVATE (dev)->type == DEVICE_TYPE_UNKNOWN);
+
+       NM_DEVICE_GET_PRIVATE (dev)->type = type;
+}
+
+
 static gboolean
 real_is_test_device (NMDevice *dev)
 {
@@ -483,13 +449,13 @@ nm_device_set_active_link (NMDevice *self,
                 * must manually choose semi-supported devices.
                 *
                 */
-               if (nm_device_is_802_3_ethernet (self) && (nm_device_get_capabilities (self) & NM_DEVICE_CAP_CARRIER_DETECT))
+               if (NM_IS_DEVICE_802_3_ETHERNET (self) && (nm_device_get_capabilities (self) & NM_DEVICE_CAP_CARRIER_DETECT))
                {
                        gboolean                do_switch = act_dev ? FALSE : TRUE;     /* If no currently active device, switch to this one */
                        NMActRequest *  act_req;
 
                        /* If active device is wireless, switch to this one */
-                       if (act_dev && nm_device_is_802_11_wireless (act_dev) && act_dev_req && !nm_act_request_get_user_requested (act_dev_req))
+                       if (act_dev && NM_IS_DEVICE_802_11_WIRELESS (act_dev) && act_dev_req && !nm_act_request_get_user_requested (act_dev_req))
                                do_switch = TRUE;
 
                        if (do_switch && (act_req = nm_act_request_new (app_data, self, NULL, TRUE)))
@@ -499,6 +465,8 @@ nm_device_set_active_link (NMDevice *self,
                        }
                }
        }
+
+       g_signal_emit_by_name (self, "carrier_changed", link_active);
        nm_dbus_schedule_device_status_change_signal (app_data, self, NULL, link_active ? DEVICE_CARRIER_ON : DEVICE_CARRIER_OFF);
 }
 
@@ -515,6 +483,7 @@ nm_device_set_active_link (NMDevice *self,
 gboolean
 nm_device_activation_start (NMActRequest *req)
 {
+       NMDevicePrivate *priv;
        NMData *                data = NULL;
        NMDevice *      self = NULL;
 
@@ -526,7 +495,11 @@ nm_device_activation_start (NMActRequest *req)
        self = nm_act_request_get_dev (req);
        g_assert (self);
 
-       g_return_val_if_fail (!nm_device_is_activating (self), TRUE);   /* Return if activation has already begun */
+       priv = NM_DEVICE_GET_PRIVATE (self);
+
+       if (priv->state != NM_DEVICE_STATE_DISCONNECTED)
+               /* Already activating or activated */
+               return FALSE;
 
        nm_act_request_ref (req);
        self->priv->act_request = req;
@@ -572,11 +545,13 @@ nm_device_activate_stage1_device_prepare (gpointer user_data)
 
        iface = nm_device_get_iface (self);
        nm_info ("Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface);
+       nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE);
 
        ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, req);
        if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
                goto out;
        } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
+               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
                nm_policy_schedule_activation_failed (req);
                goto out;
        }
@@ -659,6 +634,7 @@ nm_device_activate_stage2_device_config (gpointer user_data)
 
        iface = nm_device_get_iface (self);
        nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface);
+       nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG);
 
        /* Bring the device up */
        if (!nm_device_is_up (self))
@@ -669,6 +645,7 @@ nm_device_activate_stage2_device_config (gpointer user_data)
                goto out;
        else if (ret == NM_ACT_STAGE_RETURN_FAILURE)
        {
+               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
                nm_policy_schedule_activation_failed (req);
                goto out;
        }
@@ -778,12 +755,14 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
 
        iface = nm_device_get_iface (self);
        nm_info ("Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface);
+       nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG);
 
        ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self, req);
        if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
                goto out;
        else if (ret == NM_ACT_STAGE_RETURN_FAILURE)
        {
+               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
                nm_policy_schedule_activation_failed (req);
                goto out;
        }
@@ -929,6 +908,7 @@ nm_device_activate_stage4_ip_config_get (gpointer user_data)
                goto out;
        else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE))
        {
+               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
                nm_policy_schedule_activation_failed (req);
                goto out;
        }
@@ -1022,6 +1002,7 @@ nm_device_activate_stage4_ip_config_timeout (gpointer user_data)
        if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
                goto out;
        } else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) {
+               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
                nm_policy_schedule_activation_failed (req);
                goto out;
        }
@@ -1105,10 +1086,14 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
                nm_system_set_hostname (self->priv->ip4_config);
                nm_system_activate_nis (self->priv->ip4_config);
                nm_system_set_mtu (self);
+
                if (NM_DEVICE_GET_CLASS (self)->update_link)
                        NM_DEVICE_GET_CLASS (self)->update_link (self);
+
+               nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED);
                nm_policy_schedule_activation_finish (req);
        } else {
+               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
                nm_policy_schedule_activation_failed (req);
        }
 
@@ -1150,7 +1135,7 @@ real_activation_cancel_handler (NMDevice *self,
        g_return_if_fail (self != NULL);
        g_return_if_fail (req != NULL);
 
-       if (nm_act_request_get_stage (req) == NM_ACT_STAGE_IP_CONFIG_START)
+       if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG)
                nm_dhcp_manager_cancel_transaction (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
                                                                                        nm_device_get_iface (self),
                                                                                        TRUE);
@@ -1217,7 +1202,7 @@ nm_device_deactivate_quickly (NMDevice *self)
        app_data = self->priv->app_data;
        nm_vpn_manager_deactivate_vpn_connection (app_data->vpn_manager, self);
 
-       if (nm_device_is_activated (self))
+       if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED)
                nm_dbus_schedule_device_status_change_signal (app_data, self, NULL, DEVICE_NO_LONGER_ACTIVE);
        else if (nm_device_is_activating (self))
                nm_device_activation_cancel (self);
@@ -1278,6 +1263,7 @@ nm_device_deactivate (NMDevice *self)
        if (NM_DEVICE_GET_CLASS (self)->deactivate)
                NM_DEVICE_GET_CLASS (self)->deactivate (self);
 
+       nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED);
        nm_schedule_state_change_signal_broadcast (self->priv->app_data);
 }
 
@@ -1289,38 +1275,22 @@ nm_device_deactivate (NMDevice *self)
  *
  */
 gboolean
-nm_device_is_activating (NMDevice *dev)
+nm_device_is_activating (NMDevice *device)
 {
-       NMActRequest *  req;
-       NMActStage      stage;
-       gboolean                activating = FALSE;
-
-       g_return_val_if_fail (dev != NULL, FALSE);
-
-       if (!(req = nm_device_get_act_request (dev)))
-               return FALSE;
-
-       stage = nm_act_request_get_stage (req);
-       switch (stage)
-       {
-               case NM_ACT_STAGE_DEVICE_PREPARE:
-               case NM_ACT_STAGE_DEVICE_CONFIG:
-               case NM_ACT_STAGE_NEED_USER_KEY:
-               case NM_ACT_STAGE_IP_CONFIG_START:
-               case NM_ACT_STAGE_IP_CONFIG_GET:
-               case NM_ACT_STAGE_IP_CONFIG_COMMIT:
-                       activating = TRUE;
-                       break;
+       g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
 
-               case NM_ACT_STAGE_ACTIVATED:
-               case NM_ACT_STAGE_FAILED:
-               case NM_ACT_STAGE_CANCELLED:
-               case NM_ACT_STAGE_UNKNOWN:
-               default:
-                       break;
+       switch (nm_device_get_state (device)) {
+       case NM_DEVICE_STATE_PREPARE:
+       case NM_DEVICE_STATE_CONFIG:
+       case NM_DEVICE_STATE_NEED_AUTH:
+       case NM_DEVICE_STATE_IP_CONFIG:
+               return TRUE;
+               break;
+       default:
+               break;
        }
 
-       return activating;
+       return FALSE;
 }
 
 
@@ -1563,10 +1533,7 @@ nm_device_set_up_down (NMDevice *self,
         * Make sure that we have a valid MAC address, some cards reload firmware when they
         * are brought up.
         */
-       if (nm_device_is_802_3_ethernet (self))
-               nm_device_802_3_ethernet_set_address (NM_DEVICE_802_3_ETHERNET (self));
-       else if (nm_device_is_802_11_wireless (self))
-               nm_device_802_11_wireless_set_address (NM_DEVICE_802_11_WIRELESS (self));
+       nm_device_set_address (self);
 }
 
 
@@ -1684,9 +1651,7 @@ nm_device_get_system_config_data (NMDevice *self)
 static void
 nm_device_dispose (GObject *object)
 {
-       NMDevice *              self = NM_DEVICE (object);
-       NMDeviceClass * klass;
-       GObjectClass *          parent_class;  
+       NMDevice *self = NM_DEVICE (object);
 
        if (self->priv->dispose_has_run)
                /* If dispose did already run, return. */
@@ -1722,27 +1687,95 @@ nm_device_dispose (GObject *object)
 
        nm_device_set_use_dhcp (self, FALSE);
 
-       /* Chain up to the parent class */
-       klass = NM_DEVICE_CLASS (g_type_class_peek (NM_TYPE_DEVICE));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->dispose (object);
+       G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
 }
 
 static void
 nm_device_finalize (GObject *object)
 {
-       NMDevice *              self = NM_DEVICE (object);
-       NMDeviceClass * klass;
-       GObjectClass *          parent_class;  
+       NMDevice *self = NM_DEVICE (object);
 
        g_free (self->priv->udi);
        g_free (self->priv->iface);
        g_free (self->priv->driver);
 
-       /* Chain up to the parent class */
-       klass = NM_DEVICE_CLASS (g_type_class_peek (NM_TYPE_DEVICE));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->finalize (object);
+       G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
+}
+
+
+static void
+set_property (GObject *object, guint prop_id,
+                         const GValue *value, GParamSpec *pspec)
+{
+       NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
+       switch (prop_id) {
+       case NM_DEVICE_INTERFACE_PROP_UDI:
+               /* construct-only */
+               priv->udi = g_strdup (g_value_get_string (value));
+               break;
+       case NM_DEVICE_INTERFACE_PROP_IFACE:
+               priv->iface = g_strdup (g_value_get_string (value));
+               break;
+       case NM_DEVICE_INTERFACE_PROP_DRIVER:
+               priv->driver = g_strdup (g_value_get_string (value));
+               break;
+       case NM_DEVICE_INTERFACE_PROP_APP_DATA:
+               priv->app_data = g_value_get_pointer (value);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_CAPABILITIES:
+               priv->capabilities = g_value_get_uint (value);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS:
+               priv->ip4_address = g_value_get_uint (value);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_USE_DHCP:
+               nm_device_set_use_dhcp (NM_DEVICE (object), g_value_get_boolean (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+                         GValue *value, GParamSpec *pspec)
+{
+       NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
+
+       switch (prop_id) {
+       case NM_DEVICE_INTERFACE_PROP_UDI:
+               g_value_set_string (value, priv->udi);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_IFACE:
+               g_value_set_string (value, priv->iface);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_DRIVER:
+               g_value_set_string (value, priv->driver);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_APP_DATA:
+               g_value_set_pointer (value, priv->app_data);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_CAPABILITIES:
+               g_value_set_uint (value, priv->capabilities);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS:
+               g_value_set_uint (value, priv->ip4_address);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_USE_DHCP:
+               g_value_set_boolean (value, nm_device_get_use_dhcp (NM_DEVICE (object)));
+               break;
+       case NM_DEVICE_INTERFACE_PROP_STATE:
+               g_value_set_uint (value, priv->state);
+               break;
+       case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE:
+               g_value_set_uint (value, priv->type);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
 }
 
 
@@ -1751,8 +1784,14 @@ nm_device_class_init (NMDeviceClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+       g_type_class_add_private (object_class, sizeof (NMDevicePrivate));
+
+       /* Virtual methods */
        object_class->dispose = nm_device_dispose;
        object_class->finalize = nm_device_finalize;
+       object_class->set_property = set_property;
+       object_class->get_property = get_property;
+       object_class->constructor = constructor;
 
        klass->is_test_device = real_is_test_device;
        klass->activation_cancel_handler = real_activation_cancel_handler;
@@ -1765,31 +1804,72 @@ nm_device_class_init (NMDeviceClass *klass)
        klass->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config;
        klass->act_stage4_ip_config_timeout = real_act_stage4_ip_config_timeout;
 
-       g_type_class_add_private (object_class, sizeof (NMDevicePrivate));
+       /* Properties */
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_UDI,
+                                                                         NM_DEVICE_INTERFACE_UDI);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_IFACE,
+                                                                         NM_DEVICE_INTERFACE_IFACE);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_DRIVER,
+                                                                         NM_DEVICE_INTERFACE_DRIVER);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_CAPABILITIES,
+                                                                         NM_DEVICE_INTERFACE_CAPABILITIES);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS,
+                                                                         NM_DEVICE_INTERFACE_IP4_ADDRESS);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_USE_DHCP,
+                                                                         NM_DEVICE_INTERFACE_USE_DHCP);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_STATE,
+                                                                         NM_DEVICE_INTERFACE_STATE);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_APP_DATA,
+                                                                         NM_DEVICE_INTERFACE_APP_DATA);
+
+       g_object_class_override_property (object_class,
+                                                                         NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE,
+                                                                         NM_DEVICE_INTERFACE_DEVICE_TYPE);
 }
 
-GType
-nm_device_get_type (void)
-{
-       static GType type = 0;
-       if (type == 0)
-       {
-               static const GTypeInfo info =
-               {
-                       sizeof (NMDeviceClass),
-                       NULL,   /* base_init */
-                       NULL,   /* base_finalize */
-                       (GClassInitFunc) nm_device_class_init,
-                       NULL,   /* class_finalize */
-                       NULL,   /* class_data */
-                       sizeof (NMDevice),
-                       0,              /* n_preallocs */
-                       (GInstanceInitFunc) nm_device_init,
-                       NULL            /* value_table */
-               };
-               type = g_type_register_static (G_TYPE_OBJECT,
-                                              "NMDevice",
-                                              &info, 0);
+void
+nm_device_state_changed (NMDevice *device, NMDeviceState state)
+{
+       g_return_if_fail (NM_IS_DEVICE (device));
+
+       device->priv->state = state;
+
+       switch (state) {
+       case NM_DEVICE_STATE_ACTIVATED:
+               nm_info ("Activation (%s) successful, device activated.", nm_device_get_iface (device));
+               break;
+       case NM_DEVICE_STATE_FAILED:
+               nm_info ("Activation (%s) failed.", nm_device_get_iface (device));
+               nm_device_deactivate (device);
+               break;
+       default:
+               break;
        }
-       return type;
+
+       g_signal_emit_by_name (device, "state_changed", state);
+}
+
+
+NMDeviceState
+nm_device_get_state (NMDevice *device)
+{
+       g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN);
+
+       return NM_DEVICE_GET_PRIVATE (device)->state;
 }
index 40f53d1..7d0b706 100644 (file)
@@ -94,6 +94,8 @@ struct _NMDeviceClass
        void                    (* bring_up)            (NMDevice *self);
        void                    (* bring_down)          (NMDevice *self);
 
+       void        (* set_hw_address) (NMDevice *self);
+
        guint32         (* get_type_capabilities)       (NMDevice *self);
        guint32         (* get_generic_capabilities)    (NMDevice *self);
 
@@ -125,12 +127,6 @@ struct _NMDeviceClass
 
 GType nm_device_get_type (void);
 
-NMDevice *     nm_device_new (const char *iface, 
-                                               const char *udi,
-                                               gboolean test_dev,
-                                               NMDeviceType test_dev_type,
-                                               struct NMData *app_data);
-
 void           nm_device_stop (NMDevice *self);
 
 const char *   nm_device_get_udi               (NMDevice *dev);
@@ -197,6 +193,8 @@ void                        nm_device_activation_success_handler    (NMDevice *dev,
 
 gboolean               nm_device_can_interrupt_activation              (NMDevice *self);
 
+NMDeviceState nm_device_get_state (NMDevice *device);
+
 G_END_DECLS
 
 #endif /* NM_DEVICE_H */
index d1f7a5f..09b0e01 100644 (file)
                                              NM_TYPE_SUPPLICANT_CONFIG, \
                                              NMSupplicantConfigPrivate))
 
+G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT)
 
-static void nm_supplicant_config_set_device (NMSupplicantConfig *con,
-                                             NMDevice *dev);
-
-
-struct option {
-       char * key;
-       char * value;
-       guint32 len;
+typedef struct {
+       char *value;
+       guint32 len;    
        enum OptType type;
-};
+} ConfigOption;
 
-struct _NMSupplicantConfigPrivate
+typedef struct
 {
-       NMDevice * dev;
-       GSList *   config;
+       char *     ifname;
+       GHashTable *config;
        guint32    ap_scan;
        gboolean   dispose_has_run;
-};
+} NMSupplicantConfigPrivate;
 
 NMSupplicantConfig *
-nm_supplicant_config_new (NMDevice *dev)
+nm_supplicant_config_new (const char *ifname)
 {
        NMSupplicantConfig * scfg;
 
-       g_return_val_if_fail (dev != NULL, NULL);
+       g_return_val_if_fail (ifname != NULL, NULL);
 
        scfg = g_object_new (NM_TYPE_SUPPLICANT_CONFIG, NULL);
-       nm_supplicant_config_set_device (scfg, dev);
+       NM_SUPPLICANT_CONFIG_GET_PRIVATE (scfg)->ifname = g_strdup (ifname);
+
        return scfg;
 }
 
 static void
-nm_supplicant_config_init (NMSupplicantConfig * self)
+config_option_free (ConfigOption *opt)
 {
-       self->priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
-       self->priv->config = NULL;
-       self->priv->ap_scan = 1;
-       self->priv->dispose_has_run = FALSE;
+       g_free (opt->value);
+       g_slice_free (ConfigOption, opt);
 }
 
 static void
-nm_supplicant_config_set_device (NMSupplicantConfig *self,
-                                 NMDevice *dev)
+nm_supplicant_config_init (NMSupplicantConfig * self)
 {
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (dev != NULL);
-
-       g_object_ref (G_OBJECT (dev));
-       self->priv->dev = dev;
+       NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
+
+       priv->config = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                                                 (GDestroyNotify) g_free,
+                                                                                 (GDestroyNotify) config_option_free);
+                                                                                  
+       priv->ap_scan = 1;
+       priv->dispose_has_run = FALSE;
 }
 
 gboolean
@@ -90,14 +87,17 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self,
                                  const char * value,
                                  gint32 len)
 {
-       GSList * elt;
-       struct option * opt;
+       NMSupplicantConfigPrivate *priv;
+       ConfigOption *old_opt;
+       ConfigOption *opt;
        OptType type;
 
-       g_return_val_if_fail (self != NULL, FALSE);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
        g_return_val_if_fail (key != NULL, FALSE);
        g_return_val_if_fail (value != NULL, FALSE);
 
+       priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
+
        if (len < 0)
                len = strlen (value);
 
@@ -110,130 +110,52 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self,
                return FALSE;
        }
 
-       for (elt = self->priv->config; elt; elt = g_slist_next (elt)) {
-               struct option * tmp_opt = (struct option *) elt->data;
-
-               if (strcmp (tmp_opt->key, key) == 0) {
-                       nm_debug ("Key '%s' already in table.", key);
-                       return FALSE;
-               }
+       old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key);
+       if (old_opt) {
+               nm_debug ("Key '%s' already in table.", key);
+               return FALSE;
        }
 
-       opt = g_slice_new0 (struct option);
+       opt = g_slice_new0 (ConfigOption);
        if (opt == NULL) {
                nm_debug ("Couldn't allocate memory for new config option.");
                return FALSE;
        }
-       opt->key = g_strdup (key);
-       if (opt->key == NULL) {
-               nm_debug ("Couldn't allocate memory for new config option key.");
-               g_slice_free (struct option, opt);
-               return FALSE;
-       }
+
        opt->value = g_malloc0 (sizeof (char) * len);
        if (opt->value == NULL) {
                nm_debug ("Couldn't allocate memory for new config option value.");
-               g_free (opt->key);
-               g_slice_free (struct option, opt);
+               g_slice_free (ConfigOption, opt);
                return FALSE;
        }
        memcpy (opt->value, value, len);
 
        opt->len = len;
        opt->type = type;       
-       self->priv->config = g_slist_append (self->priv->config, opt);
 
-       return TRUE;
-}
+       g_hash_table_insert (priv->config, g_strdup (key), opt);
 
-static void
-free_option (struct option * opt)
-{
-       g_return_if_fail (opt != NULL);
-       g_free (opt->key);
-       g_free (opt->value);
+       return TRUE;
 }
 
 gboolean
 nm_supplicant_config_remove_option (NMSupplicantConfig *self,
                                     const char * key)
 {
-       GSList * elt;
-       GSList * found = NULL;
-
-       g_return_val_if_fail (self != NULL, FALSE);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
        g_return_val_if_fail (key != NULL, FALSE);
 
-       for (elt = self->priv->config; elt; elt = g_slist_next (elt)) {
-               struct option * opt = (struct option *) elt->data;
-
-               if (strcmp (opt->key, key) == 0) {
-                       found = elt;
-                       break;
-               }
-       }
-
-       if (!found)
-               return FALSE;
-
-       self->priv->config = g_slist_remove_link (self->priv->config, found);
-       free_option (found->data);
-       g_slice_free (struct option, found->data);
-       g_slist_free1 (found);
-       return TRUE;
-}
-
-static void
-nm_supplicant_config_dispose (GObject *object)
-{
-       NMSupplicantConfig *            self = NM_SUPPLICANT_CONFIG (object);
-       NMSupplicantConfigClass *       klass;
-       GObjectClass *                          parent_class;  
-
-       if (self->priv->dispose_has_run)
-               /* If dispose did already run, return. */
-               return;
-
-       /* Make sure dispose does not run twice. */
-       self->priv->dispose_has_run = TRUE;
-
-       /* 
-        * In dispose, you are supposed to free all types referenced from this
-        * object which might themselves hold a reference to self. Generally,
-        * the most simple solution is to unref all members on which you own a 
-        * reference.
-        */
-       if (self->priv->dev) {
-               g_object_unref (G_OBJECT (self->priv->dev));
-               self->priv->dev = NULL;
-       }
-
-       /* Chain up to the parent class */
-       klass = NM_SUPPLICANT_CONFIG_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_CONFIG));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->dispose (object);
+       return g_hash_table_remove (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config, key);
 }
 
 static void
 nm_supplicant_config_finalize (GObject *object)
 {
-       NMSupplicantConfig *      self = NM_SUPPLICANT_CONFIG (object);
-       NMSupplicantConfigClass * klass;
-       GObjectClass *            parent_class;  
-       GSList *                  elt;
-
        /* Complete object destruction */
-       for (elt = self->priv->config; elt; elt = g_slist_next (elt)) {
-               free_option (elt->data);
-               g_slice_free (struct option, elt->data);
-       }
-       g_slist_free (self->priv->config);
-       self->priv->config = NULL;
+       g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config);
 
        /* Chain up to the parent class */
-       klass = NM_SUPPLICANT_CONFIG_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_CONFIG));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->finalize (object);
+       G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object);
 }
 
 
@@ -242,117 +164,61 @@ nm_supplicant_config_class_init (NMSupplicantConfigClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-       object_class->dispose = nm_supplicant_config_dispose;
        object_class->finalize = nm_supplicant_config_finalize;
 
        g_type_class_add_private (object_class, sizeof (NMSupplicantConfigPrivate));
 }
 
-GType
-nm_supplicant_config_get_type (void)
-{
-       static GType type = 0;
-       if (type == 0) {
-               static const GTypeInfo info = {
-                       sizeof (NMSupplicantConfigClass),
-                       NULL,   /* base_init */
-                       NULL,   /* base_finalize */
-                       (GClassInitFunc) nm_supplicant_config_class_init,
-                       NULL,   /* class_finalize */
-                       NULL,   /* class_data */
-                       sizeof (NMSupplicantConfig),
-                       0,              /* n_preallocs */
-                       (GInstanceInitFunc) nm_supplicant_config_init,
-                       NULL            /* value_table */
-               };
-
-               type = g_type_register_static (G_TYPE_OBJECT,
-                                                                "NMSupplicantConfig",
-                                                                &info, 0);
-       }
-       return type;
-}
-
 guint32
 nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self)
 {
-       g_return_val_if_fail (self != NULL, 1);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 1);
 
-       return self->priv->ap_scan;
+       return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan;
 }
 
 void
 nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
                                   guint32 ap_scan)
 {
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (ap_scan >= 0 && ap_scan <=2);
+       g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self));
+       g_return_if_fail (ap_scan >= 0 && ap_scan <= 2);
 
-       self->priv->ap_scan = ap_scan;
+       NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan;
 }
 
-gboolean
-nm_supplicant_config_add_to_dbus_message (NMSupplicantConfig * self,
-                                          DBusMessage * message)
+static void
+get_hash_cb (gpointer key, gpointer value, gpointer user_data)
 {
-       GSList * elt;
-       DBusMessageIter iter, iter_dict;
-       gboolean success = FALSE;
+       ConfigOption *opt = (ConfigOption *) value;
+       GValue *variant;
 
-       g_return_val_if_fail (self != NULL, FALSE);
-       g_return_val_if_fail (message != NULL, FALSE);
+       variant = g_slice_new0 (GValue);
+       g_value_init (variant, G_TYPE_STRING);
+       g_value_set_string (variant, opt->value);
 
-       dbus_message_iter_init_append (message, &iter);
+       g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), variant);
+}
 
-       if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) {
-               nm_warning ("dict open write failed!");
-               goto out;
-       }
+static void
+destroy_hash_value (gpointer data)
+{
+       g_slice_free (GValue, data);
+}
 
-       for (elt = self->priv->config; elt; elt = g_slist_next (elt)) {
-               struct option * opt = (struct option *) elt->data;
-
-               switch (opt->type) {
-                       case TYPE_INT:
-                               if (!nmu_dbus_dict_append_string (&iter_dict, opt->key, opt->value)) {
-                                       nm_warning ("couldn't append INT option '%s' to dict", opt->key);
-                                       goto out;
-                               }
-                               break;
-
-                       case TYPE_KEYWORD:
-                               if (!nmu_dbus_dict_append_string (&iter_dict, opt->key, opt->value)) {
-                                       nm_warning ("couldn't append KEYWORD option '%s' to dict", opt->key);
-                                       goto out;
-                               }
-                               break;
-
-                       case TYPE_BYTES:
-                               {
-                                       if (!nmu_dbus_dict_append_byte_array (&iter_dict,
-                                                                             opt->key,
-                                                                             opt->value,
-                                                                             opt->len)) {
-                                               nm_warning ("couldn't append BYTES option '%s' to dict", opt->key);
-                                               goto out;
-                                       }
-                               }
-                               break;
-
-                       default:
-                               nm_warning ("unknown option '%s', type %d", opt->key, opt->type);
-                               goto out;
-                               break;
-               }
-       }
+GHashTable *
+nm_supplicant_config_get_hash (NMSupplicantConfig * self)
+{
+       GHashTable *hash;
 
-       if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) {
-               nm_warning ("dict close write failed!");
-               goto out;
-       }
+       g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
+
+       hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                                 (GDestroyNotify) g_free,
+                                                                 destroy_hash_value);
 
-       success = TRUE;
+       g_hash_table_foreach (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config,
+                                                 get_hash_cb, hash);
 
-out:
-       return success;
+       return hash;
 }
index feb357b..f492ab1 100644 (file)
@@ -24,7 +24,6 @@
 
 #include <glib-object.h>
 #include "nm-supplicant-types.h"
-#include "nm-device.h"
 
 G_BEGIN_DECLS
 
@@ -35,28 +34,20 @@ G_BEGIN_DECLS
 #define NM_IS_SUPPLICANT_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_SUPPLICANT_CONFIG))
 #define NM_SUPPLICANT_CONFIG_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_SUPPLICANT_CONFIG, NMSupplicantConfigClass))
 
-typedef struct _NMSupplicantConfigClass NMSupplicantConfigClass;
-typedef struct _NMSupplicantConfigPrivate NMSupplicantConfigPrivate;
-
 struct _NMSupplicantConfig
 {
        GObject parent;
-
-       /*< private >*/
-       NMSupplicantConfigPrivate *priv;
 };
 
-struct _NMSupplicantConfigClass
+typedef struct
 {
        GObjectClass parent;
-
-       /* class members */
-};
+} NMSupplicantConfigClass;
 
 
 GType nm_supplicant_config_get_type (void);
 
-NMSupplicantConfig * nm_supplicant_config_new (NMDevice *dev);
+NMSupplicantConfig * nm_supplicant_config_new (const char *ifname);
 
 gboolean nm_supplicant_config_add_option (NMSupplicantConfig *scfg,
                                           const char * key,
@@ -71,8 +62,7 @@ guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self);
 void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
                                        guint32 ap_scan);
 
-gboolean nm_supplicant_config_add_to_dbus_message (NMSupplicantConfig * self,
-                                                   DBusMessage * message);
+GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig * self);
 
 G_END_DECLS
 
index aac2f7f..81e2da9 100644 (file)
  * (C) Copyright 2006 Red Hat, Inc.
  */
 
+#include <stdio.h>
 #include <string.h>
 #include <glib.h>
 
 #include "nm-supplicant-interface.h"
 #include "nm-supplicant-manager.h"
-#include "nm-device.h"
-#include "nm-device-802-3-ethernet.h"
 #include "nm-utils.h"
 #include "nm-supplicant-marshal.h"
 #include "nm-supplicant-config.h"
 #include "nm-dbus-manager.h"
 #include "dbus-dict-helpers.h"
-#include "NetworkManagerMain.h"
+#include "nm-call-store.h"
 
 #define WPAS_DBUS_IFACE_INTERFACE   WPAS_DBUS_INTERFACE ".Interface"
 #define WPAS_DBUS_IFACE_BSSID       WPAS_DBUS_INTERFACE ".BSSID"
+#define WPAS_DBUS_IFACE_NETWORK            WPAS_DBUS_INTERFACE ".Network"
+#define WPAS_ERROR_INVALID_IFACE    WPAS_DBUS_INTERFACE ".InvalidInterface"
+#define WPAS_ERROR_EXISTS_ERROR     WPAS_DBUS_INTERFACE ".ExistsError"
+
+
+G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
 
 
 #define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
@@ -89,101 +94,105 @@ enum {
 };
 
 
-struct _NMSupplicantInterfacePrivate
+typedef struct
 {
        NMSupplicantManager * smgr;
        gulong                smgr_state_sig_handler;
        NMDBusManager *       dbus_mgr;
-       NMDevice *            dev;
+       char *                dev;
+       gboolean              is_wireless;
 
        guint32               state;
-       GSList *              assoc_pcalls;
-       GSList *              other_pcalls;
+       NMCallStore *         assoc_pcalls;
+       NMCallStore *         other_pcalls;
 
        guint32               con_state;
 
-       char *                wpas_iface_op;
-       char *                wpas_net_op;
-       guint32               wpas_sig_handler_id;
+       DBusGProxy *          iface_proxy;
+       DBusGProxy *          net_proxy;
+
        GSource *             scan_results_timeout;
        guint32               last_scan;
 
        NMSupplicantConfig *  cfg;
 
        gboolean              dispose_has_run;
-};
+} NMSupplicantInterfacePrivate;
 
-static GSList *
-pcall_list_add_pcall (GSList * pcall_list,
-                      DBusPendingCall * pcall)
+static gboolean
+cancel_all_cb (GObject *object, gpointer call_id, gpointer user_data)
 {
-       GSList * elt;
+       dbus_g_proxy_cancel_call (DBUS_G_PROXY (object), (DBusGProxyCall *) call_id);
 
-       g_return_val_if_fail (pcall != NULL, pcall_list);
-
-       for (elt = pcall_list; elt; elt = g_slist_next (elt)) {
-               if (pcall == elt->data)
-                       return pcall_list;
-       }
+       return TRUE;
+}
 
-       return g_slist_append (pcall_list, pcall);
+static void
+cancel_all_callbacks (NMCallStore *store)
+{
+       nm_call_store_foreach (store, NULL, cancel_all_cb, NULL);
+       nm_call_store_clear (store);
 }
 
-static GSList *
-pcall_list_remove_pcall (GSList * pcall_list,
-                         DBusPendingCall * pcall)
+typedef struct {
+       NMSupplicantInterface *interface;
+       DBusGProxy *proxy;
+       NMCallStore *store;
+       DBusGProxyCall *call;
+} NMSupplicantInfo;
+
+NMSupplicantInfo *
+nm_supplicant_info_new (NMSupplicantInterface *interface,
+                                               DBusGProxy *proxy,
+                                               NMCallStore *store)
 {
-       GSList * elt;
+       NMSupplicantInfo *info;
 
-       g_return_val_if_fail (pcall != NULL, pcall_list);
+       info = g_slice_new0 (NMSupplicantInfo);
+       info->interface = interface;
+       info->proxy = g_object_ref (proxy);
+       info->store = store;
 
-       for (elt = pcall_list; elt; elt = g_slist_next (elt)) {
-               DBusPendingCall * item = (DBusPendingCall *) elt->data;
+       return info;
+}
 
-               if (item == pcall) {
-                       if (!dbus_pending_call_get_completed (pcall))
-                               dbus_pending_call_cancel (pcall);
-                       dbus_pending_call_unref (pcall);
-                       pcall_list = g_slist_remove_link (pcall_list, elt);
-                       g_slist_free_1 (elt);
-                       goto out;
-               }
+static void
+nm_supplicant_info_set_call (NMSupplicantInfo *info, DBusGProxyCall *call)
+{
+       if (call) {
+               nm_call_store_add (info->store, g_object_ref (info->proxy), (gpointer) call);
+               info->call = call;
        }
-
-out:
-       return pcall_list;
 }
 
-static GSList *
-pcall_list_clear (GSList * pcall_list)
+static void
+nm_supplicant_info_destroy (gpointer user_data)
 {
-       GSList * elt;
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
 
-       for (elt = pcall_list; elt; elt = g_slist_next (elt)) {
-               DBusPendingCall * pcall = (DBusPendingCall *) elt->data;
+       if (info->call)
+               nm_call_store_remove (info->store, G_OBJECT (info->proxy), info->call);
 
-               if (!dbus_pending_call_get_completed (pcall))
-                       dbus_pending_call_cancel (pcall);
-               dbus_pending_call_unref (pcall);
-       }
-       g_slist_free (pcall_list);
-       return NULL;
+       g_object_unref (info->proxy);
+
+       g_slice_free (NMSupplicantInfo, info);
 }
 
 
 NMSupplicantInterface *
-nm_supplicant_interface_new (NMSupplicantManager * smgr, NMDevice * dev)
+nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, gboolean is_wireless)
 {
        NMSupplicantInterface * iface;
 
-       g_return_val_if_fail (smgr != NULL, NULL);
-       g_return_val_if_fail (dev != NULL, NULL);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL);
+       g_return_val_if_fail (ifname != NULL, NULL);
 
        iface = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE,
                              "supplicant-manager", smgr,
-                             "device", dev,
+                             "device", ifname,
                              NULL);
        if (iface) {
+               NM_SUPPLICANT_INTERFACE_GET_PRIVATE (iface)->is_wireless = is_wireless;
                nm_supplicant_interface_start (iface);
        }
 
@@ -193,18 +202,16 @@ nm_supplicant_interface_new (NMSupplicantManager * smgr, NMDevice * dev)
 static void
 nm_supplicant_interface_init (NMSupplicantInterface * self)
 {
-       self->priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
-
-       self->priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
-       self->priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
-       self->priv->smgr = NULL;
-       self->priv->dev = NULL;
-       self->priv->wpas_iface_op = NULL;
-       self->priv->assoc_pcalls = NULL;
-       self->priv->other_pcalls = NULL;
-       self->priv->dispose_has_run = FALSE;
-
-       self->priv->dbus_mgr = nm_dbus_manager_get ();
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+       priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT;
+       priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED;
+       priv->assoc_pcalls = nm_call_store_new ();
+       priv->other_pcalls = nm_call_store_new ();
+
+       priv->dispose_has_run = FALSE;
+
+       priv->dbus_mgr = nm_dbus_manager_get ();
 }
 
 
@@ -214,23 +221,23 @@ nm_supplicant_interface_set_property (GObject *      object,
                                       const GValue * value,
                                       GParamSpec *   pspec)
 {
-       NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object);
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
        gulong id;
 
        switch (prop_id) {
                case PROP_SUPPLICANT_MANAGER:
-                       self->priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value));
-                       g_object_ref (G_OBJECT (self->priv->smgr));
+                       priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value));
+                       g_object_ref (G_OBJECT (priv->smgr));
                        
-                       id = g_signal_connect (G_OBJECT (self->priv->smgr),
+                       id = g_signal_connect (priv->smgr,
                                               "state",
                                               G_CALLBACK (nm_supplicant_interface_smgr_state_changed),
-                                              self);
-                       self->priv->smgr_state_sig_handler = id;
+                                              object);
+                       priv->smgr_state_sig_handler = id;
                        break;
                case PROP_DEVICE:
-                       self->priv->dev = NM_DEVICE (g_value_get_object (value));
-                       g_object_ref (G_OBJECT (self->priv->dev));
+                       /* Construct-only */
+                       priv->dev = g_strdup (g_value_get_string (value));
                        break;
                case PROP_STATE:
                        /* warn on setting read-only property */
@@ -250,20 +257,20 @@ nm_supplicant_interface_get_property (GObject *     object,
                                       GValue *      value,
                                       GParamSpec *  pspec)
 {
-       NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object);
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
 
        switch (prop_id) {
                case PROP_SUPPLICANT_MANAGER:
-                       g_value_set_object (value, G_OBJECT (self->priv->smgr));
+                       g_value_set_object (value, G_OBJECT (priv->smgr));
                        break;
                case PROP_DEVICE:
-                       g_value_set_object (value, G_OBJECT (self->priv->dev));
+                       g_value_set_string (value, priv->dev);
                        break;
                case PROP_STATE:
-                       g_value_set_uint (value, self->priv->state);
+                       g_value_set_uint (value, priv->state);
                        break;
                case PROP_CONNECTION_STATE:
-                       g_value_set_uint (value, self->priv->con_state);
+                       g_value_set_uint (value, priv->con_state);
                        break;
                default:
                        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -274,17 +281,15 @@ nm_supplicant_interface_get_property (GObject *     object,
 static void
 nm_supplicant_interface_dispose (GObject *object)
 {
-       NMSupplicantInterface *      self = NM_SUPPLICANT_INTERFACE (object);
-       NMSupplicantInterfaceClass * klass;
-       GObjectClass *               parent_class;  
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object);
 
-       if (self->priv->dispose_has_run) {
+       if (priv->dispose_has_run) {
                /* If dispose did already run, return. */
                return;
        }
 
        /* Make sure dispose does not run twice. */
-       self->priv->dispose_has_run = TRUE;
+       priv->dispose_has_run = TRUE;
 
        /* 
         * In dispose, you are supposed to free all types referenced from this
@@ -292,85 +297,52 @@ nm_supplicant_interface_dispose (GObject *object)
         * the most simple solution is to unref all members on which you own a 
         * reference.
         */
-       if (self->priv->scan_results_timeout) {
-               g_source_destroy (self->priv->scan_results_timeout);
-               self->priv->scan_results_timeout = NULL;
-       }
 
-       if (self->priv->smgr) {
-               g_signal_handler_disconnect (G_OBJECT (self->priv->smgr),
-                                            self->priv->smgr_state_sig_handler);
-               g_object_unref (self->priv->smgr);
-               self->priv->smgr = NULL;
-       }
+       if (priv->iface_proxy)
+               g_object_unref (priv->iface_proxy);
 
-       if (self->priv->dev) {
-               g_object_unref (self->priv->dev);
-               self->priv->dev = NULL;
-       }
+       if (priv->net_proxy)
+               g_object_unref (priv->net_proxy);
 
-       /* Cancel pending calls before unrefing the dbus manager */
-       self->priv->other_pcalls = pcall_list_clear (self->priv->other_pcalls);
-       self->priv->assoc_pcalls = pcall_list_clear (self->priv->assoc_pcalls);
-
-       if (self->priv->dbus_mgr) {
-               if (self->priv->wpas_sig_handler_id) {
-                       nm_dbus_manager_remove_signal_handler (self->priv->dbus_mgr,
-                                                              self->priv->wpas_sig_handler_id);
-                       self->priv->wpas_sig_handler_id = 0;
-               }
+       if (priv->scan_results_timeout)
+               g_source_destroy (priv->scan_results_timeout);
 
-               g_object_unref (self->priv->dbus_mgr);
-               self->priv->dbus_mgr = NULL;
+       if (priv->smgr) {
+               g_signal_handler_disconnect (priv->smgr,
+                                            priv->smgr_state_sig_handler);
+               g_object_unref (priv->smgr);
        }
 
-       if (self->priv->cfg) {
-               g_object_unref (self->priv->cfg);
-               self->priv->cfg = NULL;
-       }
+       g_free (priv->dev);
 
-       /* Chain up to the parent class */
-       klass = NM_SUPPLICANT_INTERFACE_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_INTERFACE));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->dispose (object);
-}
+       /* Cancel pending calls before unrefing the dbus manager */
+       cancel_all_callbacks (priv->other_pcalls);
+       nm_call_store_destroy (priv->other_pcalls);
 
-static void
-nm_supplicant_interface_finalize (GObject *object)
-{
-       NMSupplicantInterface *      self = NM_SUPPLICANT_INTERFACE (object);
-       NMSupplicantInterfaceClass * klass;
-       GObjectClass *               parent_class;
+       cancel_all_callbacks (priv->assoc_pcalls);
+       nm_call_store_destroy (priv->assoc_pcalls);
 
-       if (self->priv->wpas_iface_op) {
-               g_free (self->priv->wpas_iface_op);
-               self->priv->wpas_iface_op = NULL;
-       }
+       if (priv->dbus_mgr)
+               g_object_unref (priv->dbus_mgr);
 
-       if (self->priv->wpas_net_op) {
-               g_free (self->priv->wpas_net_op);
-               self->priv->wpas_net_op = NULL;
-       }
+       if (priv->cfg)
+               g_object_unref (priv->cfg);
 
        /* Chain up to the parent class */
-       klass = NM_SUPPLICANT_INTERFACE_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_INTERFACE));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->finalize (object);
+       G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object);
 }
 
-
 static void
 nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+       g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
+
        object_class->dispose = nm_supplicant_interface_dispose;
-       object_class->finalize = nm_supplicant_interface_finalize;
        object_class->set_property = nm_supplicant_interface_set_property;
        object_class->get_property = nm_supplicant_interface_get_property;
 
-       g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate));
-
        /* Properties */
        g_object_class_install_property (object_class,
                                         PROP_SUPPLICANT_MANAGER,
@@ -378,18 +350,18 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                                                              "Supplicant Manager",
                                                              "Supplicant manager to which this interface belongs",
                                                              NM_TYPE_SUPPLICANT_MANAGER,
-                                                             G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
   
        g_object_class_install_property (object_class,
                                         PROP_DEVICE,
-                                        g_param_spec_object ("device",
+                                        g_param_spec_string ("device",
                                                              "Device",
                                                              "Device which this interface represents to the supplicant",
-                                                             NM_TYPE_DEVICE,
-                                                             G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+                                                             NULL,
+                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
        g_object_class_install_property (object_class,
-                                        PROP_DEVICE,
+                                        PROP_STATE,
                                         g_param_spec_uint ("state",
                                                            "State",
                                                            "State of the supplicant interface; INIT, READY, or DOWN",
@@ -407,7 +379,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                              NULL, NULL,
                              nm_supplicant_marshal_VOID__UINT_UINT,
                              G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-       klass->state = NULL;
 
        nm_supplicant_interface_signals[REMOVED] =
                g_signal_new ("removed",
@@ -417,7 +388,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                              NULL, NULL,
                              g_cclosure_marshal_VOID__VOID,
                              G_TYPE_NONE, 0);
-       klass->removed = NULL;
 
        nm_supplicant_interface_signals[SCANNED_AP] =
                g_signal_new ("scanned-ap",
@@ -427,7 +397,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                              NULL, NULL,
                              g_cclosure_marshal_VOID__POINTER,
                              G_TYPE_NONE, 1, G_TYPE_POINTER);
-       klass->scanned_ap = NULL;
 
        nm_supplicant_interface_signals[SCAN_RESULT] =
                g_signal_new ("scan-result",
@@ -437,7 +406,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                              NULL, NULL,
                              g_cclosure_marshal_VOID__UINT,
                              G_TYPE_NONE, 1, G_TYPE_UINT);
-       klass->scan_result = NULL;
 
        nm_supplicant_interface_signals[CONNECTION_STATE] =
                g_signal_new ("connection-state",
@@ -447,7 +415,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                              NULL, NULL,
                              nm_supplicant_marshal_VOID__UINT_UINT,
                              G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-       klass->connection_state = NULL;
 
        nm_supplicant_interface_signals[CONNECTION_ERROR] =
                g_signal_new ("connection-error",
@@ -457,301 +424,146 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass)
                              NULL, NULL,
                              nm_supplicant_marshal_VOID__CHAR_CHAR,
                              G_TYPE_NONE, 2, G_TYPE_CHAR, G_TYPE_CHAR);
-       klass->connection_error = NULL;
-}
-
-GType
-nm_supplicant_interface_get_type (void)
-{
-       static GType type = 0;
-       if (type == 0) {
-               static const GTypeInfo info = {
-                       sizeof (NMSupplicantInterfaceClass),
-                       NULL,   /* base_init */
-                       NULL,   /* base_finalize */
-                       (GClassInitFunc) nm_supplicant_interface_class_init,
-                       NULL,   /* class_finalize */
-                       NULL,   /* class_data */
-                       sizeof (NMSupplicantInterface),
-                       0,              /* n_preallocs */
-                       (GInstanceInitFunc) nm_supplicant_interface_init,
-                       NULL            /* value_table */
-               };
-
-               type = g_type_register_static (G_TYPE_OBJECT,
-                                                                "NMSupplicantInterface",
-                                                                &info, 0);
-       }
-       return type;
 }
 
 static void
-emit_error_helper (NMSupplicantInterface * self,
-                   const char * name,
-                   const char * message)
+emit_error_helper (NMSupplicantInterface *self,
+                                  GError *err)
 {
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (name != NULL);
-       g_return_if_fail (message != NULL);
+       const char *name = NULL;
 
-       g_signal_emit (G_OBJECT (self),
+       if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION)
+               name = dbus_g_error_get_name (err);
+
+       g_signal_emit (self,
                       nm_supplicant_interface_signals[CONNECTION_ERROR],
                       0,
                       name,
-                      message);
+                      err->message);
 }
 
-
 static void
-set_wpas_iface_op_from_message (NMSupplicantInterface * self,
-                                DBusMessage * message)
+bssid_properties_cb  (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError error;
-       char * path = NULL;
-
-       dbus_error_init (&error);
-
-       /* Interface was found; cache its object path */
-       if (!dbus_message_get_args (message,
-                                   &error,
-                                   DBUS_TYPE_OBJECT_PATH, &path,
-                                   DBUS_TYPE_INVALID)) {
-               nm_warning ("Error getting interface path from supplicant: %s - %s",
-                           error.name,
-                           error.message);
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       GHashTable *hash = NULL;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+                                                               dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash,
+                                                               G_TYPE_INVALID)) {
+               nm_warning ("Couldn't retrieve BSSID properties: %s.", err->message);
+               g_error_free (err);
        } else {
-               if (self->priv->wpas_iface_op)
-                       g_free (self->priv->wpas_iface_op);
-               self->priv->wpas_iface_op = g_strdup (path);
-       }
-
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-}
-
-static void
-bssid_properties_cb (DBusPendingCall * pcall,
-                     NMSupplicantInterface * self)
-{
-       DBusError     error;
-       DBusMessage * reply = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
+               g_signal_emit (info->interface,
+                                          nm_supplicant_interface_signals[SCANNED_AP],
+                                          0,
+                                          hash);
 
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
-
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               if (!dbus_set_error_from_message (&error, reply)) {
-                       nm_warning ("Couldn't set error from DBus message.");
-                       goto out;
-               }
-               nm_warning ("Couldn't retrieve BSSID properties: %s - %s",
-                           error.name,
-                           error.message);
-               goto out;
+               g_hash_table_destroy (hash);
        }
-
-       g_signal_emit (G_OBJECT (self),
-                      nm_supplicant_interface_signals[SCANNED_AP],
-                      0,
-                      reply);
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
 }
 
 static void
 request_bssid_properties (NMSupplicantInterface * self,
                           const char * op)
 {
-       DBusMessage * message = NULL;
-       DBusConnection * connection = NULL;
-       DBusPendingCall * pcall = NULL;
-
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (op != NULL);
-
-       connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!connection) {
-               nm_warning ("could not get dbus connection.");
-               goto out;
-       }
-
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               op,
-                                               WPAS_DBUS_IFACE_BSSID,
-                                               "properties");
-       if (!message) {
-               nm_warning ("could not allocate dbus message.");
-               goto out;
-       }
-
-       pcall = nm_dbus_send_with_callback (connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) bssid_properties_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       if (!pcall) {
-               nm_warning ("could not send dbus message.");
-               goto out;
-       }
-       self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall);
-
-out:
-       if (message)
-               dbus_message_unref (message);
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+       NMSupplicantInfo *info;
+       DBusGProxy *proxy;
+       DBusGProxyCall *call;
+
+       proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+                                                                          WPAS_DBUS_SERVICE,
+                                                                          op,
+                                                                          WPAS_DBUS_IFACE_BSSID);
+       info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
+       call = dbus_g_proxy_begin_call (proxy, "properties",
+                                                                       bssid_properties_cb,
+                                                                       info,
+                                                                       nm_supplicant_info_destroy,
+                                                                       G_TYPE_INVALID);
+       nm_supplicant_info_set_call (info, call);
+       g_object_unref (proxy);
 }
 
 static void
-scan_results_cb (DBusPendingCall * pcall,
-                 NMSupplicantInterface * self)
+scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError     error;
-       DBusMessage * reply = NULL;
-       char **       bssids;
-       int           num_bssids;
-       char **       item;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
-
-       if (!dbus_message_get_args (reply,
-                                   &error,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &bssids, &num_bssids,
-                                   DBUS_TYPE_INVALID)) {
-               nm_warning ("could not get scan results: %s - %s.",
-                           error.name,
-                           error.message);
-               goto out;
-       }
-
-       /* Notify listeners of the result of the scan */
-       g_signal_emit (G_OBJECT (self),
-                      nm_supplicant_interface_signals[SCAN_RESULT],
-                      0,
-                      NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS);
+       GError *err = NULL;
+       GPtrArray *array = NULL;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+                                                               dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &array,
+                                                               G_TYPE_INVALID)) {
+               nm_warning ("could not get scan results: %s.", err->message);
+               g_error_free (err);
+       } else {
+               int i;
+               NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+
+               /* Notify listeners of the result of the scan */
+               g_signal_emit (info->interface,
+                                          nm_supplicant_interface_signals[SCAN_RESULT],
+                                          0,
+                                          NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS);
+
+               /* Fire off a "properties" call for each returned BSSID */
+               for (i = 0; i < array->len; i++) {
+                       request_bssid_properties (info->interface, g_ptr_array_index (array, i));
+               }
 
-       /* Fire off a "properties" call for each returned BSSID */
-       for (item = bssids; *item; item++) {
-               request_bssid_properties (self, *item);
+               g_ptr_array_free (array, TRUE);
        }
-       dbus_free_string_array (bssids);
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
 }
 
 static gboolean
 request_scan_results (gpointer user_data)
 {
-       NMSupplicantInterface * self = (NMSupplicantInterface *) user_data;
-       DBusMessage *           message = NULL;
-       DBusPendingCall *       pcall;
-       DBusConnection *        connection;
-       GTimeVal                cur_time;
-
-       if (!self || !self->priv->wpas_iface_op) {
-               nm_warning ("Invalid user_data or bad supplicant interface object path.");
-               goto out;
-       }
-
-       connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!connection) {
-               nm_warning ("could not get dbus connection.");
-               goto out;
-       }
-
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "scanResults");
-       if (!message) {
-               nm_warning ("could not allocate dbus message.");
-               goto out;
-       }
-
-       pcall = nm_dbus_send_with_callback (connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) scan_results_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       if (!pcall) {
-               nm_warning ("could not send dbus message.");
-               goto out;
-       }
-       self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall);
+       NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data);
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+       NMSupplicantInfo *info;
+       DBusGProxyCall *call;
+       GTimeVal cur_time;
+
+       info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+       call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanResults", scan_results_cb, 
+                                                                       info,
+                                                                       nm_supplicant_info_destroy,
+                                                                       G_TYPE_INVALID);
+       nm_supplicant_info_set_call (info, call);
 
        g_get_current_time (&cur_time);
-       self->priv->last_scan = cur_time.tv_sec;
+       priv->last_scan = cur_time.tv_sec;
 
-out:
-       if (message)
-               dbus_message_unref (message);
-
-       if (self->priv->scan_results_timeout) {
-               g_source_unref (self->priv->scan_results_timeout);
-               self->priv->scan_results_timeout = NULL;
+       if (priv->scan_results_timeout) {
+               g_source_unref (priv->scan_results_timeout);
+               priv->scan_results_timeout = NULL;
        }
 
        return FALSE;
 }
 
 static void
-wpas_iface_query_scan_results (NMSupplicantInterface * self)
+wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data)
 {
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
        guint id;
        GSource * source;
-       NMData * app_data;
-
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (self->priv->dev);
 
        /* Only query scan results if a query is not queued */
-       if (self->priv->scan_results_timeout)
-               return;
-
-       app_data = nm_device_get_app_data (self->priv->dev);
-       if (!app_data)
+       if (priv->scan_results_timeout)
                return;
 
        /* Only fetch scan results every 4s max, but initially do it right away */
-       if (self->priv->last_scan == 0) {
-               id = g_idle_add (request_scan_results, self);
+       if (priv->last_scan == 0) {
+               id = g_idle_add (request_scan_results, user_data);
        } else {
-               id = g_timeout_add (4000, request_scan_results, self);
+               id = g_timeout_add (4000, request_scan_results, user_data);
        }
        if (id > 0) {
                source = g_main_context_find_source_by_id (NULL, id);
-               self->priv->scan_results_timeout = source;
+               priv->scan_results_timeout = source;
        }
 }
 
@@ -782,323 +594,174 @@ wpas_state_string_to_enum (const char * str_state)
 }
 
 static void
-wpas_iface_handle_state_change (NMSupplicantInterface * self,
-                                DBusMessage * message)
+wpas_iface_handle_state_change (DBusGProxy *proxy,
+                                                               const char *str_new_state,
+                                                               const char *str_old_state,
+                                                               gpointer user_data)
 {
-       DBusError error;
-       char *    str_old_state;
-       char *    str_new_state;
-       guint32   old_state, enum_new_state;
-
-       dbus_error_init (&error);
-       if (!dbus_message_get_args (message,
-                                   &error,
-                                   DBUS_TYPE_STRING, &str_new_state,
-                                   DBUS_TYPE_STRING, &str_old_state,
-                                   DBUS_TYPE_INVALID)) {
-               nm_warning ("could not get message arguments: %s - %s",
-                           error.name,
-                           error.message);
-               goto out;
-       }
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data);
+       guint32 old_state, enum_new_state;
 
        enum_new_state = wpas_state_string_to_enum (str_new_state);
-       old_state = self->priv->con_state;
-       self->priv->con_state = enum_new_state;
-       if (self->priv->con_state != old_state) {
-               g_signal_emit (G_OBJECT (self),
+       old_state = priv->con_state;
+       priv->con_state = enum_new_state;
+       if (priv->con_state != old_state) {
+               g_signal_emit (user_data,
                               nm_supplicant_interface_signals[CONNECTION_STATE],
                               0,
-                              self->priv->con_state,
+                              priv->con_state,
                               old_state);
        }
-
-out:
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
 }
 
-static gboolean
-wpas_iface_signal_handler (DBusConnection * connection,
-                           DBusMessage * message,
-                           gpointer user_data)
-{
-       NMSupplicantInterface * self = (NMSupplicantInterface *) user_data;
-       const char *            op = dbus_message_get_path (message);
-       gboolean                handled = FALSE;
-
-       g_return_val_if_fail (self != NULL, FALSE);
-
-       if (!op || !self->priv->wpas_iface_op)
-               return FALSE;
-
-       /* Only handle signals for our interface */
-       if (strcmp (op, self->priv->wpas_iface_op) != 0)
-               return FALSE;
-
-       if (dbus_message_is_signal (message,
-                                   WPAS_DBUS_IFACE_INTERFACE,
-                                   "ScanResultsAvailable")) {
-               wpas_iface_query_scan_results (self);
-               handled = TRUE;
-       } else if (dbus_message_is_signal (message,
-                                          WPAS_DBUS_IFACE_INTERFACE,
-                                          "StateChange")) {
-               wpas_iface_handle_state_change (self, message);
-               handled = TRUE;
-       }
-
-       return handled;
-}
 
 static void
-iface_state_cb (DBusPendingCall * pcall,
-                NMSupplicantInterface * self)
+iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError     error;
-       DBusMessage * reply = NULL;
-       char *        state_str = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
-
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               if (!dbus_set_error_from_message (&error, reply)) {
-                       nm_warning ("couldn't get error information.");
-               } else {
-                       nm_warning ("could not get interface state: %s - %s.",
-                                   error.name,
-                                   error.message);
-               }
-               goto out;
-       }
+       GError *err = NULL;
+       char *state_str = NULL;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+                                                               G_TYPE_STRING, &state_str,
+                                                               G_TYPE_INVALID)) {
+               nm_warning ("could not get interface state: %s.", err->message);
+               g_error_free (err);
+       } else {
+               NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
 
-       if (!dbus_message_get_args (reply,
-                                   &error,
-                                   DBUS_TYPE_STRING, &state_str,
-                                   DBUS_TYPE_INVALID)) {
-               nm_warning ("could not get interface state: %s - %s.",
-                           error.name,
-                           error.message);
-               goto out;
+               NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface)->con_state = wpas_state_string_to_enum (state_str);
+               nm_supplicant_interface_set_state (info->interface,
+                                                                                  NM_SUPPLICANT_INTERFACE_STATE_READY);
        }
-
-       self->priv->con_state = wpas_state_string_to_enum (state_str);
-       nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY);
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
 }
 
 static void
 wpas_iface_get_state (NMSupplicantInterface *self)
 {
-       DBusMessage *           message = NULL;
-       DBusPendingCall *       pcall;
-       DBusConnection *        connection;
-
-       if (!self || !self->priv->wpas_iface_op) {
-               nm_warning ("Invalid user_data or bad supplicant interface object path.");
-               goto out;
-       }
-
-       connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!connection) {
-               nm_warning ("could not get dbus connection.");
-               goto out;
-       }
-
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "state");
-       if (!message) {
-               nm_warning ("could not allocate dbus message.");
-               goto out;
-       }
-
-       pcall = nm_dbus_send_with_callback (connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) iface_state_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       if (!pcall) {
-               nm_warning ("could not send dbus message.");
-               goto out;
-       }
-       self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall);
-
-out:
-       if (message)
-               dbus_message_unref (message);
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+       NMSupplicantInfo *info;
+       DBusGProxyCall *call;
+
+       info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+       call = dbus_g_proxy_begin_call (priv->iface_proxy,
+                                                                       "state", iface_state_cb, 
+                                                                       info,
+                                                                       nm_supplicant_info_destroy,
+                                                                       G_TYPE_INVALID);
+       nm_supplicant_info_set_call (info, call);
 }
 
-#define WPAS_ERROR_INVALID_IFACE \
-       WPAS_DBUS_INTERFACE ".InvalidInterface"
-#define WPAS_ERROR_EXISTS_ERROR \
-       WPAS_DBUS_INTERFACE ".ExistsError"
-
 static void
-nm_supplicant_interface_add_cb (DBusPendingCall * pcall,
-                                NMSupplicantInterface * self)
+nm_supplicant_interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError error;
-       DBusMessage * reply = NULL;
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       char *path = NULL;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+                                                               DBUS_TYPE_G_OBJECT_PATH, &path,
+                                                               G_TYPE_INVALID)) {
+
+               if (dbus_g_error_has_name (err, WPAS_ERROR_INVALID_IFACE)) {
+                       /* Interface not added, try to add it */
+                       nm_supplicant_interface_add_to_supplicant (info->interface, FALSE);
+               } else if (dbus_g_error_has_name (err, WPAS_ERROR_EXISTS_ERROR)) {
+                       /* Interface already added, just try to get the interface */
+                       nm_supplicant_interface_add_to_supplicant (info->interface, TRUE);
+               } else {
+                       nm_warning ("Unexpected supplicant error getting interface: %s", err->message);
+               }
 
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
+               g_error_free (err);
+       } else {
+               NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
 
-       dbus_error_init (&error);
+               priv->iface_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+                                                                                                          WPAS_DBUS_SERVICE,
+                                                                                                          path,
+                                                                                                          WPAS_DBUS_IFACE_INTERFACE);
 
-       nm_dbus_send_with_callback_replied (pcall, __func__);
+               dbus_g_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID);
 
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
+               dbus_g_object_register_marshaller (nm_supplicant_marshal_VOID__STRING_STRING,
+                                                                                  G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
+               dbus_g_proxy_add_signal (priv->iface_proxy, "StateChange", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
 
-       if (dbus_message_is_error (reply, WPAS_ERROR_INVALID_IFACE)) {
-               /* Interface not added, try to add it */
-               nm_supplicant_interface_add_to_supplicant (self, FALSE);
-       } else if (dbus_message_is_error (reply, WPAS_ERROR_EXISTS_ERROR)) {
-               /* Interface already added, just try to get the interface */
-               nm_supplicant_interface_add_to_supplicant (self, TRUE);
-       } else if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               if (!dbus_set_error_from_message (&error, reply))
-                       goto out;
-
-               nm_warning ("Unexpected supplicant error getting interface: %s - %s",
-                           error.name,
-                           error.message);
-       } else {
-               guint32 id;
-
-               /* Success; cache the object path */
-               set_wpas_iface_op_from_message (self, reply);
+               dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanResultsAvailable",
+                                                                        G_CALLBACK (wpas_iface_query_scan_results),
+                                                                        info->interface,
+                                                                        NULL);
 
-               /* Attach to the scan results signal */
-               id = nm_dbus_manager_register_signal_handler (self->priv->dbus_mgr,
-                                                             WPAS_DBUS_IFACE_INTERFACE,
-                                                             WPAS_DBUS_SERVICE,
-                                                             wpas_iface_signal_handler,
-                                                             self);
-               self->priv->wpas_sig_handler_id = id;
+               dbus_g_proxy_connect_signal (priv->iface_proxy, "StateChange",
+                                                                        G_CALLBACK (wpas_iface_handle_state_change),
+                                                                        info->interface,
+                                                                        NULL);
 
                /* Interface added to the supplicant; get its initial state. */
-               wpas_iface_get_state (self);
+               wpas_iface_get_state (info->interface);
        }
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
 }
 
-
 static void
 nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self,
                                            gboolean get_only)
 {
-       DBusConnection *  dbus_connection;
-       DBusMessage *     message = NULL;
-       DBusMessageIter   iter;
-       const char *      dev_iface;
-       DBusPendingCall * pcall;
-
-       g_return_if_fail (self != NULL);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               goto out;
-       }
-
-       /* Request the interface object from the supplicant */
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               WPAS_DBUS_PATH,
-                                               WPAS_DBUS_INTERFACE,
-                                               get_only ? "getInterface" : "addInterface");
-       if (!message) {
-               nm_warning ("Not enough memory to allocate dbus message.");
-               goto out;
-       }
-
-       dbus_message_iter_init_append (message, &iter);
-       dev_iface = nm_device_get_iface (self->priv->dev);
-       if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dev_iface)) {
-               nm_warning ("Couldn't add device interface to message.");
-               goto out;
-       }
-
-       /* Add the supplicant driver name if we're adding */
-       if (!get_only) {
-               DBusMessageIter iter_dict;
-               char * driver = "wext";
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+       NMSupplicantInfo *info;
+       DBusGProxy *proxy;
+       DBusGProxyCall *call;
+
+       proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+                                                                          WPAS_DBUS_SERVICE,
+                                                                          WPAS_DBUS_PATH,
+                                                                          WPAS_DBUS_INTERFACE);
+       info = nm_supplicant_info_new (self, proxy, priv->other_pcalls);
+
+       if (get_only) {
+               call = dbus_g_proxy_begin_call (proxy,
+                                                                               "getInterface",
+                                                                               nm_supplicant_interface_add_cb,
+                                                                               info,
+                                                                               nm_supplicant_info_destroy,
+                                                                               G_TYPE_STRING, priv->dev,
+                                                                               G_TYPE_INVALID);
+       } else {
+               GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal);
+               GValue *driver;
 
-               if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) {
-                       nm_warning ("dict open write failed!");
-                       goto out;
-               }
+               driver = g_new0 (GValue, 1);
+               g_value_init (driver, G_TYPE_STRING);
+               g_value_set_string (driver, priv->is_wireless ? "wext" : "wired");
+               g_hash_table_insert (hash, "driver", driver);
 
-               if (nm_device_is_802_3_ethernet (self->priv->dev))
-                       driver = "wired";
-               if (!nmu_dbus_dict_append_string (&iter_dict, "driver", driver)) {
-                       nm_warning ("couldn't append driver to dict");
-                       goto out;
-               }
+               call = dbus_g_proxy_begin_call (proxy,
+                                                                               "addInterface",
+                                                                               nm_supplicant_interface_add_cb,
+                                                                               info,
+                                                                               nm_supplicant_info_destroy,
+                                                                               G_TYPE_STRING, priv->dev,
+                                                                               dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), hash,
+                                                                               G_TYPE_INVALID);
 
-               if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) {
-                       nm_warning ("dict close write failed!");
-                       goto out;
-               }
+               g_hash_table_destroy (hash);
        }
 
-       pcall = nm_dbus_send_with_callback (dbus_connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) nm_supplicant_interface_add_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       if (!pcall) {
-               nm_warning ("could not send dbus message.");
-               goto out;
-       }
-       self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall);
+       g_object_unref (proxy);
 
-out:
-       if (message)
-               dbus_message_unref (message);
+       nm_supplicant_info_set_call (info, call);
 }
 
 static void
 nm_supplicant_interface_start (NMSupplicantInterface * self)
 {
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
        guint32          state;
 
-       g_return_if_fail (self != NULL);
-
        /* Can only start the interface from INIT state */
-       g_return_if_fail (self->priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
+       g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT);
 
-       state = nm_supplicant_manager_get_state (self->priv->smgr);
+       state = nm_supplicant_manager_get_state (priv->smgr);
        if (state == NM_SUPPLICANT_MANAGER_STATE_IDLE) {
                nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING);
                nm_supplicant_interface_add_to_supplicant (self, FALSE);
@@ -1114,9 +777,7 @@ nm_supplicant_interface_start (NMSupplicantInterface * self)
 static void
 nm_supplicant_interface_handle_supplicant_manager_idle_state (NMSupplicantInterface * self)
 {
-       g_return_if_fail (self != NULL);
-
-       switch (self->priv->state) {
+       switch (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state) {
                case NM_SUPPLICANT_INTERFACE_STATE_INIT:
                        /* Move to STARTING state when supplicant is ready */
                        nm_supplicant_interface_start (self);
@@ -1141,28 +802,28 @@ static void
 nm_supplicant_interface_set_state (NMSupplicantInterface * self,
                                    guint32 new_state)
 {
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
        guint32 old_state;
 
-       g_return_if_fail (self != NULL);
        g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST);
 
-       if (new_state == self->priv->state)
+       if (new_state == priv->state)
                return;
 
-       old_state = self->priv->state;
+       old_state = priv->state;
        if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
                /* If the interface is transitioning to DOWN and there's are
                 * in-progress pending calls, cancel them.
                 */
-               self->priv->other_pcalls = pcall_list_clear (self->priv->other_pcalls);
-               self->priv->assoc_pcalls = pcall_list_clear (self->priv->assoc_pcalls);
+               cancel_all_callbacks (priv->other_pcalls);
+               cancel_all_callbacks (priv->assoc_pcalls);
        }
 
-       self->priv->state = new_state;
-       g_signal_emit (G_OBJECT (self),
+       priv->state = new_state;
+       g_signal_emit (self,
                       nm_supplicant_interface_signals[STATE],
                       0,
-                      self->priv->state,
+                      priv->state,
                       old_state);
 }
 
@@ -1194,612 +855,291 @@ nm_supplicant_interface_smgr_state_changed (NMSupplicantManager * smgr,
 
 
 static void
-remove_network_cb (DBusPendingCall * pcall,
-                   NMSupplicantInterface * self)
+remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError error;
-       DBusMessage * reply = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
+       GError *err = NULL;
+       guint tmp;
 
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               dbus_set_error_from_message (&error, reply);
-               nm_warning ("Couldn't remove network from supplicant interface: %s - %s",
-                           error.name,
-                           error.message);
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+               nm_warning ("Couldn't remove network from supplicant interface: %s.", err->message);
+               g_error_free (err);
        }
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
 }
 
 static void
-disconnect_cb (DBusPendingCall * pcall,
-               NMSupplicantInterface * self)
+disconnect_cb  (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError error;
-       DBusMessage * reply = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
+       GError *err = NULL;
+       guint tmp;
 
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+               nm_warning ("Couldn't disconnect supplicant interface: %s.", err->message);
+               g_error_free (err);
+       }
+}
 
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
+static void
+interface_disconnect_done (gpointer data)
+{
+       NMSupplicantInfo *info = (NMSupplicantInfo *) data;
+       NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
 
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
+       g_object_unref (priv->net_proxy);
+       priv->net_proxy = NULL;
 
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               dbus_set_error_from_message (&error, reply);
-               nm_warning ("Couldn't disconnect supplicant interface: %s - %s",
-                           error.name,
-                           error.message);
-       }
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
+       nm_supplicant_info_destroy (data);
 }
 
 void
 nm_supplicant_interface_disconnect (NMSupplicantInterface * self)
 {
-       DBusMessage *     message = NULL;
-       DBusPendingCall * pcall = NULL;
-       DBusConnection *  dbus_connection;
+       NMSupplicantInterfacePrivate *priv;
+       NMSupplicantInfo *info;
+       DBusGProxyCall *call;
+
+       g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self));
 
-       g_return_if_fail (self != NULL);
+       priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
 
        /* Clear and cancel all pending calls related to a prior
         * connection attempt.
         */
-       self->priv->assoc_pcalls = pcall_list_clear (self->priv->assoc_pcalls);
+       cancel_all_callbacks (priv->assoc_pcalls);
 
        /* Don't do anything if there is no connection to the supplicant yet. */
-       if (!self->priv->wpas_iface_op)
+       if (!priv->iface_proxy)
                return;
 
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               goto out;
-       }
-
        /* Don't try to disconnect if the supplicant interface is already
         * disconnected.
         */
-       if (self->priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
-           || self->priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) {
-               if (self->priv->wpas_net_op) {
-                       g_free (self->priv->wpas_net_op);
-                       self->priv->wpas_net_op = NULL;
+       if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED
+           || priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) {
+               if (priv->net_proxy) {
+                       g_object_unref (priv->net_proxy);
+                       priv->net_proxy = NULL;
                }
+
                return;
        }
 
        /* Remove any network that was added by NetworkManager */
-       if (self->priv->wpas_net_op) {
-               message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                                       self->priv->wpas_iface_op,
-                                                       WPAS_DBUS_IFACE_INTERFACE,
-                                                       "removeNetwork");
-               if (!message) {
-                       nm_warning ("Couldn't create dbus message.");
-                       goto out;
-               }
-
-               if (!dbus_message_append_args (message,
-                                              DBUS_TYPE_OBJECT_PATH, &self->priv->wpas_net_op,
-                                              DBUS_TYPE_INVALID)) {
-                       nm_warning ("Couldn't compose removeNetwork dbus message.");
-                       goto out;
-               }
-
-               pcall = nm_dbus_send_with_callback (dbus_connection,
-                                                   message,
-                                                   (DBusPendingCallNotifyFunction) remove_network_cb,
-                                                   self,
-                                                   NULL,
-                                                   __func__);
-               dbus_message_unref (message);
-               g_free (self->priv->wpas_net_op);
-               self->priv->wpas_net_op = NULL;
-       }
-
-       /* Send a general disconnect command */
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "disconnect");
-       if (!message) {
-               nm_warning ("Couldn't create dbus message.");
-               goto out;
-       }
-
-       pcall = nm_dbus_send_with_callback (dbus_connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) disconnect_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-
-out:
-       if (message)
-               dbus_message_unref (message);
+       if (priv->net_proxy) {
+               info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+               call = dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork", remove_network_cb,
+                                                                               info,
+                                                                               interface_disconnect_done,
+                                                                               DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy),
+                                                                               G_TYPE_INVALID);
+               nm_supplicant_info_set_call (info, call);
+       }
+
+       info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+       call = dbus_g_proxy_begin_call (priv->iface_proxy, "disconnect", disconnect_cb,
+                                                                       info,
+                                                                       nm_supplicant_info_destroy,
+                                                                       G_TYPE_INVALID);
+       nm_supplicant_info_set_call (info, call);
 }
 
-#define WPAS_DBUS_IFACE_NETWORK        WPAS_DBUS_INTERFACE ".Network"
-
 static void
-select_network_cb (DBusPendingCall * pcall,
-                   NMSupplicantInterface * self)
+select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError        error;
-       DBusMessage *    reply = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall)) {
-               emit_error_helper (self, "SelectNetworkError", "pending call not yet completed");
-               goto out;
-       }
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall))) {
-               emit_error_helper (self, "SelectNetworkError", "could not steal reply");
-               goto out;
-       }
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       guint tmp;
 
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               dbus_set_error_from_message (&error, reply);
-               nm_warning ("Couldn't select network config: %s - %s",
-                           error.name,
-                           error.message);
-               emit_error_helper (self, error.name, error.message);
-               goto out;
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+               nm_warning ("Couldn't select network config: %s.", err->message);
+               emit_error_helper (info->interface, err);
+               g_error_free (err);
        }
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall);
 }
 
 static void
-set_network_cb (DBusPendingCall * pcall,
-                NMSupplicantInterface * self)
+set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError        error;
-       DBusMessage *    reply = NULL;
-       DBusConnection * dbus_connection;
-       DBusMessage *    message = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               emit_error_helper (self, "SetNetworkError", "could not get the dbus connection.");
-               goto out;
-       }
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall)) {
-               emit_error_helper (self, "SetNetworkError", "pending call not yet completed");
-               goto out;
-       }
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall))) {
-               emit_error_helper (self, "SetNetworkError", "could not steal reply");
-               goto out;
-       }
-
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               dbus_set_error_from_message (&error, reply);
-               nm_warning ("Couldn't set network config: %s - %s",
-                           error.name,
-                           error.message);
-               emit_error_helper (self, error.name, error.message);
-               goto out;
-       }
-
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "selectNetwork");
-       if (!message) {
-               nm_warning ("Couldn't create dbus message.");
-               emit_error_helper (self, "SetNetworkError", "could not create dbus message.");
-               goto out;
-       }
-
-       if (!dbus_message_append_args (message,
-                                      DBUS_TYPE_OBJECT_PATH, &self->priv->wpas_net_op,
-                                      DBUS_TYPE_INVALID)) {
-               emit_error_helper (self, "SetNetworkError", "could not add arguments to message.");
-               goto out;
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       guint tmp;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+               nm_warning ("Couldn't set network config: %s.", err->message);
+               emit_error_helper (info->interface, err);
+               g_error_free (err);
+       } else {
+               NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+               DBusGProxyCall *call;
+
+               info = nm_supplicant_info_new (info->interface, priv->iface_proxy,
+                                                                          NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface)->assoc_pcalls);
+               call = dbus_g_proxy_begin_call (priv->iface_proxy, "selectNetwork", select_network_cb,
+                                                                               info,
+                                                                               nm_supplicant_info_destroy,
+                                                                               DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (proxy),
+                                                                               G_TYPE_INVALID);
+               nm_supplicant_info_set_call (info, call);
        }
-
-       nm_dbus_send_with_callback (dbus_connection,
-                                   message,
-                                   (DBusPendingCallNotifyFunction) select_network_cb,
-                                   self,
-                                   NULL,
-                                   __func__);
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (message)
-               dbus_message_unref (message);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall);
 }
 
 static void
-add_network_cb (DBusPendingCall * pcall,
-                NMSupplicantInterface * self)
+add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError error;
-       DBusMessage * reply = NULL;
-       DBusMessage * message = NULL;
-       DBusConnection * dbus_connection = NULL;
-       char * net_op = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               emit_error_helper (self, "AddNetworkError", "could not get the dbus connection.");
-               goto out;
-       }
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       char *path = NULL;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+                                                               DBUS_TYPE_G_OBJECT_PATH, &path,
+                                                               G_TYPE_INVALID)) {
+               nm_warning ("Couldn't add a network to the supplicant interface: %s.", err->message);
+               emit_error_helper (info->interface, err);
+               g_error_free (err);
+       } else {
+               NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
+               GHashTable *config_hash;
+               DBusGProxyCall *call;
 
-       if (!dbus_pending_call_get_completed (pcall)) {
-               emit_error_helper (self, "AddNetworkError", "pending call not yet completed.");
-               goto out;
-       }
+               config_hash = nm_supplicant_config_get_hash (priv->cfg);
 
-       if (!(reply = dbus_pending_call_steal_reply (pcall))) {
-               emit_error_helper (self, "AddNetworkError", "could not steal reply");
-               goto out;
-       }
+               priv->net_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr),
+                                                                                                        WPAS_DBUS_SERVICE,
+                                                                                                        path,
+                                                                                                        WPAS_DBUS_IFACE_NETWORK);
 
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               dbus_set_error_from_message (&error, reply);
-               nm_warning ("Couldn't add a network to the supplicant interface: %s - %s",
-                           error.name,
-                           error.message);
-               emit_error_helper (self, error.name, error.message);
-               goto out;
-       }
+               info = nm_supplicant_info_new (info->interface, priv->net_proxy, priv->assoc_pcalls);
+               call = dbus_g_proxy_begin_call (priv->net_proxy, "set", set_network_cb,
+                                                                               info,
+                                                                               nm_supplicant_info_destroy,
+                                                                               dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), config_hash,
+                                                                               G_TYPE_INVALID);
+               nm_supplicant_info_set_call (info, call);
 
-       if (!dbus_message_get_args (reply,
-                                   &error,
-                                   DBUS_TYPE_OBJECT_PATH, &net_op,
-                                   DBUS_TYPE_INVALID)) {
-               nm_warning ("couldn't get network object path from the supplicant: %s - %s",
-                           error.name,
-                           error.message);
-               emit_error_helper (self, error.name, error.message);
-               goto out;
+               g_hash_table_destroy (config_hash);
        }
-       self->priv->wpas_net_op = g_strdup (net_op);
-
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_net_op,
-                                               WPAS_DBUS_IFACE_NETWORK,
-                                               "set");
-       if (!message) {
-               nm_warning ("Couldn't create dbus message.");
-               emit_error_helper (self, "AddNetworkError", "could not create dbus message.");
-               goto out;
-       }
-
-       if (!nm_supplicant_config_add_to_dbus_message (self->priv->cfg, message)) {
-               emit_error_helper (self, "AddNetworkError", "could not add config to dbus message.");
-               goto out;
-       }
-
-       nm_dbus_send_with_callback (dbus_connection,
-                                   message,
-                                   (DBusPendingCallNotifyFunction) set_network_cb,
-                                   self,
-                                   NULL,
-                                   __func__);
-       dbus_message_unref (message);
-       
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall);
 }
 
 static void
-set_ap_scan_cb (DBusPendingCall * pcall,
-                NMSupplicantInterface * self)
+set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError error;
-       DBusMessage * reply = NULL;
-       DBusMessage * message = NULL;
-       DBusConnection * dbus_connection = NULL;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               emit_error_helper (self, "SetAPScanError", "could not get the dbus connection.");
-               goto out;
-       }
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall)) {
-               emit_error_helper (self, "SetAPScanError", "pending call not yet completed.");
-               goto out;
-       }
-
-       if (!(reply = dbus_pending_call_steal_reply (pcall))) {
-               emit_error_helper (self, "SetAPScanError", "could not steal reply");
-               goto out;
-       }
-
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
-               dbus_set_error_from_message (&error, reply);
-               nm_warning ("Couldn't send AP scan mode to the supplicant interface: %s - %s",
-                           error.name,
-                           error.message);
-               emit_error_helper (self, error.name, error.message);
-               goto out;
-       }
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       guint32 tmp;
+
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) {
+               nm_warning ("Couldn't send AP scan mode to the supplicant interface: %s.", err->message);
+               emit_error_helper (info->interface, err);
+               g_error_free (err);
+       } else {
+               DBusGProxyCall *call;
 
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "addNetwork");
-       if (!message) {
-               nm_warning ("Couldn't create dbus message.");
-               emit_error_helper (self, "SetAPScanError", "couldn't create addNetwork message");
-               goto out;
+               info = nm_supplicant_info_new (info->interface, proxy, info->store);
+               call = dbus_g_proxy_begin_call (proxy, "addNetwork", add_network_cb,
+                                                                               info,
+                                                                               nm_supplicant_info_destroy,
+                                                                               G_TYPE_INVALID);
+               nm_supplicant_info_set_call (info, call);
        }
-
-       pcall = nm_dbus_send_with_callback (dbus_connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) add_network_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall);
 }
 
-#include <stdio.h>
 gboolean
 nm_supplicant_interface_set_config (NMSupplicantInterface * self,
                                     NMSupplicantConfig * cfg)
 {
-       DBusConnection *  dbus_connection;
-       DBusMessage *     message = NULL;
-       DBusPendingCall * pcall = NULL;
-       gboolean          success = FALSE;
-       guint32           ap_scan;
-
-       g_return_val_if_fail (self != NULL, FALSE);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               goto out;
-       }
+       NMSupplicantInterfacePrivate *priv;
+       NMSupplicantInfo *info;
+       DBusGProxyCall *call;
+       guint32 ap_scan;
 
-       nm_supplicant_interface_disconnect (self);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
 
-       if (self->priv->cfg)
-               g_object_unref (self->priv->cfg);
-       self->priv->cfg = cfg;
+       priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
 
-       if (cfg == NULL) {
-               success = TRUE;
-               goto out;
-       }
+       nm_supplicant_interface_disconnect (self);
+       
+       if (priv->cfg)
+               g_object_unref (priv->cfg);
+       priv->cfg = cfg;
 
-       g_object_ref (self->priv->cfg);
+       if (cfg == NULL)
+               return TRUE;
 
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "setAPScan");
-       if (!message) {
-               nm_warning ("Couldn't create dbus message.");
-               goto out;
-       }
+       g_object_ref (priv->cfg);
 
-       ap_scan = nm_supplicant_config_get_ap_scan (self->priv->cfg);
-       if (!dbus_message_append_args (message,
-                                      DBUS_TYPE_UINT32, &ap_scan,
-                                      DBUS_TYPE_INVALID))
-       {
-               nm_warning ("couldn't set ap scan message arguments.");
-               goto out;
-       }
+       info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+       ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg);
+       call = dbus_g_proxy_begin_call (priv->iface_proxy, "setAPScan", set_ap_scan_cb,
+                                                                       info,
+                                                                       nm_supplicant_info_destroy,
+                                                                       G_TYPE_UINT, ap_scan,
+                                                                       G_TYPE_INVALID);
+       nm_supplicant_info_set_call (info, call);
 
-       pcall = nm_dbus_send_with_callback (dbus_connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) set_ap_scan_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       success = TRUE;
-
-out:
-       if (message)
-               dbus_message_unref (message);
-       return success;
+       return call != NULL;
 }
 
-NMDevice *
+const char *
 nm_supplicant_interface_get_device (NMSupplicantInterface * self)
 {
-       g_return_val_if_fail (self != NULL, NULL);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL);
 
-       return self->priv->dev;
+       return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev;
 }
 
 static void
-scan_request_cb (DBusPendingCall * pcall,
-                 NMSupplicantInterface * self)
+scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
 {
-       DBusError     error;
-       DBusMessage * reply = NULL;
-       guint32       success = FALSE;
-       guint32       scan_result = NM_SUPPLICANT_INTERFACE_SCAN_RESULT_ERROR;
-
-       g_return_if_fail (pcall != NULL);
-       g_return_if_fail (self != NULL);
-
-       dbus_error_init (&error);
-
-       nm_dbus_send_with_callback_replied (pcall, __func__);
-
-       if (!dbus_pending_call_get_completed (pcall))
-               goto out;
+       NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
+       GError *err = NULL;
+       guint32 success = 0;
 
-       if (!(reply = dbus_pending_call_steal_reply (pcall)))
-               goto out;
-
-       if (!dbus_message_get_args (reply,
-                                   &error,
-                                   DBUS_TYPE_UINT32, &success,
-                                   DBUS_TYPE_INVALID)) {
-               nm_warning ("could not get scan request result: %s - %s.",
-                           error.name,
-                           error.message);
-               goto out;
-       }
+       if (!dbus_g_proxy_end_call (proxy, call_id, &err,
+                                                               G_TYPE_UINT, &success,
+                                                               G_TYPE_INVALID)) {
+               nm_warning  ("Could not get scan request result: %s", err->message);
+               g_error_free (err);
+       } 
 
        /* Notify listeners of the result of the scan */
-       if (success == 1)
-               scan_result = NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS;
-       g_signal_emit (G_OBJECT (self),
+       g_signal_emit (info->interface,
                       nm_supplicant_interface_signals[SCAN_RESULT],
                       0,
-                      scan_result);    
-
-out:
-       if (reply)
-               dbus_message_unref (reply);
-       if (dbus_error_is_set (&error))
-               dbus_error_free (&error);
-       self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall);
+                                  success ? NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS : NM_SUPPLICANT_INTERFACE_SCAN_RESULT_ERROR);
 }
 
 gboolean
 nm_supplicant_interface_request_scan (NMSupplicantInterface * self)
 {
-       DBusConnection *  dbus_connection;
-       DBusMessage *     message = NULL;
-       gboolean          success = FALSE;
-       DBusPendingCall * pcall;
-
-       g_return_val_if_fail (self != NULL, FALSE);
-       g_return_val_if_fail (self->priv->state == NM_SUPPLICANT_INTERFACE_STATE_READY, FALSE);
-
-       dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr);
-       if (!dbus_connection) {
-               nm_warning ("could not get the dbus connection.");
-               goto out;
-       }
+       NMSupplicantInterfacePrivate *priv;
+       NMSupplicantInfo *info;
+       DBusGProxyCall *call;
 
-       message = dbus_message_new_method_call (WPAS_DBUS_SERVICE,
-                                               self->priv->wpas_iface_op,
-                                               WPAS_DBUS_IFACE_INTERFACE,
-                                               "scan");
-       if (!message) {
-               nm_warning ("Not enough memory to allocate dbus message.");
-               goto out;
-       }
+       g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE);
 
-       pcall = nm_dbus_send_with_callback (dbus_connection,
-                                           message,
-                                           (DBusPendingCallNotifyFunction) scan_request_cb,
-                                           self,
-                                           NULL,
-                                           __func__);
-       if (!pcall) {
-               nm_warning ("could not send dbus message.");
-               goto out;
-       }
-       self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall);
-       success = TRUE;
+       priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+
+       info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
+       call = dbus_g_proxy_begin_call (priv->iface_proxy, "scan", scan_request_cb, 
+                                                                       info,
+                                                                       nm_supplicant_info_destroy,
+                                                                       G_TYPE_INVALID);
+       nm_supplicant_info_set_call (info, call);
 
-out:
-       if (message)
-               dbus_message_unref (message);
-       return success;
+       return call != NULL;
 }
 
 guint32
 nm_supplicant_interface_get_state (NMSupplicantInterface * self)
 {
-       g_return_val_if_fail (self != NULL, NM_SUPPLICANT_INTERFACE_STATE_DOWN);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_STATE_DOWN);
 
-       return self->priv->state;
+       return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state;
 }
 
 guint32
 nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self)
 {
-       g_return_val_if_fail (self != NULL, NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED);
 
-       return self->priv->con_state;
+       return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->con_state;
 }
-
index d0c7afa..f4fe449 100644 (file)
@@ -23,8 +23,8 @@
 #define NM_SUPPLICANT_INTERFACE_H
 
 #include <glib-object.h>
+#include <dbus/dbus.h>
 #include "nm-supplicant-types.h"
-#include "nm-device.h"
 
 G_BEGIN_DECLS
 
@@ -79,18 +79,12 @@ enum {
 #define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_SUPPLICANT_INTERFACE))
 #define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass))
 
-typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass;
-typedef struct _NMSupplicantInterfacePrivate NMSupplicantInterfacePrivate;
-
 struct _NMSupplicantInterface
 {
        GObject parent;
-
-       /*< private >*/
-       NMSupplicantInterfacePrivate *priv;
 };
 
-struct _NMSupplicantInterfaceClass
+typedef struct
 {
        GObjectClass parent;
 
@@ -113,20 +107,21 @@ struct _NMSupplicantInterfaceClass
        void (* connection_error) (NMSupplicantInterface * iface,
                                   const char * name,
                                   const char * message);
-};
+} NMSupplicantInterfaceClass;
 
 
 GType nm_supplicant_interface_get_type (void);
 
 NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr,
-                                                     NMDevice * dev);
+                                                                                                        const char *ifname,
+                                                                                                        gboolean is_wireless);
 
 gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface,
                                              NMSupplicantConfig * cfg);
 
 void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface);
 
-NMDevice * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);
+const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);
 
 gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self);
 
index 2b6bcf9..6b080ec 100644 (file)
 #include "nm-dbus-manager.h"
 #include "nm-supplicant-marshal.h"
 
+typedef struct {
+       NMDBusManager * dbus_mgr;
+       guint32         state;
+       GSList *        ifaces;
+       gboolean        dispose_has_run;
+} NMSupplicantManagerPrivate;
 
 #define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
                                               NM_TYPE_SUPPLICANT_MANAGER, \
                                               NMSupplicantManagerPrivate))
 
+G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT)
+
+
 static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
                                                       DBusConnection *connection,
                                                       const char *name,
@@ -54,14 +63,6 @@ enum {
 static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 };
 
 
-struct _NMSupplicantManagerPrivate {
-       NMDBusManager * dbus_mgr;
-       guint32         state;
-       GSList *        ifaces;
-       gboolean        dispose_has_run;
-};
-
-
 NMSupplicantManager *
 nm_supplicant_manager_get (void)
 {
@@ -81,15 +82,15 @@ nm_supplicant_manager_get (void)
 static void
 nm_supplicant_manager_init (NMSupplicantManager * self)
 {
-       self->priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+       NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
 
-       self->priv->dispose_has_run = FALSE;
-       self->priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN;
-       self->priv->dbus_mgr = nm_dbus_manager_get ();
+       priv->dispose_has_run = FALSE;
+       priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN;
+       priv->dbus_mgr = nm_dbus_manager_get ();
 
        nm_supplicant_manager_startup (self);
 
-       g_signal_connect (G_OBJECT (self->priv->dbus_mgr),
+       g_signal_connect (priv->dbus_mgr,
                          "name-owner-changed",
                          G_CALLBACK (nm_supplicant_manager_name_owner_changed),
                          self);
@@ -98,17 +99,15 @@ nm_supplicant_manager_init (NMSupplicantManager * self)
 static void
 nm_supplicant_manager_dispose (GObject *object)
 {
-       NMSupplicantManager *      self = NM_SUPPLICANT_MANAGER (object);
-       NMSupplicantManagerClass * klass;
-       GObjectClass *             parent_class;  
+       NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
 
-       if (self->priv->dispose_has_run) {
+       if (priv->dispose_has_run) {
                /* If dispose did already run, return. */
                return;
        }
 
        /* Make sure dispose does not run twice. */
-       self->priv->dispose_has_run = TRUE;
+       priv->dispose_has_run = TRUE;
 
        /* 
         * In dispose, you are supposed to free all types referenced from this
@@ -116,27 +115,13 @@ nm_supplicant_manager_dispose (GObject *object)
         * the most simple solution is to unref all members on which you own a 
         * reference.
         */
-       if (self->priv->dbus_mgr) {
-               g_object_unref (G_OBJECT (self->priv->dbus_mgr));
-               self->priv->dbus_mgr = NULL;
+       if (priv->dbus_mgr) {
+               g_object_unref (G_OBJECT (priv->dbus_mgr));
+               priv->dbus_mgr = NULL;
        }
 
        /* Chain up to the parent class */
-       klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->dispose (object);
-}
-
-static void
-nm_supplicant_manager_finalize (GObject *object)
-{
-       NMSupplicantManagerClass * klass;
-       GObjectClass *             parent_class;  
-
-       /* Chain up to the parent class */
-       klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER));
-       parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
-       parent_class->finalize (object);
+       G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
 }
 
 static void
@@ -144,11 +129,10 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
 {
        GObjectClass * object_class = G_OBJECT_CLASS (klass);
 
-       object_class->dispose = nm_supplicant_manager_dispose;
-       object_class->finalize = nm_supplicant_manager_finalize;
-
        g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
 
+       object_class->dispose = nm_supplicant_manager_dispose;
+
        /* Signals */
        nm_supplicant_manager_signals[STATE] =
                g_signal_new ("state",
@@ -158,32 +142,6 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
                              NULL, NULL,
                              nm_supplicant_marshal_VOID__UINT_UINT,
                              G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-       klass->state = NULL;
-}
-
-GType
-nm_supplicant_manager_get_type (void)
-{
-       static GType type = 0;
-       if (type == 0) {
-               static const GTypeInfo info = {
-                       sizeof (NMSupplicantManagerClass),
-                       NULL,   /* base_init */
-                       NULL,   /* base_finalize */
-                       (GClassInitFunc) nm_supplicant_manager_class_init,
-                       NULL,   /* class_finalize */
-                       NULL,   /* class_data */
-                       sizeof (NMSupplicantManager),
-                       0,              /* n_preallocs */
-                       (GInstanceInitFunc) nm_supplicant_manager_init,
-                       NULL            /* value_table */
-               };
-
-               type = g_type_register_static (G_TYPE_OBJECT,
-                                                                "NMSupplicantManager",
-                                                                &info, 0);
-       }
-       return type;
 }
 
 static void
@@ -215,28 +173,26 @@ nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
 guint32
 nm_supplicant_manager_get_state (NMSupplicantManager * self)
 {
-       g_return_val_if_fail (self != NULL, FALSE);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE);
 
-       return self->priv->state;
+       return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->state;
 }
 
 static void
 nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state)
 {
+       NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
        guint32 old_state;
 
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (new_state < NM_SUPPLICANT_MANAGER_STATE_LAST);
-
-       if (new_state == self->priv->state)
+       if (new_state == priv->state)
                return;
 
-       old_state = self->priv->state;
-       self->priv->state = new_state;
-       g_signal_emit (G_OBJECT (self),
+       old_state = priv->state;
+       priv->state = new_state;
+       g_signal_emit (self,
                       nm_supplicant_manager_signals[STATE],
                       0,
-                      self->priv->state,
+                      priv->state,
                       old_state);
 }
 
@@ -246,7 +202,7 @@ nm_supplicant_manager_startup (NMSupplicantManager * self)
        gboolean running;
 
        /* FIXME: convert to pending call */
-       running = nm_dbus_manager_name_has_owner (self->priv->dbus_mgr,
+       running = nm_dbus_manager_name_has_owner (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->dbus_mgr,
                                                  WPAS_DBUS_SERVICE);
        if (running) {
                nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE);
@@ -255,39 +211,34 @@ nm_supplicant_manager_startup (NMSupplicantManager * self)
 
 NMSupplicantInterface *
 nm_supplicant_manager_get_iface (NMSupplicantManager * self,
-                                 NMDevice * dev)
+                                                                const char *ifname,
+                                                                gboolean is_wireless)
 {
+       NMSupplicantManagerPrivate *priv;
        NMSupplicantInterface * iface = NULL;
        GSList * elt;
-       const char * ifname;
 
-       g_return_val_if_fail (self != NULL, NULL);
-       g_return_val_if_fail (dev != NULL, NULL);
+       g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
+       g_return_val_if_fail (ifname != NULL, NULL);
+
+       priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
 
        /* Ensure we don't already have this interface */
-       ifname = nm_device_get_iface (dev);
-       for (elt = self->priv->ifaces; elt; elt = g_slist_next (elt)) {
+       for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) {
                NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data;
-               NMDevice * if_dev = nm_supplicant_interface_get_device (if_tmp);
 
-               if (!strcmp (nm_device_get_iface (if_dev), ifname)) {
+               if (!strcmp (ifname, nm_supplicant_interface_get_device (if_tmp))) {
                        iface = if_tmp;
                        break;
                }
        }
 
        if (!iface) {
-               iface = nm_supplicant_interface_new (self, dev);
+               iface = nm_supplicant_interface_new (self, ifname, is_wireless);
                if (iface)
-                       self->priv->ifaces = g_slist_append (self->priv->ifaces, iface);
+                       priv->ifaces = g_slist_append (priv->ifaces, iface);
        }
 
-       /* Object should have 2 references by now; one from the object's creation
-        * which is for the caller of this function, and one for the supplicant
-        * manager (because it's kept in the ifaces list) which is grabbed below.
-        */
-       g_object_ref (iface);
-
        return iface;
 }
 
@@ -295,25 +246,25 @@ void
 nm_supplicant_manager_release_iface (NMSupplicantManager * self,
                                      NMSupplicantInterface * iface)
 {
+       NMSupplicantManagerPrivate *priv;
        GSList * elt;
 
-       g_return_if_fail (self != NULL);
-       g_return_if_fail (iface != NULL);
+       g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self));
+       g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface));
 
-       for (elt = self->priv->ifaces; elt; elt = g_slist_next (elt)) {
+       priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
+
+       for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) {
                NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data;
 
                if (if_tmp == iface) {
                        /* Remove the iface from the supplicant manager's list and
                         * dereference to match additional reference in get_iface.
                         */
-                       self->priv->ifaces = g_slist_remove_link (self->priv->ifaces, elt);
+                       priv->ifaces = g_slist_remove_link (priv->ifaces, elt);
                        g_slist_free_1 (elt);
                        g_object_unref (iface);
                        break;
                }
        }
-
-       /* One further dereference to match g_object_new() initial refcount of 1 */
-       g_object_unref (iface);
 }
index d3f88d3..148fadb 100644 (file)
@@ -57,24 +57,18 @@ enum {
 #define NM_IS_SUPPLICANT_MANAGER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  NM_TYPE_SUPPLICANT_MANAGER))
 #define NM_SUPPLICANT_MANAGER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass))
 
-typedef struct _NMSupplicantManagerClass NMSupplicantManagerClass;
-typedef struct _NMSupplicantManagerPrivate NMSupplicantManagerPrivate;
-
 struct _NMSupplicantManager
 {
        GObject parent;
-
-       /*< private >*/
-       NMSupplicantManagerPrivate *priv;
 };
 
-struct _NMSupplicantManagerClass
+typedef struct
 {
        GObjectClass parent;
 
        /* class members */
        void (* state)  (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state);
-};
+} NMSupplicantManagerClass;
 
 GType nm_supplicant_manager_get_type (void);
 
@@ -83,7 +77,8 @@ NMSupplicantManager * nm_supplicant_manager_get (void);
 guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr);
 
 NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * mgr,
-                                                         NMDevice * dev);
+                                                         const char *ifname,
+                                                                                                                gboolean is_wireless);
 
 void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr,
                                           NMSupplicantInterface * iface);