diff --git a/ChangeLog b/ChangeLog index edd0acf33f..3da8bb8fdd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2007-09-19 Dan Williams + + * src/NetworkManagerAP.c + src/NetworkManagerAP.h + introspection/nm-access-point.xml + - Change strength-changed signal into a properties-changed signal + for all properties, not just strength. Export that signal over dbus + so listeners don't have to poll NM for changes. + - (nm_ap_export_to_dbus, nm_ap_new): not every NMAccessPoint should + get exported over D-Bus, so break up the logic and let other bits + decided when to export the AP + - (nm_ap_new_from_ap): remove, unused + + * src/nm-device-802-11-wireless.c + - (merge_scanned_ap): only export APs that are actually on the device + list, not every AP created internally + + * libnm-glib/nm-access-point.c + libnm-glib/nm-access-point.h + - Cache properties internally and only hit DBus when needed. Get + property updates from NM signals + 2007-09-16 Dan Williams * libnm-util/nm-connection.c diff --git a/introspection/nm-access-point.xml b/introspection/nm-access-point.xml index 50d1758753..12e90c47c4 100644 --- a/introspection/nm-access-point.xml +++ b/introspection/nm-access-point.xml @@ -12,10 +12,9 @@ - - + + - diff --git a/libnm-glib/nm-access-point.c b/libnm-glib/nm-access-point.c index b57fa0e29a..e6e3aef3b4 100644 --- a/libnm-glib/nm-access-point.c +++ b/libnm-glib/nm-access-point.c @@ -1,3 +1,5 @@ +#include + #include "nm-access-point.h" #include "NetworkManager.h" @@ -8,25 +10,131 @@ G_DEFINE_TYPE (NMAccessPoint, nm_access_point, NM_TYPE_OBJECT) #define NM_ACCESS_POINT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACCESS_POINT, NMAccessPointPrivate)) typedef struct { + gboolean disposed; DBusGProxy *ap_proxy; + guint32 flags; + guint32 wpa_flags; + guint32 rsn_flags; + GByteArray *ssid; + guint32 frequency; + char *hw_address; + int mode; + guint32 rate; gint8 strength; } NMAccessPointPrivate; enum { - STRENGTH_CHANGED, + PROP_0, + PROP_FLAGS, + PROP_WPA_FLAGS, + PROP_RSN_FLAGS, + PROP_SSID, + PROP_FREQUENCY, + PROP_HW_ADDRESS, + PROP_MODE, + PROP_RATE, + PROP_STRENGTH, - LAST_SIGNAL + LAST_PROP }; -static guint signals[LAST_SIGNAL] = { 0 }; +#define DBUS_PROP_FLAGS "Flags" +#define DBUS_PROP_WPA_FLAGS "WpaFlags" +#define DBUS_PROP_RSN_FLAGS "RsnFlags" +#define DBUS_PROP_SSID "Ssid" +#define DBUS_PROP_FREQUENCY "Frequency" +#define DBUS_PROP_HW_ADDRESS "HwAddress" +#define DBUS_PROP_MODE "Mode" +#define DBUS_PROP_RATE "Rate" +#define DBUS_PROP_STRENGTH "Strength" -static void strength_changed_proxy (NMAccessPoint *ap, guchar strength); +static void properties_changed_proxy (DBusGProxy *proxy, + GHashTable *properties, + gpointer user_data); static void nm_access_point_init (NMAccessPoint *ap) { } +static void +dispose (GObject *object) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); + + if (priv->disposed) + return; + priv->disposed = TRUE; + + g_object_unref (priv->ap_proxy); + + G_OBJECT_CLASS (nm_access_point_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); + + if (priv->ssid) + g_byte_array_free (priv->ssid, TRUE); + + if (priv->hw_address) + g_free (priv->hw_address); + + G_OBJECT_CLASS (nm_access_point_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); + GArray * ssid; + int len; + int i; + + switch (prop_id) { + case PROP_FLAGS: + g_value_set_uint (value, priv->flags); + break; + case PROP_WPA_FLAGS: + g_value_set_uint (value, priv->wpa_flags); + break; + case PROP_RSN_FLAGS: + g_value_set_uint (value, priv->rsn_flags); + break; + case PROP_SSID: + len = priv->ssid ? priv->ssid->len : 0; + ssid = g_array_sized_new (FALSE, TRUE, sizeof (unsigned char), len); + for (i = 0; i < len; i++) + g_array_append_val (ssid, priv->ssid->data[i]); + g_value_set_boxed (value, ssid); + g_array_free (ssid, TRUE); + break; + case PROP_FREQUENCY: + g_value_set_uint (value, priv->frequency); + break; + case PROP_HW_ADDRESS: + g_value_set_string (value, priv->hw_address); + break; + case PROP_MODE: + g_value_set_int (value, priv->mode); + break; + case PROP_RATE: + g_value_set_uint (value, priv->rate); + break; + case PROP_STRENGTH: + g_value_set_char (value, priv->strength); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static GObject* constructor (GType type, guint n_construct_params, @@ -46,13 +154,15 @@ constructor (GType type, priv->ap_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), NM_DBUS_SERVICE, nm_object_get_path (object), - NM_DBUS_INTERFACE_DEVICE); + NM_DBUS_INTERFACE_ACCESS_POINT); - dbus_g_proxy_add_signal (priv->ap_proxy, "StrengthChanged", G_TYPE_UCHAR, G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->ap_proxy, "PropertiesChanged", + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), + G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->ap_proxy, - "StrengthChanged", - G_CALLBACK (strength_changed_proxy), - NULL, + "PropertiesChanged", + G_CALLBACK (properties_changed_proxy), + NM_ACCESS_POINT (object), NULL); return G_OBJECT (object); } @@ -67,18 +177,84 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) /* virtual methods */ object_class->constructor = constructor; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; - /* signals */ - signals[STRENGTH_CHANGED] = - g_signal_new ("strength-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMAccessPointClass, strength_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UCHAR, - G_TYPE_NONE, 1, - G_TYPE_UCHAR); + /* properties */ + g_object_class_install_property + (object_class, PROP_FLAGS, + g_param_spec_uint (NM_ACCESS_POINT_FLAGS, + "Flags", + "Flags", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_FLAGS_NONE, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_WPA_FLAGS, + g_param_spec_uint (NM_ACCESS_POINT_WPA_FLAGS, + "WPA Flags", + "WPA Flags", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_RSN_FLAGS, + g_param_spec_uint (NM_ACCESS_POINT_RSN_FLAGS, + "RSN Flags", + "RSN Flags", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_SSID, + g_param_spec_boxed (NM_ACCESS_POINT_SSID, + "SSID", + "SSID", + DBUS_TYPE_G_UCHAR_ARRAY, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_FREQUENCY, + g_param_spec_uint (NM_ACCESS_POINT_FREQUENCY, + "Frequency", + "Frequency", + 0, 10000, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_ACCESS_POINT_HW_ADDRESS, + "MAC Address", + "Hardware MAC address", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_MODE, + g_param_spec_int (NM_ACCESS_POINT_MODE, + "Mode", + "Mode", + IW_MODE_ADHOC, IW_MODE_INFRA, IW_MODE_INFRA, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_RATE, + g_param_spec_uint (NM_ACCESS_POINT_RATE, + "Rate", + "Rate", + 0, G_MAXUINT16, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_STRENGTH, + g_param_spec_char (NM_ACCESS_POINT_STRENGTH, + "Strength", + "Strength", + G_MININT8, G_MAXINT8, 0, + G_PARAM_READABLE)); } NMAccessPoint * @@ -91,78 +267,226 @@ nm_access_point_new (DBusGConnection *connection, const char *path) } static void -strength_changed_proxy (NMAccessPoint *ap, guchar strength) +handle_property_changed (gpointer key, gpointer data, gpointer user_data) { + NMAccessPoint *ap = NM_ACCESS_POINT (user_data); + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + char *g_propname = NULL; + GValue *value = (GValue *) data; + gboolean success = TRUE; + + if (!strcmp (key, DBUS_PROP_FLAGS)) { + g_propname = NM_ACCESS_POINT_FLAGS; + if (G_VALUE_HOLDS_UINT (value)) + priv->flags = g_value_get_uint (value); + } else if (!strcmp (key, DBUS_PROP_WPA_FLAGS)) { + g_propname = NM_ACCESS_POINT_WPA_FLAGS; + if (G_VALUE_HOLDS_UINT (value)) + priv->wpa_flags = g_value_get_uint (value); + } else if (!strcmp (key, DBUS_PROP_RSN_FLAGS)) { + g_propname = NM_ACCESS_POINT_RSN_FLAGS; + if (G_VALUE_HOLDS_UINT (value)) + priv->rsn_flags = g_value_get_uint (value); + } else if (!strcmp (key, DBUS_PROP_SSID)) { + GArray * tmp = g_value_get_boxed (value); + + g_propname = NM_ACCESS_POINT_SSID; + + if (priv->ssid) { + g_byte_array_free (priv->ssid, TRUE); + priv->ssid = NULL; + } + + if (tmp && tmp->len) { + int i; + unsigned char byte; + + priv->ssid = g_byte_array_sized_new (tmp->len); + for (i = 0; i < tmp->len; i++) { + byte = g_array_index (tmp, unsigned char, i); + g_byte_array_append (priv->ssid, &byte, 1); + } + } + } else if (!strcmp (key, DBUS_PROP_FREQUENCY)) { + g_propname = NM_ACCESS_POINT_FREQUENCY; + if (G_VALUE_HOLDS_UINT (value)) + priv->frequency = g_value_get_uint (value); + } else if (!strcmp (key, DBUS_PROP_HW_ADDRESS)) { + g_propname = NM_ACCESS_POINT_HW_ADDRESS; + + if (priv->hw_address) { + g_free (priv->hw_address); + priv->hw_address = NULL; + } + + if (G_VALUE_HOLDS_STRING (value)) + priv->hw_address = g_strdup (g_value_get_string (value)); + } else if (!strcmp (key, DBUS_PROP_MODE)) { + g_propname = NM_ACCESS_POINT_MODE; + if (G_VALUE_HOLDS_UINT (value)) + priv->mode = g_value_get_uint (value); + } else if (!strcmp (key, DBUS_PROP_RATE)) { + g_propname = NM_ACCESS_POINT_RATE; + if (G_VALUE_HOLDS_UINT (value)) + priv->rate = g_value_get_uint (value); + } else if (!strcmp (key, DBUS_PROP_STRENGTH)) { + g_propname = NM_ACCESS_POINT_STRENGTH; + if (G_VALUE_HOLDS_CHAR (value)) + priv->strength = g_value_get_char (value); + } else { + success = FALSE; + } + + if (success) { + g_object_notify (G_OBJECT (ap), g_propname); + } +} + +static void +properties_changed_proxy (DBusGProxy *proxy, + GHashTable *properties, + gpointer user_data) +{ + NMAccessPoint *ap = NM_ACCESS_POINT (user_data); NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - if (priv->strength != strength) { - priv->strength = strength; - g_signal_emit (ap, signals[STRENGTH_CHANGED], 0, strength); - } + g_hash_table_foreach (properties, handle_property_changed, ap); } guint32 nm_access_point_get_flags (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NM_802_11_AP_FLAGS_NONE); - return nm_object_get_uint_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Flags"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->flags) { + priv->flags = nm_object_get_uint_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_FLAGS); + } + + return priv->flags; } guint32 nm_access_point_get_wpa_flags (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NM_802_11_AP_SEC_NONE); - return nm_object_get_uint_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "WpaFlags"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->wpa_flags) { + priv->wpa_flags = nm_object_get_uint_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_WPA_FLAGS); + } + + return priv->wpa_flags; } guint32 nm_access_point_get_rsn_flags (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NM_802_11_AP_SEC_NONE); - return nm_object_get_uint_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "RsnFlags"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->rsn_flags) { + priv->rsn_flags = nm_object_get_uint_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_RSN_FLAGS); + } + + return priv->rsn_flags; } -GByteArray * +const GByteArray * nm_access_point_get_ssid (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL); - return nm_object_get_byte_array_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Ssid"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->ssid) { + priv->ssid = nm_object_get_byte_array_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_SSID); + } + + return priv->ssid; } guint32 nm_access_point_get_frequency (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); - return nm_object_get_uint_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Frequency"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->frequency) { + priv->frequency = nm_object_get_uint_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_FREQUENCY); + } + + return priv->frequency; } char * nm_access_point_get_hw_address (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL); - return nm_object_get_string_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "HwAddress"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->hw_address) { + priv->hw_address = nm_object_get_string_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_HW_ADDRESS); + } + + return priv->hw_address; } int nm_access_point_get_mode (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); - return nm_object_get_int_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Mode"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->mode) { + priv->mode = nm_object_get_int_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_MODE); + } + + return priv->mode; } guint32 nm_access_point_get_rate (NMAccessPoint *ap) { + NMAccessPointPrivate *priv; + g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); - return nm_object_get_uint_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Rate"); + priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + if (!priv->rate) { + priv->rate = nm_object_get_uint_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_RATE); + } + + return priv->rate; } gint8 @@ -173,9 +497,11 @@ nm_access_point_get_strength (NMAccessPoint *ap) g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), 0); priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - if (priv->strength == 0) - priv->strength = nm_object_get_byte_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Strength"); + if (!priv->strength) { + priv->strength = nm_object_get_byte_property (NM_OBJECT (ap), + NM_DBUS_INTERFACE_ACCESS_POINT, + DBUS_PROP_STRENGTH); + } return priv->strength; } diff --git a/libnm-glib/nm-access-point.h b/libnm-glib/nm-access-point.h index 3dcd13480c..81953e8a13 100644 --- a/libnm-glib/nm-access-point.h +++ b/libnm-glib/nm-access-point.h @@ -20,11 +20,18 @@ typedef struct { typedef struct { NMObjectClass parent; - - /* Signals */ - void (*strength_changed) (NMAccessPoint *ap, gint8 strength); } NMAccessPointClass; +#define NM_ACCESS_POINT_FLAGS "flags" +#define NM_ACCESS_POINT_WPA_FLAGS "wpa_flags" +#define NM_ACCESS_POINT_RSN_FLAGS "rsn_flags" +#define NM_ACCESS_POINT_SSID "ssid" +#define NM_ACCESS_POINT_FREQUENCY "frequency" +#define NM_ACCESS_POINT_HW_ADDRESS "hw_address" +#define NM_ACCESS_POINT_MODE "mode" +#define NM_ACCESS_POINT_RATE "rate" +#define NM_ACCESS_POINT_STRENGTH "strength" + GType nm_access_point_get_type (void); NMAccessPoint *nm_access_point_new (DBusGConnection *connection, const char *path); @@ -32,7 +39,7 @@ NMAccessPoint *nm_access_point_new (DBusGConnection *connection, const char *pat guint32 nm_access_point_get_flags (NMAccessPoint *ap); guint32 nm_access_point_get_wpa_flags (NMAccessPoint *ap); guint32 nm_access_point_get_rsn_flags (NMAccessPoint *ap); -GByteArray * nm_access_point_get_ssid (NMAccessPoint *ap); +const GByteArray * nm_access_point_get_ssid (NMAccessPoint *ap); guint32 nm_access_point_get_frequency (NMAccessPoint *ap); char * nm_access_point_get_hw_address (NMAccessPoint *ap); int nm_access_point_get_mode (NMAccessPoint *ap); diff --git a/src/NetworkManagerAP.c b/src/NetworkManagerAP.c index 4f726f0ffb..8c2eb6c727 100644 --- a/src/NetworkManagerAP.c +++ b/src/NetworkManagerAP.c @@ -81,7 +81,7 @@ typedef struct G_DEFINE_TYPE (NMAccessPoint, nm_ap, G_TYPE_OBJECT) enum { - STRENGTH_CHANGED, + PROPERTIES_CHANGED, LAST_SIGNAL }; @@ -102,14 +102,22 @@ enum { LAST_PROP }; +#define DBUS_PROP_FLAGS "Flags" +#define DBUS_PROP_WPA_FLAGS "WpaFlags" +#define DBUS_PROP_RSN_FLAGS "RsnFlags" +#define DBUS_PROP_SSID "Ssid" +#define DBUS_PROP_FREQUENCY "Frequency" +#define DBUS_PROP_HW_ADDRESS "HwAddress" +#define DBUS_PROP_MODE "Mode" +#define DBUS_PROP_RATE "Rate" +#define DBUS_PROP_STRENGTH "Strength" static void nm_ap_init (NMAccessPoint *ap) { NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (ap); - static guint32 counter = 0; - priv->dbus_path = g_strdup_printf (NM_DBUS_PATH_ACCESS_POINT "/%d", counter++); + priv->dbus_path = NULL; priv->mode = IW_MODE_INFRA; priv->flags = NM_802_11_AP_FLAGS_NONE; priv->wpa_flags = NM_802_11_AP_SEC_NONE; @@ -138,18 +146,23 @@ set_property (GObject *object, guint prop_id, NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object); GArray * ssid; int mode; + char *dbus_prop = NULL; switch (prop_id) { case PROP_FLAGS: + dbus_prop = DBUS_PROP_FLAGS; priv->flags = g_value_get_uint (value); break; case PROP_WPA_FLAGS: + dbus_prop = DBUS_PROP_WPA_FLAGS; priv->wpa_flags = g_value_get_uint (value); break; case PROP_RSN_FLAGS: + dbus_prop = DBUS_PROP_RSN_FLAGS; priv->rsn_flags = g_value_get_uint (value); break; case PROP_SSID: + dbus_prop = DBUS_PROP_SSID; ssid = g_value_get_boxed (value); if (priv->ssid) { g_byte_array_free (priv->ssid, TRUE); @@ -166,9 +179,11 @@ set_property (GObject *object, guint prop_id, } break; case PROP_FREQUENCY: + dbus_prop = DBUS_PROP_FREQUENCY; priv->freq = g_value_get_uint (value); break; case PROP_MODE: + dbus_prop = DBUS_PROP_MODE; mode = g_value_get_int (value); if (mode == IW_MODE_ADHOC || mode == IW_MODE_INFRA) @@ -177,15 +192,26 @@ set_property (GObject *object, guint prop_id, g_warning ("Invalid mode"); break; case PROP_RATE: + dbus_prop = DBUS_PROP_RATE; priv->rate = g_value_get_uint (value); break; case PROP_STRENGTH: - nm_ap_set_strength (NM_AP (object), g_value_get_char (value)); + dbus_prop = DBUS_PROP_STRENGTH; + priv->strength = g_value_get_char (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + + if (dbus_prop) { + GHashTable * hash; + + hash = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (hash, dbus_prop, (gpointer) value); + g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash); + g_hash_table_destroy (hash); + } } static void @@ -345,20 +371,48 @@ nm_ap_class_init (NMAccessPointClass *ap_class) G_PARAM_READWRITE)); /* Signals */ - signals[STRENGTH_CHANGED] = - g_signal_new ("strength_changed", + signals[PROPERTIES_CHANGED] = + g_signal_new ("properties_changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMAccessPointClass, strength_changed), + G_STRUCT_OFFSET (NMAccessPointClass, properties_changed), NULL, NULL, - g_cclosure_marshal_VOID__CHAR, - G_TYPE_NONE, 1, - G_TYPE_CHAR); + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (ap_class), &dbus_glib_nm_access_point_object_info); } +void +nm_ap_export_to_dbus (NMAccessPoint *ap) +{ + NMAccessPointPrivate *priv; + NMDBusManager *mgr; + DBusGConnection *g_connection; + static guint32 counter = 0; + + g_return_if_fail (NM_IS_AP (ap)); + + priv = NM_AP_GET_PRIVATE (ap); + + if (priv->dbus_path) { + nm_warning ("Tried to export AP %s twice.", priv->dbus_path); + return; + } + + mgr = nm_dbus_manager_get (); + g_assert (mgr); + + g_connection = nm_dbus_manager_get_connection (mgr); + g_assert (g_connection); + + priv->dbus_path = g_strdup_printf (NM_DBUS_PATH_ACCESS_POINT "/%d", counter++); + dbus_g_connection_register_g_object (g_connection, priv->dbus_path, G_OBJECT (ap)); + + g_object_unref (mgr); +} + /* * nm_ap_new * @@ -373,59 +427,10 @@ NMAccessPoint *nm_ap_new (void) if (!object) return NULL; - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (nm_dbus_manager_get ()), - nm_ap_get_dbus_path (NM_AP (object)), - object); - return (NMAccessPoint *) object; } -/* - * nm_ap_new_from_ap - * - * Create a new user access point info structure, duplicating an existing one - * - */ -NMAccessPoint * -nm_ap_new_from_ap (NMAccessPoint *src_ap) -{ - NMAccessPoint * new_ap; - NMAccessPointPrivate *src_priv; - NMAccessPointPrivate *new_priv; - - g_return_val_if_fail (NM_IS_AP (src_ap), NULL); - - if (!(new_ap = nm_ap_new ())) - { - nm_warning ("nm_ap_new_from_uap() could not allocate a new user access point structure. Not enough memory?"); - return NULL; - } - - src_priv = NM_AP_GET_PRIVATE (src_ap); - new_priv = NM_AP_GET_PRIVATE (new_ap); - - if (src_priv->ssid) { - new_priv->ssid = g_byte_array_sized_new (src_priv->ssid->len); - g_byte_array_append (new_priv->ssid, - src_priv->ssid->data, - src_priv->ssid->len); - } - memcpy (&new_priv->address, &src_priv->address, sizeof (struct ether_addr)); - new_priv->mode = src_priv->mode; - new_priv->strength = src_priv->strength; - new_priv->freq = src_priv->freq; - new_priv->rate = src_priv->rate; - new_priv->artificial = src_priv->artificial; - new_priv->broadcast = src_priv->broadcast; - new_priv->flags = src_priv->flags; - new_priv->wpa_flags = src_priv->wpa_flags; - new_priv->rsn_flags = src_priv->rsn_flags; - - return new_ap; -} - - #define IEEE80211_CAP_ESS 0x0001 #define IEEE80211_CAP_IBSS 0x0002 #define IEEE80211_CAP_PRIVACY 0x0010 @@ -620,8 +625,21 @@ const GByteArray * nm_ap_get_ssid (const NMAccessPoint *ap) void nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid) { + NMAccessPointPrivate *priv; + g_return_if_fail (NM_IS_AP (ap)); + priv = NM_AP_GET_PRIVATE (ap); + + if ((ssid == priv->ssid) && ssid == NULL) + return; + + /* same SSID */ + if ((ssid && priv->ssid) && (ssid->len == priv->ssid->len)) { + if (!memcmp (ssid->data, priv->ssid->data, ssid->len)) + return; + } + g_object_set (ap, NM_AP_SSID, ssid, NULL); } @@ -642,9 +660,14 @@ nm_ap_get_flags (NMAccessPoint *ap) void nm_ap_set_flags (NMAccessPoint *ap, guint32 flags) { + NMAccessPointPrivate *priv; + g_return_if_fail (NM_IS_AP (ap)); - g_object_set (ap, NM_AP_FLAGS, flags, NULL); + priv = NM_AP_GET_PRIVATE (ap); + + if (priv->flags != flags) + g_object_set (ap, NM_AP_FLAGS, flags, NULL); } guint32 @@ -663,9 +686,14 @@ nm_ap_get_wpa_flags (NMAccessPoint *ap) void nm_ap_set_wpa_flags (NMAccessPoint *ap, guint32 flags) { + NMAccessPointPrivate *priv; + g_return_if_fail (NM_IS_AP (ap)); - g_object_set (ap, NM_AP_WPA_FLAGS, flags, NULL); + priv = NM_AP_GET_PRIVATE (ap); + + if (priv->wpa_flags != flags) + g_object_set (ap, NM_AP_WPA_FLAGS, flags, NULL); } guint32 @@ -684,9 +712,14 @@ nm_ap_get_rsn_flags (NMAccessPoint *ap) void nm_ap_set_rsn_flags (NMAccessPoint *ap, guint32 flags) { + NMAccessPointPrivate *priv; + g_return_if_fail (NM_IS_AP (ap)); - g_object_set (ap, NM_AP_RSN_FLAGS, flags, NULL); + priv = NM_AP_GET_PRIVATE (ap); + + if (priv->rsn_flags != flags) + g_object_set (ap, NM_AP_RSN_FLAGS, flags, NULL); } /* @@ -702,10 +735,31 @@ const struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap) void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr * addr) { + NMAccessPointPrivate *priv; + g_return_if_fail (NM_IS_AP (ap)); g_return_if_fail (addr != NULL); - memcpy (&NM_AP_GET_PRIVATE (ap)->address, addr, sizeof (struct ether_addr)); + priv = NM_AP_GET_PRIVATE (ap); + + if (memcmp (addr, &priv->address, sizeof (priv->address))) { + GHashTable * hash; + char buf[20]; + GValue value = {0,}; + + memcpy (&NM_AP_GET_PRIVATE (ap)->address, addr, sizeof (struct ether_addr)); + + hash = g_hash_table_new (g_str_hash, g_str_equal); + + memset (buf, 0, sizeof (buf)); + iw_ether_ntop (&priv->address, buf); + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, &buf[0]); + + g_hash_table_insert (hash, DBUS_PROP_HW_ADDRESS, (gpointer) &value); + g_signal_emit (ap, signals[PROPERTIES_CHANGED], 0, hash); + g_hash_table_destroy (hash); + } } @@ -726,9 +780,14 @@ int nm_ap_get_mode (NMAccessPoint *ap) void nm_ap_set_mode (NMAccessPoint *ap, const int mode) { + NMAccessPointPrivate *priv; + g_return_if_fail (NM_IS_AP (ap)); - g_object_set (ap, NM_AP_MODE, mode, NULL); + priv = NM_AP_GET_PRIVATE (ap); + + if (priv->mode != mode) + g_object_set (ap, NM_AP_MODE, mode, NULL); } @@ -755,10 +814,8 @@ void nm_ap_set_strength (NMAccessPoint *ap, const gint8 strength) priv = NM_AP_GET_PRIVATE (ap); - if (priv->strength != strength) { - priv->strength = strength; - g_signal_emit (ap, signals[STRENGTH_CHANGED], 0, strength); - } + if (priv->strength != strength) + g_object_set (ap, NM_AP_STRENGTH, strength, NULL); } diff --git a/src/NetworkManagerAP.h b/src/NetworkManagerAP.h index 874e46e87d..68e784aabe 100644 --- a/src/NetworkManagerAP.h +++ b/src/NetworkManagerAP.h @@ -54,14 +54,14 @@ typedef struct { GObjectClass parent; /* Signals */ - void (*strength_changed) (NMAccessPoint *ap, gint8 strength); + void (*properties_changed) (NMAccessPoint *ap, GHashTable *properties); } NMAccessPointClass; GType nm_ap_get_type (void); NMAccessPoint * nm_ap_new (void); -NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *ap); NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties); +void nm_ap_export_to_dbus (NMAccessPoint *ap); const char * nm_ap_get_dbus_path (NMAccessPoint *ap); const GTimeVal * nm_ap_get_timestamp (const NMAccessPoint *ap); diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index e08a535a72..e18ede0333 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -1711,6 +1711,7 @@ merge_scanned_ap (NMDevice80211Wireless *self, // FIXME: figure out if reference counts are correct here for AP objects g_object_ref (merge_ap); self->priv->ap_list = g_slist_append (self->priv->ap_list, merge_ap); + nm_ap_export_to_dbus (merge_ap); network_added (self, merge_ap); } }