diff options
author | Dan Williams <dcbw@redhat.com> | 2008-03-24 15:17:30 +0000 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2008-03-24 15:17:30 +0000 |
commit | 007351657f84fa9cc27ab4271539984d1c395c81 (patch) | |
tree | c625ad9edf8b807390765d2ade0b6d12dff4a25e /libnm-glib | |
parent | 1a6782962bce688df8026c1c3924009c304b1ae1 (diff) | |
download | NetworkManager-007351657f84fa9cc27ab4271539984d1c395c81.tar.gz |
2008-03-24 Dan Williams <dcbw@redhat.com>
Massive fixup of libnm-glib to:
a) have all objects (with the exception of VPN) cache their properties and
update them asynchronously on PropertiesChanged signals from NM
b) return internal const data for most attributes/properties instead of
allocated values that the caller must free
c) cache wrapped objects such that a given D-Bus path will always map to the
same GObject returned by libnm-glib
d) remove a few signals and move them to GObject property notifications
e) match recent NM D-Bus API changes for activation/deactivation
f) remove some private functions from libnm-glib headers
git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3491 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
Diffstat (limited to 'libnm-glib')
31 files changed, 2450 insertions, 1162 deletions
diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index ba306fe437..a88ca59e56 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -12,7 +12,8 @@ BUILT_SOURCES = \ nm-settings-glue.h \ nm-vpn-manager-bindings.h \ nm-vpn-connection-bindings.h \ - nm-vpn-plugin-glue.h + nm-vpn-plugin-glue.h \ + nm-active-connection-bindings.h lib_LTLIBRARIES = libnm_glib.la libnm_glib_vpn.la @@ -39,11 +40,14 @@ libnminclude_HEADERS = \ nm-cdma-device.h \ nm-vpn-connection.h \ nm-vpn-manager.h \ - nm-vpn-plugin.h + nm-vpn-plugin.h \ + nm-types.h \ + nm-active-connection.h libnm_glib_la_SOURCES = \ libnm_glib.c \ nm-object.c \ + nm-object-private.h \ nm-client.c \ nm-dbus-utils.c \ nm-dbus-utils.h \ @@ -58,7 +62,12 @@ libnm_glib_la_SOURCES = \ nm-cdma-device.c \ nm-vpn-connection.c \ nm-vpn-manager.c \ - nm-marshal-main.c + nm-marshal-main.c \ + nm-types.c \ + nm-types-private.h \ + nm-object-cache.c \ + nm-object-cache.h \ + nm-active-connection.c libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ @@ -123,6 +132,9 @@ nm-vpn-connection-bindings.h: $(top_srcdir)/introspection/nm-vpn-connection.xml nm-vpn-plugin-glue.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml dbus-binding-tool --prefix=nm_vpn_plugin --mode=glib-server --output=nm-vpn-plugin-glue.h $(top_srcdir)/introspection/nm-vpn-plugin.xml +nm-active-connection-bindings.h: $(top_srcdir)/introspection/nm-active-connection.xml + dbus-binding-tool --prefix=nm_active_connection --mode=glib-client --output=nm-active-connection-bindings.h $(top_srcdir)/introspection/nm-active-connection.xml + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm_glib.pc diff --git a/libnm-glib/libnm-glib-test.c b/libnm-glib/libnm-glib-test.c index 1f155318c6..66b26cb9cb 100644 --- a/libnm-glib/libnm-glib-test.c +++ b/libnm-glib/libnm-glib-test.c @@ -1,4 +1,5 @@ #include <stdlib.h> +#include <signal.h> #include <sys/socket.h> #include <netinet/in.h> @@ -11,8 +12,8 @@ #include "nm-device-802-3-ethernet.h" #include "nm-device-802-11-wireless.h" #include "nm-utils.h" +#include "nm-active-connection.h" -#if 0 static gboolean test_wireless_enabled (NMClient *client) { @@ -21,16 +22,15 @@ test_wireless_enabled (NMClient *client) wireless = nm_client_wireless_get_enabled (client); g_print ("Wireless enabled? %s\n", wireless ? "yes" : "no"); - nm_client_wireless_set_enabled (client, !wireless); +// nm_client_wireless_set_enabled (client, !wireless); - wireless = nm_client_wireless_get_enabled (client); - g_print ("Wireless enabled? %s\n", wireless ? "yes" : "no"); + wireless = nm_client_wireless_hardware_get_enabled (client); + g_print ("Wireless HW enabled? %s\n", wireless ? "yes" : "no"); - nm_client_wireless_set_enabled (client, !wireless); +// nm_client_wireless_set_enabled (client, !wireless); return TRUE; } -#endif static gboolean test_get_state (NMClient *client) @@ -59,8 +59,8 @@ static void dump_ip4_config (NMIP4Config *cfg) { char *tmp; - GArray *array; - char **ptr_array; + const GArray *array; + const GPtrArray *ptr_array; int i; tmp = ip4_address_as_string (nm_ip4_config_get_address (cfg)); @@ -79,9 +79,7 @@ dump_ip4_config (NMIP4Config *cfg) g_print ("IP4 broadcast: %s\n", tmp); g_free (tmp); - tmp = nm_ip4_config_get_hostname (cfg); - g_print ("IP4 hostname: %s\n", tmp); - g_free (tmp); + g_print ("IP4 hostname: %s\n", nm_ip4_config_get_hostname (cfg)); array = nm_ip4_config_get_nameservers (cfg); if (array) { @@ -91,23 +89,16 @@ dump_ip4_config (NMIP4Config *cfg) g_print ("\t%s\n", tmp); g_free (tmp); } - - g_array_free (array, TRUE); } ptr_array = nm_ip4_config_get_domains (cfg); if (ptr_array) { g_print ("IP4 domains:\n"); - for (i = 0; ptr_array[i]; i++) { - g_print ("\t%s\n", ptr_array[i]); - } - - g_strfreev (ptr_array); + for (i = 0; i < ptr_array->len; i++) + g_print ("\t%s\n", (const char *) g_ptr_array_index (ptr_array, i)); } - tmp = nm_ip4_config_get_nis_domain (cfg); - g_print ("IP4 NIS domain: %s\n", tmp); - g_free (tmp); + g_print ("IP4 NIS domain: %s\n", nm_ip4_config_get_nis_domain (cfg)); array = nm_ip4_config_get_nis_servers (cfg); if (array) { @@ -117,8 +108,6 @@ dump_ip4_config (NMIP4Config *cfg) g_print ("\t%s\n", tmp); g_free (tmp); } - - g_array_free (array, TRUE); } } @@ -149,8 +138,8 @@ static void dump_wireless (NMDevice80211Wireless *device) { const char *str; - GSList *iter; - GSList *aps; + GPtrArray *aps; + int i; g_print ("Mode: %d\n", nm_device_802_11_wireless_get_mode (device)); g_print ("Bitrate: %d\n", nm_device_802_11_wireless_get_bitrate (device)); @@ -160,13 +149,10 @@ dump_wireless (NMDevice80211Wireless *device) g_print ("AccessPoints:\n"); aps = nm_device_802_11_wireless_get_access_points (device); - for (iter = aps; iter; iter = iter->next) { - dump_access_point (NM_ACCESS_POINT (iter->data)); + for (i = 0; i < aps->len; i++) { + dump_access_point (NM_ACCESS_POINT (g_ptr_array_index (aps, i))); g_print ("\n"); } - - g_slist_foreach (aps, (GFunc) g_object_unref, NULL); - g_slist_free (aps); } static void @@ -183,33 +169,29 @@ dump_wired (NMDevice8023Ethernet *device) static void dump_device (NMDevice *device) { - char *str; - guint32 u; + const char *str; NMDeviceState state; str = nm_device_get_iface (device); g_print ("Interface: %s\n", str); - g_free (str); str = nm_device_get_udi (device); g_print ("Udi: %s\n", str); - g_free (str); str = nm_device_get_driver (device); g_print ("Driver: %s\n", str); - g_free (str); - u = nm_device_get_ip4_address (device); - g_print ("IP address: %d\n", u); + str = nm_device_get_vendor (device); + g_print ("Vendor: %s\n", str); + + str = nm_device_get_product (device); + g_print ("Product: %s\n", str); state = nm_device_get_state (device); g_print ("State: %d\n", state); - if (state == NM_DEVICE_STATE_ACTIVATED) { - NMIP4Config *cfg = nm_device_get_ip4_config (device); - dump_ip4_config (cfg); - g_object_unref (cfg); - } + if (state == NM_DEVICE_STATE_ACTIVATED) + dump_ip4_config (nm_device_get_ip4_config (device)); if (NM_IS_DEVICE_802_3_ETHERNET (device)) dump_wired (NM_DEVICE_802_3_ETHERNET (device)); @@ -220,76 +202,132 @@ dump_device (NMDevice *device) static gboolean test_devices (NMClient *client) { - GSList *list, *iter; + GPtrArray *devices; + int i; - list = nm_client_get_devices (client); + devices = nm_client_get_devices (client); g_print ("Got devices:\n"); - for (iter = list; iter; iter = iter->next) { - NMDevice *device = NM_DEVICE (iter->data); + if (!devices) { + g_print (" NONE\n"); + return TRUE; + } + + for (i = 0; i < devices->len; i++) { + NMDevice *device = g_ptr_array_index (devices, i); dump_device (device); g_print ("\n"); } - g_slist_free (list); - return TRUE; } static void -device_added_cb (NMClient *client, NMDevice *device, gpointer user_data) +active_connections_changed (NMClient *client, GParamSpec *pspec, gpointer user_data) { - g_print ("New device added\n"); - dump_device (device); + const GPtrArray *connections; + int i, j; + + g_print ("Active connections changed:\n"); + connections = nm_client_get_active_connections (client); + for (i = 0; i < connections->len; i++) { + NMActiveConnection *connection; + const GPtrArray *devices; + + connection = g_ptr_array_index (connections, i); + g_print (" %s\n", nm_object_get_path (NM_OBJECT (connection))); + devices = nm_active_connection_get_devices (connection); + for (j = 0; j < devices->len; j++) + g_print (" %s\n", nm_device_get_udi (g_ptr_array_index (devices, j))); + } } static void -device_removed_cb (NMClient *client, NMDevice *device, gpointer user_data) +show_active_connection_device (gpointer data, gpointer user_data) { - g_print ("Device removed\n"); - dump_device (device); + NMDevice *device = NM_DEVICE (data); + + g_print (" %s\n", nm_device_get_udi (device)); } -#if 0 -static gboolean -device_deactivate (gpointer user_data) +static void +test_get_active_connections (NMClient *client) { - NMDevice *device = NM_DEVICE (user_data); + const GPtrArray *connections; + int i; - nm_device_deactivate (device); + g_print ("Active connections:\n"); + connections = nm_client_get_active_connections (client); + for (i = 0; i < connections->len; i++) { + const GPtrArray *devices; - return FALSE; + g_print (" %s\n", nm_object_get_path (g_ptr_array_index (connections, i))); + devices = nm_active_connection_get_devices (g_ptr_array_index (connections, i)); + g_ptr_array_foreach ((GPtrArray *) devices, show_active_connection_device, NULL); + } } static void -device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) +device_state_changed (NMDevice *device, GParamSpec *pspec, gpointer user_data) { - char *str; + g_print ("Device state changed: %s %d\n", + nm_device_get_iface (device), + nm_device_get_state (device)); +} - str = nm_device_get_iface (device); - g_print ("Device state changed: %s %d\n", str, state); - g_free (str); - - if (state == NM_DEVICE_STATE_ACTIVATED) { - g_print ("Scheduling device deactivation\n"); - g_timeout_add (5 * 1000, - device_deactivate, - device); - } +static void +device_added_cb (NMClient *client, NMDevice *device, gpointer user_data) +{ + g_print ("New device added\n"); + dump_device (device); + g_signal_connect (G_OBJECT (device), "notify::state", + (GCallback) device_state_changed, NULL); } -#endif static void -manager_running (NMClient *client, gboolean running, gpointer user_data) +device_removed_cb (NMClient *client, NMDevice *device, gpointer user_data) { - if (running) { + g_print ("Device removed\n"); + dump_device (device); +} + +static void +manager_running (NMClient *client, GParamSpec *pspec, gpointer user_data) +{ + if (nm_client_get_manager_running (client)) { g_print ("NM appeared\n"); - /* test_wireless_enabled (client); */ + test_wireless_enabled (client); test_get_state (client); + test_get_active_connections (client); test_devices (client); } else g_print ("NM disappeared\n"); } +static GMainLoop *loop = NULL; + +static void +signal_handler (int signo) +{ + if (signo == SIGINT || signo == SIGTERM) { + g_message ("Caught signal %d, shutting down...", signo); + g_main_loop_quit (loop); + } +} + +static void +setup_signals (void) +{ + struct sigaction action; + sigset_t mask; + + sigemptyset (&mask); + action.sa_handler = signal_handler; + action.sa_mask = mask; + action.sa_flags = 0; + sigaction (SIGTERM, &action, NULL); + sigaction (SIGINT, &action, NULL); +} + int main (int argc, char *argv[]) { @@ -302,15 +340,20 @@ main (int argc, char *argv[]) exit (1); } - g_signal_connect (client, "manager-running", G_CALLBACK (manager_running), NULL); - manager_running (client, nm_client_manager_is_running (client), NULL); + g_signal_connect (client, "notify::" NM_CLIENT_MANAGER_RUNNING, + G_CALLBACK (manager_running), NULL); + g_signal_connect (client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS, + G_CALLBACK (active_connections_changed), NULL); + manager_running (client, NULL, NULL); g_signal_connect (client, "device-added", G_CALLBACK (device_added_cb), NULL); g_signal_connect (client, "device-removed", G_CALLBACK (device_removed_cb), NULL); - g_main_loop_run (g_main_loop_new (NULL, FALSE)); + loop = g_main_loop_new (NULL, FALSE); + setup_signals (); + g_main_loop_run (loop); g_object_unref (client); diff --git a/libnm-glib/nm-access-point.c b/libnm-glib/nm-access-point.c index 2373c95a54..691e88909d 100644 --- a/libnm-glib/nm-access-point.c +++ b/libnm-glib/nm-access-point.c @@ -6,6 +6,8 @@ #include "nm-access-point.h" #include "NetworkManager.h" +#include "nm-types-private.h" +#include "nm-object-private.h" #include "nm-access-point-bindings.h" @@ -15,7 +17,8 @@ G_DEFINE_TYPE (NMAccessPoint, nm_access_point, NM_TYPE_OBJECT) typedef struct { gboolean disposed; - DBusGProxy *ap_proxy; + DBusGProxy *proxy; + guint32 flags; guint32 wpa_flags; guint32 rsn_flags; @@ -24,7 +27,7 @@ typedef struct { char *hw_address; int mode; guint32 max_bitrate; - gint8 strength; + guint8 strength; } NMAccessPointPrivate; enum { @@ -52,22 +55,16 @@ enum { #define DBUS_PROP_MAX_BITRATE "MaxBitrate" #define DBUS_PROP_STRENGTH "Strength" -NMAccessPoint * +GObject * nm_access_point_new (DBusGConnection *connection, const char *path) { - return (NMAccessPoint *) g_object_new (NM_TYPE_ACCESS_POINT, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, path, - NULL); -} - -static void -nm_access_point_set_flags (NMAccessPoint *ap, guint32 flags) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); - priv->flags = flags; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_FLAGS); + return (GObject *) g_object_new (NM_TYPE_ACCESS_POINT, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } guint32 @@ -87,15 +84,6 @@ nm_access_point_get_flags (NMAccessPoint *ap) return priv->flags; } -static void -nm_access_point_set_wpa_flags (NMAccessPoint *ap, guint32 flags) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - priv->wpa_flags = flags; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_WPA_FLAGS); -} - guint32 nm_access_point_get_wpa_flags (NMAccessPoint *ap) { @@ -113,15 +101,6 @@ nm_access_point_get_wpa_flags (NMAccessPoint *ap) return priv->wpa_flags; } -static void -nm_access_point_set_rsn_flags (NMAccessPoint *ap, guint32 flags) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - priv->rsn_flags = flags; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_RSN_FLAGS); -} - guint32 nm_access_point_get_rsn_flags (NMAccessPoint *ap) { @@ -139,25 +118,6 @@ nm_access_point_get_rsn_flags (NMAccessPoint *ap) return priv->rsn_flags; } -static void -nm_access_point_set_ssid (NMAccessPoint *ap, GArray *ssid) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - if (priv->ssid) { - g_byte_array_free (priv->ssid, TRUE); - priv->ssid = NULL; - } - - if (ssid && ssid->len > 0) { - priv->ssid = g_byte_array_sized_new (ssid->len); - priv->ssid->len = ssid->len; - memcpy (priv->ssid->data, ssid->data, ssid->len); - } - - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_SSID); -} - const GByteArray * nm_access_point_get_ssid (NMAccessPoint *ap) { @@ -175,15 +135,6 @@ nm_access_point_get_ssid (NMAccessPoint *ap) return priv->ssid; } -static void -nm_access_point_set_frequency (NMAccessPoint *ap, guint32 frequency) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - priv->frequency = frequency; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_FREQUENCY); -} - guint32 nm_access_point_get_frequency (NMAccessPoint *ap) { @@ -201,16 +152,6 @@ nm_access_point_get_frequency (NMAccessPoint *ap) return priv->frequency; } -static void -nm_access_point_set_hw_address (NMAccessPoint *ap, const char *address) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - g_free (priv->hw_address); - priv->hw_address = address ? g_strdup (address) : NULL; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_HW_ADDRESS); -} - const char * nm_access_point_get_hw_address (NMAccessPoint *ap) { @@ -228,15 +169,6 @@ nm_access_point_get_hw_address (NMAccessPoint *ap) return priv->hw_address; } -static void -nm_access_point_set_mode (NMAccessPoint *ap, int mode) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - priv->mode = mode; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_MODE); -} - int nm_access_point_get_mode (NMAccessPoint *ap) { @@ -254,15 +186,6 @@ nm_access_point_get_mode (NMAccessPoint *ap) return priv->mode; } -static void -nm_access_point_set_max_bitrate (NMAccessPoint *ap, guint32 bitrate) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - priv->max_bitrate = bitrate; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_MAX_BITRATE); -} - guint32 nm_access_point_get_max_bitrate (NMAccessPoint *ap) { @@ -280,16 +203,7 @@ nm_access_point_get_max_bitrate (NMAccessPoint *ap) return priv->max_bitrate; } -static void -nm_access_point_set_strength (NMAccessPoint *ap, gint8 strength) -{ - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); - - priv->strength = strength; - g_object_notify (G_OBJECT (ap), NM_ACCESS_POINT_STRENGTH); -} - -gint8 +guint8 nm_access_point_get_strength (NMAccessPoint *ap) { NMAccessPointPrivate *priv; @@ -325,7 +239,7 @@ dispose (GObject *object) priv->disposed = TRUE; - g_object_unref (priv->ap_proxy); + g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_access_point_parent_class)->dispose (object); } @@ -345,38 +259,40 @@ finalize (GObject *object) } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { NMAccessPoint *ap = NM_ACCESS_POINT (object); switch (prop_id) { case PROP_FLAGS: - nm_access_point_set_flags (ap, g_value_get_uint (value)); + g_value_set_uint (value, nm_access_point_get_flags (ap)); break; case PROP_WPA_FLAGS: - nm_access_point_set_wpa_flags (ap, g_value_get_uint (value)); + g_value_set_uint (value, nm_access_point_get_wpa_flags (ap)); break; case PROP_RSN_FLAGS: - nm_access_point_set_rsn_flags (ap, g_value_get_uint (value)); + g_value_set_uint (value, nm_access_point_get_rsn_flags (ap)); break; case PROP_SSID: - nm_access_point_set_ssid (ap, (GArray *) g_value_get_boxed (value)); + g_value_set_boxed (value, nm_access_point_get_ssid (ap)); break; case PROP_FREQUENCY: - nm_access_point_set_frequency (ap, g_value_get_uint (value)); + g_value_set_uint (value, nm_access_point_get_frequency (ap)); break; case PROP_HW_ADDRESS: - nm_access_point_set_hw_address (ap, g_value_get_string (value)); + g_value_set_string (value, nm_access_point_get_hw_address (ap)); break; case PROP_MODE: - nm_access_point_set_mode (ap, g_value_get_int (value)); + g_value_set_int (value, nm_access_point_get_mode (ap)); break; case PROP_MAX_BITRATE: - nm_access_point_set_max_bitrate (ap, g_value_get_uint (value)); + g_value_set_uint (value, nm_access_point_get_max_bitrate (ap)); break; case PROP_STRENGTH: - nm_access_point_set_strength (ap, g_value_get_char (value)); + g_value_set_uchar (value, nm_access_point_get_strength (ap)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -384,54 +300,36 @@ set_property (GObject *object, guint prop_id, } } -static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +static gboolean +demarshal_ssid (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { - NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object); - GArray * ssid; - int len; - int i; + if (!nm_ssid_demarshal (value, (GByteArray **) field)) + return FALSE; - 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_MAX_BITRATE: - g_value_set_uint (value, priv->max_bitrate); - break; - case PROP_STRENGTH: - g_value_set_char (value, priv->strength); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + g_object_notify (G_OBJECT (object), NM_ACCESS_POINT_SSID); + return TRUE; +} + +static void +register_for_property_changed (NMAccessPoint *ap) +{ + NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (ap); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_ACCESS_POINT_FLAGS, nm_object_demarshal_generic, &priv->flags }, + { NM_ACCESS_POINT_WPA_FLAGS, nm_object_demarshal_generic, &priv->wpa_flags }, + { NM_ACCESS_POINT_RSN_FLAGS, nm_object_demarshal_generic, &priv->rsn_flags }, + { NM_ACCESS_POINT_SSID, demarshal_ssid, &priv->ssid }, + { NM_ACCESS_POINT_FREQUENCY, nm_object_demarshal_generic, &priv->frequency }, + { NM_ACCESS_POINT_HW_ADDRESS, nm_object_demarshal_generic, &priv->hw_address }, + { NM_ACCESS_POINT_MODE, nm_object_demarshal_generic, &priv->mode }, + { NM_ACCESS_POINT_MAX_BITRATE, nm_object_demarshal_generic, &priv->max_bitrate }, + { NM_ACCESS_POINT_STRENGTH, nm_object_demarshal_generic, &priv->strength }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (ap), + priv->proxy, + property_changed_info); } static GObject* @@ -450,12 +348,12 @@ constructor (GType type, priv = NM_ACCESS_POINT_GET_PRIVATE (object); - priv->ap_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), NM_DBUS_SERVICE, nm_object_get_path (object), NM_DBUS_INTERFACE_ACCESS_POINT); - nm_object_handle_properties_changed (NM_OBJECT (object), priv->ap_proxy); + register_for_property_changed (NM_ACCESS_POINT (object)); return G_OBJECT (object); } @@ -470,7 +368,6 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) /* virtual methods */ object_class->constructor = constructor; - object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; @@ -484,7 +381,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_FLAGS_NONE, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_WPA_FLAGS, @@ -492,7 +389,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) "WPA Flags", "WPA Flags", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_RSN_FLAGS, @@ -500,15 +397,15 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) "RSN Flags", "RSN Flags", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); + 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_READWRITE)); + NM_TYPE_SSID, + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_FREQUENCY, @@ -516,7 +413,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) "Frequency", "Frequency", 0, 10000, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_HW_ADDRESS, @@ -524,7 +421,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) "MAC Address", "Hardware MAC address", NULL, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_MODE, @@ -532,7 +429,7 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) "Mode", "Mode", IW_MODE_ADHOC, IW_MODE_INFRA, IW_MODE_INFRA, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_MAX_BITRATE, @@ -540,13 +437,13 @@ nm_access_point_class_init (NMAccessPointClass *ap_class) "Max Bitrate", "Max Bitrate", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_STRENGTH, - g_param_spec_char (NM_ACCESS_POINT_STRENGTH, + g_param_spec_uchar (NM_ACCESS_POINT_STRENGTH, "Strength", "Strength", - G_MININT8, G_MAXINT8, 0, - G_PARAM_READWRITE)); + 0, G_MAXUINT8, 0, + G_PARAM_READABLE)); } diff --git a/libnm-glib/nm-access-point.h b/libnm-glib/nm-access-point.h index a35785f63d..a9024f4a7e 100644 --- a/libnm-glib/nm-access-point.h +++ b/libnm-glib/nm-access-point.h @@ -34,7 +34,7 @@ typedef struct { GType nm_access_point_get_type (void); -NMAccessPoint *nm_access_point_new (DBusGConnection *connection, const char *path); +GObject *nm_access_point_new (DBusGConnection *connection, const char *path); guint32 nm_access_point_get_flags (NMAccessPoint *ap); guint32 nm_access_point_get_wpa_flags (NMAccessPoint *ap); @@ -44,7 +44,7 @@ guint32 nm_access_point_get_frequency (NMAccessPoint *ap); const char * nm_access_point_get_hw_address (NMAccessPoint *ap); int nm_access_point_get_mode (NMAccessPoint *ap); guint32 nm_access_point_get_max_bitrate (NMAccessPoint *ap); -gint8 nm_access_point_get_strength (NMAccessPoint *ap); +guint8 nm_access_point_get_strength (NMAccessPoint *ap); G_END_DECLS diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c new file mode 100644 index 0000000000..b282262a70 --- /dev/null +++ b/libnm-glib/nm-active-connection.c @@ -0,0 +1,366 @@ +/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ + +#include <string.h> + +#include "NetworkManager.h" +#include "nm-active-connection.h" +#include "nm-object-private.h" +#include "nm-types-private.h" +#include "nm-device.h" + +#include "nm-active-connection-bindings.h" + +G_DEFINE_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_OBJECT) + +#define NM_ACTIVE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate)) + +static gboolean demarshal_devices (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field); + + +typedef struct { + gboolean disposed; + DBusGProxy *proxy; + + char *service_name; + char *connection; + char *specific_object; + char *shared_service_name; + char *shared_connection; + GPtrArray *devices; +} NMActiveConnectionPrivate; + +enum { + PROP_0, + PROP_SERVICE_NAME, + PROP_CONNECTION, + PROP_SPECIFIC_OBJECT, + PROP_SHARED_SERVICE_NAME, + PROP_SHARED_CONNECTION, + PROP_DEVICES, + + LAST_PROP +}; + +#define DBUS_PROP_SERVICE_NAME "ServiceName" +#define DBUS_PROP_CONNECTION "Connection" +#define DBUS_PROP_SPECIFIC_OBJECT "SpecificObject" +#define DBUS_PROP_SHARED_SERVICE_NAME "SharedServiceName" +#define DBUS_PROP_SHARED_CONNECTION "SharedConnection" +#define DBUS_PROP_DEVICES "Devices" + +GObject * +nm_active_connection_new (DBusGConnection *connection, const char *path) +{ + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + return g_object_new (NM_TYPE_ACTIVE_CONNECTION, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); +} + +const char * +nm_active_connection_get_service_name (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + if (!priv->service_name) { + priv->service_name = nm_object_get_string_property (NM_OBJECT (connection), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + DBUS_PROP_SERVICE_NAME); + } + + return priv->service_name; +} + +const char * +nm_active_connection_get_connection (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + if (!priv->connection) { + priv->connection = nm_object_get_string_property (NM_OBJECT (connection), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + DBUS_PROP_CONNECTION); + } + + return priv->connection; +} + +const char * +nm_active_connection_get_specific_object (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + if (!priv->specific_object) { + priv->specific_object = nm_object_get_string_property (NM_OBJECT (connection), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + DBUS_PROP_SPECIFIC_OBJECT); + } + + return priv->specific_object; +} + +const char * +nm_active_connection_get_shared_service_name (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + if (!priv->shared_service_name) { + priv->shared_service_name = nm_object_get_string_property (NM_OBJECT (connection), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + DBUS_PROP_SHARED_SERVICE_NAME); + } + + return priv->shared_service_name; +} + +const char * +nm_active_connection_get_shared_connection (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + if (!priv->shared_connection) { + priv->shared_connection = nm_object_get_string_property (NM_OBJECT (connection), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + DBUS_PROP_SHARED_CONNECTION); + } + + return priv->shared_connection; +} + +const GPtrArray * +nm_active_connection_get_devices (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv; + GValue value = { 0, }; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + if (priv->devices) + return priv->devices; + + if (!nm_object_get_property (NM_OBJECT (connection), + NM_DBUS_INTERFACE, + DBUS_PROP_DEVICES, + &value)) { + return NULL; + } + + demarshal_devices (NM_OBJECT (connection), NULL, &value, &priv->devices); + g_value_unset (&value); + + return priv->devices; +} + +static void +nm_active_connection_init (NMActiveConnection *ap) +{ +} + +static void +dispose (GObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + if (priv->disposed) { + G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); + return; + } + + priv->disposed = TRUE; + + if (priv->devices) { + g_ptr_array_foreach (priv->devices, (GFunc) g_object_unref, NULL); + g_ptr_array_free (priv->devices, TRUE); + } + g_object_unref (priv->proxy); + + G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + g_free (priv->service_name); + g_free (priv->connection); + g_free (priv->specific_object); + g_free (priv->shared_service_name); + g_free (priv->shared_service_name); + + G_OBJECT_CLASS (nm_active_connection_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMActiveConnection *self = NM_ACTIVE_CONNECTION (object); + + switch (prop_id) { + case PROP_SERVICE_NAME: + g_value_set_string (value, nm_active_connection_get_service_name (self)); + break; + case PROP_CONNECTION: + g_value_set_boxed (value, nm_active_connection_get_connection (self)); + break; + case PROP_SPECIFIC_OBJECT: + g_value_set_boxed (value, nm_active_connection_get_specific_object (self)); + break; + case PROP_SHARED_SERVICE_NAME: + g_value_set_string (value, nm_active_connection_get_shared_service_name (self)); + break; + case PROP_SHARED_CONNECTION: + g_value_set_boxed (value, nm_active_connection_get_shared_connection (self)); + break; + case PROP_DEVICES: + g_value_set_boxed (value, nm_active_connection_get_devices (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +demarshal_devices (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + DBusGConnection *connection; + + connection = nm_object_get_connection (object); + if (!nm_object_array_demarshal (value, (GPtrArray **) field, connection, nm_device_new)) + return FALSE; + + g_object_notify (G_OBJECT (object), NM_ACTIVE_CONNECTION_DEVICES); + return TRUE; +} + +static void +register_for_property_changed (NMActiveConnection *connection) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_ACTIVE_CONNECTION_SERVICE_NAME, nm_object_demarshal_generic, &priv->service_name }, + { NM_ACTIVE_CONNECTION_CONNECTION, nm_object_demarshal_generic, &priv->connection }, + { NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, nm_object_demarshal_generic, &priv->specific_object }, + { NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME, nm_object_demarshal_generic, &priv->shared_service_name }, + { NM_ACTIVE_CONNECTION_SHARED_CONNECTION, nm_object_demarshal_generic, &priv->shared_connection }, + { NM_ACTIVE_CONNECTION_DEVICES, demarshal_devices, &priv->devices }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (connection), + priv->proxy, + property_changed_info); +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + NMObject *object; + NMActiveConnectionPrivate *priv; + + object = (NMObject *) G_OBJECT_CLASS (nm_active_connection_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), + NM_DBUS_SERVICE, + nm_object_get_path (object), + NM_DBUS_INTERFACE_ACTIVE_CONNECTION); + + register_for_property_changed (NM_ACTIVE_CONNECTION (object)); + + return G_OBJECT (object); +} + + +static void +nm_active_connection_class_init (NMActiveConnectionClass *ap_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (ap_class); + + g_type_class_add_private (ap_class, sizeof (NMActiveConnectionPrivate)); + + /* virtual methods */ + object_class->constructor = constructor; + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /* properties */ + g_object_class_install_property + (object_class, PROP_SERVICE_NAME, + g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME, + "Service Name", + "Service Name", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CONNECTION, + g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION, + "Connection", + "Connection", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_SPECIFIC_OBJECT, + g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, + "Specific object", + "Specific object", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_SHARED_SERVICE_NAME, + g_param_spec_string (NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME, + "Shared Service Name", + "Shared Service Name", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_SHARED_CONNECTION, + g_param_spec_string (NM_ACTIVE_CONNECTION_SHARED_CONNECTION, + "Shared Connection", + "Shared Connection", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, + "Devices", + "Devices", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE)); +} diff --git a/libnm-glib/nm-active-connection.h b/libnm-glib/nm-active-connection.h new file mode 100644 index 0000000000..b42aa51221 --- /dev/null +++ b/libnm-glib/nm-active-connection.h @@ -0,0 +1,45 @@ +#ifndef NM_ACTIVE_CONNECTION_H +#define NM_ACTIVE_CONNECTION_H + +#include <glib/gtypes.h> +#include <glib-object.h> +#include "nm-object.h" + +G_BEGIN_DECLS + +#define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type ()) +#define NM_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection)) +#define NM_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) +#define NM_IS_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_IS_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ACTIVE_CONNECTION)) +#define NM_ACTIVE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) + +#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name" +#define NM_ACTIVE_CONNECTION_CONNECTION "connection" +#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" +#define NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME "shared-service-name" +#define NM_ACTIVE_CONNECTION_SHARED_CONNECTION "shared-connection" +#define NM_ACTIVE_CONNECTION_DEVICES "devices" + +typedef struct { + NMObject parent; +} NMActiveConnection; + +typedef struct { + NMObjectClass parent; +} NMActiveConnectionClass; + +GType nm_active_connection_get_type (void); + +GObject *nm_active_connection_new (DBusGConnection *connection, const char *path); + +const char * nm_active_connection_get_service_name (NMActiveConnection *connection); +const char * nm_active_connection_get_connection (NMActiveConnection *connection); +const char * nm_active_connection_get_specific_object (NMActiveConnection *connection); +const char * nm_active_connection_get_shared_service_name (NMActiveConnection *connection); +const char * nm_active_connection_get_shared_connection (NMActiveConnection *connection); +const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection); + +G_END_DECLS + +#endif /* NM_ACTIVE_CONNECTION_H */ diff --git a/libnm-glib/nm-cdma-device.c b/libnm-glib/nm-cdma-device.c index 5ba2f47821..e2c4de0959 100644 --- a/libnm-glib/nm-cdma-device.c +++ b/libnm-glib/nm-cdma-device.c @@ -7,7 +7,7 @@ G_DEFINE_TYPE (NMCdmaDevice, nm_cdma_device, NM_TYPE_DEVICE) #define NM_CDMA_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CDMA_DEVICE, NMCdmaDevicePrivate)) typedef struct { - DBusGProxy *cdma_proxy; + DBusGProxy *proxy; gboolean disposed; } NMCdmaDevicePrivate; @@ -33,10 +33,10 @@ constructor (GType type, priv = NM_CDMA_DEVICE_GET_PRIVATE (object); - priv->cdma_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_CDMA_DEVICE); + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), + NM_DBUS_SERVICE, + nm_object_get_path (NM_OBJECT (object)), + NM_DBUS_INTERFACE_CDMA_DEVICE); return object; } @@ -52,7 +52,7 @@ dispose (GObject *object) priv->disposed = TRUE; - g_object_unref (priv->cdma_proxy); + g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_cdma_device_parent_class)->dispose (object); } @@ -69,14 +69,14 @@ nm_cdma_device_class_init (NMCdmaDeviceClass *device_class) object_class->dispose = dispose; } -NMCdmaDevice * +GObject * nm_cdma_device_new (DBusGConnection *connection, const char *path) { g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (path != NULL, NULL); - return (NMCdmaDevice *) g_object_new (NM_TYPE_CDMA_DEVICE, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, path, - NULL); + return g_object_new (NM_TYPE_CDMA_DEVICE, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } diff --git a/libnm-glib/nm-cdma-device.h b/libnm-glib/nm-cdma-device.h index f69a8c0a80..b65f9a4681 100644 --- a/libnm-glib/nm-cdma-device.h +++ b/libnm-glib/nm-cdma-device.h @@ -24,8 +24,7 @@ typedef struct { GType nm_cdma_device_get_type (void); -NMCdmaDevice *nm_cdma_device_new (DBusGConnection *connection, - const char *path); +GObject *nm_cdma_device_new (DBusGConnection *connection, const char *path); G_END_DECLS diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 933306bc0f..6229b53806 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -2,6 +2,8 @@ #include <dbus/dbus-glib.h> #include <string.h> +#include <nm-utils.h> + #include "nm-client.h" #include "nm-device-802-3-ethernet.h" #include "nm-device-802-11-wireless.h" @@ -9,7 +11,11 @@ #include "nm-cdma-device.h" #include "nm-device-private.h" #include "nm-marshal.h" -#include <nm-utils.h> +#include "nm-types-private.h" +#include "nm-object-private.h" +#include "nm-active-connection.h" +#include "nm-object-cache.h" +#include "nm-dbus-glib-types.h" #include "nm-client-bindings.h" @@ -18,12 +24,14 @@ G_DEFINE_TYPE (NMClient, nm_client, NM_TYPE_OBJECT) #define NM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_CLIENT, NMClientPrivate)) typedef struct { + gboolean disposed; + DBusGProxy *client_proxy; DBusGProxy *bus_proxy; gboolean manager_running; NMState state; - gboolean have_device_list; - GHashTable *devices; + GPtrArray *devices; + GPtrArray *active_connections; gboolean wireless_enabled; gboolean wireless_hw_enabled; @@ -31,17 +39,18 @@ typedef struct { enum { PROP_0, + PROP_STATE, + PROP_MANAGER_RUNNING, PROP_WIRELESS_ENABLED, PROP_WIRELESS_HARDWARE_ENABLED, + PROP_ACTIVE_CONNECTIONS, LAST_PROP }; enum { - MANAGER_RUNNING, DEVICE_ADDED, DEVICE_REMOVED, - STATE_CHANGED, LAST_SIGNAL }; @@ -54,7 +63,6 @@ static void proxy_name_owner_changed (DBusGProxy *proxy, const char *new_owner, gpointer user_data); -static void client_state_changed_proxy (DBusGProxy *proxy, guint state, gpointer user_data); static void client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data); static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data); @@ -64,24 +72,63 @@ nm_client_init (NMClient *client) NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); priv->state = NM_STATE_UNKNOWN; - priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); } static void -update_wireless_status (NMClient *client) +update_wireless_status (NMClient *client, gboolean notify) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + gboolean val; + + val = nm_object_get_boolean_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WirelessHardwareEnabled"); + if (val != priv->wireless_hw_enabled) { + priv->wireless_hw_enabled = val; + g_object_notify (G_OBJECT (client), NM_CLIENT_WIRELESS_HARDWARE_ENABLED); + } - priv->wireless_enabled = nm_object_get_boolean_property (NM_OBJECT (client), - NM_DBUS_INTERFACE, - "WirelessEnabled"); + val = priv->wireless_hw_enabled ? TRUE : + nm_object_get_boolean_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WirelessEnabled"); + if (val != priv->wireless_enabled) { + priv->wireless_enabled = val; + g_object_notify (G_OBJECT (client), NM_CLIENT_WIRELESS_ENABLED); + } +} + +static gboolean +demarshal_active_connections (NMObject *object, + GParamSpec *pspec, + GValue *value, + gpointer field) +{ + DBusGConnection *connection; - priv->wireless_hw_enabled = priv->wireless_enabled ? - TRUE : nm_object_get_boolean_property (NM_OBJECT (client), - NM_DBUS_INTERFACE, - "WirelessHardwareEnabled"); + connection = nm_object_get_connection (object); + if (!nm_object_array_demarshal (value, (GPtrArray **) field, connection, nm_active_connection_new)) + return FALSE; + + g_object_notify (G_OBJECT (object), NM_CLIENT_ACTIVE_CONNECTIONS); + return TRUE; +} + +static void +register_for_property_changed (NMClient *client) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_CLIENT_STATE, nm_object_demarshal_generic, &priv->state }, + { NM_CLIENT_WIRELESS_ENABLED, nm_object_demarshal_generic, &priv->wireless_enabled }, + { NM_CLIENT_WIRELESS_HARDWARE_ENABLED, nm_object_demarshal_generic, &priv->wireless_hw_enabled }, + { NM_CLIENT_ACTIVE_CONNECTIONS, demarshal_active_connections, &priv->active_connections }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (client), + priv->client_proxy, + property_changed_info); } static GObject* @@ -108,12 +155,7 @@ constructor (GType type, nm_object_get_path (object), NM_DBUS_INTERFACE); - dbus_g_proxy_add_signal (priv->client_proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->client_proxy, - "StateChanged", - G_CALLBACK (client_state_changed_proxy), - object, - NULL); + register_for_property_changed (NM_CLIENT (object)); dbus_g_proxy_add_signal (priv->client_proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->client_proxy, @@ -129,9 +171,8 @@ constructor (GType type, object, NULL); - nm_object_handle_properties_changed (NM_OBJECT (object), priv->client_proxy); - - update_wireless_status (NM_CLIENT (object)); + update_wireless_status (NM_CLIENT (object), FALSE); + nm_client_get_state (NM_CLIENT (object)); priv->bus_proxy = dbus_g_proxy_new_for_name (connection, "org.freedesktop.DBus", @@ -160,15 +201,34 @@ constructor (GType type, } static void -finalize (GObject *object) +free_device_list (NMClient *client) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + + if (!priv->devices) + return; + + g_ptr_array_foreach (priv->devices, (GFunc) g_object_unref, NULL); + g_ptr_array_free (priv->devices, TRUE); + priv->devices = NULL; +} + +static void +dispose (GObject *object) { NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + if (priv->disposed) { + G_OBJECT_CLASS (nm_client_parent_class)->dispose (object); + return; + } + g_object_unref (priv->client_proxy); g_object_unref (priv->bus_proxy); - g_hash_table_destroy (priv->devices); - G_OBJECT_CLASS (nm_client_parent_class)->finalize (object); + free_device_list (NM_CLIENT (object)); + + G_OBJECT_CLASS (nm_client_parent_class)->dispose (object); } static void @@ -205,38 +265,31 @@ get_property (GObject *object, GValue *value, GParamSpec *pspec) { - NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object); + NMClient *self = NM_CLIENT (object); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); switch (prop_id) { + case PROP_STATE: + g_value_set_uint (value, nm_client_get_state (self)); + break; + case PROP_MANAGER_RUNNING: + g_value_set_boolean (value, priv->manager_running); + break; case PROP_WIRELESS_ENABLED: g_value_set_boolean (value, priv->wireless_enabled); break; case PROP_WIRELESS_HARDWARE_ENABLED: g_value_set_boolean (value, priv->wireless_hw_enabled); break; + case PROP_ACTIVE_CONNECTIONS: + g_value_set_boxed (value, nm_client_get_active_connections (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } - -static void -manager_running (NMClient *client, gboolean running) -{ - if (!running) { - NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); - - priv->state = NM_STATE_UNKNOWN; - g_hash_table_remove_all (priv->devices); - priv->have_device_list = FALSE; - priv->wireless_enabled = FALSE; - priv->wireless_hw_enabled = FALSE; - } else { - update_wireless_status (client); - } -} - static void nm_client_class_init (NMClientClass *client_class) { @@ -248,16 +301,30 @@ nm_client_class_init (NMClientClass *client_class) object_class->constructor = constructor; object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; - - client_class->manager_running = manager_running; + object_class->dispose = dispose; /* properties */ g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_uint (NM_CLIENT_STATE, + "State", + "NetworkManager state", + NM_STATE_UNKNOWN, NM_STATE_DISCONNECTED, NM_STATE_UNKNOWN, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_MANAGER_RUNNING, + g_param_spec_boolean (NM_CLIENT_MANAGER_RUNNING, + "ManagerRunning", + "Whether NetworkManager is running", + FALSE, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_WIRELESS_ENABLED, g_param_spec_boolean (NM_CLIENT_WIRELESS_ENABLED, "WirelessEnabled", - "Is wirless enabled", + "Is wireless enabled", TRUE, G_PARAM_READWRITE)); @@ -265,20 +332,19 @@ nm_client_class_init (NMClientClass *client_class) (object_class, PROP_WIRELESS_HARDWARE_ENABLED, g_param_spec_boolean (NM_CLIENT_WIRELESS_HARDWARE_ENABLED, "WirelessHardwareEnabled", - "Is wirless hardware enabled", + "Is wireless hardware enabled", TRUE, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_ACTIVE_CONNECTIONS, + g_param_spec_boxed (NM_CLIENT_ACTIVE_CONNECTIONS, + "Active connections", + "Active connections", + NM_TYPE_OBJECT_ARRAY, + G_PARAM_READABLE)); /* signals */ - signals[MANAGER_RUNNING] = - g_signal_new ("manager-running", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMClientClass, manager_running), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); signals[DEVICE_ADDED] = g_signal_new ("device-added", G_OBJECT_CLASS_TYPE (object_class), @@ -298,16 +364,6 @@ nm_client_class_init (NMClientClass *client_class) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[STATE_CHANGED] = - g_signal_new ("state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMClientClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); } NMClient * @@ -324,8 +380,8 @@ nm_client_new (void) } return (NMClient *) g_object_new (NM_TYPE_CLIENT, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, NM_DBUS_PATH, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, NULL); } @@ -336,75 +392,34 @@ proxy_name_owner_changed (DBusGProxy *proxy, const char *new_owner, gpointer user_data) { - if (name && !strcmp (name, NM_DBUS_SERVICE)) { - NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (user_data); - gboolean old_good = (old_owner && strlen (old_owner)); - gboolean new_good = (new_owner && strlen (new_owner)); - gboolean new_running = FALSE; - - if (!old_good && new_good) - new_running = TRUE; - else if (old_good && !new_good) - new_running = FALSE; - - if (new_running != priv->manager_running) { - priv->manager_running = new_running; - g_signal_emit (NM_CLIENT (user_data), - signals[MANAGER_RUNNING], - 0, - priv->manager_running); - } - } -} - -static void -client_state_changed_proxy (DBusGProxy *proxy, guint state, gpointer user_data) -{ NMClient *client = NM_CLIENT (user_data); NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + gboolean old_good = (old_owner && strlen (old_owner)); + gboolean new_good = (new_owner && strlen (new_owner)); + gboolean new_running = FALSE; - if (priv->state != state) { - priv->state = state; - g_signal_emit (client, signals[STATE_CHANGED], 0, state); - } -} + if (!name || strcmp (name, NM_DBUS_SERVICE)) + return; -static NMDevice * -get_device (NMClient *client, const char *path, gboolean create_if_not_found) -{ - NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); - NMDevice *device; - - device = g_hash_table_lookup (priv->devices, path); - if (!device && create_if_not_found) { - DBusGConnection *connection; - NMDeviceType type; + if (!old_good && new_good) + new_running = TRUE; + else if (old_good && !new_good) + new_running = FALSE; - connection = nm_object_get_connection (NM_OBJECT (client)); - type = nm_device_type_for_path (connection, path); + if (new_running == priv->manager_running) + return; - switch (type) { - case DEVICE_TYPE_802_3_ETHERNET: - device = NM_DEVICE (nm_device_802_3_ethernet_new (connection, path)); - break; - case DEVICE_TYPE_802_11_WIRELESS: - device = NM_DEVICE (nm_device_802_11_wireless_new (connection, path)); - break; - case DEVICE_TYPE_GSM: - device = NM_DEVICE (nm_gsm_device_new (connection, path)); - break; - case DEVICE_TYPE_CDMA: - device = NM_DEVICE (nm_cdma_device_new (connection, path)); - break; - default: - device = nm_device_new (connection, path); - } - - if (device) - g_hash_table_insert (priv->devices, g_strdup (path), device); + priv->manager_running = new_running; + if (!priv->manager_running) { + priv->state = NM_STATE_UNKNOWN; + g_object_notify (G_OBJECT (client), NM_CLIENT_MANAGER_RUNNING); + free_device_list (client); + priv->wireless_enabled = FALSE; + priv->wireless_hw_enabled = FALSE; + } else { + g_object_notify (G_OBJECT (client), NM_CLIENT_MANAGER_RUNNING); + update_wireless_status (client, TRUE); } - - return device; } static void @@ -413,7 +428,7 @@ client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data) NMClient *client = NM_CLIENT (user_data); NMDevice *device; - device = get_device (client, path, TRUE); + device = nm_client_get_device_by_path (client, path); if (device) g_signal_emit (client, signals[DEVICE_ADDED], 0, device); } @@ -422,90 +437,68 @@ static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { NMClient *client = NM_CLIENT (user_data); + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); NMDevice *device; - device = get_device (client, path, FALSE); + device = nm_client_get_device_by_path (client, path); if (device) { g_signal_emit (client, signals[DEVICE_REMOVED], 0, device); - g_hash_table_remove (NM_CLIENT_GET_PRIVATE (client)->devices, path); + g_ptr_array_remove (priv->devices, device); + g_object_unref (device); } } -gboolean -nm_client_manager_is_running (NMClient *client) -{ - g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); - - return NM_CLIENT_GET_PRIVATE (client)->manager_running; -} - -static void -devices_to_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_prepend (*list, value); -} - -GSList * +GPtrArray * nm_client_get_devices (NMClient *client) { NMClientPrivate *priv; - GSList *list = NULL; - GPtrArray *array = NULL; - GError *err = NULL; + DBusGConnection *connection; + GValue value = { 0, }; + GError *error = NULL; + GPtrArray *temp; g_return_val_if_fail (NM_IS_CLIENT (client), NULL); priv = NM_CLIENT_GET_PRIVATE (client); + if (priv->devices) + return priv->devices; - if (priv->have_device_list) { - g_hash_table_foreach (priv->devices, devices_to_slist, &list); - return list; + if (!org_freedesktop_NetworkManager_get_devices (priv->client_proxy, &temp, &error)) { + g_warning ("%s: error getting devices: %s\n", __func__, error->message); + g_error_free (error); + return NULL; } - if (!org_freedesktop_NetworkManager_get_devices (priv->client_proxy, &array, &err)) { - g_warning ("Error in get_devices: %s", err->message); - g_error_free (err); - } else { - int i; - - for (i = 0; i < array->len; i++) { - NMDevice *device; - char *path = g_ptr_array_index (array, i); - - device = get_device (client, (const char *) path, TRUE); - if (device) - list = g_slist_append (list, device); - g_free (path); - } - - g_ptr_array_free (array, TRUE); + g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH); + g_value_take_boxed (&value, temp); + connection = nm_object_get_connection (NM_OBJECT (client)); + nm_object_array_demarshal (&value, &priv->devices, connection, nm_device_new); + g_value_unset (&value); - priv->have_device_list = TRUE; - } - - return list; + return priv->devices; } NMDevice * nm_client_get_device_by_path (NMClient *client, const char *object_path) { - GSList *devices; - GSList *iter; + GPtrArray *devices; + int i; NMDevice *device = NULL; g_return_val_if_fail (NM_IS_CLIENT (client), NULL); g_return_val_if_fail (object_path, NULL); devices = nm_client_get_devices (client); - for (iter = devices; iter; iter = iter->next) { - if (!strcmp (nm_object_get_path (NM_OBJECT (iter->data)), object_path)) { - device = NM_DEVICE (iter->data); + if (!devices) + return NULL; + + for (i = 0; i < devices->len; i++) { + NMDevice *candidate = g_ptr_array_index (devices, i); + if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), object_path)) { + device = candidate; break; } } - g_slist_free (devices); return device; } @@ -516,7 +509,10 @@ typedef struct { } ActivateDeviceInfo; static void -activate_cb (DBusGProxy *proxy, GError *err, gpointer user_data) +activate_cb (DBusGProxy *proxy, + char *active_connection, + GError *err, + gpointer user_data) { ActivateDeviceInfo *info = (ActivateDeviceInfo *) user_data; @@ -567,132 +563,47 @@ nm_client_activate_connection (NMClient *client, } void -nm_client_free_active_connections_element (GHashTable *item) +nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) { - GSList *devices, *iter; - - g_free (g_hash_table_lookup (item, NM_AC_KEY_SERVICE_NAME)); - g_free (g_hash_table_lookup (item, NM_AC_KEY_CONNECTION)); - g_free (g_hash_table_lookup (item, NM_AC_KEY_SPECIFIC_OBJECT)); - g_free (g_hash_table_lookup (item, NM_AC_KEY_SHARED_TO_SERVICE_NAME)); - g_free (g_hash_table_lookup (item, NM_AC_KEY_SHARED_TO_CONNECTION)); - - devices = g_hash_table_lookup (item, NM_AC_KEY_DEVICES); - for (iter = devices; iter; iter = g_slist_next (iter)) - g_object_unref (iter->data); - g_slist_free (devices); -} + NMClientPrivate *priv; + const char *path; + GError *error = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (active)); -#define DBUS_TYPE_G_OBJECT_PATH_ARRAY (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) + // FIXME: return errors + priv = NM_CLIENT_GET_PRIVATE (client); + path = nm_object_get_path (NM_OBJECT (active)); + if (!org_freedesktop_NetworkManager_deactivate_connection (priv->client_proxy, path, &error)) { + g_warning ("Could not deactivate connection '%s': %s", path, error->message); + g_error_free (error); + } +} -GSList * +const GPtrArray * nm_client_get_active_connections (NMClient *client) { NMClientPrivate *priv; - GSList *connections = NULL; - GPtrArray *array = NULL; - GError *err = NULL; - int i, j; + GValue value = { 0, }; g_return_val_if_fail (NM_IS_CLIENT (client), NULL); priv = NM_CLIENT_GET_PRIVATE (client); - if (!org_freedesktop_NetworkManager_get_active_connections (priv->client_proxy, &array, &err)) { - g_warning ("Error in get_active_connections: %s", err->message); - g_error_free (err); + if (priv->active_connections) + return priv->active_connections; + + if (!nm_object_get_property (NM_OBJECT (client), + "org.freedesktop.DBus.Properties", + "ActiveConnections", + &value)) { return NULL; } - for (i = 0; i < array->len; i++) { - GHashTable *reply; - GHashTable *active; - GValue *value, *value2; - GPtrArray *devices_array = NULL; - GSList *devices = NULL; - gboolean have_shared_service = TRUE; - - active = g_hash_table_new (g_str_hash, g_str_equal); - - reply = g_ptr_array_index (array, i); - - /* Service name */ - value = g_hash_table_lookup (reply, NM_AC_KEY_SERVICE_NAME); - if (!value || !G_VALUE_HOLDS_STRING (value)) { - g_warning ("%s: missing item " NM_AC_KEY_SERVICE_NAME, __func__); - nm_client_free_active_connections_element (active); - g_hash_table_destroy (reply); - continue; - } - g_hash_table_insert (active, NM_AC_KEY_SERVICE_NAME, g_value_dup_string (value)); - - /* Connection path */ - value = g_hash_table_lookup (reply, NM_AC_KEY_CONNECTION); - if (!value || !G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) { - g_warning ("%s: missing item " NM_AC_KEY_CONNECTION, __func__); - nm_client_free_active_connections_element (active); - g_hash_table_destroy (reply); - continue; - } - g_hash_table_insert (active, NM_AC_KEY_CONNECTION, g_value_dup_boxed (value)); - - /* Specific object path */ - value = g_hash_table_lookup (reply, NM_AC_KEY_SPECIFIC_OBJECT); - if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) - g_hash_table_insert (active, NM_AC_KEY_SPECIFIC_OBJECT, g_value_dup_boxed (value)); - - /* Shared to service name */ - value = g_hash_table_lookup (reply, NM_AC_KEY_SHARED_TO_SERVICE_NAME); - if (!value || !G_VALUE_HOLDS_STRING (value)) - have_shared_service = FALSE; - - value2 = g_hash_table_lookup (reply, NM_AC_KEY_SHARED_TO_CONNECTION); - if (have_shared_service && value2 && G_VALUE_HOLDS (value2, DBUS_TYPE_G_OBJECT_PATH)) { - g_hash_table_insert (active, NM_AC_KEY_SHARED_TO_SERVICE_NAME, g_value_dup_string (value)); - g_hash_table_insert (active, NM_AC_KEY_SHARED_TO_CONNECTION, g_value_dup_boxed (value2)); - } else { - /* Ignore missing shared-to-service _and_ missing shared-to-connection */ - if (have_shared_service) { - g_warning ("%s: missing item " NM_AC_KEY_SHARED_TO_SERVICE_NAME, __func__); - nm_client_free_active_connections_element (active); - g_hash_table_destroy (reply); - continue; - } - } - - /* Device array */ - value = g_hash_table_lookup (reply, NM_AC_KEY_DEVICES); - if (!value || !G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH_ARRAY)) { - g_warning ("%s: missing item " NM_AC_KEY_DEVICES, __func__); - nm_client_free_active_connections_element (active); - g_hash_table_destroy (reply); - continue; - } - - devices_array = g_value_get_boxed (value); - if (!devices_array || (devices_array->len == 0)) { - g_warning ("%s: no devices for this active connection.", __func__); - nm_client_free_active_connections_element (active); - g_hash_table_destroy (reply); - continue; - } - - for (j = 0; j < devices_array->len; j++) { - NMDevice *device; - const char *path; - - path = (const char *) g_ptr_array_index (devices_array, j); - device = get_device (client, path, TRUE); - devices = g_slist_append (devices, g_object_ref (device)); - } - - g_hash_table_insert (active, NM_AC_KEY_DEVICES, devices); - - connections = g_slist_append (connections, active); - g_hash_table_destroy (reply); - } + demarshal_active_connections (NM_OBJECT (client), NULL, &value, &priv->active_connections); + g_value_unset (&value); - g_ptr_array_free (array, TRUE); - return connections; + return priv->active_connections; } gboolean @@ -736,6 +647,9 @@ nm_client_get_state (NMClient *client) priv = NM_CLIENT_GET_PRIVATE (client); + if (!priv->manager_running) + return NM_STATE_UNKNOWN; + if (priv->state == NM_STATE_UNKNOWN) priv->state = nm_object_get_uint_property (NM_OBJECT (client), NM_DBUS_INTERFACE, "State"); @@ -754,3 +668,12 @@ nm_client_sleep (NMClient *client, gboolean sleep) g_error_free (err); } } + +gboolean +nm_client_get_manager_running (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return NM_CLIENT_GET_PRIVATE (client)->manager_running; +} + diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 6c25abff50..df1a44e2af 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -1,7 +1,7 @@ /* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ #ifndef NM_CLIENT_H -#define NM_CLIENT_H 1 +#define NM_CLIENT_H #include <glib/gtypes.h> #include <glib-object.h> @@ -9,6 +9,7 @@ #include <NetworkManager.h> #include "nm-object.h" #include "nm-device.h" +#include "nm-active-connection.h" G_BEGIN_DECLS @@ -19,8 +20,11 @@ G_BEGIN_DECLS #define NM_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CLIENT)) #define NM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CLIENT, NMClientClass)) -#define NM_CLIENT_WIRELESS_ENABLED "wireless_enabled" -#define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless_hardware_enabled" +#define NM_CLIENT_STATE "state" +#define NM_CLIENT_MANAGER_RUNNING "manager-running" +#define NM_CLIENT_WIRELESS_ENABLED "wireless-enabled" +#define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" +#define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections" typedef struct { NMObject parent; @@ -30,23 +34,16 @@ typedef struct { NMObjectClass parent; /* Signals */ - void (*manager_running) (NMClient *client, gboolean running); void (*device_added) (NMClient *client, NMDevice *device); void (*device_removed) (NMClient *client, NMDevice *device); - void (*state_changed) (NMClient *client, NMState state); } NMClientClass; GType nm_client_get_type (void); +NMClient *nm_client_new (void); -NMClient *nm_client_new (void); - -gboolean nm_client_manager_is_running (NMClient *client); -GSList *nm_client_get_devices (NMClient *client); -NMDevice *nm_client_get_device_by_path (NMClient *client, - const char *object_path); -GSList * nm_client_get_active_connections (NMClient *client); -void nm_client_free_active_connections_element (GHashTable *item); +GPtrArray *nm_client_get_devices (NMClient *client); +NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_path); typedef void (*NMClientActivateDeviceFn) (gpointer user_data, GError *error); @@ -58,10 +55,14 @@ void nm_client_activate_connection (NMClient *client, NMClientActivateDeviceFn callback, gpointer user_data); +void nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active); + gboolean nm_client_wireless_get_enabled (NMClient *client); void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled); gboolean nm_client_wireless_hardware_get_enabled (NMClient *client); NMState nm_client_get_state (NMClient *client); +gboolean nm_client_get_manager_running (NMClient *client); +const GPtrArray *nm_client_get_active_connections (NMClient *client); void nm_client_sleep (NMClient *client, gboolean sleep); G_END_DECLS diff --git a/libnm-glib/nm-device-802-11-wireless.c b/libnm-glib/nm-device-802-11-wireless.c index c4d4be6cf1..9c5b73607b 100644 --- a/libnm-glib/nm-device-802-11-wireless.c +++ b/libnm-glib/nm-device-802-11-wireless.c @@ -6,6 +6,10 @@ #include "nm-device-802-11-wireless.h" #include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-object-cache.h" +#include "nm-dbus-glib-types.h" +#include "nm-types-private.h" #include "nm-device-802-11-wireless-bindings.h" @@ -13,18 +17,18 @@ G_DEFINE_TYPE (NMDevice80211Wireless, nm_device_802_11_wireless, NM_TYPE_DEVICE) #define NM_DEVICE_802_11_WIRELESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_802_11_WIRELESS, NMDevice80211WirelessPrivate)) +static gboolean demarshal_active_ap (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field); + typedef struct { - DBusGProxy *wireless_proxy; - gboolean have_ap_list; - GHashTable *aps; + gboolean disposed; + DBusGProxy *proxy; - char * hw_address; + char *hw_address; int mode; guint32 rate; - NMAccessPoint *current_ap; + NMAccessPoint *active_ap; guint32 wireless_caps; - - gboolean disposed; + GPtrArray *aps; } NMDevice80211WirelessPrivate; enum { @@ -53,27 +57,16 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -NMDevice80211Wireless * +GObject * nm_device_802_11_wireless_new (DBusGConnection *connection, const char *path) { g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (path != NULL, NULL); - return (NMDevice80211Wireless *) g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, path, - NULL); -} - -static void -nm_device_802_11_wireless_set_hw_address (NMDevice80211Wireless *self, - const char *address) -{ - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - - g_free (priv->hw_address); - priv->hw_address = g_strdup (address); - g_object_notify (G_OBJECT (self), NM_DEVICE_802_11_WIRELESS_HW_ADDRESS); + return g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } const char * @@ -93,15 +86,6 @@ nm_device_802_11_wireless_get_hw_address (NMDevice80211Wireless *device) return priv->hw_address; } -static void -nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self, int mode) -{ - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - - priv->mode = mode; - g_object_notify (G_OBJECT (self), NM_DEVICE_802_11_WIRELESS_MODE); -} - int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *device) { @@ -119,17 +103,6 @@ nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *device) return priv->mode; } -static void -nm_device_802_11_wireless_set_bitrate (NMDevice80211Wireless *self, guint32 bitrate) -{ - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - - if (priv->rate != bitrate) { - priv->rate = bitrate; - g_object_notify (G_OBJECT (self), NM_DEVICE_802_11_WIRELESS_BITRATE); - } -} - guint32 nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *device) { @@ -161,15 +134,6 @@ nm_device_802_11_wireless_get_bitrate (NMDevice80211Wireless *device) return priv->rate; } -static void -nm_device_802_11_wireless_set_capabilities (NMDevice80211Wireless *self, guint caps) -{ - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - - priv->wireless_caps = caps; - g_object_notify (G_OBJECT (self), NM_DEVICE_802_11_WIRELESS_CAPABILITIES); -} - guint32 nm_device_802_11_wireless_get_capabilities (NMDevice80211Wireless *device) { @@ -187,60 +151,17 @@ nm_device_802_11_wireless_get_capabilities (NMDevice80211Wireless *device) return priv->wireless_caps; } -static NMAccessPoint * -get_access_point (NMDevice80211Wireless *device, const char *path, gboolean create_if_not_found) -{ - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); - NMAccessPoint *ap; - - g_return_val_if_fail (path != NULL, NULL); - - /* path of "/" means NULL */ - if (!strcmp (path, "/")) - return NULL; - - ap = g_hash_table_lookup (priv->aps, path); - if (!ap && create_if_not_found) { - ap = nm_access_point_new (nm_object_get_connection (NM_OBJECT (device)), path); - if (ap) - g_hash_table_insert (priv->aps, g_strdup (path), ap); - } - - return ap; -} - -static void -nm_device_802_11_wireless_set_active_ap (NMDevice80211Wireless *self, - const char *ap_path) -{ - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - - if (!priv->current_ap && !ap_path) - return; - - if (priv->current_ap) { - g_object_unref (priv->current_ap); - priv->current_ap = NULL; - } - - if (ap_path) { - priv->current_ap = get_access_point (self, ap_path, TRUE); - if (priv->current_ap) - g_object_ref (priv->current_ap); - } - - g_object_notify (G_OBJECT (self), NM_DEVICE_802_11_WIRELESS_ACTIVE_ACCESS_POINT); -} - NMAccessPoint * -nm_device_802_11_wireless_get_active_access_point (NMDevice80211Wireless *device) +nm_device_802_11_wireless_get_active_access_point (NMDevice80211Wireless *self) { NMDevice80211WirelessPrivate *priv; NMDeviceState state; + char *path; + GValue value = { 0, }; - g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (device), NULL); + g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self), NULL); - state = nm_device_get_state (NM_DEVICE (device)); + state = nm_device_get_state (NM_DEVICE (self)); switch (state) { case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: @@ -253,105 +174,103 @@ nm_device_802_11_wireless_get_active_access_point (NMDevice80211Wireless *device break; } - priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); - if (!priv->current_ap) { - char *path; - - path = nm_object_get_object_path_property (NM_OBJECT (device), - NM_DBUS_INTERFACE_DEVICE_WIRELESS, - DBUS_PROP_ACTIVE_ACCESS_POINT); - if (path) { - priv->current_ap = get_access_point (device, path, TRUE); - if (priv->current_ap) - g_object_ref (priv->current_ap); - g_free (path); - } - } - - return priv->current_ap; -} - -NMAccessPoint * -nm_device_802_11_wireless_get_access_point_by_path (NMDevice80211Wireless *device, - const char *object_path) -{ - g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (device), NULL); - g_return_val_if_fail (object_path != NULL, NULL); - - return get_access_point (device, object_path, TRUE); -} + priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + if (priv->active_ap) + return priv->active_ap; -static void -access_points_to_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **list = (GSList **) user_data; + path = nm_object_get_object_path_property (NM_OBJECT (self), + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + DBUS_PROP_ACTIVE_ACCESS_POINT); - *list = g_slist_prepend (*list, value); + g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH); + g_value_take_boxed (&value, path); + demarshal_active_ap (NM_OBJECT (self), NULL, &value, &priv->active_ap); + g_value_unset (&value); + return priv->active_ap; } -GSList * -nm_device_802_11_wireless_get_access_points (NMDevice80211Wireless *device) +GPtrArray * +nm_device_802_11_wireless_get_access_points (NMDevice80211Wireless *self) { NMDevice80211WirelessPrivate *priv; - GSList *list = NULL; - GPtrArray *array = NULL; - GError *err = NULL; + DBusGConnection *connection; + GValue value = { 0, }; + GError *error = NULL; + GPtrArray *temp; - g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (device), NULL); + g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self), NULL); - priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); + priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); + if (priv->aps) + return priv->aps; - if (priv->have_ap_list) { - g_hash_table_foreach (priv->aps, access_points_to_slist, &list); - return list; + if (!org_freedesktop_NetworkManager_Device_Wireless_get_access_points (priv->proxy, &temp, &error)) { + g_warning ("%s: error getting access points: %s", __func__, error->message); + g_error_free (error); + return NULL; } - if (!org_freedesktop_NetworkManager_Device_Wireless_get_access_points - (NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device)->wireless_proxy, &array, &err)) { + g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH); + g_value_take_boxed (&value, temp); + connection = nm_object_get_connection (NM_OBJECT (self)); + nm_object_array_demarshal (&value, &priv->aps, connection, nm_access_point_new); + g_value_unset (&value); - g_warning ("Error in get_access_points: %s", err->message); - g_error_free (err); - } else { - int i; + return priv->aps; +} - for (i = 0; i < array->len; i++) { - char *path = (char *) g_ptr_array_index (array, i); - NMAccessPoint *ap = get_access_point (device, (const char *) path, TRUE); - if (ap) - list = g_slist_prepend (list, ap); - g_free (path); - } +NMAccessPoint * +nm_device_802_11_wireless_get_access_point_by_path (NMDevice80211Wireless *self, + const char *path) +{ + GPtrArray *aps; + int i; + NMAccessPoint *ap = NULL; + + g_return_val_if_fail (NM_IS_DEVICE_802_11_WIRELESS (self), NULL); + g_return_val_if_fail (path != NULL, NULL); - g_ptr_array_free (array, TRUE); - list = g_slist_reverse (list); + aps = nm_device_802_11_wireless_get_access_points (self); + if (!aps) + return NULL; - priv->have_ap_list = TRUE; + for (i = 0; i < aps->len; i++) { + NMAccessPoint *candidate = g_ptr_array_index (aps, i); + if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), path)) { + ap = candidate; + break; + } } - return list; + return ap; } static void access_point_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { - NMDevice80211Wireless *device = NM_DEVICE_802_11_WIRELESS (user_data); + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (user_data); NMAccessPoint *ap; - ap = get_access_point (device, path, TRUE); - if (device && ap) - g_signal_emit (device, signals[ACCESS_POINT_ADDED], 0, ap); + g_return_if_fail (self != NULL); + + ap = nm_device_802_11_wireless_get_access_point_by_path (self, path); + if (ap) + g_signal_emit (self, signals[ACCESS_POINT_ADDED], 0, ap); } static void access_point_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { - NMDevice80211Wireless *device = NM_DEVICE_802_11_WIRELESS (user_data); + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (user_data); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); NMAccessPoint *ap; - ap = get_access_point (device, path, FALSE); - if (device && ap) { - g_signal_emit (device, signals[ACCESS_POINT_REMOVED], 0, ap); - g_hash_table_remove (NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device)->aps, path); + g_return_if_fail (self != NULL); + + ap = nm_device_802_11_wireless_get_access_point_by_path (self, path); + if (ap) { + g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap); + g_ptr_array_remove (priv->aps, ap); } } @@ -363,37 +282,6 @@ nm_device_802_11_wireless_init (NMDevice80211Wireless *device) NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); priv->disposed = FALSE; - priv->aps = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) g_object_unref); -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMDevice80211Wireless *device = NM_DEVICE_802_11_WIRELESS (object); - - switch (prop_id) { - case PROP_HW_ADDRESS: - nm_device_802_11_wireless_set_hw_address (device, g_value_get_string (value)); - break; - case PROP_MODE: - nm_device_802_11_wireless_set_mode (device, g_value_get_int (value)); - break; - case PROP_BITRATE: - nm_device_802_11_wireless_set_bitrate (device, g_value_get_uint (value)); - break; - case PROP_ACTIVE_ACCESS_POINT: - nm_device_802_11_wireless_set_active_ap (device, (char *) g_value_get_boxed (value)); - break; - case PROP_WIRELESS_CAPABILITIES: - nm_device_802_11_wireless_set_capabilities (device, g_value_get_uint (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } } static void @@ -402,23 +290,23 @@ get_property (GObject *object, GValue *value, GParamSpec *pspec) { - NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (object); + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (object); switch (prop_id) { case PROP_HW_ADDRESS: - g_value_set_string (value, priv->hw_address); + g_value_set_string (value, nm_device_802_11_wireless_get_hw_address (self)); break; case PROP_MODE: - g_value_set_int (value, priv->mode); + g_value_set_int (value, nm_device_802_11_wireless_get_mode (self)); break; case PROP_BITRATE: - g_value_set_uint (value, priv->rate); + g_value_set_uint (value, nm_device_802_11_wireless_get_bitrate (self)); break; case PROP_ACTIVE_ACCESS_POINT: - g_value_set_boxed (value, priv->current_ap ? nm_object_get_path (NM_OBJECT (priv->current_ap)) : "/"); + g_value_set_object (value, nm_device_802_11_wireless_get_active_access_point (self)); break; case PROP_WIRELESS_CAPABILITIES: - g_value_set_uint (value, priv->wireless_caps); + g_value_set_uint (value, nm_device_802_11_wireless_get_capabilities (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -427,11 +315,12 @@ get_property (GObject *object, } static void -state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data) +state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) { NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (device); + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self); - switch (state) { + switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_PREPARE: case NM_DEVICE_STATE_CONFIG: case NM_DEVICE_STATE_NEED_AUTH: @@ -444,12 +333,69 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data) case NM_DEVICE_STATE_FAILED: case NM_DEVICE_STATE_CANCELLED: default: - nm_device_802_11_wireless_set_active_ap (self, NULL); - nm_device_802_11_wireless_set_bitrate (self, 0); + if (priv->active_ap) { + g_object_unref (priv->active_ap); + priv->active_ap = NULL; + } + g_object_notify (G_OBJECT (device), NM_DEVICE_802_11_WIRELESS_ACTIVE_ACCESS_POINT); + priv->rate = 0; + g_object_notify (G_OBJECT (device), NM_DEVICE_802_11_WIRELESS_BITRATE); break; } } +static gboolean +demarshal_active_ap (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (object); + const char *path; + NMAccessPoint *ap = NULL; + DBusGConnection *connection; + + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) + return FALSE; + + path = g_value_get_boxed (value); + if (strcmp (path, "/")) { + ap = NM_ACCESS_POINT (nm_object_cache_get (path)); + if (ap) + ap = g_object_ref (ap); + else { + connection = nm_object_get_connection (object); + ap = NM_ACCESS_POINT (nm_access_point_new (connection, path)); + } + } + + if (priv->active_ap) { + g_object_unref (priv->active_ap); + priv->active_ap = NULL; + } + + if (ap) + priv->active_ap = ap; + + g_object_notify (G_OBJECT (object), NM_DEVICE_802_11_WIRELESS_ACTIVE_ACCESS_POINT); + return TRUE; +} + +static void +register_for_property_changed (NMDevice80211Wireless *device) +{ + NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_DEVICE_802_11_WIRELESS_HW_ADDRESS, nm_object_demarshal_generic, &priv->hw_address }, + { NM_DEVICE_802_11_WIRELESS_MODE, nm_object_demarshal_generic, &priv->mode }, + { NM_DEVICE_802_11_WIRELESS_BITRATE, nm_object_demarshal_generic, &priv->rate }, + { NM_DEVICE_802_11_WIRELESS_ACTIVE_ACCESS_POINT, demarshal_active_ap, &priv->active_ap }, + { NM_DEVICE_802_11_WIRELESS_CAPABILITIES, nm_object_demarshal_generic, &priv->wireless_caps }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (device), + priv->proxy, + property_changed_info); +} + static GObject* constructor (GType type, guint n_construct_params, @@ -466,29 +412,29 @@ constructor (GType type, priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (object); - priv->wireless_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), NM_DBUS_SERVICE, nm_object_get_path (NM_OBJECT (object)), NM_DBUS_INTERFACE_DEVICE_WIRELESS); - dbus_g_proxy_add_signal (priv->wireless_proxy, "AccessPointAdded", + dbus_g_proxy_add_signal (priv->proxy, "AccessPointAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->wireless_proxy, "AccessPointAdded", + dbus_g_proxy_connect_signal (priv->proxy, "AccessPointAdded", G_CALLBACK (access_point_added_proxy), object, NULL); - dbus_g_proxy_add_signal (priv->wireless_proxy, "AccessPointRemoved", + dbus_g_proxy_add_signal (priv->proxy, "AccessPointRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->wireless_proxy, "AccessPointRemoved", + dbus_g_proxy_connect_signal (priv->proxy, "AccessPointRemoved", G_CALLBACK (access_point_removed_proxy), object, NULL); - nm_object_handle_properties_changed (NM_OBJECT (object), priv->wireless_proxy); + register_for_property_changed (NM_DEVICE_802_11_WIRELESS (object)); g_signal_connect (NM_DEVICE (object), - "state-changed", + "notify::" NM_DEVICE_STATE, G_CALLBACK (state_changed_cb), NULL); @@ -507,13 +453,16 @@ dispose (GObject *object) priv->disposed = TRUE; - g_object_unref (priv->wireless_proxy); + if (priv->active_ap) + g_object_unref (priv->active_ap); - g_hash_table_destroy (priv->aps); - priv->aps = NULL; + if (priv->aps) { + g_ptr_array_foreach (priv->aps, (GFunc) g_object_unref, NULL); + g_ptr_array_free (priv->aps, TRUE); + priv->aps = NULL; + } - if (priv->current_ap) - g_object_unref (priv->current_ap); + g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_device_802_11_wireless_parent_class)->dispose (object); } @@ -538,7 +487,6 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *device_class) /* virtual methods */ object_class->constructor = constructor; - object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; @@ -550,7 +498,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *device_class) "MAC Address", "Hardware MAC address", NULL, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_MODE, @@ -558,7 +506,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *device_class) "Mode", "Mode", 0, IW_MODE_INFRA, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_BITRATE, @@ -566,15 +514,15 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *device_class) "Bit Rate", "Bit Rate", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_ACTIVE_ACCESS_POINT, - g_param_spec_boxed (NM_DEVICE_802_11_WIRELESS_ACTIVE_ACCESS_POINT, + g_param_spec_object (NM_DEVICE_802_11_WIRELESS_ACTIVE_ACCESS_POINT, "Active Access Point", "Active Access Point", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READWRITE)); + NM_TYPE_ACCESS_POINT, + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_WIRELESS_CAPABILITIES, @@ -582,7 +530,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *device_class) "Wireless Capabilities", "Wireless Capabilities", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); /* signals */ signals[ACCESS_POINT_ADDED] = diff --git a/libnm-glib/nm-device-802-11-wireless.h b/libnm-glib/nm-device-802-11-wireless.h index 456d77d574..01363a9c66 100644 --- a/libnm-glib/nm-device-802-11-wireless.h +++ b/libnm-glib/nm-device-802-11-wireless.h @@ -33,8 +33,7 @@ typedef struct { GType nm_device_802_11_wireless_get_type (void); -NMDevice80211Wireless *nm_device_802_11_wireless_new (DBusGConnection *connection, - const char *path); +GObject *nm_device_802_11_wireless_new (DBusGConnection *connection, const char *path); const char * nm_device_802_11_wireless_get_hw_address (NMDevice80211Wireless *device); int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *device); @@ -43,9 +42,9 @@ guint32 nm_device_802_11_wireless_get_capabilities (NMDevice8021 NMAccessPoint * nm_device_802_11_wireless_get_active_access_point (NMDevice80211Wireless *device); NMAccessPoint * nm_device_802_11_wireless_get_access_point_by_path (NMDevice80211Wireless *device, - const char *object_path); + const char *path); -GSList * nm_device_802_11_wireless_get_access_points (NMDevice80211Wireless *device); +GPtrArray * nm_device_802_11_wireless_get_access_points (NMDevice80211Wireless *device); G_END_DECLS diff --git a/libnm-glib/nm-device-802-3-ethernet.c b/libnm-glib/nm-device-802-3-ethernet.c index 213b8f35fe..1bcc896a52 100644 --- a/libnm-glib/nm-device-802-3-ethernet.c +++ b/libnm-glib/nm-device-802-3-ethernet.c @@ -1,5 +1,6 @@ #include "nm-device-802-3-ethernet.h" #include "nm-device-private.h" +#include "nm-object-private.h" #include "nm-device-802-3-ethernet-bindings.h" @@ -8,7 +9,7 @@ G_DEFINE_TYPE (NMDevice8023Ethernet, nm_device_802_3_ethernet, NM_TYPE_DEVICE) #define NM_DEVICE_802_3_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_802_3_ETHERNET, NMDevice8023EthernetPrivate)) typedef struct { - DBusGProxy *wired_proxy; + DBusGProxy *proxy; char * hw_address; guint32 speed; @@ -31,27 +32,16 @@ enum { #define DBUS_PROP_SPEED "Speed" #define DBUS_PROP_CARRIER "Carrier" -NMDevice8023Ethernet * +GObject * nm_device_802_3_ethernet_new (DBusGConnection *connection, const char *path) { g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (path != NULL, NULL); - return (NMDevice8023Ethernet *) g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, path, - NULL); -} - -static void -nm_device_802_3_ethernet_set_hw_address (NMDevice8023Ethernet *self, - const char *address) -{ - NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - - g_free (priv->hw_address); - priv->hw_address = g_strdup (address); - g_object_notify (G_OBJECT (self), NM_DEVICE_802_3_ETHERNET_HW_ADDRESS); + return g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } const char * @@ -71,15 +61,6 @@ nm_device_802_3_ethernet_get_hw_address (NMDevice8023Ethernet *device) return priv->hw_address; } -static void -nm_device_802_3_ethernet_set_speed (NMDevice8023Ethernet *self, guint32 speed) -{ - NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - - priv->speed = speed; - g_object_notify (G_OBJECT (self), NM_DEVICE_802_3_ETHERNET_SPEED); -} - guint32 nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *device) { @@ -97,18 +78,6 @@ nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *device) return priv->speed; } -static void -nm_device_802_3_ethernet_set_carrier (NMDevice8023Ethernet *self, gboolean carrier) -{ - NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (self); - - if (priv->carrier != carrier) { - priv->carrier_valid = TRUE; - priv->carrier = carrier; - g_object_notify (G_OBJECT (self), NM_DEVICE_802_3_ETHERNET_CARRIER); - } -} - gboolean nm_device_802_3_ethernet_get_carrier (NMDevice8023Ethernet *device) { @@ -137,6 +106,22 @@ nm_device_802_3_ethernet_init (NMDevice8023Ethernet *device) priv->carrier_valid = FALSE; } +static void +register_for_property_changed (NMDevice8023Ethernet *device) +{ + NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (device); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_DEVICE_802_3_ETHERNET_HW_ADDRESS, nm_object_demarshal_generic, &priv->hw_address }, + { NM_DEVICE_802_3_ETHERNET_SPEED, nm_object_demarshal_generic, &priv->speed }, + { NM_DEVICE_802_3_ETHERNET_CARRIER, nm_object_demarshal_generic, &priv->carrier }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (device), + priv->proxy, + property_changed_info); +} + static GObject* constructor (GType type, guint n_construct_params, @@ -153,12 +138,12 @@ constructor (GType type, priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (object); - priv->wired_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), - NM_DBUS_SERVICE, - nm_object_get_path (NM_OBJECT (object)), - NM_DBUS_INTERFACE_DEVICE_WIRED); + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), + NM_DBUS_SERVICE, + nm_object_get_path (NM_OBJECT (object)), + NM_DBUS_INTERFACE_DEVICE_WIRED); - nm_object_handle_properties_changed (NM_OBJECT (object), priv->wired_proxy); + register_for_property_changed (NM_DEVICE_802_3_ETHERNET (object)); return object; } @@ -175,7 +160,7 @@ dispose (GObject *object) priv->disposed = TRUE; - g_object_unref (priv->wired_proxy); + g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_device_802_3_ethernet_parent_class)->dispose (object); } @@ -192,44 +177,22 @@ finalize (GObject *object) } static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMDevice8023Ethernet *device = NM_DEVICE_802_3_ETHERNET (object); - - switch (prop_id) { - case PROP_HW_ADDRESS: - nm_device_802_3_ethernet_set_hw_address (device, g_value_get_string (value)); - break; - case PROP_SPEED: - nm_device_802_3_ethernet_set_speed (device, g_value_get_uint (value)); - break; - case PROP_CARRIER: - nm_device_802_3_ethernet_set_carrier (device, 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) { - NMDevice8023EthernetPrivate *priv = NM_DEVICE_802_3_ETHERNET_GET_PRIVATE (object); + NMDevice8023Ethernet *device = NM_DEVICE_802_3_ETHERNET (object); switch (prop_id) { case PROP_HW_ADDRESS: - g_value_set_string (value, priv->hw_address); + g_value_set_string (value, nm_device_802_3_ethernet_get_hw_address (device)); break; case PROP_SPEED: - g_value_set_uint (value, priv->speed); + g_value_set_uint (value, nm_device_802_3_ethernet_get_speed (device)); break; case PROP_CARRIER: - g_value_set_boolean (value, priv->carrier); + g_value_set_boolean (value, nm_device_802_3_ethernet_get_carrier (device)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -248,7 +211,6 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *device_class) object_class->constructor = constructor; object_class->dispose = dispose; object_class->finalize = finalize; - object_class->set_property = set_property; object_class->get_property = get_property; /* properties */ @@ -258,7 +220,7 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *device_class) "MAC Address", "Hardware MAC address", NULL, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_SPEED, @@ -266,14 +228,15 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *device_class) "Speed", "Speed", 0, G_MAXUINT32, 0, - G_PARAM_READWRITE)); + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_CARRIER, g_param_spec_boolean (NM_DEVICE_802_3_ETHERNET_CARRIER, "Carrier", "Carrier", - FALSE, G_PARAM_READWRITE)); + FALSE, + G_PARAM_READABLE)); } diff --git a/libnm-glib/nm-device-802-3-ethernet.h b/libnm-glib/nm-device-802-3-ethernet.h index 0bbb03f3fa..bcde6adef1 100644 --- a/libnm-glib/nm-device-802-3-ethernet.h +++ b/libnm-glib/nm-device-802-3-ethernet.h @@ -26,8 +26,7 @@ typedef struct { GType nm_device_802_3_ethernet_get_type (void); -NMDevice8023Ethernet *nm_device_802_3_ethernet_new (DBusGConnection *connection, - const char *path); +GObject *nm_device_802_3_ethernet_new (DBusGConnection *connection, const char *path); const char * nm_device_802_3_ethernet_get_hw_address (NMDevice8023Ethernet *device); guint32 nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *device); diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index 3883fa3f52..241fcda9fc 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -1,5 +1,14 @@ +#include <string.h> + +#include "NetworkManager.h" +#include "nm-device-802-3-ethernet.h" +#include "nm-device-802-11-wireless.h" +#include "nm-gsm-device.h" +#include "nm-cdma-device.h" #include "nm-device.h" #include "nm-device-private.h" +#include "nm-object-private.h" +#include "nm-object-cache.h" #include "nm-device-bindings.h" @@ -8,35 +17,34 @@ G_DEFINE_TYPE (NMDevice, nm_device, NM_TYPE_OBJECT) #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) typedef struct { - DBusGProxy *device_proxy; - NMDeviceState state; + gboolean disposed; + DBusGProxy *proxy; + char *iface; + char *udi; + char *driver; + guint32 capabilities; + NMIP4Config *ip4_config; + NMDeviceState state; char *product; char *vendor; - - gboolean disposed; } NMDevicePrivate; enum { - STATE_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - - -enum { PROP_0, - PROP_CONNECTION, - PROP_PATH, + PROP_INTERFACE, + PROP_UDI, + PROP_DRIVER, + PROP_CAPABILITIES, + PROP_IP4_CONFIG, + PROP_STATE, + PROP_PRODUCT, + PROP_VENDOR, LAST_PROP }; -static void device_state_change_proxy (DBusGProxy *proxy, guint state, gpointer user_data); - static void nm_device_init (NMDevice *device) { @@ -44,8 +52,59 @@ nm_device_init (NMDevice *device) priv->state = NM_DEVICE_STATE_UNKNOWN; priv->disposed = FALSE; - priv->product = NULL; - priv->vendor = NULL; +} + +static gboolean +demarshal_ip4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + const char *path; + NMIP4Config *config = NULL; + DBusGConnection *connection; + + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) + return FALSE; + + path = g_value_get_boxed (value); + if (strcmp (path, "/")) { + config = NM_IP4_CONFIG (nm_object_cache_get (path)); + if (config) + config = g_object_ref (config); + else { + connection = nm_object_get_connection (object); + config = NM_IP4_CONFIG (nm_ip4_config_new (connection, path)); + } + } + + if (priv->ip4_config) { + g_object_unref (priv->ip4_config); + priv->ip4_config = NULL; + } + + if (config) + priv->ip4_config = config; + + g_object_notify (G_OBJECT (object), NM_DEVICE_IP4_CONFIG); + return TRUE; +} + +static void +register_for_property_changed (NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_DEVICE_UDI, nm_object_demarshal_generic, &priv->udi }, + { NM_DEVICE_INTERFACE, nm_object_demarshal_generic, &priv->iface }, + { NM_DEVICE_DRIVER, nm_object_demarshal_generic, &priv->driver }, + { NM_DEVICE_CAPABILITIES, nm_object_demarshal_generic, &priv->capabilities }, + { NM_DEVICE_IP4_CONFIG, demarshal_ip4_config, &priv->ip4_config }, + { NM_DEVICE_STATE, nm_object_demarshal_generic, &priv->state }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (device), + priv->proxy, + property_changed_info); } static GObject* @@ -64,15 +123,12 @@ constructor (GType type, priv = NM_DEVICE_GET_PRIVATE (object); - priv->device_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), - NM_DBUS_SERVICE, - nm_object_get_path (object), - NM_DBUS_INTERFACE_DEVICE); + priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), + NM_DBUS_SERVICE, + nm_object_get_path (object), + NM_DBUS_INTERFACE_DEVICE); - dbus_g_proxy_add_signal (priv->device_proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->device_proxy, "StateChanged", - G_CALLBACK (device_state_change_proxy), - object, NULL); + register_for_property_changed (NM_DEVICE (object)); return G_OBJECT (object); } @@ -89,7 +145,9 @@ dispose (GObject *object) priv->disposed = TRUE; - g_object_unref (priv->device_proxy); + g_object_unref (priv->proxy); + if (priv->ip4_config) + g_object_unref (priv->ip4_config); G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); } @@ -99,6 +157,9 @@ finalize (GObject *object) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + g_free (priv->iface); + g_free (priv->udi); + g_free (priv->driver); g_free (priv->product); g_free (priv->vendor); @@ -106,6 +167,45 @@ finalize (GObject *object) } static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMDevice *device = NM_DEVICE (object); + + switch (prop_id) { + case PROP_UDI: + g_value_set_string (value, nm_device_get_udi (device)); + break; + case PROP_INTERFACE: + g_value_set_string (value, nm_device_get_iface (device)); + break; + case PROP_DRIVER: + g_value_set_string (value, nm_device_get_driver (device)); + break; + case PROP_CAPABILITIES: + g_value_set_uint (value, nm_device_get_capabilities (device)); + break; + case PROP_IP4_CONFIG: + g_value_set_object (value, nm_device_get_ip4_config (device)); + break; + case PROP_STATE: + g_value_set_uint (value, nm_device_get_state (device)); + break; + case PROP_PRODUCT: + g_value_set_string (value, nm_device_get_product (device)); + break; + case PROP_VENDOR: + g_value_set_string (value, nm_device_get_vendor (device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void nm_device_class_init (NMDeviceClass *device_class) { GObjectClass *object_class = G_OBJECT_CLASS (device_class); @@ -114,98 +214,226 @@ nm_device_class_init (NMDeviceClass *device_class) /* virtual methods */ object_class->constructor = constructor; + object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; - /* signals */ - signals[STATE_CHANGED] = - g_signal_new ("state-changed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMDeviceClass, state_changed), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, - G_TYPE_UINT); + /* properties */ + g_object_class_install_property + (object_class, PROP_INTERFACE, + g_param_spec_string (NM_DEVICE_INTERFACE, + "Interface", + "Interface name", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_UDI, + g_param_spec_string (NM_DEVICE_UDI, + "UDI", + "HAL UDI", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_DRIVER, + g_param_spec_string (NM_DEVICE_DRIVER, + "Driver", + "Driver", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CAPABILITIES, + g_param_spec_uint (NM_DEVICE_CAPABILITIES, + "Capabilities", + "Capabilities", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_IP4_CONFIG, + g_param_spec_object (NM_DEVICE_IP4_CONFIG, + "IP4 Config", + "IP4 Config", + NM_TYPE_IP4_CONFIG, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_uint (NM_DEVICE_STATE, + "State", + "State", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_VENDOR, + g_param_spec_string (NM_DEVICE_VENDOR, + "Vendor", + "Vendor string", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_PRODUCT, + g_param_spec_string (NM_DEVICE_PRODUCT, + "Product", + "Product string", + NULL, + G_PARAM_READABLE)); } -static void -device_state_change_proxy (DBusGProxy *proxy, guint state, gpointer user_data) +GObject * +nm_device_new (DBusGConnection *connection, const char *path) { - NMDevice *device = NM_DEVICE (user_data); - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device); + DBusGProxy *proxy; + GError *err = NULL; + GValue value = {0,}; + GType dtype = 0; + NMDevice *device = NULL; - if (priv->state != state) { - priv->state = state; - g_signal_emit (device, signals[STATE_CHANGED], 0, state); + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + + proxy = dbus_g_proxy_new_for_name (connection, + NM_DBUS_SERVICE, + path, + "org.freedesktop.DBus.Properties"); + if (!proxy) { + g_warning ("%s: couldn't create D-Bus object proxy.", __func__); + return NULL; } -} -NMDevice * -nm_device_new (DBusGConnection *connection, const char *path) -{ - return (NMDevice *) g_object_new (NM_TYPE_DEVICE, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, path, - NULL); + if (!dbus_g_proxy_call (proxy, + "Get", &err, + G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, + G_TYPE_STRING, "DeviceType", + G_TYPE_INVALID, + G_TYPE_VALUE, &value, G_TYPE_INVALID)) { + g_warning ("Error in get_property: %s\n", err->message); + g_error_free (err); + goto out; + } + + switch (g_value_get_uint (&value)) { + case DEVICE_TYPE_802_3_ETHERNET: + dtype = NM_TYPE_DEVICE_802_3_ETHERNET; + break; + case DEVICE_TYPE_802_11_WIRELESS: + dtype = NM_TYPE_DEVICE_802_11_WIRELESS; + break; + case DEVICE_TYPE_GSM: + dtype = NM_TYPE_GSM_DEVICE; + break; + case DEVICE_TYPE_CDMA: + dtype = NM_TYPE_CDMA_DEVICE; + break; + default: + g_warning ("Unknown device type %d", g_value_get_uint (&value)); + break; + } + + if (dtype) { + device = (NMDevice *) g_object_new (dtype, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, + NULL); + } + +out: + g_object_unref (proxy); + return G_OBJECT (device); } -char * +const char * nm_device_get_iface (NMDevice *device) { + NMDevicePrivate *priv; + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - return nm_object_get_string_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Interface"); + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->iface) { + priv->iface = nm_object_get_string_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "Interface"); + } + + return priv->iface; } -char * +const char * nm_device_get_udi (NMDevice *device) { + NMDevicePrivate *priv; + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - return nm_object_get_string_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Udi"); + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->udi) { + priv->udi = nm_object_get_string_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "Udi"); + } + + return priv->udi; } -char * +const char * nm_device_get_driver (NMDevice *device) { + NMDevicePrivate *priv; + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - return nm_object_get_string_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Driver"); + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->driver) { + priv->driver = nm_object_get_string_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "Driver"); + } + + return priv->driver; } guint32 nm_device_get_capabilities (NMDevice *device) { - g_return_val_if_fail (NM_IS_DEVICE (device), 0); - - return nm_object_get_uint_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Capabilities"); -} + NMDevicePrivate *priv; -guint32 -nm_device_get_ip4_address (NMDevice *device) -{ g_return_val_if_fail (NM_IS_DEVICE (device), 0); - return nm_object_get_uint_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip4Address"); + priv = NM_DEVICE_GET_PRIVATE (device); + if (!priv->capabilities) { + priv->capabilities = nm_object_get_uint_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "Capabilities"); + } + + return priv->capabilities; } NMIP4Config * nm_device_get_ip4_config (NMDevice *device) { + NMDevicePrivate *priv; char *path; - NMIP4Config *config = NULL; + GValue value = { 0, }; g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - path = nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip4Config"); + priv = NM_DEVICE_GET_PRIVATE (device); + if (priv->ip4_config) + return priv->ip4_config; - if (path) { - config = nm_ip4_config_new (nm_object_get_connection (NM_OBJECT (device)), path); - g_free (path); - } + path = nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip4Config"); - return config; + g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH); + g_value_take_boxed (&value, path); + demarshal_ip4_config (NM_OBJECT (device), NULL, &value, &priv->ip4_config); + g_value_unset (&value); + return priv->ip4_config; } NMDeviceState @@ -216,9 +444,11 @@ nm_device_get_state (NMDevice *device) g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); priv = NM_DEVICE_GET_PRIVATE (device); - - if (priv->state == NM_DEVICE_STATE_UNKNOWN) - priv->state = nm_object_get_uint_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "State"); + if (priv->state == NM_DEVICE_STATE_UNKNOWN) { + priv->state = nm_object_get_uint_property (NM_OBJECT (device), + NM_DBUS_INTERFACE_DEVICE, + "State"); + } return priv->state; } @@ -316,7 +546,7 @@ nm_device_update_description (NMDevice *device) { NMDevicePrivate *priv; DBusGConnection *connection; - char *udi; + const char *udi; char *orig_dev_udi = NULL; char *pd_parent_udi = NULL; @@ -334,7 +564,6 @@ nm_device_update_description (NMDevice *device) /* First, get the originating device info */ udi = nm_device_get_udi (device); orig_dev_udi = get_product_and_vendor (connection, udi, TRUE, FALSE, &priv->product, &priv->vendor); - g_free (udi); /* Ignore product and vendor for the Network Interface */ if (priv->product || priv->vendor) { @@ -363,6 +592,9 @@ nm_device_update_description (NMDevice *device) g_free (ignore); } g_free (pd_parent_udi); + + g_object_notify (G_OBJECT (device), NM_DEVICE_VENDOR); + g_object_notify (G_OBJECT (device), NM_DEVICE_PRODUCT); } const char * @@ -391,37 +623,3 @@ nm_device_get_vendor (NMDevice *device) return priv->vendor; } -NMDeviceType -nm_device_type_for_path (DBusGConnection *connection, - const char *path) -{ - DBusGProxy *proxy; - GError *err = NULL; - GValue value = {0,}; - NMDeviceType type = DEVICE_TYPE_UNKNOWN; - - g_return_val_if_fail (connection != NULL, type); - g_return_val_if_fail (path != NULL, type); - - proxy = dbus_g_proxy_new_for_name (connection, - NM_DBUS_SERVICE, - path, - "org.freedesktop.DBus.Properties"); - - if (dbus_g_proxy_call (proxy, - "Get", &err, - G_TYPE_STRING, NM_DBUS_INTERFACE_DEVICE, - G_TYPE_STRING, "DeviceType", - G_TYPE_INVALID, - G_TYPE_VALUE, &value, - G_TYPE_INVALID)) { - type = (NMDeviceType) g_value_get_uint (&value); - } else { - g_warning ("Error in get_property: %s\n", err->message); - g_error_free (err); - } - - g_object_unref (proxy); - - return type; -} diff --git a/libnm-glib/nm-device.h b/libnm-glib/nm-device.h index cd781b32c6..afafcf11b4 100644 --- a/libnm-glib/nm-device.h +++ b/libnm-glib/nm-device.h @@ -18,34 +18,35 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE)) #define NM_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE, NMDeviceClass)) +#define NM_DEVICE_UDI "udi" +#define NM_DEVICE_INTERFACE "interface" +#define NM_DEVICE_DRIVER "driver" +#define NM_DEVICE_CAPABILITIES "capabilities" +#define NM_DEVICE_IP4_CONFIG "ip4-config" +#define NM_DEVICE_STATE "state" +#define NM_DEVICE_VENDOR "vendor" +#define NM_DEVICE_PRODUCT "product" + typedef struct { NMObject parent; } NMDevice; typedef struct { NMObjectClass parent; - - /* Signals */ - void (*state_changed) (NMDevice *device, NMDeviceState state); } NMDeviceClass; GType nm_device_get_type (void); -NMDevice *nm_device_new (DBusGConnection *connection, - const char *path); +GObject * nm_device_new (DBusGConnection *connection, const char *path); -char *nm_device_get_iface (NMDevice *device); -char *nm_device_get_udi (NMDevice *device); -char *nm_device_get_driver (NMDevice *device); +const char * nm_device_get_iface (NMDevice *device); +const char * nm_device_get_udi (NMDevice *device); +const char * nm_device_get_driver (NMDevice *device); guint32 nm_device_get_capabilities (NMDevice *device); -guint32 nm_device_get_ip4_address (NMDevice *device); -NMIP4Config *nm_device_get_ip4_config (NMDevice *device); +NMIP4Config * nm_device_get_ip4_config (NMDevice *device); NMDeviceState nm_device_get_state (NMDevice *device); -const char *nm_device_get_product (NMDevice *device); -const char *nm_device_get_vendor (NMDevice *device); - -NMDeviceType nm_device_type_for_path (DBusGConnection *connection, - const char *path); +const char * nm_device_get_product (NMDevice *device); +const char * nm_device_get_vendor (NMDevice *device); G_END_DECLS diff --git a/libnm-glib/nm-gsm-device.c b/libnm-glib/nm-gsm-device.c index 33da0945b8..bd1d127d60 100644 --- a/libnm-glib/nm-gsm-device.c +++ b/libnm-glib/nm-gsm-device.c @@ -76,7 +76,7 @@ nm_gsm_device_new (DBusGConnection *connection, const char *path) g_return_val_if_fail (path != NULL, NULL); return (NMGsmDevice *) g_object_new (NM_TYPE_GSM_DEVICE, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, path, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, path, NULL); } diff --git a/libnm-glib/nm-ip4-config.c b/libnm-glib/nm-ip4-config.c index 107d6eb29b..25ee05b51c 100644 --- a/libnm-glib/nm-ip4-config.c +++ b/libnm-glib/nm-ip4-config.c @@ -1,133 +1,461 @@ +#include <string.h> + #include "nm-ip4-config.h" #include "NetworkManager.h" - -#define INTERFACE NM_DBUS_INTERFACE ".IP4Config" +#include "nm-types-private.h" +#include "nm-object-private.h" G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_OBJECT) +#define NM_IP4_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP4_CONFIG, NMIP4ConfigPrivate)) + +typedef struct { + DBusGProxy *proxy; + + guint32 address; + guint32 gateway; + guint32 netmask; + guint32 broadcast; + char *hostname; + GArray *nameservers; + GPtrArray *domains; + char *nis_domain; + GArray *nis_servers; +} NMIP4ConfigPrivate; + +enum { + PROP_0, + PROP_ADDRESS, + PROP_GATEWAY, + PROP_NETMASK, + PROP_BROADCAST, + PROP_HOSTNAME, + PROP_NAMESERVERS, + PROP_DOMAINS, + PROP_NIS_DOMAIN, + PROP_NIS_SERVERS, + + LAST_PROP +}; + static void nm_ip4_config_init (NMIP4Config *config) { } +static gboolean +demarshal_ip4_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + if (!nm_uint_array_demarshal (value, (GArray **) field)) + return FALSE; + + if (!strcmp (pspec->name, NM_IP4_CONFIG_NAMESERVERS)) + g_object_notify (G_OBJECT (object), NM_IP4_CONFIG_NAMESERVERS); + else if (!strcmp (pspec->name, NM_IP4_CONFIG_NIS_SERVERS)) + g_object_notify (G_OBJECT (object), NM_IP4_CONFIG_NAMESERVERS); + return TRUE; +} + +static gboolean +demarshal_domains (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + if (!nm_string_array_demarshal (value, (GPtrArray **) field)) + return FALSE; + + g_object_notify (G_OBJECT (object), NM_IP4_CONFIG_DOMAINS); + return TRUE; +} + +static void +register_for_property_changed (NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + const NMPropertiesChangedInfo property_changed_info[] = { + { NM_IP4_CONFIG_ADDRESS, nm_object_demarshal_generic, &priv->address }, + { NM_IP4_CONFIG_GATEWAY, nm_object_demarshal_generic, &priv->gateway }, + { NM_IP4_CONFIG_NETMASK, nm_object_demarshal_generic, &priv->netmask }, + { NM_IP4_CONFIG_BROADCAST, nm_object_demarshal_generic, &priv->broadcast }, + { NM_IP4_CONFIG_HOSTNAME, nm_object_demarshal_generic, &priv->hostname }, + { NM_IP4_CONFIG_NAMESERVERS, demarshal_ip4_array, &priv->nameservers }, + { NM_IP4_CONFIG_DOMAINS, demarshal_domains, &priv->domains }, + { NM_IP4_CONFIG_NIS_DOMAIN, nm_object_demarshal_generic, &priv->nis_domain }, + { NM_IP4_CONFIG_NIS_SERVERS, demarshal_ip4_array, &priv->nis_servers }, + { NULL }, + }; + + nm_object_handle_properties_changed (NM_OBJECT (config), + priv->proxy, + property_changed_info); +} + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + NMObject *object; + DBusGConnection *connection; + NMIP4ConfigPrivate *priv; + + object = (NMObject *) G_OBJECT_CLASS (nm_ip4_config_parent_class)->constructor (type, + n_construct_params, + construct_params); + if (!object) + return NULL; + + priv = NM_IP4_CONFIG_GET_PRIVATE (object); + connection = nm_object_get_connection (object); + + priv->proxy = dbus_g_proxy_new_for_name (connection, + NM_DBUS_SERVICE, + nm_object_get_path (object), + NM_DBUS_INTERFACE_IP4_CONFIG); + + register_for_property_changed (NM_IP4_CONFIG (object)); + + return G_OBJECT (object); +} + +static void +finalize (GObject *object) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (object); + int i; + + g_free (priv->hostname); + g_free (priv->nis_domain); + if (priv->nameservers) + g_array_free (priv->nameservers, TRUE); + if (priv->nis_servers) + g_array_free (priv->nis_servers, TRUE); + + if (priv->domains) { + for (i = 0; i < priv->domains->len; i++) + g_free (g_ptr_array_index (priv->domains, i)); + g_ptr_array_free (priv->domains, TRUE); + } + + G_OBJECT_CLASS (nm_ip4_config_parent_class)->finalize (object); +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMIP4Config *self = NM_IP4_CONFIG (object); + + switch (prop_id) { + case PROP_ADDRESS: + g_value_set_uint (value, nm_ip4_config_get_address (self)); + break; + case PROP_GATEWAY: + g_value_set_uint (value, nm_ip4_config_get_gateway (self)); + break; + case PROP_NETMASK: + g_value_set_uint (value, nm_ip4_config_get_netmask (self)); + break; + case PROP_BROADCAST: + g_value_set_uint (value, nm_ip4_config_get_broadcast (self)); + break; + case PROP_HOSTNAME: + g_value_set_string (value, nm_ip4_config_get_hostname (self)); + break; + case PROP_NAMESERVERS: + g_value_set_boxed (value, nm_ip4_config_get_nameservers (self)); + break; + case PROP_DOMAINS: + g_value_set_boxed (value, nm_ip4_config_get_domains (self)); + break; + case PROP_NIS_DOMAIN: + g_value_set_string (value, nm_ip4_config_get_nis_domain (self)); + break; + case PROP_NIS_SERVERS: + g_value_set_boxed (value, nm_ip4_config_get_nis_servers (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void nm_ip4_config_class_init (NMIP4ConfigClass *config_class) { + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMIP4ConfigPrivate)); + + /* virtual methods */ + object_class->constructor = constructor; + object_class->get_property = get_property; + object_class->finalize = finalize; + + /* properties */ + g_object_class_install_property + (object_class, PROP_ADDRESS, + g_param_spec_uint (NM_IP4_CONFIG_ADDRESS, + "Address", + "Address", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_GATEWAY, + g_param_spec_uint (NM_IP4_CONFIG_GATEWAY, + "Gateway", + "Gateway", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_NETMASK, + g_param_spec_uint (NM_IP4_CONFIG_NETMASK, + "Netmask", + "Netmask", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_BROADCAST, + g_param_spec_uint (NM_IP4_CONFIG_BROADCAST, + "Broadcast", + "Broadcast", + 0, G_MAXUINT32, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_IP4_CONFIG_HOSTNAME, + "Hostname", + "Hostname", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_NAMESERVERS, + g_param_spec_boxed (NM_IP4_CONFIG_NAMESERVERS, + "Nameservers", + "Nameservers", + NM_TYPE_UINT_ARRAY, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_DOMAINS, + g_param_spec_boxed (NM_IP4_CONFIG_DOMAINS, + "Domains", + "Domains", + NM_TYPE_STRING_ARRAY, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_NIS_DOMAIN, + g_param_spec_string (NM_IP4_CONFIG_NIS_DOMAIN, + "NIS domain", + "NIS domain", + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_NIS_SERVERS, + g_param_spec_boxed (NM_IP4_CONFIG_NIS_SERVERS, + "NIS servers", + "NIS servers", + NM_TYPE_UINT_ARRAY, + G_PARAM_READABLE)); } -NMIP4Config * +GObject * nm_ip4_config_new (DBusGConnection *connection, const char *object_path) { - return (NMIP4Config *) g_object_new (NM_TYPE_IP4_CONFIG, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, object_path, - NULL); + return (GObject *) g_object_new (NM_TYPE_IP4_CONFIG, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, object_path, + NULL); } guint32 nm_ip4_config_get_address (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); - return nm_object_get_uint_property (NM_OBJECT (config), INTERFACE, "Address"); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->address) { + priv->address = nm_object_get_uint_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Address"); + } + + return priv->address; } guint32 nm_ip4_config_get_gateway (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); - return nm_object_get_uint_property (NM_OBJECT (config), INTERFACE, "Gateway"); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->gateway) { + priv->gateway = nm_object_get_uint_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Gateway"); + } + + return priv->gateway; } guint32 nm_ip4_config_get_netmask (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); - return nm_object_get_uint_property (NM_OBJECT (config), INTERFACE, "Netmask"); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->netmask) { + priv->netmask = nm_object_get_uint_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Netmask"); + } + + return priv->netmask; } guint32 nm_ip4_config_get_broadcast (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), 0); - return nm_object_get_uint_property (NM_OBJECT (config), INTERFACE, "Broadcast"); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->broadcast) { + priv->broadcast = nm_object_get_uint_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Broadcast"); + } + + return priv->broadcast; } -char * +const char * nm_ip4_config_get_hostname (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; + g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); - return nm_object_get_string_property (NM_OBJECT (config), INTERFACE, "Hostname"); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->hostname) { + priv->hostname = nm_object_get_string_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Hostname"); + } + + return priv->hostname; } -GArray * +const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; GArray *array = NULL; GValue value = {0,}; g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); - if (nm_object_get_property (NM_OBJECT (config), - INTERFACE, - "Nameservers", - &value)) - array = (GArray *) g_value_get_boxed (&value); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->nameservers) { + if (nm_object_get_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Nameservers", + &value)) { + array = (GArray *) g_value_get_boxed (&value); + if (array && array->len) { + priv->nameservers = g_array_sized_new (FALSE, TRUE, sizeof (guint32), array->len); + g_array_append_vals (priv->nameservers, array->data, array->len); + } + g_value_unset (&value); + } + } - return array; + return priv->nameservers; } -char ** +const GPtrArray * nm_ip4_config_get_domains (NMIP4Config *config) { - char **array = NULL; + NMIP4ConfigPrivate *priv; GValue value = {0,}; g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); - if (nm_object_get_property (NM_OBJECT (config), - INTERFACE, - "Domains", - &value)) - array = (char **) g_value_get_boxed (&value); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->domains) { + if (nm_object_get_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "Domains", + &value)) { + char **array = NULL, **p; - return array; + array = (char **) g_value_get_boxed (&value); + if (array && g_strv_length (array)) { + priv->domains = g_ptr_array_sized_new (g_strv_length (array)); + for (p = array; *p; p++) + g_ptr_array_add (priv->domains, g_strdup (*p)); + } + g_value_unset (&value); + } + } + + return priv->domains; } -char * +const char * nm_ip4_config_get_nis_domain (NMIP4Config *config) { - char *address = NULL; - GValue value = {0,}; + NMIP4ConfigPrivate *priv; g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); - if (nm_object_get_property (NM_OBJECT (config), - INTERFACE, - "NisDomain", - &value)) - address = g_strdup (g_value_get_string (&value)); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->nis_domain) { + priv->nis_domain = nm_object_get_string_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "NisDomain"); + } - return address; + return priv->nis_domain; } GArray * nm_ip4_config_get_nis_servers (NMIP4Config *config) { + NMIP4ConfigPrivate *priv; GArray *array = NULL; GValue value = {0,}; g_return_val_if_fail (NM_IS_IP4_CONFIG (config), NULL); - if (nm_object_get_property (NM_OBJECT (config), - INTERFACE, - "NisServers", - &value)) - array = (GArray *) g_value_get_boxed (&value); + priv = NM_IP4_CONFIG_GET_PRIVATE (config); + if (!priv->nis_servers) { + if (nm_object_get_property (NM_OBJECT (config), + NM_DBUS_INTERFACE_IP4_CONFIG, + "NisServers", + &value)) { + array = (GArray *) g_value_get_boxed (&value); + if (array && array->len) { + priv->nis_servers = g_array_sized_new (FALSE, TRUE, sizeof (guint32), array->len); + g_array_append_vals (priv->nis_servers, array->data, array->len); + } + g_value_unset (&value); + } + } - return array; + return priv->nis_servers; } diff --git a/libnm-glib/nm-ip4-config.h b/libnm-glib/nm-ip4-config.h index 4d354b7e3b..b4f9215806 100644 --- a/libnm-glib/nm-ip4-config.h +++ b/libnm-glib/nm-ip4-config.h @@ -23,20 +23,29 @@ typedef struct { NMObjectClass parent; } NMIP4ConfigClass; +#define NM_IP4_CONFIG_ADDRESS "address" +#define NM_IP4_CONFIG_GATEWAY "gateway" +#define NM_IP4_CONFIG_NETMASK "netmask" +#define NM_IP4_CONFIG_BROADCAST "broadcast" +#define NM_IP4_CONFIG_HOSTNAME "hostname" +#define NM_IP4_CONFIG_NAMESERVERS "nameservers" +#define NM_IP4_CONFIG_DOMAINS "domains" +#define NM_IP4_CONFIG_NIS_DOMAIN "nis-domain" +#define NM_IP4_CONFIG_NIS_SERVERS "nis-servers" + GType nm_ip4_config_get_type (void); -NMIP4Config *nm_ip4_config_new (DBusGConnection *connection, - const char *object_path); - -guint32 nm_ip4_config_get_address (NMIP4Config *config); -guint32 nm_ip4_config_get_gateway (NMIP4Config *config); -guint32 nm_ip4_config_get_netmask (NMIP4Config *config); -guint32 nm_ip4_config_get_broadcast (NMIP4Config *config); -char *nm_ip4_config_get_hostname (NMIP4Config *config); -GArray *nm_ip4_config_get_nameservers (NMIP4Config *config); -char **nm_ip4_config_get_domains (NMIP4Config *config); -char *nm_ip4_config_get_nis_domain (NMIP4Config *config); -GArray *nm_ip4_config_get_nis_servers (NMIP4Config *config); +GObject *nm_ip4_config_new (DBusGConnection *connection, const char *object_path); + +guint32 nm_ip4_config_get_address (NMIP4Config *config); +guint32 nm_ip4_config_get_gateway (NMIP4Config *config); +guint32 nm_ip4_config_get_netmask (NMIP4Config *config); +guint32 nm_ip4_config_get_broadcast (NMIP4Config *config); +const char * nm_ip4_config_get_hostname (NMIP4Config *config); +const GArray * nm_ip4_config_get_nameservers (NMIP4Config *config); +const GPtrArray *nm_ip4_config_get_domains (NMIP4Config *config); +const char * nm_ip4_config_get_nis_domain (NMIP4Config *config); +GArray * nm_ip4_config_get_nis_servers (NMIP4Config *config); G_END_DECLS diff --git a/libnm-glib/nm-object-cache.c b/libnm-glib/nm-object-cache.c new file mode 100644 index 0000000000..b669fc0778 --- /dev/null +++ b/libnm-glib/nm-object-cache.c @@ -0,0 +1,81 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * Dan Williams <dcbw@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#include <string.h> +#include <glib.h> +#include "nm-object-cache.h" +#include "nm-object.h" + +static GStaticMutex cache_mutex = G_STATIC_MUTEX_INIT; +static GHashTable *cache = NULL; + +static void +_init_cache (void) +{ + if (G_UNLIKELY (cache == NULL)) + cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +} + +void +nm_object_cache_remove_by_path (const char *path) +{ + g_static_mutex_lock (&cache_mutex); + _init_cache (); + g_hash_table_remove (cache, path); + g_static_mutex_unlock (&cache_mutex); +} + +void +nm_object_cache_remove_by_object (NMObject *object) +{ + g_static_mutex_lock (&cache_mutex); + _init_cache (); + g_hash_table_remove (cache, nm_object_get_path (object)); + g_static_mutex_unlock (&cache_mutex); +} + +void +nm_object_cache_add (NMObject *object) +{ + char *path; + + g_static_mutex_lock (&cache_mutex); + _init_cache (); + path = g_strdup (nm_object_get_path (object)); + g_hash_table_insert (cache, path, object); + g_object_set_data_full (G_OBJECT (object), "nm-object-cache-tag", + path, (GDestroyNotify) nm_object_cache_remove_by_path); + g_static_mutex_unlock (&cache_mutex); +} + +NMObject * +nm_object_cache_get (const char *path) +{ + NMObject *object; + + g_static_mutex_lock (&cache_mutex); + _init_cache (); + object = g_hash_table_lookup (cache, path); + g_static_mutex_unlock (&cache_mutex); + return object; +} + diff --git a/libnm-glib/nm-object-cache.h b/libnm-glib/nm-object-cache.h new file mode 100644 index 0000000000..5cb47c844f --- /dev/null +++ b/libnm-glib/nm-object-cache.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * Dan Williams <dcbw@redhat.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef NM_OBJECT_CACHE_H +#define NM_OBJECT_CACHE_H + +#include <glib/gtypes.h> +#include <glib-object.h> +#include "nm-object.h" + +G_BEGIN_DECLS + +NMObject *nm_object_cache_get (const char *path); +void nm_object_cache_add (NMObject *object); +void nm_object_cache_remove_by_object (NMObject *object); +void nm_object_cache_remove_by_path (const char *path); + +G_END_DECLS + +#endif /* NM_OBJECT_CACHE_H */ diff --git a/libnm-glib/nm-object-private.h b/libnm-glib/nm-object-private.h new file mode 100644 index 0000000000..21d58c9322 --- /dev/null +++ b/libnm-glib/nm-object-private.h @@ -0,0 +1,69 @@ +#ifndef NM_OBJECT_PRIVATE_H +#define NM_OBJECT_PRIVATE_H + +#include <glib.h> +#include <glib-object.h> +#include "nm-object.h" + +typedef gboolean (*PropChangedMarshalFunc) (NMObject *, GParamSpec *, GValue *, gpointer); +typedef GObject * (*NMObjectCreatorFunc) (DBusGConnection *, const char *); + +typedef struct { + const char *name; + PropChangedMarshalFunc func; + gpointer field; +} NMPropertiesChangedInfo; + + +void nm_object_handle_properties_changed (NMObject *object, + DBusGProxy *proxy, + const NMPropertiesChangedInfo *info); + +gboolean nm_object_demarshal_generic (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field); + + +/* DBus property accessors */ + +gboolean nm_object_get_property (NMObject *object, + const char *interface, + const char *prop_name, + GValue *value); + +void nm_object_set_property (NMObject *object, + const char *interface, + const char *prop_name, + GValue *value); + +char *nm_object_get_string_property (NMObject *object, + const char *interface, + const char *prop_name); + +char *nm_object_get_object_path_property (NMObject *object, + const char *interface, + const char *prop_name); + +gint32 nm_object_get_int_property (NMObject *object, + const char *interface, + const char *prop_name); + +guint32 nm_object_get_uint_property (NMObject *object, + const char *interface, + const char *prop_name); + +gboolean nm_object_get_boolean_property (NMObject *object, + const char *interface, + const char *prop_name); + +gint8 nm_object_get_byte_property (NMObject *object, + const char *interface, + const char *prop_name); + +gdouble nm_object_get_double_property (NMObject *object, + const char *interface, + const char *prop_name); + +GByteArray *nm_object_get_byte_array_property (NMObject *object, + const char *interface, + const char *prop_name); + +#endif /* NM_OBJECT_PRIVATE_H */ diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c index f2e0e58380..f18c6aa4a5 100644 --- a/libnm-glib/nm-object.c +++ b/libnm-glib/nm-object.c @@ -1,17 +1,29 @@ /* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ +#include <string.h> #include <nm-utils.h> -#include "nm-object.h" #include "NetworkManager.h" +#include "nm-object.h" +#include "nm-object-cache.h" +#include "nm-object-private.h" +#include "nm-dbus-glib-types.h" + G_DEFINE_ABSTRACT_TYPE (NMObject, nm_object, G_TYPE_OBJECT) #define NM_OBJECT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_OBJECT, NMObjectPrivate)) typedef struct { + PropChangedMarshalFunc func; + gpointer field; +} PropChangedInfo; + +typedef struct { DBusGConnection *connection; char *path; DBusGProxy *properties_proxy; + GSList *pcs; + NMObject *parent; gboolean disposed; } NMObjectPrivate; @@ -43,6 +55,8 @@ constructor (GType type, if (!object) return NULL; + nm_object_cache_add (NM_OBJECT (object)); + priv = NM_OBJECT_GET_PRIVATE (object); if (priv->connection == NULL || priv->path == NULL) { @@ -82,6 +96,8 @@ finalize (GObject *object) { NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + g_slist_foreach (priv->pcs, (GFunc) g_hash_table_destroy, NULL); + g_slist_free (priv->pcs); g_free (priv->path); G_OBJECT_CLASS (nm_object_parent_class)->finalize (object); @@ -100,7 +116,7 @@ set_property (GObject *object, guint prop_id, break; case PROP_PATH: /* Construct only */ - priv->path = g_strdup (g_value_get_string (value)); + priv->path = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -144,7 +160,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) /* porperties */ g_object_class_install_property (object_class, PROP_CONNECTION, - g_param_spec_boxed (NM_OBJECT_CONNECTION, + g_param_spec_boxed (NM_OBJECT_DBUS_CONNECTION, "Connection", "Connection", DBUS_TYPE_G_CONNECTION, @@ -152,7 +168,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) g_object_class_install_property (object_class, PROP_PATH, - g_param_spec_string (NM_OBJECT_PATH, + g_param_spec_string (NM_OBJECT_DBUS_PATH, "Object Path", "DBus Object Path", NULL, @@ -177,7 +193,7 @@ nm_object_get_path (NMObject *object) /* Stolen from dbus-glib */ static char* -wincaps_to_uscore (const char *caps) +wincaps_to_dash (const char *caps) { const char *p; GString *str; @@ -186,8 +202,8 @@ wincaps_to_uscore (const char *caps) p = caps; while (*p) { if (g_ascii_isupper (*p)) { - if (str->len > 0 && (str->len < 2 || str->str[str->len-2] != '_')) - g_string_append_c (str, '_'); + if (str->len > 0 && (str->len < 2 || str->str[str->len-2] != '-')) + g_string_append_c (str, '-'); g_string_append_c (str, g_ascii_tolower (*p)); } else g_string_append_c (str, *p); @@ -200,16 +216,38 @@ wincaps_to_uscore (const char *caps) static void handle_property_changed (gpointer key, gpointer data, gpointer user_data) { - GObject *object = G_OBJECT (user_data); + NMObject *self = NM_OBJECT (user_data); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self); char *prop_name; - GValue *value = (GValue *) data; + PropChangedInfo *pci; + GParamSpec *pspec; + gboolean success = FALSE, found = FALSE; + GSList *iter; + + prop_name = wincaps_to_dash ((char *) key); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name); + if (!pspec) { + g_warning ("Property '%s' change detected but couldn't be found on the object.", prop_name); + goto out; + } + + /* Iterate through the object and it's parents to find the property */ + for (iter = priv->pcs; iter; iter = g_slist_next (iter)) { + pci = g_hash_table_lookup ((GHashTable *) iter->data, prop_name); + if (pci) { + found = TRUE; + success = (*(pci->func)) (self, pspec, (GValue *) data, pci->field); + if (success) + break; + } + } - prop_name = wincaps_to_uscore ((char *) key); - if (g_object_class_find_property (G_OBJECT_GET_CLASS (object), prop_name)) - g_object_set_property (object, prop_name, value); - else - nm_warning ("Property '%s' change detected but can't be set", prop_name); + if (!found) + g_warning ("Property '%s' unhandled.", prop_name); + else if (!success) + g_warning ("Property '%s' could not be set due to errors.", prop_name); +out: g_free (prop_name); } @@ -218,26 +256,109 @@ properties_changed_proxy (DBusGProxy *proxy, GHashTable *properties, gpointer user_data) { - GObject *object = G_OBJECT (user_data); - - g_object_freeze_notify (object); - g_hash_table_foreach (properties, handle_property_changed, object); - g_object_thaw_notify (object); + g_hash_table_foreach (properties, handle_property_changed, user_data); } void -nm_object_handle_properties_changed (NMObject *object, DBusGProxy *proxy) +nm_object_handle_properties_changed (NMObject *object, + DBusGProxy *proxy, + const NMPropertiesChangedInfo *info) { - dbus_g_proxy_add_signal (proxy, "PropertiesChanged", - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - G_TYPE_INVALID); + NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object); + NMPropertiesChangedInfo *tmp; + GHashTable *instance; + + g_return_if_fail (NM_IS_OBJECT (object)); + g_return_if_fail (proxy != NULL); + g_return_if_fail (info != NULL); + + dbus_g_proxy_add_signal (proxy, "PropertiesChanged", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (proxy, "PropertiesChanged", G_CALLBACK (properties_changed_proxy), object, NULL); + + instance = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->pcs = g_slist_prepend (priv->pcs, instance); + + for (tmp = (NMPropertiesChangedInfo *) info; tmp->name; tmp++) { + PropChangedInfo *pci; + + if (!tmp->name || !tmp->func || !tmp->field) { + g_warning ("%s: missing field in NMPropertiesChangedInfo", __func__); + continue; + } + + pci = g_malloc0 (sizeof (PropChangedInfo)); + if (!pci) { + g_warning ("%s: not enough memory for PropChangedInfo", __func__); + continue; + } + pci->func = tmp->func; + pci->field = tmp->field; + g_hash_table_insert (instance, g_strdup (tmp->name), pci); + } } +#define HANDLE_TYPE(ucase, lcase) \ + } else if (pspec->value_type == G_TYPE_##ucase) { \ + if (G_VALUE_HOLDS_##ucase (value)) { \ + g##lcase *param = (g##lcase *) field; \ + *param = g_value_get_##lcase (value); \ + } else { \ + success = FALSE; \ + goto done; \ + } + +gboolean +nm_object_demarshal_generic (NMObject *object, + GParamSpec *pspec, + GValue *value, + gpointer field) +{ + gboolean success = TRUE; + + if (pspec->value_type == G_TYPE_STRING) { + if (G_VALUE_HOLDS_STRING (value)) { + char **param = (char **) field; + g_free (*param); + *param = g_value_dup_string (value); + } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) { + char **param = (char **) field; + g_free (*param); + *param = g_strdup (g_value_get_boxed (value)); + } else { + success = FALSE; + goto done; + } + HANDLE_TYPE(BOOLEAN, boolean) + HANDLE_TYPE(CHAR, char) + HANDLE_TYPE(UCHAR, uchar) + HANDLE_TYPE(DOUBLE, double) + HANDLE_TYPE(INT, int) + HANDLE_TYPE(UINT, uint) + HANDLE_TYPE(INT64, int) + HANDLE_TYPE(UINT64, uint) + HANDLE_TYPE(LONG, long) + HANDLE_TYPE(ULONG, ulong) + } else { + g_warning ("%s: %s/%s unhandled type %s.", + __func__, G_OBJECT_TYPE_NAME (object), pspec->name, + g_type_name (pspec->value_type)); + success = FALSE; + } + +done: + if (success) { + g_object_notify (G_OBJECT (object), pspec->name); + } else { + g_warning ("%s: %s/%s (type %s) couldn't be set with type %s.", + __func__, G_OBJECT_TYPE_NAME (object), pspec->name, + g_type_name (pspec->value_type), G_VALUE_TYPE_NAME (value)); + } + return success; +} gboolean nm_object_get_property (NMObject *object, @@ -299,7 +420,10 @@ nm_object_get_string_property (NMObject *object, GValue value = {0,}; if (nm_object_get_property (object, interface, prop_name, &value)) { - str = g_strdup (g_value_get_string (&value)); + if (G_VALUE_HOLDS_STRING (&value)) + str = g_strdup (g_value_get_string (&value)); + else if (G_VALUE_HOLDS (&value, DBUS_TYPE_G_OBJECT_PATH)) + str = g_strdup (g_value_get_boxed (&value)); g_value_unset (&value); } diff --git a/libnm-glib/nm-object.h b/libnm-glib/nm-object.h index 15af78a300..04c4a6c1c9 100644 --- a/libnm-glib/nm-object.h +++ b/libnm-glib/nm-object.h @@ -14,8 +14,8 @@ G_BEGIN_DECLS #define NM_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_OBJECT)) #define NM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OBJECT, NMObjectClass)) -#define NM_OBJECT_CONNECTION "connection" -#define NM_OBJECT_PATH "path" +#define NM_OBJECT_DBUS_CONNECTION "dbus-connection" +#define NM_OBJECT_DBUS_PATH "dbus-path" typedef struct { GObject parent; @@ -30,54 +30,6 @@ GType nm_object_get_type (void); DBusGConnection *nm_object_get_connection (NMObject *object); const char *nm_object_get_path (NMObject *object); -void nm_object_handle_properties_changed (NMObject *object, - DBusGProxy *proxy); - -/* DBus property accessors */ - -gboolean nm_object_get_property (NMObject *object, - const char *interface, - const char *prop_name, - GValue *value); - -void nm_object_set_property (NMObject *object, - const char *interface, - const char *prop_name, - GValue *value); - -char *nm_object_get_string_property (NMObject *object, - const char *interface, - const char *prop_name); - -char *nm_object_get_object_path_property (NMObject *object, - const char *interface, - const char *prop_name); - -gint32 nm_object_get_int_property (NMObject *object, - const char *interface, - const char *prop_name); - -guint32 nm_object_get_uint_property (NMObject *object, - const char *interface, - const char *prop_name); - -gboolean nm_object_get_boolean_property (NMObject *object, - const char *interface, - const char *prop_name); - -gint8 nm_object_get_byte_property (NMObject *object, - const char *interface, - const char *prop_name); - -gdouble nm_object_get_double_property (NMObject *object, - const char *interface, - const char *prop_name); - -GByteArray *nm_object_get_byte_array_property (NMObject *object, - const char *interface, - const char *prop_name); - - G_END_DECLS #endif /* NM_OBJECT_H */ diff --git a/libnm-glib/nm-settings.c b/libnm-glib/nm-settings.c index 05f2dbccd7..8381c94d87 100644 --- a/libnm-glib/nm-settings.c +++ b/libnm-glib/nm-settings.c @@ -2,6 +2,7 @@ #include <nm-utils.h> #include <nm-setting-connection.h> #include "nm-settings.h" +#include "nm-dbus-glib-types.h" GQuark @@ -279,9 +280,6 @@ nm_exported_connection_dispose (GObject *object) G_OBJECT_CLASS (nm_exported_connection_parent_class)->dispose (object); } -#define DBUS_TYPE_G_STRING_VARIANT_HASHTABLE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) -#define DBUS_TYPE_G_DICT_OF_DICTS (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_STRING_VARIANT_HASHTABLE)) - static void nm_exported_connection_class_init (NMExportedConnectionClass *exported_connection_class) { @@ -316,7 +314,7 @@ nm_exported_connection_class_init (NMExportedConnectionClass *exported_connectio NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, - DBUS_TYPE_G_DICT_OF_DICTS); + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); connection_signals[EC_REMOVED] = g_signal_new ("removed", diff --git a/libnm-glib/nm-types-private.h b/libnm-glib/nm-types-private.h new file mode 100644 index 0000000000..42edad345b --- /dev/null +++ b/libnm-glib/nm-types-private.h @@ -0,0 +1,18 @@ + +#ifndef NM_TYPES_PRIVATE_H +#define NM_TYPES_PRIVATE_H + +#include <dbus/dbus-glib.h> +#include "nm-types.h" +#include "nm-object-private.h" + +gboolean nm_ssid_demarshal (GValue *value, GByteArray **dest); +gboolean nm_uint_array_demarshal (GValue *value, GArray **dest); +gboolean nm_string_array_demarshal (GValue *value, GPtrArray **dest); +gboolean nm_object_array_demarshal (GValue *value, + GPtrArray **dest, + DBusGConnection *connection, + NMObjectCreatorFunc func); + + +#endif /* NM_TYPES_PRIVATE_H */ diff --git a/libnm-glib/nm-types.c b/libnm-glib/nm-types.c new file mode 100644 index 0000000000..8036952cec --- /dev/null +++ b/libnm-glib/nm-types.c @@ -0,0 +1,255 @@ + +#include <glib.h> +#include <dbus/dbus-glib.h> +#include <string.h> +#include "nm-types.h" +#include "nm-types-private.h" +#include "nm-object-private.h" +#include "nm-object-cache.h" +#include "nm-dbus-glib-types.h" + +static gpointer +nm_ssid_copy (GByteArray *src) +{ + GByteArray *dest; + + dest = g_byte_array_sized_new (src->len); + g_byte_array_append (dest, src->data, src->len); + return dest; +} + +static void +nm_ssid_free (GByteArray *ssid) +{ + g_byte_array_free (ssid, TRUE); +} + +GType +nm_ssid_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("nm-ssid"), + (GBoxedCopyFunc) nm_ssid_copy, + (GBoxedFreeFunc) nm_ssid_free); + return our_type; +} + +gboolean +nm_ssid_demarshal (GValue *value, GByteArray **dest) +{ + GByteArray *array; + + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)) + return FALSE; + + if (*dest) { + g_boxed_free (NM_TYPE_SSID, *dest); + *dest = NULL; + } + + array = (GByteArray *) g_value_get_boxed (value); + if (array && (array->len > 0)) { + *dest = g_byte_array_sized_new (array->len); + (*dest)->len = array->len; + memcpy ((*dest)->data, array->data, array->len); + } + + return TRUE; +} + +/*****************************/ + +static gpointer +nm_uint_array_copy (GArray *src) +{ + GArray *dest; + + dest = g_array_sized_new (FALSE, TRUE, sizeof (guint32), src->len); + g_array_append_vals (dest, src->data, src->len); + return dest; +} + +static void +nm_uint_array_free (GArray *array) +{ + g_array_free (array, TRUE); +} + +GType +nm_uint_array_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("nm-uint-array"), + (GBoxedCopyFunc) nm_uint_array_copy, + (GBoxedFreeFunc) nm_uint_array_free); + return our_type; +} + +gboolean +nm_uint_array_demarshal (GValue *value, GArray **dest) +{ + GArray *array; + + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY)) + return FALSE; + + if (*dest) { + g_boxed_free (NM_TYPE_UINT_ARRAY, *dest); + *dest = NULL; + } + + array = (GArray *) g_value_get_boxed (value); + if (array && (array->len > 0)) { + *dest = g_array_sized_new (FALSE, TRUE, sizeof (guint32), array->len); + g_array_append_vals (*dest, array->data, array->len); + } + + return TRUE; +} + +/*****************************/ + +static gpointer +nm_string_array_copy (GPtrArray *src) +{ + GPtrArray *dest; + int i; + + dest = g_ptr_array_sized_new (src->len); + for (i = 0; i < src->len; i++) + g_ptr_array_add (dest, g_strdup (g_ptr_array_index (src, i))); + return dest; +} + +static void +nm_string_array_free (GPtrArray *array) +{ + int i; + + for (i = 0; i < array->len; i++) + g_free (g_ptr_array_index (array, i)); + g_ptr_array_free (array, TRUE); +} + +GType +nm_string_array_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("nm-string-array"), + (GBoxedCopyFunc) nm_string_array_copy, + (GBoxedFreeFunc) nm_string_array_free); + return our_type; +} + +gboolean +nm_string_array_demarshal (GValue *value, GPtrArray **dest) +{ + GPtrArray *array; + + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_STRING)) + return FALSE; + + if (*dest) { + g_boxed_free (NM_TYPE_STRING_ARRAY, *dest); + *dest = NULL; + } + + array = (GPtrArray *) g_value_get_boxed (value); + if (array && array->len) { + int i; + + *dest = g_ptr_array_sized_new (array->len); + for (i = 0; i < array->len; i++) + g_ptr_array_add (*dest, g_strdup (g_ptr_array_index (array, i))); + } + + return TRUE; +} + +/*****************************/ + +static gpointer +nm_object_array_copy (GPtrArray *src) +{ + GPtrArray *dest; + int i; + + dest = g_ptr_array_sized_new (src->len); + for (i = 0; i < src->len; i++) + g_ptr_array_add (dest, g_object_ref (g_ptr_array_index (src, i))); + return dest; +} + +static void +nm_object_array_free (GPtrArray *array) +{ + int i; + + for (i = 0; i < array->len; i++) + g_object_unref (g_ptr_array_index (array, i)); + g_ptr_array_free (array, TRUE); +} + +GType +nm_object_array_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("nm-object-array"), + (GBoxedCopyFunc) nm_object_array_copy, + (GBoxedFreeFunc) nm_object_array_free); + return our_type; +} + +gboolean +nm_object_array_demarshal (GValue *value, + GPtrArray **dest, + DBusGConnection *connection, + NMObjectCreatorFunc func) +{ + GPtrArray *temp = NULL; + GPtrArray *array; + + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) + return FALSE; + + array = (GPtrArray *) g_value_get_boxed (value); + if (array && array->len) { + int i; + + temp = g_ptr_array_sized_new (array->len); + for (i = 0; i < array->len; i++) { + const char *path; + GObject *object; + + path = g_ptr_array_index (array, i); + object = G_OBJECT (nm_object_cache_get (path)); + if (object) { + g_ptr_array_add (temp, g_object_ref (object)); + } else { + object = (*func) (connection, path); + if (object) + g_ptr_array_add (temp, object); + else + g_warning ("%s: couldn't create object for %s", __func__, path); + } + } + } + + /* Deallocate after to ensure that an object that might already + * be in the array doesn't get destroyed due to refcounting. + */ + if (*dest) + g_boxed_free (NM_TYPE_OBJECT_ARRAY, *dest); + *dest = temp; + + return TRUE; +} + diff --git a/libnm-glib/nm-types.h b/libnm-glib/nm-types.h new file mode 100644 index 0000000000..67c1efdf78 --- /dev/null +++ b/libnm-glib/nm-types.h @@ -0,0 +1,19 @@ +#ifndef NM_TYPES_H +#define NM_TYPES_H + +#include <glib.h> +#include <glib-object.h> + +#define NM_TYPE_SSID (nm_ssid_get_type ()) +GType nm_ssid_get_type (void) G_GNUC_CONST; + +#define NM_TYPE_UINT_ARRAY (nm_uint_array_get_type ()) +GType nm_uint_array_get_type (void) G_GNUC_CONST; + +#define NM_TYPE_STRING_ARRAY (nm_string_array_get_type ()) +GType nm_string_array_get_type (void) G_GNUC_CONST; + +#define NM_TYPE_OBJECT_ARRAY (nm_object_array_get_type ()) +GType nm_object_array_get_type (void) G_GNUC_CONST; + +#endif /* NM_TYPES_H */ diff --git a/libnm-glib/nm-vpn-connection.c b/libnm-glib/nm-vpn-connection.c index c684052f59..ff18de924f 100644 --- a/libnm-glib/nm-vpn-connection.c +++ b/libnm-glib/nm-vpn-connection.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * (C) Copyright 2004 Red Hat, Inc. + * (C) Copyright 2008 Red Hat, Inc. */ #include <string.h> @@ -26,6 +26,7 @@ #include "nm-utils.h" #include "nm-vpn-connection-bindings.h" #include "nm-marshal.h" +#include "nm-object-private.h" G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_OBJECT) @@ -57,8 +58,8 @@ nm_vpn_connection_new (DBusGConnection *dbus_connection, g_return_val_if_fail (path != NULL, NULL); connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, - NM_OBJECT_CONNECTION, dbus_connection, - NM_OBJECT_PATH, path, + NM_OBJECT_DBUS_CONNECTION, dbus_connection, + NM_OBJECT_DBUS_PATH, path, NULL); nm_vpn_connection_get_name (connection); diff --git a/libnm-glib/nm-vpn-manager.c b/libnm-glib/nm-vpn-manager.c index fc46ceee6b..2c57687884 100644 --- a/libnm-glib/nm-vpn-manager.c +++ b/libnm-glib/nm-vpn-manager.c @@ -29,8 +29,8 @@ nm_vpn_manager_new (void) } return (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, - NM_OBJECT_CONNECTION, connection, - NM_OBJECT_PATH, NM_DBUS_PATH_VPN, + NM_OBJECT_DBUS_CONNECTION, connection, + NM_OBJECT_DBUS_PATH, NM_DBUS_PATH_VPN, NULL); } diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c index e42b0b4951..eabac2b802 100644 --- a/libnm-glib/nm-vpn-plugin.c +++ b/libnm-glib/nm-vpn-plugin.c @@ -4,6 +4,7 @@ #include "nm-vpn-plugin.h" #include "nm-utils.h" #include "nm-connection.h" +#include "nm-dbus-glib-types.h" static gboolean impl_vpn_plugin_connect (NMVPNPlugin *plugin, GHashTable *connection, @@ -704,7 +705,7 @@ nm_vpn_plugin_class_init (NMVPNPluginClass *plugin_class) NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)); + DBUS_TYPE_G_MAP_OF_VARIANT); signals[LOGIN_BANNER] = g_signal_new ("login-banner", |