summaryrefslogtreecommitdiff
path: root/libnm
diff options
context:
space:
mode:
Diffstat (limited to 'libnm')
-rw-r--r--libnm/libnm.ver1
-rw-r--r--libnm/meson.build2
-rw-r--r--libnm/nm-access-point.c94
-rw-r--r--libnm/nm-active-connection.c243
-rw-r--r--libnm/nm-checkpoint.c57
-rw-r--r--libnm/nm-client.c5075
-rw-r--r--libnm/nm-client.h4
-rw-r--r--libnm/nm-dbus-helpers.c59
-rw-r--r--libnm/nm-dbus-helpers.h2
-rw-r--r--libnm/nm-device-6lowpan.c48
-rw-r--r--libnm/nm-device-adsl.c32
-rw-r--r--libnm/nm-device-bond.c63
-rw-r--r--libnm/nm-device-bridge.c63
-rw-r--r--libnm/nm-device-bt.c34
-rw-r--r--libnm/nm-device-dummy.c38
-rw-r--r--libnm/nm-device-ethernet.c73
-rw-r--r--libnm/nm-device-generic.c32
-rw-r--r--libnm/nm-device-infiniband.c34
-rw-r--r--libnm/nm-device-ip-tunnel.c78
-rw-r--r--libnm/nm-device-macsec.c85
-rw-r--r--libnm/nm-device-macvlan.c54
-rw-r--r--libnm/nm-device-modem.c46
-rw-r--r--libnm/nm-device-olpc-mesh.c58
-rw-r--r--libnm/nm-device-ovs-bridge.c54
-rw-r--r--libnm/nm-device-ovs-interface.c6
-rw-r--r--libnm/nm-device-ovs-port.c55
-rw-r--r--libnm/nm-device-ppp.c7
-rw-r--r--libnm/nm-device-team.c65
-rw-r--r--libnm/nm-device-tun.c48
-rw-r--r--libnm/nm-device-vlan.c54
-rw-r--r--libnm/nm-device-vxlan.c102
-rw-r--r--libnm/nm-device-wifi-p2p.c109
-rw-r--r--libnm/nm-device-wifi.c241
-rw-r--r--libnm/nm-device-wireguard.c38
-rw-r--r--libnm/nm-device-wpan.c42
-rw-r--r--libnm/nm-device.c478
-rw-r--r--libnm/nm-dhcp-config.c99
-rw-r--r--libnm/nm-dns-manager.c208
-rw-r--r--libnm/nm-dns-manager.h44
-rw-r--r--libnm/nm-ip-config.c408
-rw-r--r--libnm/nm-libnm-utils.c203
-rw-r--r--libnm/nm-libnm-utils.h654
-rw-r--r--libnm/nm-manager.c1532
-rw-r--r--libnm/nm-manager.h166
-rw-r--r--libnm/nm-object-private.h82
-rw-r--r--libnm/nm-object.c1485
-rw-r--r--libnm/nm-object.h3
-rw-r--r--libnm/nm-remote-connection.c325
-rw-r--r--libnm/nm-remote-settings.c479
-rw-r--r--libnm/nm-remote-settings.h77
-rw-r--r--libnm/nm-vpn-connection.c100
-rw-r--r--libnm/nm-wifi-p2p-peer.c61
-rw-r--r--libnm/tests/test-libnm.c409
-rw-r--r--libnm/tests/test-nm-client.c16
54 files changed, 7023 insertions, 6902 deletions
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 30cf605c42..ed08865c97 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1638,6 +1638,7 @@ libnm_1_22_0 {
global:
nm_client_get_dbus_connection;
nm_client_get_dbus_name_owner;
+ nm_client_get_metered;
nm_client_reload;
nm_client_reload_finish;
nm_manager_reload_flags_get_type;
diff --git a/libnm/meson.build b/libnm/meson.build
index 8b68a63679..51ca46d2bc 100644
--- a/libnm/meson.build
+++ b/libnm/meson.build
@@ -119,10 +119,8 @@ libnm_sources = files(
'nm-ip4-config.c',
'nm-ip6-config.c',
'nm-libnm-utils.c',
- 'nm-manager.c',
'nm-object.c',
'nm-remote-connection.c',
- 'nm-remote-settings.c',
'nm-secret-agent-old.c',
'nm-vpn-connection.c',
'nm-vpn-editor.c',
diff --git a/libnm/nm-access-point.c b/libnm/nm-access-point.c
index d21bb60acc..77ba65274c 100644
--- a/libnm/nm-access-point.c
+++ b/libnm/nm-access-point.c
@@ -19,7 +19,7 @@
/*****************************************************************************/
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+NM_GOBJECT_PROPERTIES_DEFINE (NMAccessPoint,
PROP_FLAGS,
PROP_WPA_FLAGS,
PROP_RSN_FLAGS,
@@ -34,16 +34,16 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NM80211ApFlags flags;
- NM80211ApSecurityFlags wpa_flags;
- NM80211ApSecurityFlags rsn_flags;
GBytes *ssid;
- guint32 frequency;
char *bssid;
- NM80211Mode mode;
+ guint32 flags;
+ guint32 wpa_flags;
+ guint32 rsn_flags;
+ guint32 frequency;
+ guint32 mode;
guint32 max_bitrate;
+ gint32 last_seen;
guint8 strength;
- int last_seen;
} NMAccessPointPrivate;
struct _NMAccessPoint {
@@ -127,9 +127,7 @@ nm_access_point_get_ssid (NMAccessPoint *ap)
g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL);
priv = NM_ACCESS_POINT_GET_PRIVATE (ap);
- if (!priv->ssid || g_bytes_get_size (priv->ssid) == 0)
- return NULL;
-
+ nm_assert (!priv->ssid || g_bytes_get_size (priv->ssid) > 0);
return priv->ssid;
}
@@ -263,6 +261,9 @@ nm_access_point_connection_valid (NMAccessPoint *ap, NMConnection *connection)
const char *setting_band;
guint32 ap_freq, setting_chan, ap_chan;
+ g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
s_con = nm_connection_get_setting_connection (connection);
if (!s_con)
return FALSE;
@@ -368,7 +369,12 @@ GPtrArray *
nm_access_point_filter_connections (NMAccessPoint *ap, const GPtrArray *connections)
{
GPtrArray *filtered;
- int i;
+ guint i;
+
+ g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL);
+
+ if (!connections)
+ return NULL;
filtered = g_ptr_array_new_with_free_func (g_object_unref);
for (i = 0; i < connections->len; i++) {
@@ -383,6 +389,24 @@ nm_access_point_filter_connections (NMAccessPoint *ap, const GPtrArray *connecti
/*****************************************************************************/
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_hw_address (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ NMAccessPoint *self = NM_ACCESS_POINT (dbobj->nmobj);
+ NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (self);
+
+ g_free (priv->bssid);
+ priv->bssid = value ? g_variant_dup_string (value, NULL) : 0u;
+ _notify (self, PROP_HW_ADDRESS);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
+}
+
+/*****************************************************************************/
+
static void
nm_access_point_init (NMAccessPoint *ap)
{
@@ -396,7 +420,6 @@ finalize (GObject *object)
if (priv->ssid)
g_bytes_unref (priv->ssid);
-
g_free (priv->bssid);
G_OBJECT_CLASS (nm_access_point_parent_class)->finalize (object);
@@ -450,43 +473,32 @@ get_property (GObject *object,
}
}
-static void
-init_dbus (NMObject *object)
-{
- NMAccessPointPrivate *priv = NM_ACCESS_POINT_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_ACCESS_POINT_FLAGS, &priv->flags },
- { NM_ACCESS_POINT_WPA_FLAGS, &priv->wpa_flags },
- { NM_ACCESS_POINT_RSN_FLAGS, &priv->rsn_flags },
- { NM_ACCESS_POINT_SSID, &priv->ssid },
- { NM_ACCESS_POINT_FREQUENCY, &priv->frequency },
- /* The D-Bus property is HwAddress, but the GObject property is "bssid" */
- { NM_ACCESS_POINT_HW_ADDRESS, &priv->bssid },
- { NM_ACCESS_POINT_MODE, &priv->mode },
- { NM_ACCESS_POINT_MAX_BITRATE, &priv->max_bitrate },
- { NM_ACCESS_POINT_STRENGTH, &priv->strength },
- { NM_ACCESS_POINT_LAST_SEEN, &priv->last_seen },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_access_point_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_ACCESS_POINT,
- property_info);
-}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_ACCESS_POINT,
+ nm_access_point_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_U ("Flags", PROP_FLAGS, NMAccessPoint, _priv.flags ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Frequency", PROP_FREQUENCY, NMAccessPoint, _priv.frequency ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("HwAddress", PROP_BSSID, "s", _notify_update_prop_hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_I ("LastSeen", PROP_LAST_SEEN, NMAccessPoint, _priv.last_seen ),
+ NML_DBUS_META_PROPERTY_INIT_U ("MaxBitrate", PROP_MAX_BITRATE, NMAccessPoint, _priv.max_bitrate ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Mode", PROP_MODE, NMAccessPoint, _priv.mode ),
+ NML_DBUS_META_PROPERTY_INIT_U ("RsnFlags", PROP_RSN_FLAGS, NMAccessPoint, _priv.rsn_flags ),
+ NML_DBUS_META_PROPERTY_INIT_AY ("Ssid", PROP_SSID, NMAccessPoint, _priv.ssid ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("Strength", PROP_STRENGTH, NMAccessPoint, _priv.strength ),
+ NML_DBUS_META_PROPERTY_INIT_U ("WpaFlags", PROP_WPA_FLAGS, NMAccessPoint, _priv.wpa_flags ),
+ ),
+);
static void
nm_access_point_class_init (NMAccessPointClass *ap_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ap_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ap_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMAccessPoint:flags:
*
@@ -620,5 +632,5 @@ nm_access_point_class_init (NMAccessPointClass *ap_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_accesspoint);
}
diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c
index 6b49f9a5e0..aa8504e61d 100644
--- a/libnm/nm-active-connection.c
+++ b/libnm/nm-active-connection.c
@@ -21,8 +21,6 @@
#include "nm-ip6-config.h"
#include "nm-remote-connection.h"
-#include "introspection/org.freedesktop.NetworkManager.Connection.Active.h"
-
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE (NMActiveConnection,
@@ -50,26 +48,34 @@ enum {
LAST_SIGNAL
};
-static guint signals[LAST_SIGNAL] = { 0 };
+static guint signals[LAST_SIGNAL];
+
+enum {
+ PROPERTY_O_IDX_CONNECTION,
+ PROPERTY_O_IDX_MASTER,
+ PROPERTY_O_IDX_IP4_CONFIG,
+ PROPERTY_O_IDX_IP6_CONFIG,
+ PROPERTY_O_IDX_DHCP4_CONFIG,
+ PROPERTY_O_IDX_DHCP6_CONFIG,
+ _PROPERTY_O_IDX_NUM,
+};
typedef struct _NMActiveConnectionPrivate {
- NMRemoteConnection *connection;
+ NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NUM];
+ NMLDBusPropertyAO devices;
+ NMRefString *specific_object_path;
char *id;
char *uuid;
char *type;
- char *specific_object_path;
- GPtrArray *devices;
- NMActiveConnectionState state;
- guint state_flags;
- gboolean is_default;
- NMIPConfig *ip4_config;
- NMDhcpConfig *dhcp4_config;
- gboolean is_default6;
- NMIPConfig *ip6_config;
- NMDhcpConfig *dhcp6_config;
- gboolean is_vpn;
- NMDevice *master;
- NMActiveConnectionStateReason reason;
+
+ guint32 state;
+ guint32 state_flags;
+
+ bool is_default;
+ bool is_default6;
+ bool is_vpn;
+
+ guint32 reason;
} NMActiveConnectionPrivate;
G_DEFINE_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_OBJECT);
@@ -92,7 +98,7 @@ nm_active_connection_get_connection (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->connection;
+ return nml_dbus_property_o_get_obj (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->property_o[PROPERTY_O_IDX_CONNECTION]);
}
/**
@@ -166,7 +172,7 @@ nm_active_connection_get_specific_object_path (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->specific_object_path;
+ return _nml_coerce_property_object_path (NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->specific_object_path);
}
/**
@@ -183,7 +189,7 @@ nm_active_connection_get_devices (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->devices;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->devices);
}
/**
@@ -269,7 +275,7 @@ nm_active_connection_get_ip4_config (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->ip4_config;
+ return nml_dbus_property_o_get_obj (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->property_o[PROPERTY_O_IDX_IP4_CONFIG]);
}
/**
@@ -288,7 +294,7 @@ nm_active_connection_get_dhcp4_config (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->dhcp4_config;
+ return nml_dbus_property_o_get_obj (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->property_o[PROPERTY_O_IDX_DHCP4_CONFIG]);
}
/**
@@ -322,7 +328,7 @@ nm_active_connection_get_ip6_config (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->ip6_config;
+ return nml_dbus_property_o_get_obj (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->property_o[PROPERTY_O_IDX_IP6_CONFIG]);
}
/**
@@ -341,7 +347,7 @@ nm_active_connection_get_dhcp6_config (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->dhcp6_config;
+ return nml_dbus_property_o_get_obj (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->property_o[PROPERTY_O_IDX_DHCP6_CONFIG]);
}
/**
@@ -373,71 +379,63 @@ nm_active_connection_get_master (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL);
- return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->master;
+ return nml_dbus_property_o_get_obj (&NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->property_o[PROPERTY_O_IDX_MASTER]);
}
+/*****************************************************************************/
+
static void
-nm_active_connection_init (NMActiveConnection *self)
+_notify_event_state_changed (NMClient *client,
+ NMClientNotifyEventWithPtr *notify_event)
{
- NMActiveConnectionPrivate *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate);
-
- self->_priv = priv;
-
- priv->devices = g_ptr_array_new ();
+ gs_unref_object NMActiveConnection *self = notify_event->user_data;
+ NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
+
+ /* we expose here the value cache in @priv. In practice, this is the same
+ * value as we received from the signal. In the unexpected case where they
+ * differ, the cached value of the current instance would still be more correct. */
+ g_signal_emit (self,
+ signals[STATE_CHANGED],
+ 0,
+ (guint) priv->state,
+ (guint) priv->reason);
}
-static void
-state_changed_proxy (NMDBusActiveConnectionProxy *proxy,
- NMActiveConnectionState state,
- NMActiveConnectionStateReason reason,
- gpointer user_data)
+void
+_nm_active_connection_state_changed_commit (NMActiveConnection *self,
+ guint32 state,
+ guint32 reason)
{
- NMActiveConnection *connection = NM_ACTIVE_CONNECTION (user_data);
- NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
+ NMClient *client;
+ NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
- priv->state = state;
- priv->reason = reason;
- g_signal_emit (connection, signals[STATE_CHANGED], 0, state, reason);
- _notify (connection, PROP_STATE);
-}
+ client = _nm_object_get_client (self);
-static void
-constructed (GObject *object)
-{
- GDBusProxy *proxy;
+ if (priv->state != state) {
+ priv->state = state;
+ _nm_client_queue_notify_object (client,
+ self,
+ obj_properties[PROP_STATE]);
+ }
- proxy = _nm_object_get_proxy (NM_OBJECT (object), NM_DBUS_INTERFACE_ACTIVE_CONNECTION);
- g_signal_connect (proxy, "state-changed",
- G_CALLBACK (state_changed_proxy), object);
- g_object_unref (proxy);
+ priv->reason = reason;
- G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
+ _nm_client_notify_event_queue_with_ptr (client,
+ NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP + 1,
+ _notify_event_state_changed,
+ g_object_ref (self));
}
+/*****************************************************************************/
+
static void
-dispose (GObject *object)
+nm_active_connection_init (NMActiveConnection *self)
{
- NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
- GDBusProxy *proxy;
-
- g_clear_pointer (&priv->devices, g_ptr_array_unref);
-
- g_clear_object (&priv->connection);
- g_clear_object (&priv->master);
- g_clear_object (&priv->ip4_config);
- g_clear_object (&priv->dhcp4_config);
- g_clear_object (&priv->ip6_config);
- g_clear_object (&priv->dhcp6_config);
+ NMActiveConnectionPrivate *priv;
- proxy = _nm_object_get_proxy (NM_OBJECT (object), NM_DBUS_INTERFACE_ACTIVE_CONNECTION);
- if (proxy) {
- g_signal_handlers_disconnect_by_data (proxy, object);
- g_object_unref (proxy);
- }
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionPrivate);
- G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object);
+ self->_priv = priv;
}
static void
@@ -448,7 +446,7 @@ finalize (GObject *object)
g_free (priv->id);
g_free (priv->uuid);
g_free (priv->type);
- g_free (priv->specific_object_path);
+ nm_ref_string_unref (priv->specific_object_path);
G_OBJECT_CLASS (nm_active_connection_parent_class)->finalize (object);
}
@@ -516,73 +514,46 @@ get_property (GObject *object,
}
}
-static gboolean
-demarshal_specific_object_path (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
-{
- const char *v;
- char **param = (char **) field;
-
- /* We have to demarshal this manually, because the D-Bus property name
- * ("SpecificObject"), doesn't match the object property name
- * ("specific-object-path"). (The name "specific-object" is reserved for
- * future use as an NMObject-valued property.)
- */
- if (!g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
- return FALSE;
-
- v = g_variant_get_string (value, NULL);
-
- g_free (*param);
- *param = nm_streq0 (v, "/") ? NULL : g_strdup (v);
- return TRUE;
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_ACTIVE_CONNECTION_CONNECTION, &priv->connection, NULL, NM_TYPE_REMOTE_CONNECTION },
- { NM_ACTIVE_CONNECTION_ID, &priv->id },
- { NM_ACTIVE_CONNECTION_UUID, &priv->uuid },
- { NM_ACTIVE_CONNECTION_TYPE, &priv->type },
- { "specific-object", &priv->specific_object_path, demarshal_specific_object_path },
- { NM_ACTIVE_CONNECTION_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE },
- { NM_ACTIVE_CONNECTION_STATE, &priv->state },
- { NM_ACTIVE_CONNECTION_STATE_FLAGS, &priv->state_flags },
- { NM_ACTIVE_CONNECTION_DEFAULT, &priv->is_default },
- { NM_ACTIVE_CONNECTION_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG },
- { NM_ACTIVE_CONNECTION_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG },
- { NM_ACTIVE_CONNECTION_DEFAULT6, &priv->is_default6 },
- { NM_ACTIVE_CONNECTION_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG },
- { NM_ACTIVE_CONNECTION_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG },
- { NM_ACTIVE_CONNECTION_VPN, &priv->is_vpn },
- { NM_ACTIVE_CONNECTION_MASTER, &priv->master, NULL, NM_TYPE_DEVICE },
-
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_active_connection_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
- property_info);
-}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_connection_active = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ nm_active_connection_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Connection", PROP_CONNECTION, NMActiveConnectionPrivate, property_o[PROPERTY_O_IDX_CONNECTION], nm_remote_connection_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Default", PROP_DEFAULT, NMActiveConnectionPrivate, is_default ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Default6", PROP_DEFAULT6, NMActiveConnectionPrivate, is_default6 ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Devices", PROP_DEVICES, NMActiveConnectionPrivate, devices, nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Dhcp4Config", PROP_DHCP4_CONFIG, NMActiveConnectionPrivate, property_o[PROPERTY_O_IDX_DHCP4_CONFIG], nm_dhcp4_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Dhcp6Config", PROP_DHCP6_CONFIG, NMActiveConnectionPrivate, property_o[PROPERTY_O_IDX_DHCP6_CONFIG], nm_dhcp6_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Id", PROP_ID, NMActiveConnectionPrivate, id ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Ip4Config", PROP_IP4_CONFIG, NMActiveConnectionPrivate, property_o[PROPERTY_O_IDX_IP4_CONFIG], nm_ip4_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Ip6Config", PROP_IP6_CONFIG, NMActiveConnectionPrivate, property_o[PROPERTY_O_IDX_IP6_CONFIG], nm_ip6_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Master", PROP_MASTER, NMActiveConnectionPrivate, property_o[PROPERTY_O_IDX_MASTER], nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_O ("SpecificObject", PROP_SPECIFIC_OBJECT_PATH, NMActiveConnectionPrivate, specific_object_path ),
+ NML_DBUS_META_PROPERTY_INIT_U ("State", PROP_STATE, NMActiveConnectionPrivate, state ),
+ NML_DBUS_META_PROPERTY_INIT_U ("StateFlags", PROP_STATE_FLAGS, NMActiveConnectionPrivate, state_flags ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Type", PROP_TYPE, NMActiveConnectionPrivate, type ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Uuid", PROP_UUID, NMActiveConnectionPrivate, uuid ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Vpn", PROP_VPN, NMActiveConnectionPrivate, is_vpn ),
+ ),
+ .base_struct_offset = G_STRUCT_OFFSET (NMActiveConnection, _priv),
+);
static void
-nm_active_connection_class_init (NMActiveConnectionClass *ap_class)
+nm_active_connection_class_init (NMActiveConnectionClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (ap_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ap_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
- g_type_class_add_private (ap_class, sizeof (NMActiveConnectionPrivate));
+ g_type_class_add_private (klass, sizeof (NMActiveConnectionPrivate));
object_class->get_property = get_property;
- object_class->constructed = constructed;
- object_class->dispose = dispose;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT (nm_object_class, NMActiveConnection);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N (nm_object_class, NMActiveConnectionPrivate, property_o);
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMActiveConnectionPrivate, devices);
/**
* NMActiveConnection:connection:
@@ -765,7 +736,13 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_connection_active);
+
+ /* TODO: the state reason should also be exposed as a property in libnm's NMActiveConnection,
+ * like done for NMDevice's state reason. */
+
+ /* TODO: the D-Bus API should also expose the state-reason as a property instead of
+ * a "StateChanged" signal. Like done for Device's "StateReason". */
/**
* NMActiveConnection::state-changed:
diff --git a/libnm/nm-checkpoint.c b/libnm/nm-checkpoint.c
index d029d6db84..89d4aa8dcb 100644
--- a/libnm/nm-checkpoint.c
+++ b/libnm/nm-checkpoint.c
@@ -6,6 +6,7 @@
#include "nm-default.h"
#include "nm-checkpoint.h"
+
#include "nm-core-internal.h"
#include "nm-dbus-interface.h"
#include "nm-device.h"
@@ -20,7 +21,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- GPtrArray *devices;
+ NMLDBusPropertyAO devices;
gint64 created;
guint32 rollback_timeout;
} NMCheckpointPrivate;
@@ -55,7 +56,7 @@ nm_checkpoint_get_devices (NMCheckpoint *checkpoint)
{
g_return_val_if_fail (NM_IS_CHECKPOINT (checkpoint), NULL);
- return NM_CHECKPOINT_GET_PRIVATE (checkpoint)->devices;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_CHECKPOINT_GET_PRIVATE (checkpoint)->devices);
}
/**
@@ -105,16 +106,6 @@ nm_checkpoint_init (NMCheckpoint *checkpoint)
}
static void
-finalize (GObject *object)
-{
- NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (NM_CHECKPOINT (object));
-
- g_ptr_array_unref (priv->devices);
-
- G_OBJECT_CLASS (nm_checkpoint_parent_class)->finalize (object);
-}
-
-static void
get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -125,7 +116,7 @@ get_property (GObject *object,
switch (prop_id) {
case PROP_DEVICES:
- g_value_take_boxed (value, _nm_utils_copy_object_array (priv->devices));
+ g_value_take_boxed (value, _nm_utils_copy_object_array (nm_checkpoint_get_devices (checkpoint)));
break;
case PROP_CREATED:
g_value_set_int64 (value, priv->created);
@@ -139,34 +130,28 @@ get_property (GObject *object,
}
}
-static void
-init_dbus (NMObject *object)
-{
- NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (NM_CHECKPOINT (object));
- const NMPropertiesInfo property_info[] = {
- { NM_CHECKPOINT_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE },
- { NM_CHECKPOINT_CREATED, &priv->created },
- { NM_CHECKPOINT_ROLLBACK_TIMEOUT, &priv->rollback_timeout },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_checkpoint_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_CHECKPOINT,
- property_info);
-}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_checkpoint = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_CHECKPOINT,
+ nm_checkpoint_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_X ("Created", PROP_CREATED, NMCheckpoint, _priv.created ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Devices", PROP_DEVICES, NMCheckpoint, _priv.devices, nm_device_get_type, .ready_without_visible = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_U ("RollbackTimeout", PROP_ROLLBACK_TIMEOUT, NMCheckpoint, _priv.rollback_timeout ),
+ ),
+);
static void
-nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class)
+nm_checkpoint_class_init (NMCheckpointClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (checkpoint_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (checkpoint_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
object_class->get_property = get_property;
- object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMCheckpoint);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMCheckpointPrivate, devices);
/**
* NMCheckpoint:devices: (type GPtrArray(NMDevice))
@@ -207,5 +192,5 @@ nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_checkpoint);
}
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index 56367eedc1..25b36f238f 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -10,34 +10,16 @@
#include <libudev.h>
+#include "nm-std-aux/c-list-util.h"
+#include "nm-glib-aux/nm-c-list.h"
#include "nm-glib-aux/nm-dbus-aux.h"
-#include "nm-utils.h"
-#include "nm-manager.h"
-#include "nm-dns-manager.h"
-#include "nm-remote-settings.h"
-#include "nm-device-ethernet.h"
-#include "nm-device-wifi.h"
-#include "nm-core-internal.h"
-#include "nm-active-connection.h"
-#include "nm-vpn-connection.h"
-#include "nm-remote-connection.h"
-#include "nm-dbus-helpers.h"
-#include "nm-wimax-nsp.h"
-#include "nm-object-private.h"
-
-#include "introspection/org.freedesktop.NetworkManager.h"
-#include "introspection/org.freedesktop.NetworkManager.Device.Wireless.h"
-#include "introspection/org.freedesktop.NetworkManager.Device.WifiP2P.h"
-#include "introspection/org.freedesktop.NetworkManager.Device.h"
-#include "introspection/org.freedesktop.NetworkManager.DnsManager.h"
-#include "introspection/org.freedesktop.NetworkManager.Settings.h"
-#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h"
-#include "introspection/org.freedesktop.NetworkManager.VPN.Connection.h"
-#include "introspection/org.freedesktop.NetworkManager.Connection.Active.h"
+#include "nm-libnm-core-intern/nm-common-macros.h"
#include "nm-access-point.h"
#include "nm-active-connection.h"
#include "nm-checkpoint.h"
+#include "nm-core-internal.h"
+#include "nm-dbus-helpers.h"
#include "nm-device-6lowpan.h"
#include "nm-device-adsl.h"
#include "nm-device-bond.h"
@@ -62,31 +44,90 @@
#include "nm-device-vxlan.h"
#include "nm-device-wifi-p2p.h"
#include "nm-device-wifi.h"
-#include "nm-device-wimax.h"
#include "nm-device-wireguard.h"
#include "nm-device-wpan.h"
#include "nm-dhcp-config.h"
#include "nm-dhcp4-config.h"
#include "nm-dhcp6-config.h"
+#include "nm-dns-manager.h"
#include "nm-ip4-config.h"
#include "nm-ip6-config.h"
-#include "nm-manager.h"
-#include "nm-wifi-p2p-peer.h"
+#include "nm-object-private.h"
#include "nm-remote-connection.h"
-#include "nm-remote-settings.h"
+#include "nm-utils.h"
#include "nm-vpn-connection.h"
+#include "nm-wifi-p2p-peer.h"
/*****************************************************************************/
-static void nm_client_initable_iface_init (GInitableIface *iface);
-static void nm_client_async_initable_iface_init (GAsyncInitableIface *iface);
+struct _NMLDBusObjPropData {
+
+ /* It is quite wasteful to require 2 pointers per property (of an instance) only to track whether
+ * the property got changed. But it's convenient! */
+ CList changed_prop_lst;
+
+ GVariant *prop_data_value;
+};
+
+struct _NMLDBusObjIfaceData {
+ CList iface_lst;
+ union {
+ const NMLDBusMetaIface *meta;
+ NMRefString *name;
+ } dbus_iface;
+
+ CList changed_prop_lst_head;
+
+ /* We also keep track of non-well known interfaces. The presence of a D-Bus interface
+ * is what makes a D-Bus alive or not. As we should track all D-Bus objects, we also
+ * need to track whether there are any interfaces on it -- even if we otherwise don't
+ * care about the interface. */
+ bool dbus_iface_is_wellknown:1;
+
+ bool nmobj_checked:1;
+ bool nmobj_compatible:1;
+
+ NMLDBusObjPropData prop_datas[];
+};
+
+/* The dbus_path must be the first element, so when we hash the object by the dbus_path,
+ * we also can lookup the object by only having a NMRefString at hand
+ * using nm_pdirect_hash()/nm_pdirect_equal(). */
+G_STATIC_ASSERT (G_STRUCT_OFFSET (NMLDBusObject, dbus_path) == 0);
+
+typedef void (*NMLDBusObjWatchNotifyFcn) (NMClient *client,
+ gpointer obj_watcher);
+
+struct _NMLDBusObjWatcher {
+ NMLDBusObject *dbobj;
+ struct {
+ CList watcher_lst;
+ NMLDBusObjWatchNotifyFcn notify_fcn;
+ } _priv;
+};
+
+typedef struct {
+ NMLDBusObjWatcher parent;
+ gpointer user_data;
+} NMLDBusObjWatcherWithPtr;
+
+/*****************************************************************************/
typedef struct {
- NMClient *client;
GCancellable *cancellable;
- GSimpleAsyncResult *result;
- int pending_init;
-} NMClientInitData;
+ GSource *cancel_on_idle_source;
+ gulong cancelled_id;
+ union {
+ struct {
+ GTask *task;
+ } async;
+ struct {
+ GMainLoop *main_loop;
+ GError **error_location;
+ } sync;
+ } data;
+ bool is_sync:1;
+} InitData;
NM_GOBJECT_PROPERTIES_DEFINE (NMClient,
PROP_DBUS_CONNECTION,
@@ -104,6 +145,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMClient,
PROP_WIMAX_HARDWARE_ENABLED,
PROP_ACTIVE_CONNECTIONS,
PROP_CONNECTIVITY,
+ PROP_CONNECTIVITY_CHECK_URI,
PROP_CONNECTIVITY_CHECK_AVAILABLE,
PROP_CONNECTIVITY_CHECK_ENABLED,
PROP_PRIMARY_CONNECTION,
@@ -137,27 +179,102 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
+ struct udev *udev;
GMainContext *main_context;
- NMManager *manager;
- NMRemoteSettings *settings;
- NMDnsManager *dns_manager;
+ GMainContext *dbus_context;
+ GSource *dbus_context_integration;
GDBusConnection *dbus_connection;
- GDBusObjectManager *object_manager;
- GCancellable *new_object_manager_cancellable;
- char *name_owner_cached;
- struct udev *udev;
+ InitData *init_data;
+ GHashTable *dbus_objects;
+ CList dbus_object_changed_lst_head;
+ GCancellable *name_owner_get_cancellable;
+ GCancellable *get_managed_objects_cancellable;
+
+ CList queue_notify_lst_head;
+ CList notify_event_lst_head;
+
+ CList dbus_objects_lst_head_watched_only;
+ CList dbus_objects_lst_head_on_dbus;
+ CList dbus_objects_lst_head_with_nmobj_not_ready;
+ CList dbus_objects_lst_head_with_nmobj_maybe_ready;
+ CList dbus_objects_lst_head_with_nmobj_visible;
+ CList dbus_objects_lst_head_with_nmobj_hidden;
+
+ NMLDBusObject *dbobj_nm;
+ NMLDBusObject *dbobj_settings;
+ NMLDBusObject *dbobj_dns_manager;
+
+ GHashTable *permissions;
+ GCancellable *permissions_cancellable;
+
+ char *name_owner;
+ guint name_owner_changed_id;
+ guint dbsid_nm_object_manager;
+ guint dbsid_dbus_properties_properties_changed;
+ guint dbsid_nm_settings_connection_updated;
+ guint dbsid_nm_connection_active_state_changed;
+ guint dbsid_nm_vpn_connection_state_changed;
+ guint dbsid_nm_check_permissions;
+
bool udev_inited:1;
+ bool notify_event_lst_changed:1;
+ bool check_dbobj_visible_all:1;
+ bool nm_running:1;
+
+ struct {
+ NMLDBusPropertyO activating_connection;
+ NMLDBusPropertyO primary_connection;
+ NMLDBusPropertyAO devices;
+ NMLDBusPropertyAO all_devices;
+ NMLDBusPropertyAO active_connections;
+ NMLDBusPropertyAO checkpoints;
+ char *connectivity_check_uri;
+ char *version;
+ guint32 connectivity;
+ guint32 state;
+ guint32 metered;
+ bool connectivity_check_available;
+ bool connectivity_check_enabled;
+ bool networking_enabled;
+ bool startup;
+ bool wireless_enabled;
+ bool wireless_hardware_enabled;
+ bool wwan_enabled;
+ bool wwan_hardware_enabled;
+ } nm;
+
+ struct {
+ NMLDBusPropertyAO connections;
+ char *hostname;
+ bool can_modify;
+ } settings;
+
+ struct {
+ GPtrArray *configuration;
+ char *mode;
+ char *rc_manager;
+ } dns_manager;
+
} NMClientPrivate;
struct _NMClient {
- GObject parent;
+ union {
+ GObject parent;
+ NMObjectBase obj_base;
+ };
NMClientPrivate _priv;
};
struct _NMClientClass {
- GObjectClass parent;
+ union {
+ GObjectClass parent;
+ NMObjectBaseClass obj_base;
+ };
};
+static void nm_client_initable_iface_init (GInitableIface *iface);
+static void nm_client_async_initable_iface_init (GAsyncInitableIface *iface);
+
G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_client_initable_iface_init);
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_client_async_initable_iface_init);
@@ -167,11 +284,40 @@ G_DEFINE_TYPE_WITH_CODE (NMClient, nm_client, G_TYPE_OBJECT,
/*****************************************************************************/
-void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
+static void _init_start_check_complete (NMClient *self);
+
+static void name_owner_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data);
+
+static void name_owner_get_cb (const char *name_owner,
+ GError *error,
+ gpointer user_data);
+
+static void _set_nm_running (NMClient *self);
+
+/*****************************************************************************/
+
+static NMRefString *_dbus_path_nm = NULL;
+static NMRefString *_dbus_path_settings = NULL;
+static NMRefString *_dbus_path_dns_manager = NULL;
/*****************************************************************************/
-static const GPtrArray empty = { 0, };
+NM_UTILS_LOOKUP_STR_DEFINE_STATIC (nml_dbus_obj_state_to_string, NMLDBusObjState,
+ NM_UTILS_LOOKUP_DEFAULT_WARN ("???"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_UNLINKED, "unlinked"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_WATCHED_ONLY, "watched-only"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_ON_DBUS, "on-dbus"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, "not-ready"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY, "maybe-ready"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE, "visible"),
+ NM_UTILS_LOOKUP_ITEM (NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN, "hidden"),
+);
/*****************************************************************************/
@@ -186,44 +332,2985 @@ NM_CACHED_QUARK_FCN ("nm-client-error-quark", nm_client_error_quark)
/*****************************************************************************/
-GDBusConnection *
-_nm_client_get_dbus_connection (NMClient *client)
+static InitData *
+_init_data_new_sync (GCancellable *cancellable,
+ GMainLoop *main_loop,
+ GError **error_location)
{
- nm_assert (NM_IS_CLIENT (client));
+ InitData *init_data;
- return NM_CLIENT_GET_PRIVATE (client)->dbus_connection;
+ init_data = g_slice_new (InitData);
+ *init_data = (InitData) {
+ .cancellable = nm_g_object_ref (cancellable),
+ .is_sync = TRUE,
+ .data.sync = {
+ .main_loop = main_loop,
+ .error_location = error_location,
+ },
+ };
+ return init_data;
+}
+
+static InitData *
+_init_data_new_async (GCancellable *cancellable,
+ GTask *task_take)
+{
+ InitData *init_data;
+
+ init_data = g_slice_new (InitData);
+ *init_data = (InitData) {
+ .cancellable = nm_g_object_ref (cancellable),
+ .is_sync = FALSE,
+ .data.async = {
+ .task = g_steal_pointer (&task_take),
+ },
+ };
+ return init_data;
+}
+
+/*****************************************************************************/
+
+GError *
+_nm_client_new_error_nm_not_running (void)
+{
+ return g_error_new_literal (NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
+ "NetworkManager is not running");
+}
+
+GError *
+_nm_client_new_error_nm_not_cached (void)
+{
+ return g_error_new_literal (NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_FAILED,
+ "Object is no longer in the client cache");
+}
+
+void
+_nm_client_dbus_call_simple (NMClient *self,
+ GCancellable *cancellable,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
+
+ nm_assert (priv->name_owner);
+ nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+ nm_assert (callback);
+ nm_assert (object_path);
+ nm_assert (interface_name);
+ nm_assert (method_name);
+ nm_assert (parameters);
+ nm_assert (reply_type);
+
+ dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context);
+
+ g_dbus_connection_call (priv->dbus_connection,
+ priv->name_owner,
+ object_path,
+ interface_name,
+ method_name,
+ parameters,
+ reply_type,
+ flags,
+ timeout_msec,
+ cancellable,
+ callback,
+ user_data);
+}
+
+void
+_nm_client_dbus_call (NMClient *self,
+ gpointer source_obj,
+ gpointer source_tag,
+ GCancellable *cancellable,
+ GAsyncReadyCallback user_callback,
+ gpointer user_callback_data,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ GAsyncReadyCallback internal_callback)
+{
+ NMClientPrivate *priv;
+ gs_unref_object GTask *task = NULL;
+
+ nm_assert (!source_obj || G_IS_OBJECT (source_obj));
+ nm_assert (source_tag);
+ nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+ nm_assert (internal_callback);
+ nm_assert (object_path);
+ nm_assert (interface_name);
+ nm_assert (method_name);
+ nm_assert (parameters);
+ nm_assert (reply_type);
+
+ task = nm_g_task_new (source_obj, cancellable, source_tag, user_callback, user_callback_data);
+
+ if (!self) {
+ nm_g_variant_unref_floating (parameters);
+ g_task_return_error (task, _nm_client_new_error_nm_not_cached ());
+ return;
+ }
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (!priv->name_owner) {
+ nm_g_variant_unref_floating (parameters);
+ g_task_return_error (task, _nm_client_new_error_nm_not_running ());
+ return;
+ }
+
+ _nm_client_dbus_call_simple (self,
+ cancellable,
+ object_path,
+ interface_name,
+ method_name,
+ parameters,
+ reply_type,
+ flags,
+ timeout_msec,
+ internal_callback,
+ g_steal_pointer (&task));
+}
+
+GVariant *
+_nm_client_dbus_call_sync (NMClient *self,
+ GCancellable *cancellable,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ gboolean strip_dbus_error,
+ GError **error)
+{
+ NMClientPrivate *priv;
+ gs_unref_variant GVariant *ret = NULL;
+
+ nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
+ nm_assert (!error || !*error);
+ nm_assert (object_path);
+ nm_assert (interface_name);
+ nm_assert (method_name);
+ nm_assert (parameters);
+ nm_assert (reply_type);
+
+ if (!self) {
+ nm_g_variant_unref_floating (parameters);
+ nm_g_set_error_take_lazy (error, _nm_client_new_error_nm_not_cached ());
+ return NULL;
+ }
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (!priv->name_owner) {
+ nm_g_variant_unref_floating (parameters);
+ nm_g_set_error_take_lazy (error, _nm_client_new_error_nm_not_running ());
+ return NULL;
+ }
+
+ ret = g_dbus_connection_call_sync (priv->dbus_connection,
+ priv->name_owner,
+ object_path,
+ interface_name,
+ method_name,
+ parameters,
+ reply_type,
+ flags,
+ timeout_msec,
+ cancellable,
+ error);
+ if (!ret) {
+ if (error && strip_dbus_error)
+ g_dbus_error_strip_remote_error (*error);
+ return NULL;
+ }
+
+ return g_steal_pointer (&ret);
+}
+
+gboolean
+_nm_client_dbus_call_sync_void (NMClient *self,
+ GCancellable *cancellable,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ gboolean strip_dbus_error,
+ GError **error)
+{
+ gs_unref_variant GVariant *ret = NULL;
+
+ ret = _nm_client_dbus_call_sync (self,
+ cancellable,
+ object_path,
+ interface_name,
+ method_name,
+ parameters,
+ G_VARIANT_TYPE ("()"),
+ flags,
+ timeout_msec,
+ strip_dbus_error,
+ error);
+ return !!ret;
+}
+
+void
+_nm_client_set_property_sync_legacy (NMClient *self,
+ const char *object_path,
+ const char *interface_name,
+ const char *property_name,
+ const char *format_string,
+ ...)
+{
+ NMClientPrivate *priv;
+ gs_unref_variant GVariant *val = NULL;
+ gs_unref_variant GVariant *ret = NULL;
+ va_list ap;
+
+ nm_assert (!self || NM_IS_CLIENT (self));
+ nm_assert (interface_name);
+ nm_assert (property_name);
+ nm_assert (format_string);
+
+ if (!self)
+ return;
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (!priv->name_owner)
+ return;
+
+ va_start (ap, format_string);
+ val = g_variant_new_va (format_string, NULL, &ap);
+ va_end (ap);
+
+ nm_assert (val);
+
+ /* A synchronous D-Bus call that is not cancellable an ignores the return value.
+ * This function only exists for backward compatibility. */
+ ret = g_dbus_connection_call_sync (priv->dbus_connection,
+ priv->name_owner,
+ object_path,
+ DBUS_INTERFACE_PROPERTIES,
+ "Set",
+ g_variant_new ("(ssv)", interface_name, property_name, val),
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ 2000,
+ NULL,
+ NULL);
+}
+
+/*****************************************************************************/
+
+#define _assert_main_context_is_current_source(self, x_context) \
+ G_STMT_START { \
+ if (NM_MORE_ASSERTS > 0) { \
+ GSource *_source = g_main_current_source (); \
+ \
+ if (_source) { \
+ NMClientPrivate *_priv = NM_CLIENT_GET_PRIVATE (self); \
+ \
+ nm_assert (g_source_get_context (_source) == _priv->x_context); \
+ nm_assert (g_main_context_is_owner (_priv->x_context)); \
+ } \
+ } \
+ } G_STMT_END
+
+#define _assert_main_context_is_current_thread_default(self, x_context) \
+ G_STMT_START { \
+ if (NM_MORE_ASSERTS > 0) { \
+ NMClientPrivate *_priv = NM_CLIENT_GET_PRIVATE (self); \
+ \
+ nm_assert ((g_main_context_get_thread_default () ?: g_main_context_default ()) == _priv->x_context); \
+ nm_assert (g_main_context_is_owner (_priv->x_context)); \
+ } \
+ } G_STMT_END
+
+/*****************************************************************************/
+
+void
+_nm_client_queue_notify_object (NMClient *self,
+ gpointer nmobj,
+ const GParamSpec *pspec)
+{
+ NMObjectBase *base;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (NM_IS_OBJECT (nmobj) || NM_IS_CLIENT (nmobj));
+
+ base = (NMObjectBase *) nmobj;
+ if (c_list_is_empty (&base->queue_notify_lst)) {
+ c_list_link_tail (&NM_CLIENT_GET_PRIVATE (self)->queue_notify_lst_head,
+ &base->queue_notify_lst);
+ g_object_ref (nmobj);
+ g_object_freeze_notify (nmobj);
+ }
+
+ if (pspec)
+ g_object_notify_by_pspec (nmobj, (GParamSpec *) pspec);
+}
+
+/*****************************************************************************/
+
+gpointer
+_nm_client_notify_event_queue (NMClient *self,
+ int priority,
+ NMClientNotifyEventCb callback,
+ gsize event_size)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ NMClientNotifyEvent *notify_event;
+
+ nm_assert (callback);
+ nm_assert (event_size > sizeof (NMClientNotifyEvent));
+
+ notify_event = g_malloc (event_size);
+ notify_event->priority = priority;
+ notify_event->callback = callback;
+ c_list_link_tail (&priv->notify_event_lst_head, &notify_event->lst);
+ priv->notify_event_lst_changed = TRUE;
+ return notify_event;
+}
+
+NMClientNotifyEventWithPtr *
+_nm_client_notify_event_queue_with_ptr (NMClient *self,
+ int priority,
+ NMClientNotifyEventWithPtrCb callback,
+ gpointer user_data)
+{
+ NMClientNotifyEventWithPtr *notify_event;
+
+ notify_event = _nm_client_notify_event_queue (self,
+ priority,
+ (NMClientNotifyEventCb) callback,
+ sizeof (NMClientNotifyEventWithPtr));
+ notify_event->user_data = user_data;
+ return notify_event;
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ NMClientNotifyEvent parent;
+ GObject *source;
+ NMObject *obj;
+ guint signal_id;
+} NMClientNotifyEventObjAddedRemove;
+
+static void
+_nm_client_notify_event_queue_emit_obj_signal_cb (NMClient *self,
+ gpointer notify_event_base)
+{
+ NMClientNotifyEventObjAddedRemove *notify_event = notify_event_base;
+
+ NML_NMCLIENT_LOG_T (self, "[%s] emit \"%s\" signal for %s",
+ NM_IS_CLIENT (notify_event->source)
+ ? "nmclient"
+ : _nm_object_get_path (notify_event->source),
+ g_signal_name (notify_event->signal_id),
+ _nm_object_get_path (notify_event->obj));
+
+ nm_assert ( NM_IS_OBJECT (notify_event->source)
+ || NM_IS_CLIENT (notify_event->source));
+
+ g_signal_emit (notify_event->source,
+ notify_event->signal_id,
+ 0,
+ notify_event->obj);
+
+ g_object_unref (notify_event->obj);
+ g_object_unref (notify_event->source);
+}
+
+void
+_nm_client_notify_event_queue_emit_obj_signal (NMClient *self,
+ GObject *source,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */,
+ int prio_offset,
+ guint signal_id)
+{
+ NMClientNotifyEventObjAddedRemove *notify_event;
+
+ nm_assert (prio_offset >= 0);
+ nm_assert (prio_offset < 20);
+ nm_assert ( NM_IS_OBJECT (source)
+ || NM_IS_CLIENT (source));
+ nm_assert (NM_IS_OBJECT (nmobj));
+
+ if (((NMObjectBase *) source)->is_disposing) {
+ nm_assert (NM_IS_CLIENT (source));
+ return;
+ }
+
+ notify_event = _nm_client_notify_event_queue (self,
+ is_added
+ ? NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER - 20 + prio_offset
+ : NM_CLIENT_NOTIFY_EVENT_PRIO_BEFORE + 20 - prio_offset,
+ _nm_client_notify_event_queue_emit_obj_signal_cb,
+ sizeof (NMClientNotifyEventObjAddedRemove));
+ notify_event->source = g_object_ref (source);
+ notify_event->obj = g_object_ref (nmobj);
+ notify_event->signal_id = signal_id;
+}
+
+/*****************************************************************************/
+
+static int
+_nm_client_notify_event_cmp (const CList *a,
+ const CList *b,
+ const void *user_data)
+{
+ NM_CMP_DIRECT (c_list_entry (a, NMClientNotifyEvent, lst)->priority,
+ c_list_entry (b, NMClientNotifyEvent, lst)->priority);
+ return 0;
+}
+
+static void
+_nm_client_notify_event_emit_parts (NMClient *self,
+ int max_priority /* included! */)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ NMClientNotifyEvent *notify_event;
+
+ while (TRUE) {
+ if (priv->notify_event_lst_changed) {
+ priv->notify_event_lst_changed = FALSE;
+ c_list_sort (&priv->notify_event_lst_head, _nm_client_notify_event_cmp, NULL);
+ }
+ notify_event = c_list_first_entry (&priv->notify_event_lst_head, NMClientNotifyEvent, lst);
+ if (!notify_event)
+ return;
+ if (notify_event->priority > max_priority)
+ return;
+ c_list_unlink_stale (&notify_event->lst);
+ notify_event->callback (self, notify_event);
+ g_free (notify_event);
+ }
+}
+
+static void
+_nm_client_notify_event_emit (NMClient *self)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ NMObjectBase *base;
+
+ _nm_client_notify_event_emit_parts (self, NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP);
+
+ while ((base = c_list_first_entry (&priv->queue_notify_lst_head, NMObjectBase, queue_notify_lst))) {
+ c_list_unlink (&base->queue_notify_lst);
+ g_object_thaw_notify (G_OBJECT (base));
+ g_object_unref (base);
+ }
+
+ _nm_client_notify_event_emit_parts (self, G_MAXINT);
+}
+
+/*****************************************************************************/
+
+GDBusConnection *
+_nm_client_get_dbus_connection (NMClient *self)
+{
+ return NM_CLIENT_GET_PRIVATE (self)->dbus_connection;
}
const char *
-_nm_client_get_dbus_name_owner (NMClient *client)
+_nm_client_get_dbus_name_owner (NMClient *self)
+{
+ return NM_CLIENT_GET_PRIVATE (self)->name_owner;
+}
+
+GMainContext *
+_nm_client_get_context_main (NMClient *self)
+{
+ return NM_CLIENT_GET_PRIVATE (self)->main_context;
+}
+
+GMainContext *
+_nm_client_get_context_dbus (NMClient *self)
+{
+ return NM_CLIENT_GET_PRIVATE (self)->dbus_context;
+}
+
+struct udev *
+_nm_client_get_udev (NMClient *self)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+
+ if (G_UNLIKELY (!priv->udev_inited)) {
+ priv->udev_inited = TRUE;
+ /* for testing, we don't want to use udev in libnm. */
+ if (!nm_streq0 (g_getenv ("LIBNM_USE_NO_UDEV"), "1"))
+ priv->udev = udev_new ();
+ }
+
+ return priv->udev;
+}
+
+/*****************************************************************************/
+
+static void
+_ASSERT_dbobj (NMLDBusObject *dbobj,
+ NMClient *self)
+{
+#if NM_MORE_ASSERTS > 5
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (NML_IS_DBUS_OBJECT (dbobj));
+ nm_assert (dbobj == g_hash_table_lookup (NM_CLIENT_GET_PRIVATE (self)->dbus_objects, dbobj));
+#endif
+}
+
+static NMLDBusObject *
+nml_dbus_object_new (NMRefString *dbus_path_take)
+{
+ NMLDBusObject *dbobj;
+
+ nm_assert (NM_IS_REF_STRING (dbus_path_take));
+
+ dbobj = g_slice_new (NMLDBusObject);
+ *dbobj = (NMLDBusObject) {
+ .dbus_path = g_steal_pointer (&dbus_path_take),
+ .ref_count = 1,
+ .iface_lst_head = C_LIST_INIT (dbobj->iface_lst_head),
+ .removed_iface_lst_head = C_LIST_INIT (dbobj->removed_iface_lst_head),
+ .changed_obj_lst = C_LIST_INIT (dbobj->changed_obj_lst),
+ .watcher_lst_head = C_LIST_INIT (dbobj->watcher_lst_head),
+ .obj_state = NML_DBUS_OBJ_STATE_UNLINKED,
+ .dbus_objects_lst = C_LIST_INIT (dbobj->dbus_objects_lst),
+ };
+ return dbobj;
+}
+
+NMLDBusObject *
+nml_dbus_object_ref (NMLDBusObject *dbobj)
+{
+ nm_assert (dbobj);
+ nm_assert (dbobj->ref_count > 0);
+
+ dbobj->ref_count++;
+ return dbobj;
+}
+
+void
+nml_dbus_object_unref (NMLDBusObject *dbobj)
+{
+ nm_assert (dbobj);
+ nm_assert (dbobj->ref_count > 0);
+
+ if (--dbobj->ref_count > 0)
+ return;
+
+ nm_assert (c_list_is_empty (&dbobj->changed_obj_lst));
+ nm_assert (c_list_is_empty (&dbobj->iface_lst_head));
+ nm_assert (c_list_is_empty (&dbobj->removed_iface_lst_head));
+ nm_assert (c_list_is_empty (&dbobj->watcher_lst_head));
+ nm_assert (!dbobj->nmobj);
+
+ nm_ref_string_unref (dbobj->dbus_path);
+ nm_g_slice_free (dbobj);
+}
+
+NMLDBusObjIfaceData *
+nml_dbus_object_iface_data_get (NMLDBusObject *dbobj,
+ const char *dbus_iface_name,
+ gboolean allow_create)
+{
+ const NMLDBusMetaIface *meta_iface;
+ NMLDBusObjIfaceData *db_iface_data;
+ NMLDBusObjPropData *db_prop_data;
+ guint count = 0;
+ guint i;
+
+ nm_assert (NML_IS_DBUS_OBJECT (dbobj));
+ nm_assert (dbus_iface_name);
+
+#if NM_MORE_ASSERTS > 10
+ {
+ gboolean expect_well_known = TRUE;
+
+ /* all well-known interfaces must come first in the list. */
+ c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
+ if (db_iface_data->dbus_iface_is_wellknown == expect_well_known)
+ continue;
+ nm_assert (expect_well_known);
+ expect_well_known = FALSE;
+ }
+ }
+#endif
+
+ meta_iface = nml_dbus_meta_iface_get (dbus_iface_name);
+ if (meta_iface) {
+ c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
+ if (!db_iface_data->dbus_iface_is_wellknown)
+ break;
+ if (db_iface_data->dbus_iface.meta == meta_iface)
+ return db_iface_data;
+ count++;
+ }
+ } else {
+ nm_c_list_for_each_entry_prev (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
+ if (db_iface_data->dbus_iface_is_wellknown)
+ break;
+ if (nm_streq (db_iface_data->dbus_iface.name->str, dbus_iface_name))
+ return db_iface_data;
+ count++;
+ }
+ }
+
+ if (!allow_create)
+ return NULL;
+
+ if (count > 20) {
+ /* We track the list of interfaces that an object has in a linked list.
+ * That is efficient and convenient, if we assume that each object only has a small
+ * number of interfaces (which very much should be the case). Here, something is very
+ * odd, maybe there is a bug or the server side is misbehaving. Anyway, error out. */
+ return NULL;
+ }
+
+ db_iface_data = g_malloc ( G_STRUCT_OFFSET (NMLDBusObjIfaceData, prop_datas)
+ + (meta_iface ? (sizeof (NMLDBusObjPropData) * meta_iface->n_dbus_properties): 0u));
+ if (meta_iface) {
+ *db_iface_data = (NMLDBusObjIfaceData) {
+ .dbus_iface.meta = meta_iface,
+ .dbus_iface_is_wellknown = TRUE,
+ .changed_prop_lst_head = C_LIST_INIT (db_iface_data->changed_prop_lst_head),
+ };
+ db_prop_data = &db_iface_data->prop_datas[0];
+ for (i = 0; i < meta_iface->n_dbus_properties; i++, db_prop_data++) {
+ *db_prop_data = (NMLDBusObjPropData) {
+ .prop_data_value = NULL,
+ .changed_prop_lst = C_LIST_INIT (db_prop_data->changed_prop_lst),
+ };
+ }
+ c_list_link_front (&dbobj->iface_lst_head, &db_iface_data->iface_lst);
+ } else {
+ /* Intentionally don't initialize the other fields. We are not supposed
+ * to touch them, and a valgrind warning would be preferable. */
+ db_iface_data->dbus_iface.name = nm_ref_string_new (dbus_iface_name);
+ db_iface_data->dbus_iface_is_wellknown = FALSE;
+ c_list_link_tail (&dbobj->iface_lst_head, &db_iface_data->iface_lst);
+ }
+
+ return db_iface_data;
+}
+
+static void
+nml_dbus_obj_iface_data_destroy (NMLDBusObjIfaceData *db_iface_data)
+{
+ guint i;
+
+ nm_assert (db_iface_data);
+ nm_assert (c_list_is_empty (&db_iface_data->iface_lst));
+
+ if (db_iface_data->dbus_iface_is_wellknown) {
+ for (i = 0; i < db_iface_data->dbus_iface.meta->n_dbus_properties; i++)
+ nm_g_variant_unref (db_iface_data->prop_datas[i].prop_data_value);
+ } else
+ nm_ref_string_unref (db_iface_data->dbus_iface.name);
+
+ g_free (db_iface_data);
+}
+
+gpointer
+nml_dbus_object_get_property_location (NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ const NMLDBusMetaProperty *meta_property)
+{
+ char *target_c;
+
+ target_c = (char *) dbobj->nmobj;
+ if (meta_iface->base_struct_offset > 0)
+ target_c = *((gpointer *) (&target_c[meta_iface->base_struct_offset]));
+ return &target_c[meta_property->prop_struct_offset];
+}
+
+static void
+nml_dbus_object_set_obj_state (NMLDBusObject *dbobj,
+ NMLDBusObjState obj_state,
+ NMClient *self)
{
NMClientPrivate *priv;
- nm_assert (NM_IS_CLIENT (client));
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (NML_IS_DBUS_OBJECT (dbobj));
+
+#if NM_MORE_ASSERTS > 10
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ switch (dbobj->obj_state) {
+ case NML_DBUS_OBJ_STATE_UNLINKED: nm_assert (c_list_is_empty (&dbobj->dbus_objects_lst)); break;
+ case NML_DBUS_OBJ_STATE_WATCHED_ONLY: nm_assert (c_list_contains (&priv->dbus_objects_lst_head_watched_only, &dbobj->dbus_objects_lst)); break;
+ case NML_DBUS_OBJ_STATE_ON_DBUS: nm_assert (c_list_contains (&priv->dbus_objects_lst_head_on_dbus, &dbobj->dbus_objects_lst)); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY: nm_assert (c_list_contains (&priv->dbus_objects_lst_head_with_nmobj_not_ready, &dbobj->dbus_objects_lst)); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY: nm_assert (c_list_contains (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready, &dbobj->dbus_objects_lst)); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE: nm_assert (c_list_contains (&priv->dbus_objects_lst_head_with_nmobj_visible, &dbobj->dbus_objects_lst)); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN: nm_assert (c_list_contains (&priv->dbus_objects_lst_head_with_nmobj_hidden, &dbobj->dbus_objects_lst)); break;
+ }
+#endif
- priv = NM_CLIENT_GET_PRIVATE (client);
+ if (dbobj->obj_state == obj_state)
+ return;
- nm_clear_g_free (&priv->name_owner_cached);
+ NML_NMCLIENT_LOG_T (self, "[%s]: set D-Bus object state %s", dbobj->dbus_path->str, nml_dbus_obj_state_to_string (obj_state));
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ dbobj->obj_state = obj_state;
+ switch (obj_state) {
+ case NML_DBUS_OBJ_STATE_UNLINKED: c_list_unlink (&dbobj->dbus_objects_lst); break;
+ case NML_DBUS_OBJ_STATE_WATCHED_ONLY: nm_c_list_move_tail (&priv->dbus_objects_lst_head_watched_only, &dbobj->dbus_objects_lst); break;
+ case NML_DBUS_OBJ_STATE_ON_DBUS: nm_c_list_move_tail (&priv->dbus_objects_lst_head_on_dbus, &dbobj->dbus_objects_lst); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY: nm_c_list_move_tail (&priv->dbus_objects_lst_head_with_nmobj_not_ready, &dbobj->dbus_objects_lst); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY: nm_c_list_move_tail (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready, &dbobj->dbus_objects_lst); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE: nm_c_list_move_tail (&priv->dbus_objects_lst_head_with_nmobj_visible, &dbobj->dbus_objects_lst); break;
+ case NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN: nm_c_list_move_tail (&priv->dbus_objects_lst_head_with_nmobj_hidden, &dbobj->dbus_objects_lst); break;
+ default:
+ nm_assert_not_reached ();
+ }
+}
- if (!priv->object_manager)
+/*****************************************************************************/
+
+static void
+_dbobjs_notify_watchers_for_dbobj (NMClient *self,
+ NMLDBusObject *dbobj)
+{
+ NMLDBusObjWatcher *obj_watcher;
+ NMLDBusObjWatcher *obj_watcher_safe;
+
+ c_list_for_each_entry_safe (obj_watcher, obj_watcher_safe, &dbobj->watcher_lst_head, _priv.watcher_lst)
+ obj_watcher->_priv.notify_fcn (self, obj_watcher);
+}
+
+static gboolean
+_dbobjs_check_dbobj_visible (NMClient *self,
+ NMLDBusObject *dbobj,
+ gboolean force_recheck,
+ gboolean need_definite_answer,
+ gboolean *out_notified_watchers)
+{
+ NMClientPrivate *priv;
+ NMObjectClass *klass;
+ NMLDBusObjState obj_state;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (NML_IS_DBUS_OBJECT (dbobj));
+ nm_assert (G_IS_OBJECT (dbobj->nmobj));
+ nm_assert ( NM_IS_OBJECT (dbobj->nmobj)
+ || NM_IS_CLIENT (dbobj->nmobj));
+ nm_assert (NM_IN_SET ((NMLDBusObjState) dbobj->obj_state, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN));
+
+ NM_SET_OUT (out_notified_watchers, FALSE);
+
+ if (force_recheck)
+ nm_assert (!need_definite_answer);
+ else {
+ if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE)
+ return TRUE;
+ if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN)
+ return FALSE;
+ if (!need_definite_answer) {
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (!priv->check_dbobj_visible_all)
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY, self);
+ return FALSE;
+ }
+ }
+
+ klass = NM_OBJECT_GET_CLASS (dbobj->nmobj);
+
+ obj_state = klass->is_visible (NM_OBJECT (dbobj->nmobj));
+
+ nm_assert (NM_IN_SET (obj_state, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN));
+
+ if (obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) {
+ if (NM_IN_SET ((NMLDBusObjState) dbobj->obj_state, NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN))
+ obj_state = NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN;
+ else if (!need_definite_answer) {
+ nm_assert (NM_IN_SET ((NMLDBusObjState) dbobj->obj_state, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY));
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (!priv->check_dbobj_visible_all)
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY, self);
+ return FALSE;
+ }
+ }
+
+ if (obj_state != dbobj->obj_state) {
+ gboolean notify_watchers;
+
+ notify_watchers = ( dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY
+ || obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY);
+ nml_dbus_object_set_obj_state (dbobj, obj_state, self);
+ if (notify_watchers) {
+ _dbobjs_notify_watchers_for_dbobj (self, dbobj);
+ NM_SET_OUT (out_notified_watchers, TRUE);
+ }
+ }
+
+ return dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE;
+}
+
+void
+_nm_client_notify_object_changed (NMClient *self,
+ NMLDBusObject *dbobj)
+{
+ gboolean notified_watchers;
+
+ _dbobjs_check_dbobj_visible (self, dbobj, TRUE, FALSE, &notified_watchers);
+ if (!notified_watchers)
+ _dbobjs_notify_watchers_for_dbobj (self, dbobj);
+}
+
+static void
+_dbobjs_check_dbobj_visible_all (NMClient *self)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ NMLDBusObject *dbobj;
+
+ nm_assert (!priv->check_dbobj_visible_all);
+ priv->check_dbobj_visible_all = TRUE;
+ while ((dbobj = c_list_first_entry (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready, NMLDBusObject, dbus_objects_lst)))
+ _dbobjs_check_dbobj_visible (self, dbobj, FALSE, TRUE, NULL);
+ nm_assert (priv->check_dbobj_visible_all);
+ priv->check_dbobj_visible_all = FALSE;
+}
+
+/*****************************************************************************/
+
+static NMLDBusObject *
+_dbobjs_dbobj_get_r (NMClient *self,
+ NMRefString *dbus_path_r)
+{
+ nm_assert (NM_IS_REF_STRING (dbus_path_r));
+
+ return g_hash_table_lookup (NM_CLIENT_GET_PRIVATE (self)->dbus_objects, &dbus_path_r);
+}
+
+static NMLDBusObject *
+_dbobjs_dbobj_get_s (NMClient *self,
+ const char *dbus_path)
+{
+ nm_auto_ref_string NMRefString *dbus_path_r = NULL;
+
+ nm_assert (dbus_path);
+ dbus_path_r = nm_ref_string_new (dbus_path);
+ return _dbobjs_dbobj_get_r (self, dbus_path_r);
+}
+
+static NMLDBusObject *
+_dbobjs_dbobj_create (NMClient *self,
+ NMRefString *dbus_path_take)
+{
+ nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer (&dbus_path_take);
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ NMLDBusObject *dbobj;
+
+ nm_assert (!_dbobjs_dbobj_get_r (self, dbus_path));
+
+ dbobj = nml_dbus_object_new (g_steal_pointer (&dbus_path));
+ if (!g_hash_table_add (priv->dbus_objects, dbobj))
+ nm_assert_not_reached ();
+ return dbobj;
+}
+
+static NMLDBusObject *
+_dbobjs_dbobj_get_or_create (NMClient *self,
+ NMRefString *dbus_path_take)
+{
+ nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer (&dbus_path_take);
+ NMLDBusObject *dbobj;
+
+ dbobj = _dbobjs_dbobj_get_r (self, dbus_path);
+ if (dbobj)
+ return dbobj;
+ return _dbobjs_dbobj_create (self, g_steal_pointer (&dbus_path));
+}
+
+static NMLDBusObject *
+_dbobjs_get_nmobj (NMClient *self,
+ const char *dbus_path,
+ GType gtype)
+{
+ NMLDBusObject *dbobj;
+
+ nm_assert ( gtype == G_TYPE_NONE
+ || g_type_is_a (gtype, NM_TYPE_OBJECT));
+
+ dbobj = _dbobjs_dbobj_get_s (self, dbus_path);
+
+ if (!dbobj)
+ return NULL;
+ if (!dbobj->nmobj)
return NULL;
- priv->name_owner_cached = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager));
- return priv->name_owner_cached;
+ if ( gtype != G_TYPE_NONE
+ && !g_type_is_a (G_OBJECT_TYPE (dbobj->nmobj), gtype))
+ return NULL;
+
+ return dbobj;
+}
+
+static gpointer
+_dbobjs_get_nmobj_unpack_visible (NMClient *self,
+ const char *dbus_path,
+ GType gtype)
+{
+ NMLDBusObject *dbobj;
+
+ dbobj = _dbobjs_get_nmobj (self, dbus_path, gtype);
+ if (!dbobj)
+ return NULL;
+ if (dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE)
+ return NULL;
+ return dbobj->nmobj;
}
/*****************************************************************************/
+static gpointer
+_dbobjs_obj_watcher_register_o (NMClient *self,
+ NMLDBusObject *dbobj,
+ NMLDBusObjWatchNotifyFcn notify_fcn,
+ gsize struct_size)
+{
+ NMLDBusObjWatcher *obj_watcher;
+
+ nm_assert (NM_IS_CLIENT (self));
+ _ASSERT_dbobj (dbobj, self);
+ nm_assert (notify_fcn);
+ nm_assert (struct_size > sizeof (NMLDBusObjWatcher));
+
+ obj_watcher = g_malloc (struct_size);
+ obj_watcher->dbobj = dbobj;
+ obj_watcher->_priv.notify_fcn = notify_fcn;
+
+ /* we must enqueue the item in the front of the list. That is, because while
+ * invoking notify_fcn(), we iterate the watchers front-to-end. As we want to
+ * allow the callee to register new watches and unregister itself, this is
+ * the right way to do it. */
+ c_list_link_front (&dbobj->watcher_lst_head, &obj_watcher->_priv.watcher_lst);
+
+ return obj_watcher;
+}
+
+static gpointer
+_dbobjs_obj_watcher_register_r (NMClient *self,
+ NMRefString *dbus_path_take,
+ NMLDBusObjWatchNotifyFcn notify_fcn,
+ gsize struct_size)
+{
+ nm_auto_ref_string NMRefString *dbus_path = g_steal_pointer (&dbus_path_take);
+ NMLDBusObject *dbobj;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (notify_fcn);
+
+ dbobj = _dbobjs_dbobj_get_or_create (self, g_steal_pointer (&dbus_path));
+ if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED)
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_WATCHED_ONLY, self);
+ return _dbobjs_obj_watcher_register_o (self, dbobj, notify_fcn, struct_size);
+}
+
+static void
+_dbobjs_obj_watcher_unregister (NMClient *self,
+ gpointer obj_watcher_base)
+{
+ NMLDBusObjWatcher *obj_watcher = obj_watcher_base;
+ NMLDBusObject *dbobj;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (obj_watcher);
+ nm_assert (NML_IS_DBUS_OBJECT (obj_watcher->dbobj));
+ nm_assert (g_hash_table_lookup (NM_CLIENT_GET_PRIVATE (self)->dbus_objects, obj_watcher->dbobj) == obj_watcher->dbobj);
+ nm_assert (c_list_contains (&obj_watcher->dbobj->watcher_lst_head, &obj_watcher->_priv.watcher_lst));
+
+ c_list_unlink (&obj_watcher->_priv.watcher_lst);
+
+ dbobj = obj_watcher->dbobj;
+
+ g_free (obj_watcher);
+
+ if ( c_list_is_empty (&dbobj->iface_lst_head)
+ && c_list_is_empty (&dbobj->watcher_lst_head)
+ && c_list_is_empty (&dbobj->changed_obj_lst)) {
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+
+ NML_NMCLIENT_LOG_T (self, "[%s]: drop D-Bus watcher", dbobj->dbus_path->str);
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_UNLINKED, self);
+ if (!g_hash_table_steal (priv->dbus_objects, dbobj))
+ nm_assert_not_reached ();
+ nml_dbus_object_unref (dbobj);
+ }
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ NMLDBusObjWatcher parent;
+ NMLDBusPropertyO *pr_o;
+} PropertyOData;
+
+gpointer
+nml_dbus_property_o_get_obj (NMLDBusPropertyO *pr_o)
+{
+ return pr_o->nmobj;
+}
+
+static gboolean
+nml_dbus_property_o_get_eval (NMLDBusPropertyO *pr_o,
+ NMClient *self)
+{
+ const NMLDBusPropertVTableO *vtable;
+ GObject *nmobj = NULL;
+ gboolean is_ready;
+ GType gtype;
+
+ nm_assert (pr_o);
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (pr_o->owner_dbobj);
+
+ if (!pr_o->obj_watcher) {
+ is_ready = TRUE;
+ goto done;
+ }
+
+ if (!pr_o->obj_watcher->dbobj->nmobj) {
+ is_ready = FALSE;
+ goto done;
+ }
+
+ vtable = pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].extra.property_vtable_o;
+
+ gtype = vtable->get_o_type_fcn ();
+ if (!g_type_is_a (G_OBJECT_TYPE (pr_o->obj_watcher->dbobj->nmobj), gtype)) {
+#if NM_MORE_ASSERTS > 10
+ NML_NMCLIENT_LOG_E (self, "[%s]: property %s references %s with unexpected GObject type %s instead of %s",
+ pr_o->owner_dbobj->dbus_path->str,
+ pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].dbus_property_name,
+ pr_o->obj_watcher->dbobj->dbus_path->str,
+ G_OBJECT_TYPE_NAME (pr_o->obj_watcher->dbobj->nmobj),
+ g_type_name (gtype));
+#endif
+ is_ready = TRUE;
+ goto done;
+ }
+
+ if ( pr_o->obj_watcher->dbobj != pr_o->owner_dbobj
+ && !_dbobjs_check_dbobj_visible (self,
+ pr_o->obj_watcher->dbobj,
+ FALSE,
+ FALSE,
+ NULL)) {
+ if (pr_o->obj_watcher->dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN)
+ is_ready = TRUE;
+ else
+ is_ready = vtable->ready_without_visible;
+ goto done;
+ }
+
+ nmobj = pr_o->obj_watcher->dbobj->nmobj;
+ is_ready = TRUE;
+
+done:
+ pr_o->is_ready |= is_ready;
+ if (pr_o->nmobj != nmobj) {
+ pr_o->nmobj = nmobj;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+nml_dbus_property_o_is_ready (const NMLDBusPropertyO *pr_o)
+{
+ return pr_o->is_ready
+ || !pr_o->owner_dbobj;
+}
+
+static void
+nml_dbus_property_o_notify_watch_cb (NMClient *self,
+ gpointer obj_watcher)
+{
+ PropertyOData *pr_o_data = obj_watcher;
+ NMLDBusPropertyO *pr_o = pr_o_data->pr_o;
+
+ nm_assert (pr_o->obj_watcher == obj_watcher);
+
+ if (nml_dbus_property_o_get_eval (pr_o, self)) {
+ _nm_client_queue_notify_object (self,
+ pr_o->owner_dbobj->nmobj,
+ pr_o->meta_iface->obj_properties[pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].obj_properties_idx]);
+ }
+ if (pr_o->owner_dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY)
+ nml_dbus_object_set_obj_state (pr_o->owner_dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY, self);
+}
+
+static NMLDBusNotifyUpdatePropFlags
+nml_dbus_property_o_notify (NMClient *self,
+ NMLDBusPropertyO *pr_o,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ const char *dbus_path = NULL;
+
+ if (!pr_o->owner_dbobj) {
+ nm_assert (!pr_o->meta_iface);
+ nm_assert (pr_o->dbus_property_idx == 0);
+ nm_assert (!pr_o->is_ready);
+ pr_o->owner_dbobj = dbobj;
+ pr_o->meta_iface = meta_iface;
+ pr_o->dbus_property_idx = dbus_property_idx;
+ } else {
+ nm_assert (pr_o->owner_dbobj == dbobj);
+ nm_assert (pr_o->meta_iface == meta_iface);
+ nm_assert (pr_o->dbus_property_idx == dbus_property_idx);
+ }
+
+ if (value)
+ dbus_path = nm_dbus_path_not_empty (g_variant_get_string (value, NULL));
+
+ if ( pr_o->obj_watcher
+ && ( !dbus_path
+ || !nm_streq (dbus_path, pr_o->obj_watcher->dbobj->dbus_path->str))) {
+ _dbobjs_obj_watcher_unregister (self,
+ g_steal_pointer (&pr_o->obj_watcher));
+ }
+ if ( !pr_o->obj_watcher
+ && dbus_path) {
+ pr_o->obj_watcher = _dbobjs_obj_watcher_register_r (self,
+ nm_ref_string_new (dbus_path),
+ nml_dbus_property_o_notify_watch_cb,
+ sizeof (PropertyOData));
+ ((PropertyOData *) pr_o->obj_watcher)->pr_o = pr_o;
+ }
+
+ if (nml_dbus_property_o_get_eval (pr_o, self))
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
+
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+}
+
+void
+nml_dbus_property_o_clear (NMLDBusPropertyO *pr_o,
+ NMClient *self)
+{
+ if (pr_o->obj_watcher) {
+ nm_assert (NM_IS_CLIENT (self));
+ _dbobjs_obj_watcher_unregister (self,
+ g_steal_pointer (&pr_o->obj_watcher));
+ }
+ if ( pr_o->nmobj
+ && pr_o->owner_dbobj
+ && pr_o->owner_dbobj->nmobj) {
+ _nm_client_queue_notify_object (self,
+ pr_o->owner_dbobj->nmobj,
+ pr_o->meta_iface->obj_properties[pr_o->meta_iface->dbus_properties[pr_o->dbus_property_idx].obj_properties_idx]);
+ }
+ pr_o->owner_dbobj = NULL;
+ pr_o->meta_iface = NULL;
+ pr_o->dbus_property_idx = 0;
+ pr_o->is_ready = TRUE;
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ NMLDBusObjWatcher obj_watcher;
+ NMLDBusPropertyAO *parent;
+ CList lst;
+ GObject *nmobj;
+ bool is_ready:1;
+ bool is_new:1;
+ bool is_notified:1;
+} PropertyAOData;
+
+const GPtrArray *
+nml_dbus_property_ao_get_objs_as_ptrarray (NMLDBusPropertyAO *pr_ao)
+{
+ if (!pr_ao->arr) {
+ PropertyAOData *pr_ao_data;
+ gsize n;
+
+ n = 0;
+ if (pr_ao->owner_dbobj) {
+ c_list_for_each_entry (pr_ao_data, &pr_ao->lst, lst) {
+ if (pr_ao_data->nmobj)
+ n++;
+ }
+ }
+
+ pr_ao->arr = g_ptr_array_new_full (n, g_object_unref);
+ if (pr_ao->owner_dbobj) {
+ c_list_for_each_entry (pr_ao_data, &pr_ao->lst, lst) {
+ if (pr_ao_data->nmobj)
+ g_ptr_array_add (pr_ao->arr, g_object_ref (pr_ao_data->nmobj));
+ }
+ }
+ }
+ return pr_ao->arr;
+}
+
+static void
+nml_dbus_property_ao_notify_changed (PropertyAOData *pr_ao_data,
+ NMClient *self,
+ gboolean is_added /* or else removed */)
+{
+ NMLDBusPropertyAO *pr_ao;
+ const NMLDBusPropertVTableAO *vtable;
+
+ if (!pr_ao_data->nmobj)
+ return;
+
+ nm_assert (pr_ao_data->is_ready);
+
+ if (is_added) {
+ if (pr_ao_data->is_notified)
+ return;
+ pr_ao_data->is_notified = TRUE;
+ } else {
+ if (!pr_ao_data->is_notified)
+ return;
+ pr_ao_data->is_notified = FALSE;
+ }
+
+ pr_ao = pr_ao_data->parent;
+
+ vtable = pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].extra.property_vtable_ao;
+
+ if (vtable->notify_changed_ao)
+ vtable->notify_changed_ao (pr_ao, self, NM_OBJECT (pr_ao_data->nmobj), is_added);
+}
+
+static gboolean
+nml_dbus_property_ao_get_eval (PropertyAOData *pr_ao_data,
+ NMClient *self)
+{
+ NMLDBusPropertyAO *pr_ao;
+ const NMLDBusPropertVTableAO *vtable;
+ GObject *nmobj = NULL;
+ gboolean is_ready;
+ GType gtype;
+ gboolean changed = FALSE;
+
+ nm_assert (pr_ao_data);
+ nm_assert (NM_IS_CLIENT (self));
+
+ pr_ao = pr_ao_data->parent;
+
+ if (!pr_ao_data->obj_watcher.dbobj->nmobj) {
+ is_ready = FALSE;
+ goto done;
+ }
+
+ vtable = pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].extra.property_vtable_ao;
+
+ gtype = vtable->get_o_type_fcn ();
+
+ if (!g_type_is_a (G_OBJECT_TYPE (pr_ao_data->obj_watcher.dbobj->nmobj), gtype)) {
+#if NM_MORE_ASSERTS > 10
+ NML_NMCLIENT_LOG_E (self, "[%s]: property %s references %s with unexpected GObject type %s instead of %s",
+ pr_ao->owner_dbobj->dbus_path->str,
+ pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].dbus_property_name,
+ pr_ao_data->obj_watcher.dbobj->dbus_path->str,
+ G_OBJECT_TYPE_NAME (pr_ao_data->obj_watcher.dbobj->nmobj),
+ g_type_name (gtype));
+#endif
+ is_ready = TRUE;
+ goto done;
+ }
+
+ if ( pr_ao_data->obj_watcher.dbobj != pr_ao->owner_dbobj
+ && !_dbobjs_check_dbobj_visible (self,
+ pr_ao_data->obj_watcher.dbobj,
+ FALSE,
+ FALSE,
+ NULL)) {
+ if (pr_ao_data->obj_watcher.dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN)
+ is_ready = TRUE;
+ else
+ is_ready = vtable->ready_without_visible;
+ goto done;
+ }
+
+ if ( vtable->check_nmobj_visible_fcn
+ && !vtable->check_nmobj_visible_fcn (pr_ao_data->obj_watcher.dbobj->nmobj)) {
+ is_ready = TRUE;
+ goto done;
+ }
+
+ nmobj = pr_ao_data->obj_watcher.dbobj->nmobj;
+ is_ready = TRUE;
+
+done:
+ if ( is_ready
+ && !pr_ao_data->is_ready) {
+ nm_assert (pr_ao->n_not_ready > 0);
+ nm_assert (pr_ao->n_not_ready != G_MAXUINT);
+ pr_ao->n_not_ready--;
+ pr_ao_data->is_ready = TRUE;
+ }
+
+ if (pr_ao_data->nmobj != nmobj) {
+ nml_dbus_property_ao_notify_changed (pr_ao_data, self, FALSE);
+ pr_ao_data->nmobj = nmobj;
+ changed = TRUE;
+ }
+
+ if (!pr_ao_data->is_notified)
+ nml_dbus_property_ao_notify_changed (pr_ao_data, self, TRUE);
+
+ return changed;
+}
+
+gboolean
+nml_dbus_property_ao_is_ready (const NMLDBusPropertyAO *pr_ao)
+{
+ return NM_IN_SET (pr_ao->n_not_ready, 0, G_MAXUINT)
+ || !pr_ao->owner_dbobj;
+}
+
+static void
+nml_dbus_property_ao_notify_watch_cb (NMClient *self,
+ gpointer obj_watcher)
+{
+ PropertyAOData *pr_ao_data = obj_watcher;
+
+ nm_assert (g_hash_table_lookup (pr_ao_data->parent->hash, pr_ao_data) == pr_ao_data);
+
+ if (nml_dbus_property_ao_get_eval (pr_ao_data, self)) {
+ nm_clear_pointer (&pr_ao_data->parent->arr, g_ptr_array_unref);
+ _nm_client_queue_notify_object (self,
+ pr_ao_data->parent->owner_dbobj->nmobj,
+ pr_ao_data->parent->meta_iface->obj_properties[pr_ao_data->parent->meta_iface->dbus_properties[pr_ao_data->parent->dbus_property_idx].obj_properties_idx]);
+ }
+ if (pr_ao_data->parent->owner_dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY)
+ nml_dbus_object_set_obj_state (pr_ao_data->parent->owner_dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY, self);
+}
+
+static NMLDBusNotifyUpdatePropFlags
+nml_dbus_property_ao_notify (NMClient *self,
+ NMLDBusPropertyAO *pr_ao,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ CList stale_lst_head = C_LIST_INIT (stale_lst_head);
+ gboolean changed = FALSE;
+ PropertyAOData *pr_ao_data;
+
+ // XXX: ensure we properly handle loops. Add a unit test for that
+ // first.
+
+ if (!pr_ao->owner_dbobj) {
+ nm_assert (!pr_ao->lst.next);
+ nm_assert (!pr_ao->lst.prev);
+ nm_assert (!pr_ao->hash);
+ nm_assert (!pr_ao->meta_iface);
+ nm_assert (pr_ao->dbus_property_idx == 0);
+ nm_assert (pr_ao->n_not_ready == 0);
+ c_list_init (&pr_ao->lst);
+ pr_ao->hash = g_hash_table_new (nm_ppdirect_hash, nm_ppdirect_equal);
+ pr_ao->owner_dbobj = dbobj;
+ pr_ao->meta_iface = meta_iface;
+ pr_ao->dbus_property_idx = dbus_property_idx;
+ } else {
+ nm_assert (pr_ao->lst.next);
+ nm_assert (pr_ao->lst.prev);
+ nm_assert (pr_ao->hash);
+ nm_assert (pr_ao->meta_iface == meta_iface);
+ nm_assert (pr_ao->dbus_property_idx == dbus_property_idx);
+ }
+
+ c_list_splice (&stale_lst_head, &pr_ao->lst);
+
+ if (value) {
+ GVariantIter iter;
+ const char *path;
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "&o", &path)) {
+ nm_auto_ref_string NMRefString *dbus_path_r = NULL;
+ gpointer p_dbus_path_1;
+
+ G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (PropertyAOData, obj_watcher) == 0);
+ G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMLDBusObjWatcher, dbobj) == 0);
+ G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMLDBusObject, dbus_path) == 0);
+
+ if (!nm_dbus_path_not_empty (path)) {
+ /* should not happen. Anyway, silently skip empty paths. */
+ continue;
+ }
+
+ dbus_path_r = nm_ref_string_new (path);
+ p_dbus_path_1 = &dbus_path_r;
+ pr_ao_data = g_hash_table_lookup (pr_ao->hash, &p_dbus_path_1);
+
+ if (pr_ao_data) {
+ /* With this implementation we cannot track the same path multiple times.
+ * Of course, for none of the properties where we use this, the server
+ * should expose the same path more than once, so in practice this is fine
+ * (maybe even preferable to drop duplicates form NMClient's API). */
+ nm_assert (pr_ao_data->obj_watcher.dbobj->dbus_path == dbus_path_r);
+ nm_c_list_move_tail (&pr_ao->lst, &pr_ao_data->lst);
+ } else {
+ pr_ao_data = _dbobjs_obj_watcher_register_r (self,
+ g_steal_pointer (&dbus_path_r),
+ nml_dbus_property_ao_notify_watch_cb,
+ sizeof (PropertyAOData)),
+ pr_ao_data->parent = pr_ao;
+ pr_ao_data->nmobj = NULL;
+ pr_ao_data->is_new = TRUE;
+ pr_ao_data->is_ready = FALSE;
+ pr_ao_data->is_notified = FALSE;
+ c_list_link_tail (&pr_ao->lst, &pr_ao_data->lst);
+ if (!g_hash_table_add (pr_ao->hash, pr_ao_data))
+ nm_assert_not_reached ();
+ nm_assert (pr_ao->n_not_ready < G_MAXUINT);
+ pr_ao->n_not_ready++;
+ }
+
+#if NM_MORE_ASSERTS > 10
+ {
+ nm_auto_ref_string NMRefString *p = nm_ref_string_new (path);
+ gpointer pp = &p;
+
+ nm_assert (g_hash_table_lookup (pr_ao->hash, &pp) == pr_ao_data);
+ }
+#endif
+ }
+ }
+
+ while ((pr_ao_data = c_list_first_entry (&stale_lst_head, PropertyAOData, lst))) {
+ c_list_unlink (&pr_ao_data->lst);
+ if (!g_hash_table_remove (pr_ao->hash, pr_ao_data))
+ nm_assert_not_reached ();
+ if (pr_ao_data->nmobj)
+ changed = TRUE;
+ if (!pr_ao_data->is_ready) {
+ nm_assert (pr_ao->n_not_ready > 0);
+ nm_assert (pr_ao->n_not_ready != G_MAXUINT);
+ pr_ao->n_not_ready--;
+ } else
+ nml_dbus_property_ao_notify_changed (pr_ao_data, self, FALSE);
+ _dbobjs_obj_watcher_unregister (self, pr_ao_data);
+ }
+
+ c_list_for_each_entry (pr_ao_data, &pr_ao->lst, lst) {
+ if (pr_ao_data->is_new) {
+ pr_ao_data->is_new = FALSE;
+ if (nml_dbus_property_ao_get_eval (pr_ao_data, self))
+ changed = TRUE;
+ }
+ }
+
+#if NM_MORE_ASSERTS > 10
+ {
+ guint c = 0;
+
+ c_list_for_each_entry (pr_ao_data, &pr_ao->lst, lst)
+ c += (!pr_ao_data->is_ready);
+ nm_assert (pr_ao->n_not_ready == c);
+ }
+#endif
+
+ if (changed) {
+ nm_clear_pointer (&pr_ao->arr, g_ptr_array_unref);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
+ }
+
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+}
+
+void
+nml_dbus_property_ao_clear (NMLDBusPropertyAO *pr_ao,
+ NMClient *self)
+{
+
+ if (!pr_ao->owner_dbobj) {
+ nm_assert (NM_IN_SET (pr_ao->n_not_ready, 0, G_MAXUINT));
+ nm_assert (pr_ao->n_not_ready != G_MAXUINT || (!pr_ao->lst.next && !pr_ao->lst.prev) || c_list_is_empty (&pr_ao->lst));
+ nm_assert (pr_ao->n_not_ready != 0 || (!pr_ao->lst.next && !pr_ao->lst.prev));
+ nm_assert (!pr_ao->hash);
+ nm_assert (!pr_ao->meta_iface);
+ nm_assert (pr_ao->dbus_property_idx == 0);
+ pr_ao->n_not_ready = G_MAXUINT;
+ } else {
+ PropertyAOData *pr_ao_data;
+ gboolean changed = FALSE;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (pr_ao->lst.next);
+ nm_assert (pr_ao->lst.prev);
+ nm_assert (pr_ao->hash);
+ nm_assert (pr_ao->meta_iface);
+ nm_assert (pr_ao->n_not_ready != G_MAXUINT);
+
+ while ((pr_ao_data = c_list_first_entry (&pr_ao->lst, PropertyAOData, lst))) {
+ if (pr_ao_data->nmobj)
+ changed = TRUE;
+ if (!pr_ao_data->is_ready) {
+ nm_assert (pr_ao->n_not_ready > 0);
+ pr_ao->n_not_ready--;
+ } else
+ nml_dbus_property_ao_notify_changed (pr_ao_data, self, FALSE);
+ c_list_unlink (&pr_ao_data->lst);
+ if (!g_hash_table_remove (pr_ao->hash, pr_ao_data))
+ nm_assert_not_reached ();
+ _dbobjs_obj_watcher_unregister (self, pr_ao_data);
+ }
+
+ nm_assert (c_list_is_empty (&pr_ao->lst));
+ nm_assert (pr_ao->n_not_ready == 0);
+ nm_assert (g_hash_table_size (pr_ao->hash) == 0);
+
+ if ( changed
+ && pr_ao->owner_dbobj->nmobj) {
+ _nm_client_queue_notify_object (self,
+ pr_ao->owner_dbobj->nmobj,
+ pr_ao->meta_iface->obj_properties[pr_ao->meta_iface->dbus_properties[pr_ao->dbus_property_idx].obj_properties_idx]);
+ }
+
+ nm_assert (c_list_is_empty (&pr_ao->lst));
+ nm_assert (pr_ao->n_not_ready == 0);
+ nm_assert (g_hash_table_size (pr_ao->hash) == 0);
+ nm_clear_pointer (&pr_ao->hash, g_hash_table_unref);
+ pr_ao->owner_dbobj = NULL;
+ pr_ao->meta_iface = NULL;
+ pr_ao->dbus_property_idx = 0;
+ pr_ao->n_not_ready = G_MAXUINT;
+ }
+
+ nm_clear_pointer (&pr_ao->arr, g_ptr_array_unref);
+}
+
+/*****************************************************************************/
+
+NMLDBusNotifyUpdatePropFlags
+_nml_dbus_notify_update_prop_ignore (NMClient *self,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+}
+
+NMLDBusNotifyUpdatePropFlags
+_nml_dbus_notify_update_prop_o (NMClient *self,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ const char *path = NULL;
+ NMRefString **p_property;
+
+ if (value)
+ path = g_variant_get_string (value, NULL);
+
+ p_property = nml_dbus_object_get_property_location (dbobj,
+ meta_iface,
+ &meta_iface->dbus_properties[dbus_property_idx]);
+
+ if (!nm_streq0 (nm_ref_string_get_str (*p_property), path)) {
+ nm_ref_string_unref (*p_property);
+ *p_property = nm_ref_string_new (path);
+ }
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
+}
+
+/*****************************************************************************/
+
+static void
+_obj_notify_update_prop (NMClient *self,
+ NMLDBusObject *dbobj,
+ NMLDBusObjIfaceData *db_iface_data,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ const NMLDBusMetaIface *meta_iface = db_iface_data->dbus_iface.meta;
+ const NMLDBusMetaProperty *meta_property = &meta_iface->dbus_properties[dbus_property_idx];
+ gpointer p_property;
+ const char *dbus_type_s;
+ const GParamSpec *param_spec;
+ NMLDBusNotifyUpdatePropFlags notify_update_prop_flags;
+
+ nm_assert (G_IS_OBJECT (dbobj->nmobj));
+
+ if ( value
+ && !g_variant_is_of_type (value, meta_property->dbus_type)) {
+ NML_NMCLIENT_LOG_E (self, "[%s] property %s.%s expected of type \"%s\" but is \"%s\". Ignore",
+ dbobj->dbus_path->str,
+ meta_iface->dbus_iface_name,
+ meta_property->dbus_property_name,
+ (const char *) meta_property->dbus_type,
+ (const char *) g_variant_get_type (value));
+ value = NULL;
+ }
+
+ if (meta_property->use_notify_update_prop) {
+ notify_update_prop_flags = meta_property->notify_update_prop (self,
+ dbobj,
+ meta_iface,
+ dbus_property_idx,
+ value);
+ if (notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE)
+ return;
+
+ nm_assert (notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY);
+ nm_assert (G_IS_OBJECT (dbobj->nmobj));
+ nm_assert (meta_iface->obj_properties);
+ nm_assert (meta_property->obj_properties_idx > 0);
+ param_spec = meta_iface->obj_properties[meta_property->obj_properties_idx];
+ goto notify;
+ }
+
+ p_property = nml_dbus_object_get_property_location (dbobj, meta_iface, meta_property);
+
+ dbus_type_s = (const char *) meta_property->dbus_type;
+
+ nm_assert (G_IS_OBJECT (dbobj->nmobj));
+ nm_assert (meta_iface->obj_properties);
+ nm_assert (meta_property->obj_properties_idx > 0);
+ param_spec = meta_iface->obj_properties[meta_property->obj_properties_idx];
+
+ notify_update_prop_flags = NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
+
+ switch (dbus_type_s[0]) {
+ case 'b':
+ nm_assert (dbus_type_s[1] == '\0');
+ if (value)
+ *((bool *) p_property) = g_variant_get_boolean (value);
+ else if (param_spec->value_type == G_TYPE_BOOLEAN)
+ *((bool *) p_property) = ((GParamSpecBoolean *) param_spec)->default_value;
+ else {
+ nm_assert_not_reached ();
+ *((bool *) p_property) = FALSE;
+ }
+ break;
+ case 'y':
+ nm_assert (dbus_type_s[1] == '\0');
+ if (value)
+ *((guint8 *) p_property) = g_variant_get_byte (value);
+ else {
+ nm_assert (nm_utils_g_param_spec_is_default (param_spec));
+ *((guint8 *) p_property) = 0;
+ }
+ break;
+ case 'q':
+ nm_assert (dbus_type_s[1] == '\0');
+ if (value)
+ *((guint16 *) p_property) = g_variant_get_uint16 (value);
+ else {
+ nm_assert (nm_utils_g_param_spec_is_default (param_spec));
+ *((guint16 *) p_property) = 0;
+ }
+ break;
+ case 'i':
+ nm_assert (dbus_type_s[1] == '\0');
+ if (value)
+ *((gint32 *) p_property) = g_variant_get_int32 (value);
+ else if (param_spec->value_type == G_TYPE_INT)
+ *((gint32 *) p_property) = ((GParamSpecInt *) param_spec)->default_value;
+ else {
+ nm_assert (nm_utils_g_param_spec_is_default (param_spec));
+ *((gint32 *) p_property) = 0;
+ }
+ break;
+ case 'u':
+ nm_assert (dbus_type_s[1] == '\0');
+ if (value)
+ *((guint32 *) p_property) = g_variant_get_uint32 (value);
+ else {
+ nm_assert (nm_utils_g_param_spec_is_default (param_spec));
+ *((guint32 *) p_property) = 0;
+ }
+ break;
+ case 'x':
+ nm_assert (dbus_type_s[1] == '\0');
+ if (value)
+ *((gint64 *) p_property) = g_variant_get_int64 (value);
+ else if (param_spec->value_type == G_TYPE_INT64)
+ *((gint64 *) p_property) = ((GParamSpecInt64 *) param_spec)->default_value;
+ else {
+ nm_assert (nm_utils_g_param_spec_is_default (param_spec));
+ *((gint64 *) p_property) = 0;
+ }
+ break;
+ case 's':
+ nm_assert (dbus_type_s[1] == '\0');
+ nm_clear_g_free ((char **) p_property);
+ if (value)
+ *((char **) p_property) = g_variant_dup_string (value, NULL);
+ else {
+ nm_assert (nm_utils_g_param_spec_is_default (param_spec));
+ *((char **) p_property) = NULL;
+ }
+ break;
+ case 'o':
+ nm_assert (dbus_type_s[1] == '\0');
+ notify_update_prop_flags = nml_dbus_property_o_notify (self,
+ p_property,
+ dbobj,
+ meta_iface,
+ dbus_property_idx,
+ value);
+ break;
+ case 'a':
+ switch (dbus_type_s[1]) {
+ case 'y':
+ nm_assert (dbus_type_s[2] == '\0');
+ {
+ gconstpointer v;
+ gsize l;
+ GBytes *b = NULL;
+
+ if (value) {
+ v = g_variant_get_fixed_array (value, &l, 1);
+
+ if (l > 0) {
+ /* empty arrays are coerced to NULL. */
+ b = g_bytes_new (v, l);
+ }
+ }
+
+ nm_clear_pointer ((GBytes **) p_property, g_bytes_unref);
+ *((GBytes **) p_property) = b;
+ }
+ break;
+ case 's':
+ nm_assert (dbus_type_s[2] == '\0');
+ nm_assert (param_spec->value_type == G_TYPE_STRV);
+
+ g_strfreev (*((char ***) p_property));
+ if (value)
+ *((char ***) p_property) = g_variant_dup_strv (value, NULL);
+ else
+ *((char ***) p_property) = NULL;
+ break;
+ case 'o':
+ nm_assert (dbus_type_s[2] == '\0');
+ notify_update_prop_flags = nml_dbus_property_ao_notify (self,
+ p_property,
+ dbobj,
+ meta_iface,
+ dbus_property_idx,
+ value);
+ break;
+ default:
+ nm_assert_not_reached ();
+ }
+ break;
+ default:
+ nm_assert_not_reached ();
+ }
+
+notify:
+ if (NM_FLAGS_HAS (notify_update_prop_flags, NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY))
+ g_object_notify_by_pspec (dbobj->nmobj, (GParamSpec *) param_spec);
+}
+
+static void
+_obj_notify_update_iface (NMClient *self,
+ NMLDBusObject *dbobj,
+ NMLDBusObjIfaceData *db_iface_data)
+{
+ NMLDBusObjPropData *db_prop_data;
+ gboolean is_self = (G_OBJECT (self) == dbobj->nmobj);
+ gboolean is_removed;
+ gboolean type_compatible;
+ guint8 i_prop;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (is_self || NM_IS_OBJECT (dbobj->nmobj));
+
+ if (G_UNLIKELY (!db_iface_data->nmobj_checked)) {
+ db_iface_data->nmobj_checked = TRUE;
+ type_compatible = db_iface_data->dbus_iface.meta->get_type_fcn
+ && g_type_is_a (G_OBJECT_TYPE (dbobj->nmobj), db_iface_data->dbus_iface.meta->get_type_fcn ());
+ db_iface_data->nmobj_compatible = type_compatible;
+ } else
+ type_compatible = db_iface_data->nmobj_compatible;
+
+ if (!type_compatible) {
+ /* on D-Bus, we have this interface associate with the object, but apparently
+ * it is not compatible. This is either a bug, or NetworkManager exposed an
+ * unexpected interface on D-Bus object for which we create a certain NMObject
+ * type. */
+ return;
+ }
+
+ is_removed = c_list_is_empty (&db_iface_data->iface_lst);
+
+ nm_assert ( (is_removed && db_iface_data->dbus_iface.meta->n_dbus_properties > 0)
+ || (!is_removed && !c_list_is_empty (&db_iface_data->changed_prop_lst_head)));
+
+ _nm_client_queue_notify_object (self, dbobj->nmobj, NULL);
+
+ if (is_removed) {
+ for (i_prop = 0; i_prop < db_iface_data->dbus_iface.meta->n_dbus_properties; i_prop++) {
+ _obj_notify_update_prop (self,
+ dbobj,
+ db_iface_data,
+ i_prop,
+ NULL);
+ }
+ } else {
+ while ((db_prop_data = c_list_first_entry (&db_iface_data->changed_prop_lst_head, NMLDBusObjPropData, changed_prop_lst))) {
+ gs_unref_variant GVariant *prop_data_value = NULL;
+
+ c_list_unlink (&db_prop_data->changed_prop_lst);
+
+ nm_assert (db_prop_data >= db_iface_data->prop_datas);
+ nm_assert (db_prop_data < &db_iface_data->prop_datas[db_iface_data->dbus_iface.meta->n_dbus_properties]);
+ nm_assert (db_prop_data->prop_data_value);
+
+ /* currently NMLDBusObject forgets about the variant. Theoretically, it could cache
+ * it, but there is no need because we update the property in nmobj (which extracts and
+ * keeps the property value itself). */
+ prop_data_value = g_steal_pointer (&db_prop_data->prop_data_value);
+
+ i_prop = (db_prop_data - &db_iface_data->prop_datas[0]);
+ _obj_notify_update_prop (self,
+ dbobj,
+ db_iface_data,
+ i_prop,
+ prop_data_value);
+ }
+ }
+}
+
+static void
+_obj_notify_update (NMClient *self,
+ NMLDBusObject *dbobj)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ NMLDBusObjIfaceData *db_iface_data;
+ gboolean notify_watchers = TRUE;
+ gs_unref_object GObject *nmobj_unregistering = NULL;
+
+ _ASSERT_dbobj (dbobj, self);
+
+ if ( G_UNLIKELY (!dbobj->nmobj)
+ && !c_list_is_empty (&dbobj->iface_lst_head)) {
+
+ /* Try to create a NMObject for this D-Bus object. Note that we detect the type
+ * based on the interfaces that it has, and if we make a choice once, we don't
+ * change. That means, one D-Bus object can only be of one type. */
+
+ if (NM_IN_SET (dbobj->dbus_path, _dbus_path_nm,
+ _dbus_path_settings,
+ _dbus_path_dns_manager)) {
+ /* For the main types, we don't detect them based on the interfaces present,
+ * but on the path names. Of course, both should correspond anyway. */
+ NML_NMCLIENT_LOG_T (self, "[%s]: register NMClient for D-Bus object",
+ dbobj->dbus_path->str);
+ dbobj->nmobj = G_OBJECT (self);
+ if (dbobj->dbus_path == _dbus_path_nm) {
+ nm_assert (!priv->dbobj_nm);
+ priv->dbobj_nm = dbobj;
+ } else if (dbobj->dbus_path == _dbus_path_settings) {
+ nm_assert (!priv->dbobj_settings);
+ priv->dbobj_settings = dbobj;
+ } else {
+ nm_assert (dbobj->dbus_path == _dbus_path_dns_manager);
+ nm_assert (!priv->dbobj_dns_manager);
+ priv->dbobj_dns_manager = dbobj;
+ }
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE, self);
+ } else {
+ GType gtype = G_TYPE_NONE;
+ NMLDBusMetaInteracePrio curr_prio = NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW - 1;
+
+ c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
+ if (!db_iface_data->dbus_iface_is_wellknown)
+ break;
+ if (db_iface_data->dbus_iface.meta->interface_prio <= curr_prio)
+ continue;
+ curr_prio = db_iface_data->dbus_iface.meta->interface_prio;
+ gtype = db_iface_data->dbus_iface.meta->get_type_fcn ();
+ }
+ if (gtype != G_TYPE_NONE) {
+ dbobj->nmobj = g_object_new (gtype, NULL);
+
+ NML_NMCLIENT_LOG_T (self, "[%s]: register new NMObject "NM_HASH_OBFUSCATE_PTR_FMT" of type %s",
+ dbobj->dbus_path->str,
+ NM_HASH_OBFUSCATE_PTR (dbobj->nmobj),
+ g_type_name (gtype));
+
+ nm_assert (NM_IS_OBJECT (dbobj->nmobj));
+ NM_OBJECT_GET_CLASS (dbobj->nmobj)->register_client (NM_OBJECT (dbobj->nmobj), self, dbobj);
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY, self);
+ }
+ }
+ }
+
+ while ((db_iface_data = c_list_first_entry (&dbobj->removed_iface_lst_head, NMLDBusObjIfaceData, iface_lst))) {
+ c_list_unlink (&db_iface_data->iface_lst);
+ if ( db_iface_data->dbus_iface_is_wellknown
+ && dbobj->nmobj)
+ _obj_notify_update_iface (self, dbobj, db_iface_data);
+ nml_dbus_obj_iface_data_destroy (db_iface_data);
+ }
+
+ c_list_for_each_entry (db_iface_data, &dbobj->iface_lst_head, iface_lst) {
+ if (!db_iface_data->dbus_iface_is_wellknown)
+ break;
+ if (c_list_is_empty (&db_iface_data->changed_prop_lst_head))
+ continue;
+ if (dbobj->nmobj)
+ _obj_notify_update_iface (self, dbobj, db_iface_data);
+ }
+
+ if ( c_list_is_empty (&dbobj->iface_lst_head)
+ && dbobj->nmobj) {
+
+ if (dbobj->nmobj == G_OBJECT (self)) {
+ dbobj->nmobj = NULL;
+ NML_NMCLIENT_LOG_T (self, "[%s]: unregister NMClient from D-Bus object",
+ dbobj->dbus_path->str);
+ if (dbobj->dbus_path == _dbus_path_nm) {
+ nm_assert (priv->dbobj_nm == dbobj);
+ priv->dbobj_nm = NULL;
+ nml_dbus_property_o_clear (&priv->nm.activating_connection, self);
+ nml_dbus_property_o_clear (&priv->nm.primary_connection, self);
+ nml_dbus_property_ao_clear (&priv->nm.devices, self);
+ nml_dbus_property_ao_clear (&priv->nm.all_devices, self);
+ nml_dbus_property_ao_clear (&priv->nm.active_connections, self);
+ nml_dbus_property_ao_clear (&priv->nm.checkpoints, self);
+ } else if (dbobj->dbus_path == _dbus_path_settings) {
+ nm_assert (priv->dbobj_settings == dbobj);
+ priv->dbobj_settings = NULL;
+ nml_dbus_property_ao_clear (&priv->settings.connections, self);
+ } else {
+ nm_assert (dbobj->dbus_path == _dbus_path_dns_manager);
+ nm_assert (priv->dbobj_dns_manager == dbobj);
+ priv->dbobj_dns_manager = NULL;
+ }
+ } else {
+ nmobj_unregistering = g_steal_pointer (&dbobj->nmobj);
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_WATCHED_ONLY, self);
+ NML_NMCLIENT_LOG_T (self, "[%s]: unregister NMObject "NM_HASH_OBFUSCATE_PTR_FMT" of type %s",
+ dbobj->dbus_path->str,
+ NM_HASH_OBFUSCATE_PTR (nmobj_unregistering),
+ g_type_name (G_OBJECT_TYPE (nmobj_unregistering)));
+ NM_OBJECT_GET_CLASS (nmobj_unregistering)->unregister_client (NM_OBJECT (nmobj_unregistering), self, dbobj);
+ }
+ } else if (dbobj->nmobj) {
+ if (dbobj->nmobj != G_OBJECT (self)) {
+ gboolean notified_watchers;
+
+ _dbobjs_check_dbobj_visible (self, dbobj, FALSE, FALSE, &notified_watchers);
+ notify_watchers = !notified_watchers;
+ }
+ }
+
+ if (notify_watchers)
+ _dbobjs_notify_watchers_for_dbobj (self, dbobj);
+}
+
+/*****************************************************************************/
+
+static void
+_dbus_handle_objects_changed (NMClient *self,
+ const char *log_context)
+{
+ NMClientPrivate *priv;
+ NMLDBusObject *dbobj_next;
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+
+ while ((dbobj_next = c_list_first_entry (&priv->dbus_object_changed_lst_head, NMLDBusObject, changed_obj_lst))) {
+ nm_auto_unref_nml_dbusobj NMLDBusObject *dbobj = nml_dbus_object_ref (dbobj_next);
+
+ c_list_unlink (&dbobj->changed_obj_lst);
+
+ _obj_notify_update (self, dbobj);
+
+ if (dbobj->obj_state == NML_DBUS_OBJ_STATE_UNLINKED)
+ continue;
+
+ if ( c_list_is_empty (&dbobj->iface_lst_head)
+ && c_list_is_empty (&dbobj->watcher_lst_head)) {
+ NML_NMCLIENT_LOG_T (self, "[%s]: drop D-Bus instance", dbobj->dbus_path->str);
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_UNLINKED, self);
+ if (!g_hash_table_steal (priv->dbus_objects, dbobj))
+ nm_assert_not_reached ();
+ nml_dbus_object_unref (dbobj);
+ }
+ }
+}
+
+static void
+_dbus_handle_changes_commit (NMClient *self,
+ gboolean allow_init_start_check_complete)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
+
+ _dbobjs_check_dbobj_visible_all (self);
+
+ dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->main_context);
+
+ _nm_client_notify_event_emit (self);
+
+ _set_nm_running (self);
+
+ if (allow_init_start_check_complete)
+ _init_start_check_complete (self);
+}
+
+static void
+_dbus_handle_changes (NMClient *self,
+ const char *log_context,
+ gboolean allow_init_start_check_complete)
+{
+ _dbus_handle_objects_changed (self, log_context);
+ _dbus_handle_changes_commit (self, allow_init_start_check_complete);
+}
+
static gboolean
-_nm_client_check_nm_running (NMClient *client, GError **error)
+_dbus_handle_properties_changed (NMClient *self,
+ const char *log_context,
+ const char *object_path,
+ const char *interface_name,
+ gboolean allow_add_iface,
+ GVariant *changed_properties,
+ NMLDBusObject **inout_dbobj)
{
- if (!nm_client_get_nm_running (client)) {
- _nm_object_set_error_nm_not_running (error);
+ NMClientPrivate *priv;
+ NMLDBusObject *dbobj = NULL;
+ NMLDBusObjIfaceData *db_iface_data = NULL;
+ nm_auto_ref_string NMRefString *dbus_path = NULL;
+
+ nm_assert (!changed_properties || g_variant_is_of_type (changed_properties, G_VARIANT_TYPE ("a{sv}")));
+
+ {
+ gs_free char *ss = NULL;
+
+ NML_NMCLIENT_LOG_T (self, "[%s]: %s: properties changed for interface %s { %s }",
+ object_path, log_context, interface_name,
+ (ss = g_variant_print (changed_properties, TRUE)));
+ }
+
+ if (inout_dbobj) {
+ dbobj = *inout_dbobj;
+ nm_assert (!dbobj || nm_streq (object_path, dbobj->dbus_path->str));
+ }
+ if (!dbobj) {
+ dbus_path = nm_ref_string_new (object_path);
+ dbobj = _dbobjs_dbobj_get_r (self, dbus_path);
+ }
+
+ if (dbobj)
+ db_iface_data = nml_dbus_object_iface_data_get (dbobj, interface_name, allow_add_iface);
+ else if (allow_add_iface) {
+ dbobj = _dbobjs_dbobj_create (self, g_steal_pointer (&dbus_path));
+ nml_dbus_object_set_obj_state (dbobj, NML_DBUS_OBJ_STATE_ON_DBUS, self);
+ db_iface_data = nml_dbus_object_iface_data_get (dbobj, interface_name, TRUE);
+ }
+
+ NM_SET_OUT (inout_dbobj, dbobj);
+
+ if (!db_iface_data) {
+ if (allow_add_iface)
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] too many interfaces on object. Something is very wrong", log_context, object_path);
+ else
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] property changed signal for non existing interface %s", log_context, object_path, interface_name);
+ nm_assert ( !dbobj
+ || dbobj->obj_state != NML_DBUS_OBJ_STATE_UNLINKED);
return FALSE;
}
+
+ if (!db_iface_data->dbus_iface_is_wellknown)
+ NML_NMCLIENT_LOG_W (self, "%s: [%s] ignore unknown interface %s", log_context, object_path, interface_name);
+ else if (changed_properties) {
+ GVariantIter iter_prop;
+ const char *property_name;
+ GVariant *property_value_tmp;
+
+ g_variant_iter_init (&iter_prop, changed_properties);
+ while (g_variant_iter_next (&iter_prop, "{&sv}", &property_name, &property_value_tmp)) {
+ _nm_unused gs_unref_variant GVariant *property_value = property_value_tmp;
+ const NMLDBusMetaProperty *meta_property;
+ NMLDBusObjPropData *db_propdata;
+ guint property_idx;
+
+ meta_property = nml_dbus_meta_property_get (db_iface_data->dbus_iface.meta, property_name, &property_idx);
+ if (!meta_property) {
+ NML_NMCLIENT_LOG_W (self, "%s: [%s]: ignore unknown property %s.%s", log_context, object_path, interface_name, property_name);
+ continue;
+ }
+
+ db_propdata = &db_iface_data->prop_datas[property_idx];
+
+ NML_NMCLIENT_LOG_T (self, "[%s]: %s: %s property %s.%s",
+ object_path, log_context,
+ db_propdata->prop_data_value ? "update" : "set",
+ interface_name, property_name);
+
+ nm_g_variant_unref (db_propdata->prop_data_value);
+ db_propdata->prop_data_value = g_steal_pointer (&property_value);
+ nm_c_list_move_tail (&db_iface_data->changed_prop_lst_head, &db_propdata->changed_prop_lst);
+ }
+ }
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (c_list_is_empty (&dbobj->changed_obj_lst))
+ c_list_link_tail (&priv->dbus_object_changed_lst_head, &dbobj->changed_obj_lst);
return TRUE;
}
+static gboolean
+_dbus_handle_interface_added (NMClient *self,
+ const char *log_context,
+ const char *object_path,
+ GVariant *ifaces)
+{
+ gboolean changed = FALSE;
+ const char *interface_name;
+ GVariant *changed_properties;
+ GVariantIter iter_ifaces;
+ NMLDBusObject *dbobj = NULL;
+
+ nm_assert (g_variant_is_of_type (ifaces, G_VARIANT_TYPE ("a{sa{sv}}")));
+
+ g_variant_iter_init (&iter_ifaces, ifaces);
+ while (g_variant_iter_next (&iter_ifaces, "{&s@a{sv}}", &interface_name, &changed_properties)) {
+ _nm_unused gs_unref_variant GVariant *changed_properties_free = changed_properties;
+
+ if (_dbus_handle_properties_changed (self, log_context, object_path, interface_name, TRUE, changed_properties, &dbobj))
+ changed = TRUE;
+ }
+
+ return changed;
+}
+
+static gboolean
+_dbus_handle_interface_removed (NMClient *self,
+ const char *log_context,
+ const char *object_path,
+ NMLDBusObject **inout_dbobj,
+ const char *const*removed_interfaces)
+{
+ NMClientPrivate *priv;
+ gboolean changed = FALSE;
+ NMLDBusObject *dbobj;
+ gsize i;
+
+ if ( inout_dbobj
+ && *inout_dbobj) {
+ dbobj = *inout_dbobj;
+ nm_assert (dbobj == _dbobjs_dbobj_get_s (self, object_path));
+ } else {
+ dbobj = _dbobjs_dbobj_get_s (self, object_path);
+ if (!dbobj) {
+ NML_NMCLIENT_LOG_E (self, "%s: [%s]: receive interface removed event for non existing object", log_context, object_path);
+ return FALSE;
+ }
+ NM_SET_OUT (inout_dbobj, dbobj);
+ }
+
+ for (i = 0; removed_interfaces[i]; i++) {
+ NMLDBusObjIfaceData *db_iface_data;
+ const char *interface_name = removed_interfaces[i];
+
+ db_iface_data = nml_dbus_object_iface_data_get (dbobj, interface_name, FALSE);
+ if (!db_iface_data) {
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] receive interface remove event for unexpected interface %s", log_context, object_path, interface_name);
+ continue;
+ }
+
+ nm_c_list_move_tail (&dbobj->removed_iface_lst_head, &db_iface_data->iface_lst);
+ changed = TRUE;
+ }
+
+ if (changed) {
+ priv = NM_CLIENT_GET_PRIVATE (self);
+
+ if (c_list_is_empty (&dbobj->changed_obj_lst))
+ c_list_link_tail (&priv->dbus_object_changed_lst_head, &dbobj->changed_obj_lst);
+ }
+
+ return changed;
+}
+
+static void
+_dbus_managed_objects_changed_cb (const char *object_path,
+ GVariant *added_interfaces_and_properties,
+ const char *const*removed_interfaces,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ const char *log_context;
+ gboolean changed;
+
+ if (priv->get_managed_objects_cancellable) {
+ /* we still wait for the initial GetManagedObjects(). Ignore the event. */
+ return;
+ }
+
+ if (!added_interfaces_and_properties) {
+ log_context = "interfaces-removed";
+ changed = _dbus_handle_interface_removed (self, log_context, object_path, NULL, removed_interfaces);
+ } else {
+ log_context = "interfaces-added";
+ changed = _dbus_handle_interface_added (self, log_context, object_path, added_interfaces_and_properties);
+ }
+
+ if (changed)
+ _dbus_handle_changes (self, log_context, TRUE);
+}
+
+static void
+_dbus_properties_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *signal_interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ const char *interface_name;
+ gs_unref_variant GVariant *changed_properties = NULL;
+ gs_free const char **invalidated_properties = NULL;
+ const char *log_context = "properties-changed";
+
+ if (priv->get_managed_objects_cancellable) {
+ /* we still wait for the initial GetManagedObjects(). Ignore the event. */
+ return;
+ }
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sa{sv}as)")))
+ return;
+
+ g_variant_get (parameters,
+ "(&s@a{sv}^a&s)",
+ &interface_name,
+ &changed_properties,
+ &invalidated_properties);
+
+ if (invalidated_properties && invalidated_properties[0]) {
+ NML_NMCLIENT_LOG_W (self, "%s: [%s] ignore invalidated properties on interface %s",
+ log_context, object_path, interface_name);
+ }
+
+ if (_dbus_handle_properties_changed (self, log_context, object_path, interface_name, FALSE, changed_properties, NULL))
+ _dbus_handle_changes (self, log_context, TRUE);
+}
+
+static void
+_dbus_get_managed_objects_cb (GVariant *result,
+ GError *error,
+ gpointer user_data)
+{
+ NMClient *self;
+ NMClientPrivate *priv;
+
+ if ( !result
+ && nm_utils_error_is_cancelled (error, FALSE))
+ return;
+
+ self = user_data;
+ priv = NM_CLIENT_GET_PRIVATE (self);
+
+ g_clear_object (&priv->get_managed_objects_cancellable);
+
+ if (!result) {
+ NML_NMCLIENT_LOG_D (self, "GetManagedObjects() call failed: %s", error->message);
+ /* hm, now that's odd. Maybe NetworkManager just quit and we are about to get
+ * a name-owner changed signal soon. Treat this as if we got no managed objects at all. */
+ } else
+ NML_NMCLIENT_LOG_D (self, "GetManagedObjects() completed");
+
+ if (result) {
+ GVariantIter iter;
+ const char *object_path;
+ GVariant *ifaces_tmp;
+
+ g_variant_iter_init (&iter, result);
+ while (g_variant_iter_next (&iter, "{&o@a{sa{sv}}}", &object_path, &ifaces_tmp)) {
+ gs_unref_variant GVariant *ifaces = ifaces_tmp;
+
+ _dbus_handle_interface_added (self, "get-managed-objects", object_path, ifaces);
+ }
+ }
+
+ /* always call _dbus_handle_changes(), even if nothing changed. We need this to complete
+ * initialization. */
+ _dbus_handle_changes (self, "get-managed-objects", TRUE);
+}
+
+/*****************************************************************************/
+
+static void
+_nm_client_get_settings_call_cb (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ NMRemoteConnection *remote_connection;
+ NMClient *self;
+ gs_unref_variant GVariant *ret = NULL;
+ gs_free_error GError *error = NULL;
+ gs_unref_variant GVariant *settings = NULL;
+ NMLDBusObject *dbobj;
+
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+ if ( !ret
+ && nm_utils_error_is_cancelled (error, FALSE))
+ return;
+
+ remote_connection = user_data;
+
+ self = _nm_object_get_client (remote_connection);
+
+ dbobj = _nm_object_get_dbobj (remote_connection);
+
+ _ASSERT_dbobj (dbobj, self);
+
+ if (!ret) {
+ NML_NMCLIENT_LOG_T (self, "[%s] GetSettings() completed with error: %s",
+ dbobj->dbus_path->str,
+ error->message);
+ } else {
+ NML_NMCLIENT_LOG_T (self, "[%s] GetSettings() completed with success",
+ dbobj->dbus_path->str);
+ g_variant_get (ret,
+ "(@a{sa{sv}})",
+ &settings);
+ }
+
+ _nm_remote_settings_get_settings_commit (remote_connection, settings);
+
+ _dbus_handle_changes_commit (self, TRUE);
+}
+
+void
+_nm_client_get_settings_call (NMClient *self,
+ NMLDBusObject *dbobj)
+{
+ GCancellable *cancellable;
+
+ cancellable = _nm_remote_settings_get_settings_prepare (NM_REMOTE_CONNECTION (dbobj->nmobj));
+
+ _nm_client_dbus_call_simple (self,
+ cancellable,
+ dbobj->dbus_path->str,
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "GetSettings",
+ g_variant_new ("()"),
+ G_VARIANT_TYPE ("(a{sa{sv}})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ _nm_client_get_settings_call_cb,
+ dbobj->nmobj);
+}
+
+static void
+_dbus_settings_updated_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *signal_interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ const char *log_context = "settings-updated";
+ NMLDBusObject *dbobj;
+
+ if (priv->get_managed_objects_cancellable) {
+ /* we still wait for the initial GetManagedObjects(). Ignore the event. */
+ return;
+ }
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("()")))
+ return;
+
+ dbobj = _dbobjs_dbobj_get_s (self, object_path);
+
+ if ( !dbobj
+ || !NM_IS_REMOTE_CONNECTION (dbobj->nmobj)) {
+ NML_NMCLIENT_LOG_W (self, "%s: [%s] ignore Updated signal for non-existing setting",
+ log_context, object_path);
+ return;
+ }
+
+ NML_NMCLIENT_LOG_T (self, "%s: [%s] Updated signal received",
+ log_context, object_path);
+
+ _nm_client_get_settings_call (self, dbobj);
+}
+
+/*****************************************************************************/
+
+static void
+_dbus_nm_connection_active_state_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *signal_interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ const char *log_context = "active-connection-state-changed";
+ NMLDBusObject *dbobj;
+ guint32 state;
+ guint32 reason;
+
+ if (priv->get_managed_objects_cancellable) {
+ /* we still wait for the initial GetManagedObjects(). Ignore the event. */
+ return;
+ }
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) {
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] ignore StateChanged signal with unexpected signature",
+ log_context, object_path);
+ return;
+ }
+
+ dbobj = _dbobjs_dbobj_get_s (self, object_path);
+
+ if ( !dbobj
+ || !NM_IS_ACTIVE_CONNECTION (dbobj->nmobj)) {
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] ignore StateChanged signal for non-existing active connection",
+ log_context, object_path);
+ return;
+ }
+
+ g_variant_get (parameters, "(uu)", &state, &reason);
+
+ NML_NMCLIENT_LOG_T (self, "%s: [%s] StateChanged signal received",
+ log_context, object_path);
+
+ _nm_active_connection_state_changed_commit (NM_ACTIVE_CONNECTION (dbobj->nmobj),
+ state,
+ reason);
+
+ _dbus_handle_changes_commit (self, TRUE);
+}
+
+/*****************************************************************************/
+
+static void
+_dbus_nm_vpn_connection_state_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *signal_interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ const char *log_context = "vpn-connection-state-changed";
+ NMLDBusObject *dbobj;
+ guint32 state;
+ guint32 reason;
+
+ if (priv->get_managed_objects_cancellable) {
+ /* we still wait for the initial GetManagedObjects(). Ignore the event. */
+ return;
+ }
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)"))) {
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] ignore VpnStateChanged signal with unexpected signature",
+ log_context, object_path);
+ return;
+ }
+
+ dbobj = _dbobjs_dbobj_get_s (self, object_path);
+
+ if ( !dbobj
+ || !NM_IS_VPN_CONNECTION (dbobj->nmobj)) {
+ NML_NMCLIENT_LOG_E (self, "%s: [%s] ignore VpnStateChanged signal for non-existing vpn connection",
+ log_context, object_path);
+ return;
+ }
+
+ g_variant_get (parameters, "(uu)", &state, &reason);
+
+ NML_NMCLIENT_LOG_T (self, "%s: [%s] VpnStateChanged signal received",
+ log_context, object_path);
+
+ _nm_vpn_connection_state_changed_commit (NM_VPN_CONNECTION (dbobj->nmobj),
+ state,
+ reason);
+
+ _dbus_handle_changes_commit (self, TRUE);
+}
+
+/*****************************************************************************/
+
+static void
+_emit_permissions_changed (NMClient *self,
+ GHashTable *permissions,
+ gboolean force_unknown)
+{
+ GHashTableIter iter;
+ gpointer key;
+ gpointer value;
+
+ if (!permissions)
+ return;
+ if (self->obj_base.is_disposing)
+ return;
+
+ g_hash_table_iter_init (&iter, permissions);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ g_signal_emit (self,
+ signals[PERMISSION_CHANGED],
+ 0,
+ GPOINTER_TO_UINT (key),
+ force_unknown
+ ? (guint) NM_CLIENT_PERMISSION_NONE
+ : GPOINTER_TO_UINT (value));
+ }
+}
+
+
+static void
+_dbus_check_permissions_start_cb (GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
+ NMClient *self;
+ NMClientPrivate *priv;
+ gs_unref_variant GVariant *ret = NULL;
+ nm_auto_free_variant_iter GVariantIter *v_permissions = NULL;
+ gs_unref_hashtable GHashTable *old_permissions = NULL;
+ gs_free_error GError *error = NULL;
+ const char *pkey;
+ const char *pvalue;
+
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+ if ( !ret
+ && nm_utils_error_is_cancelled (error, FALSE))
+ return;
+
+ self = user_data;
+ priv = NM_CLIENT_GET_PRIVATE (self);
+
+ g_clear_object (&priv->permissions_cancellable);
+
+ if (!ret) {
+ NML_NMCLIENT_LOG_T (self, "GetPermissions call failed: %s", error->message);
+ return;
+ }
+
+ NML_NMCLIENT_LOG_T (self, "GetPermissions call finished with success");
+
+ /* get list of old permissions for change notification */
+ old_permissions = g_steal_pointer (&priv->permissions);
+ priv->permissions = g_hash_table_new (nm_direct_hash, NULL);
+
+ g_variant_get (ret, "(a{ss})", &v_permissions);
+ while (g_variant_iter_next (v_permissions, "{&s&s}", &pkey, &pvalue)) {
+ NMClientPermission perm;
+ NMClientPermissionResult perm_result;
+
+ perm = nm_permission_to_client (pkey);
+ if (perm == NM_CLIENT_PERMISSION_NONE)
+ continue;
+
+ perm_result = nm_permission_result_to_client (pvalue);
+
+ g_hash_table_insert (priv->permissions,
+ GUINT_TO_POINTER (perm),
+ GUINT_TO_POINTER (perm_result));
+ if (old_permissions) {
+ g_hash_table_remove (old_permissions,
+ GUINT_TO_POINTER (perm));
+ }
+ }
+
+ dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->main_context);
+ _emit_permissions_changed (self, priv->permissions, FALSE);
+ _emit_permissions_changed (self, old_permissions, TRUE);
+}
+
+static void
+_dbus_check_permissions_start (NMClient *self)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+
+ nm_clear_g_cancellable (&priv->permissions_cancellable);
+ priv->permissions_cancellable = g_cancellable_new ();
+
+ NML_NMCLIENT_LOG_T (self, "GetPermissions() call started...");
+
+ _nm_client_dbus_call_simple (self,
+ priv->permissions_cancellable,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "GetPermissions",
+ g_variant_new ("()"),
+ G_VARIANT_TYPE ("(a{ss})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ _dbus_check_permissions_start_cb,
+ self);
+}
+
+static void
+_dbus_nm_check_permissions_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *signal_interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("()"))) {
+ NML_NMCLIENT_LOG_E (self, "ignore CheckPermissions signal with unexpected signature %s",
+ g_variant_get_type_string (parameters));
+ return;
+ }
+
+ _dbus_check_permissions_start (self);
+}
+
+/*****************************************************************************/
+
+static void
+_property_ao_notify_changed_connections_cb (NMLDBusPropertyAO *pr_ao,
+ NMClient *self,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */)
+{
+ _nm_client_notify_event_queue_emit_obj_signal (self,
+ G_OBJECT (self),
+ nmobj,
+ is_added,
+ 5,
+ is_added
+ ? signals[CONNECTION_ADDED]
+ : signals[CONNECTION_REMOVED]);
+}
+
+static void
+_property_ao_notify_changed_all_devices_cb (NMLDBusPropertyAO *pr_ao,
+ NMClient *self,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */)
+{
+ _nm_client_notify_event_queue_emit_obj_signal (self,
+ G_OBJECT (self),
+ nmobj,
+ is_added,
+ 6,
+ is_added
+ ? signals[ANY_DEVICE_ADDED]
+ : signals[ANY_DEVICE_REMOVED]);
+}
+
+static void
+_property_ao_notify_changed_devices_cb (NMLDBusPropertyAO *pr_ao,
+ NMClient *self,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */)
+{
+ _nm_client_notify_event_queue_emit_obj_signal (self,
+ G_OBJECT (self),
+ nmobj,
+ is_added,
+ 7,
+ is_added
+ ? signals[DEVICE_ADDED]
+ : signals[DEVICE_REMOVED]);
+}
+
+static void
+_property_ao_notify_changed_active_connections_cb (NMLDBusPropertyAO *pr_ao,
+ NMClient *self,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */)
+{
+ _nm_client_notify_event_queue_emit_obj_signal (self,
+ G_OBJECT (self),
+ nmobj,
+ is_added,
+ 8,
+ is_added
+ ? signals[ACTIVE_CONNECTION_ADDED]
+ : signals[ACTIVE_CONNECTION_REMOVED]);
+}
+
+/*****************************************************************************/
+
+typedef struct {
+ NMLDBusObjWatcherWithPtr *obj_watcher;
+ const char *op_name;
+ NMLDBusObject *dbobj;
+ GTask *task;
+ GVariant *extra_results;
+ gpointer result;
+ GType gtype;
+ gulong cancellable_id;
+} RequestWaitData;
+
+static void
+_request_wait_data_free (RequestWaitData *request_data)
+{
+ nm_assert (!request_data->obj_watcher);
+ nm_assert (request_data->cancellable_id == 0);
+ nm_assert (!request_data->task || G_IS_TASK (request_data->task));
+
+ nm_g_object_unref (request_data->task);
+ nm_g_object_unref (request_data->result);
+ nm_g_variant_unref (request_data->extra_results);
+ if (request_data->dbobj)
+ nml_dbus_object_unref (request_data->dbobj);
+ nm_g_slice_free (request_data);
+}
+
+static void
+_request_wait_task_return (RequestWaitData *request_data)
+{
+ gs_unref_object GTask *task = NULL;
+
+ nm_assert (request_data);
+ nm_assert (G_IS_TASK (request_data->task));
+ nm_assert (request_data->dbobj);
+ nm_assert (NM_IS_OBJECT (request_data->dbobj->nmobj));
+ nm_assert (!request_data->result);
+
+ task = g_steal_pointer (&request_data->task);
+
+ request_data->result = g_object_ref (request_data->dbobj->nmobj);
+ nm_clear_g_signal_handler (g_task_get_cancellable (task), &request_data->cancellable_id);
+ nm_clear_pointer (&request_data->dbobj, nml_dbus_object_unref);
+ g_task_return_pointer (task, request_data, (GDestroyNotify) _request_wait_data_free);
+}
+
+static gboolean
+_request_wait_complete (NMClient *self,
+ RequestWaitData *request_data,
+ gboolean force_complete)
+{
+ NMLDBusObject *dbobj;
+
+ nm_assert (request_data);
+ nm_assert (!request_data->result);
+ nm_assert (!request_data->obj_watcher);
+ nm_assert (request_data->dbobj);
+
+ dbobj = request_data->dbobj;
+
+ if (dbobj->obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE) {
+ NML_NMCLIENT_LOG_D (self, "%s() succeeded with %s", request_data->op_name, dbobj->dbus_path->str);
+ nm_assert (G_TYPE_CHECK_INSTANCE_TYPE (dbobj->nmobj, request_data->gtype));
+ _request_wait_task_return (request_data);
+ return TRUE;
+ }
+
+ if ( force_complete
+ || dbobj->obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY) {
+ if (force_complete)
+ NML_NMCLIENT_LOG_D (self, "%s() succeeded with %s but object is in an unsuitable state", request_data->op_name, dbobj->dbus_path->str);
+ else
+ NML_NMCLIENT_LOG_W (self, "%s() succeeded with %s but object is in an unsuitable state", request_data->op_name, dbobj->dbus_path->str);
+
+ g_task_return_error (request_data->task, g_error_new (NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
+ _("request succeeded with %s but object is in an unsuitable state"),
+ dbobj->dbus_path->str));
+ _request_wait_data_free (request_data);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+_request_wait_complete_cb (NMClient *self,
+ NMClientNotifyEventWithPtr *notify_event)
+{
+ _request_wait_complete (self,
+ notify_event->user_data,
+ TRUE);
+}
+
+static void
+_request_wait_obj_watcher_cb (NMClient *self,
+ gpointer obj_watcher_base)
+{
+ NMLDBusObjWatcherWithPtr *obj_watcher = obj_watcher_base;
+ RequestWaitData *request_data = obj_watcher->user_data;
+ NMLDBusObject *dbobj;
+
+ dbobj = request_data->dbobj;
+
+ if (NM_IN_SET ((NMLDBusObjState) dbobj->obj_state, NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY)) {
+ /* Not ready. Wait and watch more. */
+ return;
+ }
+
+ nm_assert (NM_IN_SET ((NMLDBusObjState) dbobj->obj_state, NML_DBUS_OBJ_STATE_WATCHED_ONLY,
+ NML_DBUS_OBJ_STATE_ON_DBUS,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN));
+
+ _dbobjs_obj_watcher_unregister (self, g_steal_pointer (&request_data->obj_watcher));
+
+ nm_clear_g_signal_handler (g_task_get_cancellable (request_data->task), &request_data->cancellable_id);
+
+ _nm_client_notify_event_queue_with_ptr (self,
+ NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER + 30,
+ _request_wait_complete_cb,
+ request_data);
+}
+
+static void
+_request_wait_cancelled_cb (GCancellable *cancellable,
+ gpointer user_data)
+{
+ RequestWaitData *request_data = user_data;
+ NMClient *self;
+ GError *error = NULL;
+
+ nm_assert (cancellable == g_task_get_cancellable (request_data->task));
+
+ nm_utils_error_set_cancelled (&error, FALSE, NULL);
+
+ self = g_task_get_source_object (request_data->task);
+
+ nm_clear_g_signal_handler (cancellable, &request_data->cancellable_id);
+
+ _dbobjs_obj_watcher_unregister (self, g_steal_pointer (&request_data->obj_watcher));
+
+ g_task_return_error (request_data->task, error);
+
+ _request_wait_data_free (request_data);
+}
+
+static void
+_request_wait_start (GTask *task_take,
+ const char *op_name,
+ GType gtype,
+ const char *dbus_path,
+ GVariant *extra_results_take)
+{
+ NMClient *self;
+ gs_unref_object GTask *task = g_steal_pointer (&task_take);
+ RequestWaitData *request_data;
+ GCancellable *cancellable;
+ NMLDBusObject *dbobj;
+
+ nm_assert (G_IS_TASK (task));
+
+ self = g_task_get_source_object (task);
+
+ dbobj = _dbobjs_get_nmobj (self, dbus_path, gtype);
+
+ if (!dbobj) {
+ NML_NMCLIENT_LOG_E (self, "%s() succeeded with %s but object does not exist", op_name, dbus_path);
+ g_task_return_error (task, g_error_new (NM_CLIENT_ERROR,
+ NM_CLIENT_ERROR_FAILED,
+ _("operation succeeded but object %s does not exist"),
+ dbus_path));
+ return;
+ }
+
+ request_data = g_slice_new (RequestWaitData);
+ *request_data = (RequestWaitData) {
+ .task = g_steal_pointer (&task),
+ .op_name = op_name,
+ .gtype = gtype,
+ .dbobj = nml_dbus_object_ref (dbobj),
+ .obj_watcher = NULL,
+ .extra_results = g_steal_pointer (&extra_results_take),
+ .result = NULL,
+ .cancellable_id = 0,
+ };
+
+ if (_request_wait_complete (self, request_data, FALSE))
+ return;
+
+ NML_NMCLIENT_LOG_T (self, "%s() succeeded with %s. Wait for object to become ready", op_name, dbobj->dbus_path->str);
+
+ request_data->obj_watcher = _dbobjs_obj_watcher_register_o (self,
+ dbobj,
+ _request_wait_obj_watcher_cb,
+ sizeof (NMLDBusObjWatcherWithPtr));
+ request_data->obj_watcher->user_data = request_data;
+
+ cancellable = g_task_get_cancellable (request_data->task);
+ if (cancellable) {
+ gulong id;
+
+ id = g_cancellable_connect (cancellable,
+ G_CALLBACK (_request_wait_cancelled_cb),
+ request_data,
+ NULL);
+ if (id == 0) {
+ /* the callback was invoked synchronously, which destroyed @request_data.
+ * We must not touch @info anymore. */
+ } else
+ request_data->cancellable_id = id;
+ }
+}
+
+static gpointer *
+_request_wait_finish (NMClient *client,
+ GAsyncResult *result,
+ gpointer source_tag,
+ GVariant **out_result,
+ GError **error)
+{
+ RequestWaitData *request_data = NULL;
+ gpointer r;
+
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (nm_g_task_is_valid (result, client, source_tag), NULL);
+
+ request_data = g_task_propagate_pointer (G_TASK (result), error);
+ if (!request_data) {
+ NM_SET_OUT (out_result, NULL);
+ return NULL;
+ }
+
+ nm_assert (NM_IS_OBJECT (request_data->result));
+
+ NM_SET_OUT (out_result, g_steal_pointer (&request_data->extra_results));
+ r = g_steal_pointer (&request_data->result);
+
+ _request_wait_data_free (request_data);
+ return r;
+}
+
+/*****************************************************************************/
+
/**
* nm_client_get_dbus_connection:
* @client: a #NMClient
@@ -257,8 +3344,7 @@ nm_client_get_dbus_name_owner (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- /* FIXME(release-blocker): not yet implemented. */
- return NULL;
+ return NM_CLIENT_GET_PRIVATE (client)->name_owner;
}
/**
@@ -274,10 +3360,7 @@ nm_client_get_version (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
-
- return nm_manager_get_version (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.version;
}
/**
@@ -293,10 +3376,7 @@ nm_client_get_state (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NM_STATE_UNKNOWN);
- if (!nm_client_get_nm_running (client))
- return NM_STATE_UNKNOWN;
-
- return nm_manager_get_state (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.state;
}
/**
@@ -313,10 +3393,20 @@ nm_client_get_startup (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
+ return NM_CLIENT_GET_PRIVATE (client)->nm.startup;
+}
- return nm_manager_get_startup (NM_CLIENT_GET_PRIVATE (client)->manager);
+static void
+_set_nm_running (NMClient *self)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ gboolean nm_running;
+
+ nm_running = priv->name_owner && !priv->get_managed_objects_cancellable;
+ if (priv->nm_running != nm_running) {
+ priv->nm_running = nm_running;
+ _notify (self, PROP_NM_RUNNING);
+ }
}
/**
@@ -332,7 +3422,23 @@ nm_client_get_nm_running (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- return NM_CLIENT_GET_PRIVATE (client)->manager != NULL;
+ return NM_CLIENT_GET_PRIVATE (client)->nm_running;
+}
+
+/**
+ * nm_client_get_metered:
+ * @client: a #NMClient
+ *
+ * Returns: whether the default route is metered.
+ *
+ * Since: 1.22
+ */
+NMMetered
+nm_client_get_metered (NMClient *client)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NM_METERED_UNKNOWN);
+
+ return NM_CLIENT_GET_PRIVATE (client)->nm.metered;
}
/**
@@ -348,10 +3454,7 @@ nm_client_networking_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_networking_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.networking_enabled;
}
/**
@@ -371,22 +3474,20 @@ nm_client_networking_get_enabled (NMClient *client)
gboolean
nm_client_networking_set_enabled (NMClient *client, gboolean enable, GError **error)
{
- const char *name_owner;
-
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
/* FIXME(libnm-async-api): add nm_client_networking_set_enabled_async(). */
- name_owner = _nm_client_get_dbus_name_owner (client);
- if (!name_owner) {
- _nm_object_set_error_nm_not_running (error);
- return FALSE;
- }
-
- return _nm_manager_networking_set_enabled (_nm_client_get_dbus_connection (client),
- name_owner,
- enable,
- error);
+ return _nm_client_dbus_call_sync_void (client,
+ NULL,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "Enable",
+ g_variant_new ("(b)", enable),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ TRUE,
+ error);
}
/**
@@ -402,10 +3503,7 @@ nm_client_wireless_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_wireless_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.wireless_enabled;
}
/**
@@ -423,10 +3521,13 @@ nm_client_wireless_set_enabled (NMClient *client, gboolean enabled)
g_return_if_fail (NM_IS_CLIENT (client));
/* FIXME(libnm-async-api): add nm_client_wireless_set_enabled_async(). */
- if (!nm_client_get_nm_running (client))
- return;
- nm_manager_wireless_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
+ _nm_client_set_property_sync_legacy (client,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "WirelessEnabled",
+ "b",
+ enabled);
}
/**
@@ -442,10 +3543,7 @@ nm_client_wireless_hardware_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_wireless_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.wireless_hardware_enabled;
}
/**
@@ -461,10 +3559,7 @@ nm_client_wwan_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_wwan_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.wwan_enabled;
}
/**
@@ -479,10 +3574,14 @@ nm_client_wwan_set_enabled (NMClient *client, gboolean enabled)
{
g_return_if_fail (NM_IS_CLIENT (client));
- if (!_nm_client_check_nm_running (client, NULL))
- return;
+ /* FIXME(libnm-async-api): add nm_client_wwan_set_enabled_async(). */
- nm_manager_wwan_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
+ _nm_client_set_property_sync_legacy (client,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "WwanEnabled",
+ "b",
+ enabled);
}
/**
@@ -498,10 +3597,7 @@ nm_client_wwan_hardware_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_wwan_hardware_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.wwan_hardware_enabled;
}
/**
@@ -572,10 +3668,7 @@ nm_client_connectivity_check_get_available (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_connectivity_check_get_available (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.connectivity_check_available;
}
/**
@@ -593,10 +3686,7 @@ nm_client_connectivity_check_get_enabled (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
- if (!nm_client_get_nm_running (client))
- return FALSE;
-
- return nm_manager_connectivity_check_get_enabled (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.connectivity_check_enabled;
}
/**
@@ -615,10 +3705,14 @@ nm_client_connectivity_check_set_enabled (NMClient *client, gboolean enabled)
{
g_return_if_fail (NM_IS_CLIENT (client));
- if (!nm_client_get_nm_running (client))
- return;
+ /* FIXME(libnm-async-api): add nm_client_wireless_set_enabled_async(). */
- nm_manager_connectivity_check_set_enabled (NM_CLIENT_GET_PRIVATE (client)->manager, enabled);
+ _nm_client_set_property_sync_legacy (client,
+ NM_DBUS_PATH,
+ NM_DBUS_INTERFACE,
+ "ConnectivityCheckEnabled",
+ "b",
+ enabled);
}
/**
@@ -637,10 +3731,7 @@ nm_client_connectivity_check_get_uri (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
-
- return nm_manager_connectivity_check_get_uri (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.connectivity_check_uri;
}
/**
@@ -672,7 +3763,7 @@ nm_client_get_logging (NMClient *client,
/* FIXME(libnm-async-api): add nm_client_get_logging_async(). */
- ret = _nm_object_dbus_call_sync (client,
+ ret = _nm_client_dbus_call_sync (client,
NULL,
NM_DBUS_PATH,
NM_DBUS_INTERFACE,
@@ -715,7 +3806,7 @@ nm_client_set_logging (NMClient *client, const char *level, const char *domains,
/* FIXME(libnm-async-api): add nm_client_set_logging_async(). */
- return _nm_object_dbus_call_sync_void (client,
+ return _nm_client_dbus_call_sync_void (client,
NULL,
NM_DBUS_PATH,
NM_DBUS_INTERFACE,
@@ -742,12 +3833,19 @@ nm_client_set_logging (NMClient *client, const char *level, const char *domains,
NMClientPermissionResult
nm_client_get_permission_result (NMClient *client, NMClientPermission permission)
{
+ NMClientPrivate *priv;
+ gpointer result;
+
g_return_val_if_fail (NM_IS_CLIENT (client), NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
- if (!nm_client_get_nm_running (client))
+ priv = NM_CLIENT_GET_PRIVATE (client);
+ if ( !priv->permissions
+ || !g_hash_table_lookup_extended (priv->permissions,
+ GUINT_TO_POINTER (permission),
+ NULL,
+ &result))
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
-
- return nm_manager_get_permission_result (NM_CLIENT_GET_PRIVATE (client)->manager, permission);
+ return GPOINTER_TO_UINT (result);
}
/**
@@ -766,10 +3864,7 @@ nm_client_get_connectivity (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN);
- if (!nm_client_get_nm_running (client))
- return NM_CONNECTIVITY_UNKNOWN;
-
- return nm_manager_get_connectivity (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return NM_CLIENT_GET_PRIVATE (client)->nm.connectivity;
}
/**
@@ -794,12 +3889,13 @@ nm_client_check_connectivity (NMClient *client,
GCancellable *cancellable,
GError **error)
{
+ NMClientPrivate *priv;
gs_unref_variant GVariant *ret = NULL;
guint32 connectivity;
g_return_val_if_fail (NM_IS_CLIENT (client), NM_CONNECTIVITY_UNKNOWN);
- ret = _nm_object_dbus_call_sync (client,
+ ret = _nm_client_dbus_call_sync (client,
cancellable,
NM_DBUS_PATH,
NM_DBUS_INTERFACE,
@@ -822,8 +3918,13 @@ nm_client_check_connectivity (NMClient *client,
* "PropertiesChanged" signals).
*
* This is really ugly, we shouldn't do this. */
- _nm_manager_set_connectivity_hack (NM_CLIENT_GET_PRIVATE (client)->manager,
- connectivity);
+
+ priv = NM_CLIENT_GET_PRIVATE (client);
+
+ if (priv->nm.connectivity != connectivity) {
+ priv->nm.connectivity = connectivity;
+ _notify (client, PROP_CONNECTIVITY);
+ }
return connectivity;
}
@@ -849,7 +3950,8 @@ nm_client_check_connectivity_async (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_check_connectivity_async,
cancellable,
callback,
@@ -920,7 +4022,7 @@ nm_client_save_hostname (NMClient *client,
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
- return _nm_object_dbus_call_sync_void (client,
+ return _nm_client_dbus_call_sync_void (client,
cancellable,
NM_DBUS_PATH_SETTINGS,
NM_DBUS_INTERFACE_SETTINGS,
@@ -954,7 +4056,8 @@ nm_client_save_hostname_async (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_save_hostname_async,
cancellable,
callback,
@@ -1012,10 +4115,7 @@ nm_client_get_devices (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return &empty;
-
- return nm_manager_get_devices (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_CLIENT_GET_PRIVATE (client)->nm.devices);
}
/**
@@ -1043,10 +4143,7 @@ nm_client_get_all_devices (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return &empty;
-
- return nm_manager_get_all_devices (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_CLIENT_GET_PRIVATE (client)->nm.all_devices);
}
/**
@@ -1064,10 +4161,7 @@ nm_client_get_device_by_path (NMClient *client, const char *object_path)
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (object_path, NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
-
- return nm_manager_get_device_by_path (NM_CLIENT_GET_PRIVATE (client)->manager, object_path);
+ return _dbobjs_get_nmobj_unpack_visible (client, object_path, NM_TYPE_DEVICE);
}
/**
@@ -1082,13 +4176,21 @@ nm_client_get_device_by_path (NMClient *client, const char *object_path)
NMDevice *
nm_client_get_device_by_iface (NMClient *client, const char *iface)
{
+ const GPtrArray *devices;
+ guint i;
+
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (iface, NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
+ devices = nm_client_get_devices (client);
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *candidate = g_ptr_array_index (devices, i);
+
+ if (nm_streq0 (nm_device_get_iface (candidate), iface))
+ return candidate;
+ }
- return nm_manager_get_device_by_iface (NM_CLIENT_GET_PRIVATE (client)->manager, iface);
+ return NULL;
}
/*****************************************************************************/
@@ -1110,10 +4212,7 @@ nm_client_get_active_connections (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return &empty;
-
- return nm_manager_get_active_connections (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_CLIENT_GET_PRIVATE (client)->nm.active_connections);
}
/**
@@ -1140,10 +4239,7 @@ nm_client_get_primary_connection (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
-
- return nm_manager_get_primary_connection (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return nml_dbus_property_o_get_obj (&NM_CLIENT_GET_PRIVATE (client)->nm.primary_connection);
}
/**
@@ -1162,18 +4258,16 @@ nm_client_get_activating_connection (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
-
- return nm_manager_get_activating_connection (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return nml_dbus_property_o_get_obj (&NM_CLIENT_GET_PRIVATE (client)->nm.activating_connection);
}
+/*****************************************************************************/
+
static void
activate_connection_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
- NMClient *self;
gs_unref_object GTask *task = user_data;
gs_unref_variant GVariant *ret = NULL;
const char *v_active_connection;
@@ -1181,20 +4275,19 @@ activate_connection_cb (GObject *object,
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
if (!ret) {
- g_dbus_error_strip_remote_error (error);
+ if (!nm_utils_error_is_cancelled (error, FALSE))
+ g_dbus_error_strip_remote_error (error);
g_task_return_error (task, error);
return;
}
- self = g_task_get_source_object (task);
-
g_variant_get (ret, "(&o)", &v_active_connection);
- nm_manager_wait_for_active_connection (NM_CLIENT_GET_PRIVATE (self)->manager,
- v_active_connection,
- NULL,
- NULL,
- g_steal_pointer (&task));
+ _request_wait_start (g_steal_pointer (&task),
+ "ActivateConnection",
+ NM_TYPE_ACTIVE_CONNECTION,
+ v_active_connection,
+ NULL);
}
/**
@@ -1256,7 +4349,13 @@ nm_client_activate_connection_async (NMClient *client,
g_return_if_fail (arg_device);
}
- _nm_object_dbus_call (client,
+ NML_NMCLIENT_LOG_T (client, "ActivateConnection() for connection \"%s\", device \"%s\", specific_object \"%s",
+ arg_connection ?: "/",
+ arg_device ?: "/",
+ specific_object ?: "/");
+
+ _nm_client_dbus_call (client,
+ client,
nm_client_activate_connection_async,
cancellable,
callback,
@@ -1290,17 +4389,15 @@ nm_client_activate_connection_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
- nm_auto_free_activate_result _NMActivateResult *r = NULL;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_activate_connection_async), NULL);
-
- r = g_task_propagate_pointer (G_TASK (result), error);
- if (!r)
- return NULL;
- return g_steal_pointer (&r->active);
+ return NM_ACTIVE_CONNECTION (_request_wait_finish (client,
+ result,
+ nm_client_activate_connection_async,
+ NULL,
+ error));
}
+/*****************************************************************************/
+
static void
_add_and_activate_connection_done (GObject *object,
GAsyncResult *result,
@@ -1308,22 +4405,20 @@ _add_and_activate_connection_done (GObject *object,
GTask *task_take)
{
_nm_unused gs_unref_object GTask *task = task_take;
- NMClient *self;
gs_unref_variant GVariant *ret = NULL;
GError *error = NULL;
- const char *v_path;
- const char *v_active_connection;
gs_unref_variant GVariant *v_result = NULL;
+ const char *v_active_connection;
+ const char *v_path;
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
if (!ret) {
- g_dbus_error_strip_remote_error (error);
+ if (!nm_utils_error_is_cancelled (error, FALSE))
+ g_dbus_error_strip_remote_error (error);
g_task_return_error (task, error);
return;
}
- self = g_task_get_source_object (task);
-
if (use_add_and_activate_v2) {
g_variant_get (ret,
"(&o&o@a{sv})",
@@ -1337,11 +4432,11 @@ _add_and_activate_connection_done (GObject *object,
&v_active_connection);
}
- nm_manager_wait_for_active_connection (NM_CLIENT_GET_PRIVATE (self)->manager,
- v_active_connection,
- v_path,
- g_steal_pointer (&v_result),
- g_steal_pointer (&task));
+ _request_wait_start (g_steal_pointer (&task),
+ "AddAndActivateConnection",
+ NM_TYPE_ACTIVE_CONNECTION,
+ v_active_connection,
+ g_steal_pointer (&v_result));
}
static void
@@ -1357,7 +4452,7 @@ _add_and_activate_connection_v2_cb (GObject *object, GAsyncResult *result, gpoin
}
static void
-_add_and_activate_connection (NMClient *client,
+_add_and_activate_connection (NMClient *self,
gboolean is_v2,
NMConnection *partial,
NMDevice *device,
@@ -1372,7 +4467,7 @@ _add_and_activate_connection (NMClient *client,
const char *arg_device = NULL;
gpointer source_tag;
- g_return_if_fail (NM_IS_CLIENT (client));
+ g_return_if_fail (NM_IS_CLIENT (self));
g_return_if_fail (!partial || NM_IS_CONNECTION (partial));
if (device) {
@@ -1401,8 +4496,11 @@ _add_and_activate_connection (NMClient *client,
source_tag = nm_client_add_and_activate_connection_async;
}
+ NML_NMCLIENT_LOG_D (self, "AddAndActivateConnection() started...");
+
if (use_add_and_activate_v2) {
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (self,
+ self,
source_tag,
cancellable,
callback,
@@ -1420,7 +4518,8 @@ _add_and_activate_connection (NMClient *client,
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
_add_and_activate_connection_v2_cb);
} else {
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (self,
+ self,
source_tag,
cancellable,
callback,
@@ -1508,15 +4607,11 @@ nm_client_add_and_activate_connection_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
- nm_auto_free_activate_result _NMActivateResult *r = NULL;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_add_and_activate_connection_async), NULL);
-
- r = g_task_propagate_pointer (G_TASK (result), error);
- if (!r)
- return NULL;
- return g_steal_pointer (&r->active);
+ return NM_ACTIVE_CONNECTION (_request_wait_finish (client,
+ result,
+ nm_client_add_and_activate_connection_async,
+ NULL,
+ error));
}
/**
@@ -1606,20 +4701,15 @@ nm_client_add_and_activate_connection2_finish (NMClient *client,
GVariant **out_result,
GError **error)
{
- nm_auto_free_activate_result _NMActivateResult *r = NULL;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (nm_g_task_is_valid (result, client, nm_client_add_and_activate_connection2), NULL);
-
- r = g_task_propagate_pointer (G_TASK (result), error);
- if (!r) {
- NM_SET_OUT (out_result, NULL);
- return NULL;
- }
- NM_SET_OUT (out_result, g_steal_pointer (&r->add_and_activate_output));
- return g_steal_pointer (&r->active);
+ return NM_ACTIVE_CONNECTION (_request_wait_finish (client,
+ result,
+ nm_client_add_connection2,
+ out_result,
+ error));
}
+/*****************************************************************************/
+
/**
* nm_client_deactivate_connection:
* @client: a #NMClient
@@ -1647,7 +4737,7 @@ nm_client_deactivate_connection (NMClient *client,
active_path = nm_object_get_path (NM_OBJECT (active));
g_return_val_if_fail (active_path, FALSE);
- return _nm_object_dbus_call_sync_void (client,
+ return _nm_client_dbus_call_sync_void (client,
cancellable,
NM_DBUS_PATH,
NM_DBUS_INTERFACE,
@@ -1684,7 +4774,8 @@ nm_client_deactivate_connection_async (NMClient *client,
active_path = nm_object_get_path (NM_OBJECT (active));
g_return_if_fail (active_path);
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_deactivate_connection_async,
cancellable,
callback,
@@ -1740,10 +4831,7 @@ nm_client_get_connections (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return &empty;
-
- return nm_remote_settings_get_connections (NM_CLIENT_GET_PRIVATE (client)->settings);
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_CLIENT_GET_PRIVATE (client)->settings.connections);
}
/**
@@ -1762,13 +4850,20 @@ nm_client_get_connections (NMClient *client)
NMRemoteConnection *
nm_client_get_connection_by_id (NMClient *client, const char *id)
{
+ const GPtrArray *arr;
+ guint i;
+
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (id != NULL, NULL);
+ g_return_val_if_fail (id, NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
+ arr = nm_client_get_connections (client);
+ for (i = 0; i < arr->len; i++) {
+ NMRemoteConnection *c = NM_REMOTE_CONNECTION (arr->pdata[i]);
- return nm_remote_settings_get_connection_by_id (NM_CLIENT_GET_PRIVATE (client)->settings, id);
+ if (nm_streq0 (id, nm_connection_get_id (NM_CONNECTION (c))))
+ return c;
+ }
+ return NULL;
}
/**
@@ -1790,10 +4885,7 @@ nm_client_get_connection_by_path (NMClient *client, const char *path)
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
g_return_val_if_fail (path != NULL, NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
-
- return nm_remote_settings_get_connection_by_path (NM_CLIENT_GET_PRIVATE (client)->settings, path);
+ return _dbobjs_get_nmobj_unpack_visible (client, path, NM_TYPE_REMOTE_CONNECTION);
}
/**
@@ -1812,22 +4904,30 @@ nm_client_get_connection_by_path (NMClient *client, const char *path)
NMRemoteConnection *
nm_client_get_connection_by_uuid (NMClient *client, const char *uuid)
{
+ const GPtrArray *arr;
+ guint i;
+
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (uuid != NULL, NULL);
+ g_return_val_if_fail (uuid, NULL);
- if (!nm_client_get_nm_running (client))
- return NULL;
+ arr = nm_client_get_connections (client);
+ for (i = 0; i < arr->len; i++) {
+ NMRemoteConnection *c = NM_REMOTE_CONNECTION (arr->pdata[i]);
- return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid);
+ if (nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (c))))
+ return c;
+ }
+ return NULL;
}
+/*****************************************************************************/
+
static void
_add_connection_cb (GObject *source,
GAsyncResult *result,
gboolean with_extra_arg,
gpointer user_data)
{
- NMClient *self;
gs_unref_variant GVariant *ret = NULL;
gs_unref_object GTask *task = user_data;
gs_unref_variant GVariant *v_result = NULL;
@@ -1836,7 +4936,8 @@ _add_connection_cb (GObject *source,
ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
if (!ret) {
- g_dbus_error_strip_remote_error (error);
+ if (!nm_utils_error_is_cancelled (error, FALSE))
+ g_dbus_error_strip_remote_error (error);
g_task_return_error (task, error);
return;
}
@@ -1852,12 +4953,11 @@ _add_connection_cb (GObject *source,
&v_path);
}
- self = g_task_get_source_object (task);
-
- nm_remote_settings_wait_for_connection (NM_CLIENT_GET_PRIVATE (self)->settings,
- v_path,
- g_steal_pointer (&v_result),
- g_steal_pointer (&task));
+ _request_wait_start (g_steal_pointer (&task),
+ "AddConnection",
+ NM_TYPE_REMOTE_CONNECTION,
+ v_path,
+ g_steal_pointer (&v_result));
}
static void
@@ -1887,6 +4987,8 @@ _add_connection_call (NMClient *self,
g_return_if_fail (!settings || g_variant_is_of_type (settings, G_VARIANT_TYPE ("a{sa{sv}}")));
g_return_if_fail (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
+ NML_NMCLIENT_LOG_D (self, "AddConnection() started...");
+
if (!settings)
settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
@@ -1896,7 +4998,8 @@ _add_connection_call (NMClient *self,
* on 1.20 API whenever possible. */
if ( ignore_out_result
&& flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
- _nm_object_dbus_call (self,
+ _nm_client_dbus_call (self,
+ self,
source_tag,
cancellable,
callback,
@@ -1911,7 +5014,8 @@ _add_connection_call (NMClient *self,
_add_connection_cb_without_extra_result);
} else if ( ignore_out_result
&& flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
- _nm_object_dbus_call (self,
+ _nm_client_dbus_call (self,
+ self,
source_tag,
cancellable,
callback,
@@ -1925,7 +5029,8 @@ _add_connection_call (NMClient *self,
NM_DBUS_DEFAULT_TIMEOUT_MSEC,
_add_connection_cb_without_extra_result);
} else {
- _nm_object_dbus_call (self,
+ _nm_client_dbus_call (self,
+ self,
source_tag,
cancellable,
callback,
@@ -1945,38 +5050,6 @@ _add_connection_call (NMClient *self,
}
}
-static NMRemoteConnection *
-_add_connection_call_finish (NMClient *client,
- GAsyncResult *result,
- gpointer source_tag,
- GVariant **out_result,
- GError **error)
-{
- nm_auto_free_add_connection_result_data NMAddConnectionResultData *result_data = NULL;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (nm_g_task_is_valid (result, client, source_tag), NULL);
-
- result_data = g_task_propagate_pointer (G_TASK (result), error);
- if (!result_data) {
- NM_SET_OUT (out_result, NULL);
- return NULL;
- }
-
- nm_assert (NM_IS_REMOTE_CONNECTION (result_data->connection));
-
- NM_SET_OUT (out_result, g_steal_pointer (&result_data->extra_results));
- return g_steal_pointer (&result_data->connection);
-}
-
-void
-nm_add_connection_result_data_free (NMAddConnectionResultData *result_data)
-{
- nm_g_object_unref (result_data->connection);
- nm_g_variant_unref (result_data->extra_results);
- nm_g_slice_free (result_data);
-}
-
/**
* nm_client_add_connection_async:
* @client: the %NMClient
@@ -2041,11 +5114,11 @@ nm_client_add_connection_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
- return _add_connection_call_finish (client,
- result,
- nm_client_add_connection_async,
- NULL,
- error);
+ return NM_REMOTE_CONNECTION (_request_wait_finish (client,
+ result,
+ nm_client_add_connection_async,
+ NULL,
+ error));
}
/**
@@ -2112,13 +5185,15 @@ nm_client_add_connection2_finish (NMClient *client,
GVariant **out_result,
GError **error)
{
- return _add_connection_call_finish (client,
- result,
- nm_client_add_connection2,
- out_result,
- error);
+ return NM_REMOTE_CONNECTION (_request_wait_finish (client,
+ result,
+ nm_client_add_connection2,
+ out_result,
+ error));
}
+/*****************************************************************************/
+
/**
* nm_client_load_connections:
* @client: the %NMClient
@@ -2165,7 +5240,7 @@ nm_client_load_connections (NMClient *client,
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
- ret = _nm_object_dbus_call_sync (client,
+ ret = _nm_client_dbus_call_sync (client,
cancellable,
NM_DBUS_PATH_SETTINGS,
NM_DBUS_INTERFACE_SETTINGS,
@@ -2213,7 +5288,8 @@ nm_client_load_connections_async (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_load_connections_async,
cancellable,
callback,
@@ -2293,7 +5369,7 @@ nm_client_reload_connections (NMClient *client,
g_return_val_if_fail (NM_IS_CLIENT (client), FALSE);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
- ret = _nm_object_dbus_call_sync (client,
+ ret = _nm_client_dbus_call_sync (client,
cancellable,
NM_DBUS_PATH_SETTINGS,
NM_DBUS_INTERFACE_SETTINGS,
@@ -2330,7 +5406,8 @@ nm_client_reload_connections_async (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_reload_connections_async,
cancellable,
callback,
@@ -2388,15 +5465,9 @@ nm_client_reload_connections_finish (NMClient *client,
const char *
nm_client_get_dns_mode (NMClient *client)
{
- NMClientPrivate *priv;
-
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- priv = NM_CLIENT_GET_PRIVATE (client);
- if (priv->dns_manager)
- return nm_dns_manager_get_mode (priv->dns_manager);
- else
- return NULL;
+ return NM_CLIENT_GET_PRIVATE (client)->dns_manager.mode;
}
/**
@@ -2413,15 +5484,9 @@ nm_client_get_dns_mode (NMClient *client)
const char *
nm_client_get_dns_rc_manager (NMClient *client)
{
- NMClientPrivate *priv;
-
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- priv = NM_CLIENT_GET_PRIVATE (client);
- if (priv->dns_manager)
- return nm_dns_manager_get_rc_manager (priv->dns_manager);
- else
- return NULL;
+ return NM_CLIENT_GET_PRIVATE (client)->dns_manager.rc_manager;
}
/**
@@ -2440,115 +5505,88 @@ nm_client_get_dns_rc_manager (NMClient *client)
const GPtrArray *
nm_client_get_dns_configuration (NMClient *client)
{
- NMClientPrivate *priv;
-
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- priv = NM_CLIENT_GET_PRIVATE (client);
- if (priv->dns_manager)
- return nm_dns_manager_get_configuration (priv->dns_manager);
- else
- return NULL;
+ return NM_CLIENT_GET_PRIVATE (client)->dns_manager.configuration;
}
-/*****************************************************************************/
-
-static void
-subobject_notify (GObject *object,
- GParamSpec *pspec,
- gpointer client)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_dns_manager_configuration (NMClient *self,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- if (!g_str_has_suffix (pspec->name, "-internal"))
- g_object_notify (client, pspec->name);
-}
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ gs_unref_ptrarray GPtrArray *configuration_old = NULL;
+ gs_unref_ptrarray GPtrArray *configuration_new = NULL;
+
+ nm_assert (G_OBJECT (self) == dbobj->nmobj);
+
+ if (value) {
+ GVariant *entry_var_tmp;
+ GVariantIter iter;
+ GPtrArray *array;
+
+ configuration_new = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_dns_entry_unref);
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "@a{sv}", &entry_var_tmp)) {
+ gs_unref_variant GVariant *entry_var = entry_var_tmp;
+ nm_auto_free_variant_iter GVariantIter *iterp_nameservers = NULL;
+ nm_auto_free_variant_iter GVariantIter *iterp_domains = NULL;
+ gs_free char **nameservers = NULL;
+ gs_free char **domains = NULL;
+ gboolean vpn = FALSE;
+ NMDnsEntry *entry;
+ char *interface = NULL;
+ char *str;
+ gint32 priority = 0;
+
+ if ( !g_variant_lookup (entry_var, "nameservers", "as", &iterp_nameservers)
+ || !g_variant_lookup (entry_var, "priority", "i", &priority)) {
+ g_warning ("Ignoring invalid DNS configuration");
+ continue;
+ }
-static void
-manager_device_added (NMManager *manager,
- NMDevice *device,
- gpointer client)
-{
- g_signal_emit (client, signals[DEVICE_ADDED], 0, device);
-}
+ array = g_ptr_array_new ();
+ while (g_variant_iter_next (iterp_nameservers, "&s", &str))
+ g_ptr_array_add (array, str);
+ g_ptr_array_add (array, NULL);
+ nameservers = (char **) g_ptr_array_free (array, FALSE);
+
+ if (g_variant_lookup (entry_var, "domains", "as", &iterp_domains)) {
+ array = g_ptr_array_new ();
+ while (g_variant_iter_next (iterp_domains, "&s", &str))
+ g_ptr_array_add (array, str);
+ g_ptr_array_add (array, NULL);
+ domains = (char **) g_ptr_array_free (array, FALSE);
+ }
-static void
-manager_device_removed (NMManager *manager,
- NMDevice *device,
- gpointer client)
-{
- g_signal_emit (client, signals[DEVICE_REMOVED], 0, device);
-}
+ g_variant_lookup (entry_var, "interface", "&s", &interface);
+ g_variant_lookup (entry_var, "vpn", "b", &vpn);
-static void
-manager_any_device_added (NMManager *manager,
- NMDevice *device,
- gpointer client)
-{
- g_signal_emit (client, signals[ANY_DEVICE_ADDED], 0, device);
-}
-
-static void
-manager_any_device_removed (NMManager *manager,
- NMDevice *device,
- gpointer client)
-{
- g_signal_emit (client, signals[ANY_DEVICE_REMOVED], 0, device);
-}
+ entry = nm_dns_entry_new (interface,
+ (const char *const*) nameservers,
+ (const char *const*) domains,
+ priority,
+ vpn);
+ if (!entry) {
+ g_warning ("Ignoring invalid DNS entry");
+ continue;
+ }
-static void
-manager_permission_changed (NMManager *manager,
- NMClientPermission permission,
- NMClientPermissionResult result,
- gpointer client)
-{
- g_signal_emit (client, signals[PERMISSION_CHANGED], 0, permission, result);
-}
+ g_ptr_array_add (configuration_new, entry);
+ }
+ }
-static void
-settings_connection_added (NMRemoteSettings *manager,
- NMRemoteConnection *connection,
- gpointer client)
-{
- g_signal_emit (client, signals[CONNECTION_ADDED], 0, connection);
-}
-static void
-settings_connection_removed (NMRemoteSettings *manager,
- NMRemoteConnection *connection,
- gpointer client)
-{
- g_signal_emit (client, signals[CONNECTION_REMOVED], 0, connection);
-}
+ configuration_old = priv->dns_manager.configuration;
+ priv->dns_manager.configuration = g_steal_pointer (&configuration_new);
-static void
-manager_active_connection_added (NMManager *manager,
- NMActiveConnection *active_connection,
- gpointer client)
-{
- g_signal_emit (client, signals[ACTIVE_CONNECTION_ADDED], 0, active_connection);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
-static void
-manager_active_connection_removed (NMManager *manager,
- NMActiveConnection *active_connection,
- gpointer client)
-{
- g_signal_emit (client, signals[ACTIVE_CONNECTION_REMOVED], 0, active_connection);
-}
-
-static void
-dns_notify (GObject *object,
- GParamSpec *pspec,
- gpointer client)
-{
- char pname[128];
-
- if (NM_IN_STRSET (pspec->name,
- NM_DNS_MANAGER_MODE,
- NM_DNS_MANAGER_RC_MANAGER,
- NM_DNS_MANAGER_CONFIGURATION)) {
- nm_sprintf_buf (pname, "dns-%s", pspec->name);
- g_object_notify (client, pname);
- }
-}
+/*****************************************************************************/
/**
* nm_client_get_checkpoints:
@@ -2567,10 +5605,7 @@ nm_client_get_checkpoints (NMClient *client)
{
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- if (!nm_client_get_nm_running (client))
- return &empty;
-
- return nm_manager_get_checkpoints (NM_CLIENT_GET_PRIVATE (client)->manager);
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_CLIENT_GET_PRIVATE (client)->nm.checkpoints);
}
static void
@@ -2597,9 +5632,11 @@ checkpoint_create_cb (GObject *object,
self = g_task_get_source_object (task);
- nm_manager_wait_for_checkpoint (NM_CLIENT_GET_PRIVATE (self)->manager,
- checkpoint_path,
- g_steal_pointer (&task));
+ //
+ (void)self;
+ //nm_manager_wait_for_checkpoint (NM_CLIENT_GET_PRIVATE (self)->manager,
+ // checkpoint_path,
+ // g_steal_pointer (&task));
}
/**
@@ -2642,7 +5679,8 @@ nm_client_checkpoint_create (NMClient *client,
paths[i] = NULL;
}
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_checkpoint_create,
cancellable,
callback,
@@ -2706,7 +5744,8 @@ nm_client_checkpoint_destroy (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (checkpoint_path && checkpoint_path[0] == '/');
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_checkpoint_destroy,
cancellable,
callback,
@@ -2767,7 +5806,8 @@ nm_client_checkpoint_rollback (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (checkpoint_path && checkpoint_path[0] == '/');
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_checkpoint_rollback,
cancellable,
callback,
@@ -2854,7 +5894,8 @@ nm_client_checkpoint_adjust_rollback_timeout (NMClient *client,
g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (checkpoint_path && checkpoint_path[0] == '/');
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_checkpoint_adjust_rollback_timeout,
cancellable,
callback,
@@ -2919,7 +5960,8 @@ nm_client_reload (NMClient *client,
{
g_return_if_fail (NM_IS_CLIENT (client));
- _nm_object_dbus_call (client,
+ _nm_client_dbus_call (client,
+ client,
nm_client_reload,
cancellable,
callback,
@@ -2957,530 +5999,464 @@ nm_client_reload_finish (NMClient *client,
return g_task_propagate_boolean (G_TASK (result), error);
}
-/****************************************************************/
-/* Object Initialization */
-/****************************************************************/
+/*****************************************************************************/
-static GType
-proxy_type (GDBusObjectManagerClient *manager,
- const char *object_path,
- const char *interface_name,
- gpointer user_data)
+static void
+_init_fetch_all (NMClient *self)
{
- /* ObjectManager asks us for an object proxy. Unfortunately, we can't
- * decide that by interface name and GDBusObjectManager doesn't allow
- * us to look at the known interface list. Thus we need to create a
- * generic GDBusObject and only couple a NMObject subclass later. */
- if (!interface_name)
- return G_TYPE_DBUS_OBJECT_PROXY;
-
- /* An interface proxy */
- if (strcmp (interface_name, NM_DBUS_INTERFACE) == 0)
- return NMDBUS_TYPE_MANAGER_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_DEVICE_WIRELESS) == 0)
- return NMDBUS_TYPE_DEVICE_WIFI_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_DEVICE_WIFI_P2P) == 0)
- return NMDBUS_TYPE_DEVICE_WIFI_P2P_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_DEVICE) == 0)
- return NMDBUS_TYPE_DEVICE_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_SETTINGS_CONNECTION) == 0)
- return NMDBUS_TYPE_SETTINGS_CONNECTION_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_SETTINGS) == 0)
- return NMDBUS_TYPE_SETTINGS_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_DNS_MANAGER) == 0)
- return NMDBUS_TYPE_DNS_MANAGER_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_VPN_CONNECTION) == 0)
- return NMDBUS_TYPE_VPN_CONNECTION_PROXY;
- else if (strcmp (interface_name, NM_DBUS_INTERFACE_ACTIVE_CONNECTION) == 0)
- return NMDBUS_TYPE_ACTIVE_CONNECTION_PROXY;
-
- /* Use a generic D-Bus Proxy whenever we can. The typed GDBusProxy
- * subclasses actually use quite some memory, so they're better avoided. */
- return G_TYPE_DBUS_PROXY;
-}
-
-static NMObject *
-obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager *object_manager)
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
+
+ dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context);
+
+ NML_NMCLIENT_LOG_D (self, "fetch all");
+
+ nm_assert (!priv->get_managed_objects_cancellable);
+
+ priv->get_managed_objects_cancellable = g_cancellable_new ();
+
+ priv->dbsid_nm_object_manager = nm_dbus_connection_signal_subscribe_object_manager (priv->dbus_connection,
+ priv->name_owner,
+ "/org/freedesktop",
+ _dbus_managed_objects_changed_cb,
+ self,
+ NULL);
+
+ priv->dbsid_dbus_properties_properties_changed = nm_dbus_connection_signal_subscribe_properties_changed (priv->dbus_connection,
+ priv->name_owner,
+ NULL,
+ NULL,
+ _dbus_properties_changed_cb,
+ self,
+ NULL);
+
+ priv->dbsid_nm_settings_connection_updated = g_dbus_connection_signal_subscribe (priv->dbus_connection,
+ priv->name_owner,
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ "Updated",
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _dbus_settings_updated_cb,
+ self,
+ NULL);
+
+ priv->dbsid_nm_connection_active_state_changed = g_dbus_connection_signal_subscribe (priv->dbus_connection,
+ priv->name_owner,
+ NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
+ "StateChanged",
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _dbus_nm_connection_active_state_changed_cb,
+ self,
+ NULL);
+
+ priv->dbsid_nm_vpn_connection_state_changed = g_dbus_connection_signal_subscribe (priv->dbus_connection,
+ priv->name_owner,
+ NM_DBUS_INTERFACE_VPN_CONNECTION,
+ "VpnStateChanged",
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _dbus_nm_vpn_connection_state_changed_cb,
+ self,
+ NULL);
+
+ priv->dbsid_nm_check_permissions = g_dbus_connection_signal_subscribe (priv->dbus_connection,
+ priv->name_owner,
+ NM_DBUS_INTERFACE,
+ "CheckPermissions",
+ NULL,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ _dbus_nm_check_permissions_cb,
+ self,
+ NULL);
+
+ nm_dbus_connection_call_get_managed_objects (priv->dbus_connection,
+ priv->name_owner,
+ "/org/freedesktop",
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ priv->get_managed_objects_cancellable,
+ _dbus_get_managed_objects_cb,
+ self);
+
+ _dbus_check_permissions_start (self);
+}
+
+static void
+_init_release_all (NMClient *self)
{
- NMClientPrivate *priv;
- GList *interfaces;
- GList *l;
- GType type = G_TYPE_INVALID;
- NMObject *obj_nm;
-
- g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (object), NULL);
-
- interfaces = g_dbus_object_get_interfaces (object);
- for (l = interfaces; l; l = l->next) {
- GDBusProxy *proxy = G_DBUS_PROXY (l->data);
- const char *ifname = g_dbus_proxy_get_interface_name (proxy);
-
- /* This is a performance/scalability hack. It makes sense to call it
- * from here, since this is in the common object creation path. */
- _nm_dbus_proxy_replace_match (proxy);
-
- if (strcmp (ifname, NM_DBUS_INTERFACE) == 0)
- type = NM_TYPE_MANAGER;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_ACCESS_POINT) == 0)
- type = NM_TYPE_ACCESS_POINT;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_ACTIVE_CONNECTION) == 0 && type != NM_TYPE_VPN_CONNECTION)
- type = NM_TYPE_ACTIVE_CONNECTION;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_6LOWPAN) == 0)
- type = NM_TYPE_DEVICE_6LOWPAN;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_ADSL) == 0)
- type = NM_TYPE_DEVICE_ADSL;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_BOND) == 0)
- type = NM_TYPE_DEVICE_BOND;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_BRIDGE) == 0)
- type = NM_TYPE_DEVICE_BRIDGE;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH) == 0)
- type = NM_TYPE_DEVICE_BT;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_DUMMY) == 0)
- type = NM_TYPE_DEVICE_DUMMY;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIRED) == 0)
- type = NM_TYPE_DEVICE_ETHERNET;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_GENERIC) == 0)
- type = NM_TYPE_DEVICE_GENERIC;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_INFINIBAND) == 0)
- type = NM_TYPE_DEVICE_INFINIBAND;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL) == 0)
- type = NM_TYPE_DEVICE_IP_TUNNEL;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MACSEC) == 0)
- type = NM_TYPE_DEVICE_MACSEC;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MACVLAN) == 0)
- type = NM_TYPE_DEVICE_MACVLAN;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_MODEM) == 0)
- type = NM_TYPE_DEVICE_MODEM;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OLPC_MESH) == 0)
- type = NM_TYPE_DEVICE_OLPC_MESH;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE) == 0)
- type = NM_TYPE_DEVICE_OVS_INTERFACE;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OVS_PORT) == 0)
- type = NM_TYPE_DEVICE_OVS_PORT;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE) == 0)
- type = NM_TYPE_DEVICE_OVS_BRIDGE;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIFI_P2P) == 0)
- type = NM_TYPE_DEVICE_WIFI_P2P;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_PPP) == 0)
- type = NM_TYPE_DEVICE_PPP;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TEAM) == 0)
- type = NM_TYPE_DEVICE_TEAM;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_TUN) == 0)
- type = NM_TYPE_DEVICE_TUN;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_VLAN) == 0)
- type = NM_TYPE_DEVICE_VLAN;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WPAN) == 0)
- type = NM_TYPE_DEVICE_WPAN;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_VXLAN) == 0)
- type = NM_TYPE_DEVICE_VXLAN;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIRELESS) == 0)
- type = NM_TYPE_DEVICE_WIFI;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIREGUARD) == 0)
- type = NM_TYPE_DEVICE_WIREGUARD;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP4_CONFIG) == 0)
- type = NM_TYPE_DHCP4_CONFIG;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP6_CONFIG) == 0)
- type = NM_TYPE_DHCP6_CONFIG;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_IP4_CONFIG) == 0)
- type = NM_TYPE_IP4_CONFIG;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_IP6_CONFIG) == 0)
- type = NM_TYPE_IP6_CONFIG;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_WIFI_P2P_PEER) == 0)
- type = NM_TYPE_WIFI_P2P_PEER;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_SETTINGS_CONNECTION) == 0)
- type = NM_TYPE_REMOTE_CONNECTION;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_SETTINGS) == 0)
- type = NM_TYPE_REMOTE_SETTINGS;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_DNS_MANAGER) == 0)
- type = NM_TYPE_DNS_MANAGER;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_VPN_CONNECTION) == 0)
- type = NM_TYPE_VPN_CONNECTION;
- else if (strcmp (ifname, NM_DBUS_INTERFACE_CHECKPOINT) == 0)
- type = NM_TYPE_CHECKPOINT;
-
- if (type != G_TYPE_INVALID)
- break;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ CList **dbus_objects_lst_heads;
+ NMLDBusObject *dbobj;
+ int i;
+
+ NML_NMCLIENT_LOG_D (self, "release all");
+
+ nm_clear_g_cancellable (&priv->permissions_cancellable);
+ nm_clear_g_cancellable (&priv->get_managed_objects_cancellable);
+
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->dbsid_nm_object_manager);
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->dbsid_dbus_properties_properties_changed);
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->dbsid_nm_settings_connection_updated);
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->dbsid_nm_connection_active_state_changed);
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->dbsid_nm_vpn_connection_state_changed);
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->dbsid_nm_check_permissions);
+
+ if (priv->permissions) {
+ gs_unref_hashtable GHashTable *old_permissions = g_steal_pointer (&priv->permissions);
+
+ _emit_permissions_changed (self, old_permissions, TRUE);
}
- g_list_free_full (interfaces, g_object_unref);
- if (type == G_TYPE_INVALID)
- return NULL;
-
- obj_nm = g_object_new (type,
- NM_OBJECT_DBUS_OBJECT, object,
- NM_OBJECT_DBUS_OBJECT_MANAGER, object_manager,
- NULL);
- if (NM_IS_DEVICE (obj_nm)) {
- priv = NM_CLIENT_GET_PRIVATE (self);
- if (G_UNLIKELY (!priv->udev_inited)) {
- priv->udev_inited = TRUE;
- /* for testing, we don't want to use udev in libnm. */
- if (!nm_streq0 (g_getenv ("LIBNM_USE_NO_UDEV"), "1"))
- priv->udev = udev_new ();
+ nm_assert (c_list_is_empty (&priv->dbus_object_changed_lst_head));
+
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready));
+ dbus_objects_lst_heads = ((CList *[]) {
+ &priv->dbus_objects_lst_head_on_dbus,
+ &priv->dbus_objects_lst_head_with_nmobj_not_ready,
+ &priv->dbus_objects_lst_head_with_nmobj_visible,
+ &priv->dbus_objects_lst_head_with_nmobj_hidden,
+ NULL,
+ });
+ for (i = 0; dbus_objects_lst_heads[i]; i++) {
+ c_list_for_each_entry (dbobj, dbus_objects_lst_heads[i], dbus_objects_lst) {
+ NMLDBusObjIfaceData *db_iface_data;
+
+ nm_assert (c_list_is_empty (&dbobj->changed_obj_lst));
+ while ((db_iface_data = c_list_first_entry (&dbobj->iface_lst_head, NMLDBusObjIfaceData, iface_lst)))
+ nm_c_list_move_tail (&dbobj->removed_iface_lst_head, &db_iface_data->iface_lst);
+ c_list_link_tail (&priv->dbus_object_changed_lst_head, &dbobj->changed_obj_lst);
}
- if (priv->udev)
- _nm_device_set_udev (NM_DEVICE (obj_nm), priv->udev);
}
- g_object_set_qdata_full (G_OBJECT (object), _nm_object_obj_nm_quark (),
- obj_nm, g_object_unref);
- return obj_nm;
-}
-static void
-obj_nm_inited (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, NULL)) {
- /* This is a can-not-happen situation, the NMObject subclasses are not
- * supposed to fail initialization. */
- g_warn_if_reached ();
- }
+ _dbus_handle_changes (self, "release-all", FALSE);
+
+ /* We require that when we remove all D-Bus interfaces, that all object will go
+ * away. Note that a NMLDBusObject can be alive due to a NMLDBusObjWatcher, but
+ * even those should be all cleaned up. */
+ nm_assert (c_list_is_empty (&priv->dbus_object_changed_lst_head));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_visible));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_hidden));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_not_ready));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_watched_only));
+ nm_assert (g_hash_table_size (priv->dbus_objects) == 0);
}
+/*****************************************************************************/
+
static void
-object_added (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
+name_owner_changed (NMClient *self,
+ const char *name_owner)
{
- NMClient *client = user_data;
- NMObject *obj_nm;
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ gboolean changed;
+ gs_free char *old_name_owner_free = NULL;
+ const char *old_name_owner;
+ nm_auto_pop_gmaincontext GMainContext *dbus_context = NULL;
- obj_nm = obj_nm_for_gdbus_object (client, object, object_manager);
- if (obj_nm) {
- g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm),
- G_PRIORITY_DEFAULT, NULL,
- obj_nm_inited, NULL);
- }
-}
+ name_owner = nm_str_not_empty (name_owner);
-static void
-object_removed (GDBusObjectManager *object_manager, GDBusObject *object, gpointer user_data)
-{
- g_object_set_qdata (G_OBJECT (object), _nm_object_obj_nm_quark (), NULL);
-}
+ changed = !nm_streq0 (priv->name_owner, name_owner);
-static gboolean
-objects_created (NMClient *client, GDBusObjectManager *object_manager, GError **error)
-{
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
- gs_unref_object GDBusObject *manager = NULL;
- gs_unref_object GDBusObject *settings = NULL;
- gs_unref_object GDBusObject *dns_manager = NULL;
- NMObject *obj_nm;
- GList *objects, *iter;
-
- /* First just ensure all the NMObjects for known GDBusObjects exist. */
- objects = g_dbus_object_manager_get_objects (object_manager);
- for (iter = objects; iter; iter = iter->next)
- obj_nm_for_gdbus_object (client, iter->data, object_manager);
- g_list_free_full (objects, g_object_unref);
-
- manager = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH);
- if (!manager) {
- g_set_error_literal (error,
- NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
- "Manager object not found");
- return FALSE;
- }
+ if ( !name_owner
+ && priv->main_context != priv->dbus_context) {
- obj_nm = g_object_get_qdata (G_OBJECT (manager), _nm_object_obj_nm_quark ());
- if (!obj_nm) {
- g_set_error_literal (error,
- NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
- "Manager object lacks the proper interface");
- return FALSE;
- }
+ NML_NMCLIENT_LOG_D (self, "resync main context as we have no name owner");
- priv->manager = NM_MANAGER (g_object_ref (obj_nm));
-
- g_signal_connect (priv->manager, "notify",
- G_CALLBACK (subobject_notify), client);
- g_signal_connect (priv->manager, "device-added",
- G_CALLBACK (manager_device_added), client);
- g_signal_connect (priv->manager, "device-removed",
- G_CALLBACK (manager_device_removed), client);
- g_signal_connect (priv->manager, "any-device-added",
- G_CALLBACK (manager_any_device_added), client);
- g_signal_connect (priv->manager, "any-device-removed",
- G_CALLBACK (manager_any_device_removed), client);
- g_signal_connect (priv->manager, "permission-changed",
- G_CALLBACK (manager_permission_changed), client);
- g_signal_connect (priv->manager, "active-connection-added",
- G_CALLBACK (manager_active_connection_added), client);
- g_signal_connect (priv->manager, "active-connection-removed",
- G_CALLBACK (manager_active_connection_removed), client);
-
- settings = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH_SETTINGS);
- if (!settings) {
- g_set_error_literal (error,
- NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
- "Settings object not found");
- return FALSE;
- }
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->name_owner_changed_id);
- obj_nm = g_object_get_qdata (G_OBJECT (settings), _nm_object_obj_nm_quark ());
- if (!obj_nm) {
- g_set_error_literal (error,
- NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
- "Settings object lacks the proper interface");
- return FALSE;
- }
+ /* Our instance was initialized synchronously. Usually we must henceforth
+ * stick to a internal main context. But now we have no name-owner...
+ * at this point, we anyway are going to do a full resync. Swap the main
+ * contexts again. */
- priv->settings = NM_REMOTE_SETTINGS (g_object_ref (obj_nm));
-
- g_signal_connect (priv->settings, "notify",
- G_CALLBACK (subobject_notify), client);
- g_signal_connect (priv->settings, "connection-added",
- G_CALLBACK (settings_connection_added), client);
- g_signal_connect (priv->settings, "connection-removed",
- G_CALLBACK (settings_connection_removed), client);
-
- dns_manager = g_dbus_object_manager_get_object (object_manager, NM_DBUS_PATH_DNS_MANAGER);
- if (dns_manager) {
- obj_nm = g_object_get_qdata (G_OBJECT (dns_manager), _nm_object_obj_nm_quark ());
- if (!obj_nm) {
- g_set_error_literal (error,
- NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
- "DNS manager object lacks the proper interface");
- return FALSE;
- }
- priv->dns_manager = NM_DNS_MANAGER (g_object_ref (obj_nm));
+ g_main_context_ref (priv->main_context);
+ g_main_context_unref (priv->dbus_context);
+ priv->dbus_context = priv->main_context;
- g_signal_connect (priv->dns_manager, "notify",
- G_CALLBACK (dns_notify), client);
- }
+ nm_clear_pointer (&priv->dbus_context_integration, nm_g_source_destroy_and_unref);
- /* The handlers don't really use the client instance. However
- * it makes it convenient to unhook them by data. */
- g_signal_connect (object_manager, "object-added",
- G_CALLBACK (object_added), client);
- g_signal_connect (object_manager, "object-removed",
- G_CALLBACK (object_removed), client);
+ dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context);
- return TRUE;
-}
+ /* we need to sync again... */
-/* Synchronous initialization. */
+ _assert_main_context_is_current_thread_default (self, dbus_context);
-static void name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
+ priv->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (priv->dbus_connection,
+ NM_DBUS_SERVICE,
+ name_owner_changed_cb,
+ self,
+ NULL);
+ priv->name_owner_get_cancellable = g_cancellable_new ();
+ nm_dbus_connection_call_get_name_owner (priv->dbus_connection,
+ NM_DBUS_SERVICE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ priv->name_owner_get_cancellable,
+ name_owner_get_cb,
+ self);
+ } else
+ dbus_context = nm_g_main_context_push_thread_default_if_necessary (priv->dbus_context);
-static gboolean
-_om_has_name_owner (GDBusObjectManager *object_manager)
-{
- gs_free char *name_owner = NULL;
+ if (changed) {
+ NML_NMCLIENT_LOG_D (self, "name owner changed: %s%s%s -> %s%s%s",
+ NM_PRINT_FMT_QUOTE_STRING (priv->name_owner),
+ NM_PRINT_FMT_QUOTE_STRING (name_owner));
+ old_name_owner_free = priv->name_owner;
+ priv->name_owner = g_strdup (name_owner);
+ old_name_owner = old_name_owner_free;
+ } else
+ old_name_owner = priv->name_owner;
- nm_assert (G_IS_DBUS_OBJECT_MANAGER_CLIENT (object_manager));
+ if (changed)
+ _notify (self, PROP_DBUS_NAME_OWNER);
- name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (object_manager));
- return !!name_owner;
-}
+ if ( changed
+ && old_name_owner)
+ _init_release_all (self);
+
+ if ( changed
+ && priv->name_owner)
+ _init_fetch_all (self);
-/* Asynchronous initialization. */
+ _set_nm_running (self);
+
+ if (priv->init_data) {
+ nm_auto_pop_gmaincontext GMainContext *main_context = NULL;
+
+ if (priv->main_context != priv->dbus_context)
+ main_context = nm_g_main_context_push_thread_default_if_necessary (priv->main_context);
+ _init_start_check_complete (self);
+ }
+}
static void
-init_async_complete (NMClientInitData *init_data)
+name_owner_changed_cb (GDBusConnection *connection,
+ const char *sender_name,
+ const char *object_path,
+ const char *interface_name,
+ const char *signal_name,
+ GVariant *parameters,
+ gpointer user_data)
{
- if (init_data->pending_init > 0)
+ NMClient *self = user_data;
+ NMClientPrivate *priv;
+ const char *new_owner;
+
+ if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)")))
+ return;
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ if (priv->name_owner_get_cancellable)
return;
- g_simple_async_result_complete (init_data->result);
- g_object_unref (init_data->result);
- g_clear_object (&init_data->cancellable);
- g_slice_free (NMClientInitData, init_data);
+
+ g_variant_get (parameters,
+ "(&s&s&s)",
+ NULL,
+ NULL,
+ &new_owner);
+
+ name_owner_changed (self, new_owner);
}
static void
-async_inited_obj_nm (GObject *object, GAsyncResult *result, gpointer user_data)
+name_owner_get_cb (const char *name_owner,
+ GError *error,
+ gpointer user_data)
{
- NMClientInitData *init_data = user_data;
- GError *error = NULL;
+ NMClient *self;
+ NMClientPrivate *priv;
+
+ if ( !name_owner
+ && nm_utils_error_is_cancelled (error, FALSE))
+ return;
- nm_assert (init_data && init_data->pending_init > 0);
+ self = user_data;
+ priv = NM_CLIENT_GET_PRIVATE (self);
- if (!g_async_initable_init_finish (G_ASYNC_INITABLE (object), result, &error))
- g_simple_async_result_take_error (init_data->result, error);
+ g_clear_object (&priv->name_owner_get_cancellable);
- init_data->pending_init--;
- init_async_complete (init_data);
+ name_owner_changed (self, name_owner);
}
-static void
-init_async (GAsyncInitable *initable, int io_priority,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data);
+/*****************************************************************************/
static void
-unhook_om (NMClient *self)
+_init_start_complete (NMClient *self,
+ GError *error_take)
{
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
- GList *objects, *iter;
+ InitData *init_data;
- if (priv->manager) {
- const GPtrArray *active_connections;
- const GPtrArray *devices;
- int i;
+ init_data = g_steal_pointer (&priv->init_data);
- active_connections = nm_manager_get_active_connections (priv->manager);
- for (i = 0; i < active_connections->len; i++)
- g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active_connections->pdata[i]);
+ NML_NMCLIENT_LOG_D (self, "%s init complete with %s%s%s",
+ init_data->is_sync ? "sync" : "async",
+ NM_PRINT_FMT_QUOTED (error_take, "error: ", error_take->message, "", "success"));
- devices = nm_manager_get_all_devices (priv->manager);
- for (i = 0; i < devices->len; i++)
- g_signal_emit (self, signals[DEVICE_REMOVED], 0, devices->pdata[i]);
+ nm_clear_pointer (&init_data->cancel_on_idle_source, nm_g_source_destroy_and_unref);
+ nm_clear_g_signal_handler (init_data->cancellable, &init_data->cancelled_id);
- g_signal_handlers_disconnect_by_data (priv->manager, self);
- g_clear_object (&priv->manager);
- _notify (self, PROP_ACTIVE_CONNECTIONS);
- _notify (self, PROP_NM_RUNNING);
- }
- if (priv->settings) {
- const GPtrArray *connections;
- guint i;
-
- connections = nm_remote_settings_get_connections (priv->settings);
- for (i = 0; i < connections->len; i++)
- g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connections->pdata[i]);
-
- g_signal_handlers_disconnect_by_data (priv->settings, self);
- g_clear_object (&priv->settings);
- _notify (self, PROP_CONNECTIONS);
- _notify (self, PROP_HOSTNAME);
- _notify (self, PROP_CAN_MODIFY);
- }
- if (priv->dns_manager) {
- g_signal_handlers_disconnect_by_data (priv->dns_manager, self);
- g_clear_object (&priv->dns_manager);
+ if (init_data->is_sync) {
+ if (error_take)
+ g_propagate_error (init_data->data.sync.error_location, error_take);
+ g_main_loop_quit (init_data->data.sync.main_loop);
+ } else {
+ if (error_take)
+ g_task_return_error (init_data->data.async.task, error_take);
+ else
+ g_task_return_boolean (init_data->data.async.task, TRUE);
+ g_object_unref (init_data->data.async.task);
}
-
- objects = g_dbus_object_manager_get_objects (priv->object_manager);
- for (iter = objects; iter; iter = iter->next)
- g_object_set_qdata (iter->data, _nm_object_obj_nm_quark (), NULL);
- g_list_free_full (objects, g_object_unref);
+ nm_g_object_unref (init_data->cancellable);
+ nm_g_slice_free (init_data);
}
static void
-new_object_manager (GObject *source_object, GAsyncResult *res, gpointer user_data)
+_init_start_check_complete (NMClient *self)
{
- NMClient *self = NM_CLIENT (user_data);
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
- g_clear_object (&priv->new_object_manager_cancellable);
- _notify (user_data, PROP_NM_RUNNING);
-}
+ _assert_main_context_is_current_thread_default (self, main_context);
-static void
-got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data)
-{
- NMClientInitData *init_data = user_data;
- NMClient *client;
- NMClientPrivate *priv;
- GList *objects, *iter;
- GError *error = NULL;
- GDBusObjectManager *object_manager;
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready));
+
+ if (!priv->init_data)
+ return;
- object_manager = (gpointer) g_async_initable_new_finish (G_ASYNC_INITABLE (object), result, &error);
- if (object_manager == NULL) {
- g_simple_async_result_take_error (init_data->result, error);
- init_async_complete (init_data);
+ if (priv->get_managed_objects_cancellable) {
+ /* still initializing. Wait. */
return;
}
- nm_assert (G_IS_DBUS_OBJECT_MANAGER_CLIENT (object_manager));
+#if NM_MORE_ASSERTS > 10
+ {
+ NMLDBusObject *dbobj;
- client = init_data->client;
- priv = NM_CLIENT_GET_PRIVATE (client);
- priv->object_manager = object_manager;
- if (!priv->dbus_connection)
- priv->dbus_connection = g_object_ref (g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)));
-
- if (_om_has_name_owner (priv->object_manager)) {
- if (!objects_created (client, priv->object_manager, &error)) {
- g_simple_async_result_take_error (init_data->result, error);
- init_async_complete (init_data);
- return;
+ c_list_for_each_entry (dbobj, &priv->dbus_objects_lst_head_with_nmobj_not_ready, dbus_objects_lst) {
+ NML_NMCLIENT_LOG_T (self, "init-start waiting for %s", dbobj->dbus_path->str);
+ break;
}
+ }
+#endif
+
+ if (!c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_not_ready))
+ return;
- objects = g_dbus_object_manager_get_objects (priv->object_manager);
- for (iter = objects; iter; iter = iter->next) {
- NMObject *obj_nm;
+ _init_start_complete (self, NULL);
+}
- obj_nm = g_object_get_qdata (iter->data, _nm_object_obj_nm_quark ());
- if (!obj_nm)
- continue;
+static void
+_init_start_cancelled_cb (GCancellable *cancellable,
+ gpointer user_data)
+{
+ NMClient *self = user_data;
+ GError *error;
+
+ nm_assert (NM_IS_CLIENT (self));
+ nm_assert (NM_CLIENT_GET_PRIVATE (self)->init_data);
+ nm_assert (NM_CLIENT_GET_PRIVATE (self)->init_data->cancellable == cancellable);
+
+ nm_utils_error_set_cancelled (&error, FALSE, NULL);
+ _init_start_complete (self, error);
+}
- init_data->pending_init++;
- g_async_initable_init_async (G_ASYNC_INITABLE (obj_nm),
- G_PRIORITY_DEFAULT, init_data->cancellable,
- async_inited_obj_nm, init_data);
+static gboolean
+_init_start_cancel_on_idle_cb (gpointer user_data)
+{
+ NMClient *self = user_data;
+ GError *error;
+
+ nm_utils_error_set_cancelled (&error, FALSE, NULL);
+ _init_start_complete (self, error);
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+_init_start_with_bus (NMClient *self)
+{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+
+ if (priv->init_data->cancellable) {
+ priv->init_data->cancelled_id = g_signal_connect (priv->init_data->cancellable,
+ "cancelled",
+ G_CALLBACK (_init_start_cancelled_cb),
+ self);
+ if (g_cancellable_is_cancelled (priv->init_data->cancellable)) {
+ priv->init_data->cancel_on_idle_source = g_idle_source_new ();
+ g_source_set_callback (priv->init_data->cancel_on_idle_source, _init_start_cancel_on_idle_cb, self, NULL);
+ g_source_attach (priv->init_data->cancel_on_idle_source, priv->main_context);
+ return;
}
- g_list_free_full (objects, g_object_unref);
}
- init_async_complete (init_data);
+ _assert_main_context_is_current_thread_default (self, dbus_context);
- g_signal_connect (priv->object_manager, "notify::name-owner",
- G_CALLBACK (name_owner_changed), client);
+ priv->name_owner_changed_id = nm_dbus_connection_signal_subscribe_name_owner_changed (priv->dbus_connection,
+ NM_DBUS_SERVICE,
+ name_owner_changed_cb,
+ self,
+ NULL);
+ priv->name_owner_get_cancellable = g_cancellable_new ();
+ nm_dbus_connection_call_get_name_owner (priv->dbus_connection,
+ NM_DBUS_SERVICE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ priv->name_owner_get_cancellable,
+ name_owner_get_cb,
+ self);
}
static void
-prepare_object_manager (NMClient *client,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+_init_start_bus_get_cb (GObject *source, GAsyncResult *result, gpointer user_data)
{
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
- NMClientInitData *init_data;
- GBusType bus_type = G_BUS_TYPE_NONE;
+ NMClient *self = user_data;
+ NMClientPrivate *priv;
+ GDBusConnection *dbus_connection;
+ GError *error = NULL;
- init_data = g_slice_new0 (NMClientInitData);
- init_data->client = client;
- init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- init_data->result = g_simple_async_result_new (G_OBJECT (client), callback,
- user_data, init_async);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (init_data->result, cancellable);
- g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
+ nm_assert (NM_IS_CLIENT (self));
- if (!priv->dbus_connection)
- bus_type = _nm_dbus_bus_type ();
+ dbus_connection = g_bus_get_finish (result, &error);
- g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
- G_PRIORITY_DEFAULT,
- init_data->cancellable,
- got_object_manager,
- init_data,
- "connection", priv->dbus_connection,
- "bus-type", bus_type,
- "flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
- "name", "org.freedesktop.NetworkManager",
- "object-path", "/org/freedesktop",
- "get-proxy-type-func", proxy_type,
- "get-proxy-type-user-data", NULL,
- "get-proxy-type-destroy-notify", NULL,
- NULL);
+ if (!dbus_connection) {
+ _init_start_complete (self, error);
+ return;
+ }
+
+ priv = NM_CLIENT_GET_PRIVATE (self);
+ priv->dbus_connection = dbus_connection;
+
+ _init_start_with_bus (self);
}
static void
-name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
+_init_start (NMClient *self)
{
- NMClient *self = user_data;
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
- GDBusObjectManager *object_manager = G_DBUS_OBJECT_MANAGER (object);
- nm_assert (object_manager == priv->object_manager);
+ NML_NMCLIENT_LOG_D (self, "starting %s initialization...",
+ priv->init_data->is_sync ? "sync" : "async");
- if (_om_has_name_owner (object_manager)) {
- g_signal_handlers_disconnect_by_data (priv->object_manager, self);
- g_clear_object (&priv->object_manager);
- nm_clear_g_cancellable (&priv->new_object_manager_cancellable);
- priv->new_object_manager_cancellable = g_cancellable_new ();
- prepare_object_manager (self, priv->new_object_manager_cancellable,
- new_object_manager, self);
- } else {
- g_signal_handlers_disconnect_by_func (object_manager, object_added, self);
- unhook_om (self);
+ if (!priv->dbus_connection) {
+ g_bus_get (_nm_dbus_bus_type (),
+ priv->init_data->cancellable,
+ _init_start_bus_get_cb,
+ self);
+ return;
}
+
+ _init_start_with_bus (self);
}
/*****************************************************************************/
@@ -3520,19 +6496,13 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, nm_client_wireless_get_enabled (self));
break;
case PROP_WIRELESS_HARDWARE_ENABLED:
- if (priv->manager)
- g_object_get_property (G_OBJECT (priv->manager), pspec->name, value);
- else
- g_value_set_boolean (value, FALSE);
+ g_value_set_boolean (value, nm_client_wireless_hardware_get_enabled (self));
break;
case PROP_WWAN_ENABLED:
g_value_set_boolean (value, nm_client_wwan_get_enabled (self));
break;
case PROP_WWAN_HARDWARE_ENABLED:
- if (priv->manager)
- g_object_get_property (G_OBJECT (priv->manager), pspec->name, value);
- else
- g_value_set_boolean (value, FALSE);
+ g_value_set_boolean (value, nm_client_wwan_hardware_get_enabled (self));
break;
case PROP_WIMAX_ENABLED:
g_value_set_boolean (value, FALSE);
@@ -3552,6 +6522,9 @@ get_property (GObject *object, guint prop_id,
case PROP_CONNECTIVITY_CHECK_ENABLED:
g_value_set_boolean (value, nm_client_connectivity_check_get_enabled (self));
break;
+ case PROP_CONNECTIVITY_CHECK_URI:
+ g_value_set_string (value, nm_client_connectivity_check_get_uri (self));
+ break;
case PROP_PRIMARY_CONNECTION:
g_value_set_object (value, nm_client_get_primary_connection (self));
break;
@@ -3562,59 +6535,39 @@ get_property (GObject *object, guint prop_id,
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_devices (self)));
break;
case PROP_METERED:
- if (priv->manager)
- g_object_get_property (G_OBJECT (priv->manager), pspec->name, value);
- else
- g_value_set_uint (value, NM_METERED_UNKNOWN);
+ g_value_set_uint (value, nm_client_get_metered (self));
break;
case PROP_ALL_DEVICES:
g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_all_devices (self)));
break;
case PROP_CHECKPOINTS:
- if (priv->manager)
- g_object_get_property (G_OBJECT (priv->manager), pspec->name, value);
- else
- g_value_take_boxed (value, g_ptr_array_new ());
+ g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_checkpoints (self)));
break;
/* Settings properties. */
case PROP_CONNECTIONS:
- if (priv->settings)
- g_object_get_property (G_OBJECT (priv->settings), pspec->name, value);
- else
- g_value_take_boxed (value, _nm_utils_copy_object_array (&empty));
+ g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_connections (self)));
break;
case PROP_HOSTNAME:
- if (priv->settings)
- g_object_get_property (G_OBJECT (priv->settings), pspec->name, value);
- else
- g_value_set_string (value, NULL);
+ g_value_set_string (value, priv->settings.hostname);
break;
case PROP_CAN_MODIFY:
- if (priv->settings)
- g_object_get_property (G_OBJECT (priv->settings), pspec->name, value);
- else
- g_value_set_boolean (value, FALSE);
+ g_value_set_boolean (value, priv->settings.can_modify);
break;
/* DNS properties */
case PROP_DNS_MODE:
+ g_value_set_string (value, nm_client_get_dns_mode (self));
+ break;
case PROP_DNS_RC_MANAGER:
- g_return_if_fail (pspec->name && strlen (pspec->name) > NM_STRLEN ("dns-"));
- if (priv->dns_manager)
- g_object_get_property (G_OBJECT (priv->dns_manager),
- &pspec->name[NM_STRLEN ("dns-")], value);
- else
- g_value_set_string (value, NULL);
+ g_value_set_string (value, nm_client_get_dns_rc_manager (self));
break;
case PROP_DNS_CONFIGURATION:
- if (priv->dns_manager) {
- g_object_get_property (G_OBJECT (priv->dns_manager),
- NM_DNS_MANAGER_CONFIGURATION,
- value);
- } else
- g_value_take_boxed (value, NULL);
+ g_value_take_boxed (value, _nm_utils_copy_array (nm_client_get_dns_configuration (self),
+ (NMUtilsCopyFunc) nm_dns_entry_dup,
+ (GDestroyNotify) nm_dns_entry_unref));
break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -3625,19 +6578,45 @@ static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object);
+ NMClient *self = NM_CLIENT (object);
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+ gboolean b;
switch (prop_id) {
case PROP_DBUS_CONNECTION:
/* construct-only */
priv->dbus_connection = g_value_dup_object (value);
break;
+
case PROP_NETWORKING_ENABLED:
+ b = g_value_get_boolean (value);
+ if (priv->nm.networking_enabled != b) {
+ nm_client_networking_set_enabled (self,
+ b,
+ NULL);
+ /* Let the property value flip when we get the change signal from NM */
+ }
+ break;
case PROP_WIRELESS_ENABLED:
+ b = g_value_get_boolean (value);
+ if (priv->nm.wireless_enabled != b) {
+ nm_client_wireless_set_enabled (self, b);
+ /* Let the property value flip when we get the change signal from NM */
+ }
+ break;
case PROP_WWAN_ENABLED:
+ b = g_value_get_boolean (value);
+ if (priv->nm.wwan_enabled != b) {
+ nm_client_wwan_set_enabled (self, b);
+ /* Let the property value flip when we get the change signal from NM */
+ }
+ break;
case PROP_CONNECTIVITY_CHECK_ENABLED:
- if (priv->manager)
- g_object_set_property (G_OBJECT (priv->manager), pspec->name, value);
+ b = g_value_get_boolean (value);
+ if (priv->nm.connectivity_check_enabled != b) {
+ nm_client_connectivity_check_set_enabled (self, b);
+ /* Let the property value flip when we get the change signal from NM */
+ }
break;
case PROP_WIMAX_ENABLED:
break;
@@ -3652,73 +6631,113 @@ set_property (GObject *object, guint prop_id,
static gboolean
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
{
- NMClient *client = NM_CLIENT (initable);
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
- GList *objects, *iter;
+ gs_unref_object NMClient *self = NULL;
+ NMClientPrivate *priv;
+ GMainContext *dbus_context;
+ GError *local_error = NULL;
+ GMainLoop *main_loop;
- if (!priv->dbus_connection) {
- priv->dbus_connection = g_bus_get_sync (_nm_dbus_bus_type (),
- cancellable,
- error);
- if (!priv->dbus_connection)
- return FALSE;
- }
+ g_return_val_if_fail (NM_IS_CLIENT (initable), FALSE);
- priv->object_manager = g_dbus_object_manager_client_new_sync (priv->dbus_connection,
- G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START,
- "org.freedesktop.NetworkManager",
- "/org/freedesktop",
- proxy_type, NULL, NULL,
- cancellable, error);
- if (!priv->object_manager)
- return FALSE;
+ self = g_object_ref (NM_CLIENT (initable)); /* keep instance alive. */
- if (_om_has_name_owner (priv->object_manager)) {
- if (!objects_created (client, priv->object_manager, error))
- return FALSE;
+ priv = NM_CLIENT_GET_PRIVATE (self);
- objects = g_dbus_object_manager_get_objects (priv->object_manager);
- for (iter = objects; iter; iter = iter->next) {
- NMObject *obj_nm;
+ g_return_val_if_fail (!priv->dbus_context, FALSE);
- obj_nm = g_object_get_qdata (iter->data, _nm_object_obj_nm_quark ());
- if (!obj_nm)
- continue;
+ /* when using init_sync(), we use a separate internal GMainContext for
+ * all D-Bus operations and use our regular async-init code. That means,
+ * also in sync-init, we don't actually block waiting for our D-Bus requests,
+ * instead, we only block (g_main_loop_run()) for the overall result.
+ *
+ * Doing this has a performance overhead. Also, we cannot ever fall back
+ * to the regular main-context (not unless we lose the main-owner and
+ * need to re-initialize). The reason is that we receive events on our
+ * dbus_context, and this cannot be brought in sync -- short of full
+ * reinitalizing. Therefor, using sync init not only is slower during
+ * construction of the object, but NMClient will stick to the dual GMainContext
+ * mode.
+ *
+ * Aside from this downside, the solution is good:
+ *
+ * - we don't duplicate the implementation of async-init.
+ * - we don't iterate the main-context of the caller while waiting for
+ * initialization to happen
+ * - we still invoke all changes under the main_context of the caller.
+ * - all D-Bus events strictly go through dbus_context and are in order.
+ */
- if (!g_initable_init (G_INITABLE (obj_nm), cancellable, NULL)) {
- /* This is a can-not-happen situation, the NMObject subclasses are not
- * supposed to fail initialization. */
- g_warn_if_reached ();
- }
- }
- g_list_free_full (objects, g_object_unref);
+ dbus_context = g_main_context_new ();
+ priv->dbus_context = g_main_context_ref (dbus_context);
+
+ g_main_context_push_thread_default (dbus_context);
+
+ main_loop = g_main_loop_new (dbus_context, FALSE);
+
+ priv->init_data = _init_data_new_sync (cancellable, main_loop, &local_error);
+
+ _init_start (self);
+
+ g_main_loop_run (main_loop);
+
+ g_main_loop_unref (main_loop);
+
+ g_main_context_pop_thread_default (dbus_context);
+
+ if (priv->main_context != priv->dbus_context) {
+ priv->dbus_context_integration = nm_utils_g_main_context_create_integrate_source (priv->dbus_context);
+ g_source_attach (priv->dbus_context_integration, priv->main_context);
}
- g_signal_connect (priv->object_manager, "notify::name-owner",
- G_CALLBACK (name_owner_changed), client);
+ g_main_context_unref (dbus_context);
+ if (local_error) {
+ g_propagate_error (error, local_error);
+ return FALSE;
+ }
return TRUE;
}
/*****************************************************************************/
static void
-init_async (GAsyncInitable *initable, int io_priority,
- GCancellable *cancellable, GAsyncReadyCallback callback,
+init_async (GAsyncInitable *initable,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
gpointer user_data)
{
- prepare_object_manager (NM_CLIENT (initable), cancellable, callback, user_data);
+ NMClientPrivate *priv;
+ NMClient *self;
+ nm_auto_pop_gmaincontext GMainContext *context = NULL;
+ GTask *task;
+
+ g_return_if_fail (NM_IS_CLIENT (initable));
+
+ self = NM_CLIENT (initable);
+ priv = NM_CLIENT_GET_PRIVATE (self);
+
+ g_return_if_fail (!priv->dbus_context);
+
+ priv->dbus_context = g_main_context_ref (priv->main_context);
+
+ context = nm_g_main_context_push_thread_default_if_necessary (priv->main_context);
+
+ task = nm_g_task_new (self, cancellable, init_async, callback, user_data);
+ g_task_set_priority (task, io_priority);
+
+ priv->init_data = _init_data_new_async (cancellable, g_steal_pointer (&task));
+
+ _init_start (self);
}
static gboolean
init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+ g_return_val_if_fail (NM_IS_CLIENT (initable), FALSE);
+ g_return_val_if_fail (nm_g_task_is_valid (result, initable, init_async), FALSE);
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
- else
- return TRUE;
+ return g_task_propagate_boolean (G_TASK (result), error);
}
/*****************************************************************************/
@@ -3726,6 +6745,20 @@ init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
static void
nm_client_init (NMClient *self)
{
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
+
+ c_list_init (&self->obj_base.queue_notify_lst);
+ c_list_init (&priv->queue_notify_lst_head);
+ c_list_init (&priv->notify_event_lst_head);
+
+ priv->dbus_objects = g_hash_table_new (nm_pdirect_hash, nm_pdirect_equal);
+ c_list_init (&priv->dbus_objects_lst_head_watched_only);
+ c_list_init (&priv->dbus_objects_lst_head_on_dbus);
+ c_list_init (&priv->dbus_objects_lst_head_with_nmobj_not_ready);
+ c_list_init (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready);
+ c_list_init (&priv->dbus_objects_lst_head_with_nmobj_visible);
+ c_list_init (&priv->dbus_objects_lst_head_with_nmobj_hidden);
+ c_list_init (&priv->dbus_object_changed_lst_head);
}
/**
@@ -3808,59 +6841,144 @@ constructed (GObject *object)
priv->main_context = g_main_context_ref_thread_default ();
G_OBJECT_CLASS (nm_client_parent_class)->constructed (object);
+
+ NML_NMCLIENT_LOG_D (self, "new NMClient instance");
}
static void
dispose (GObject *object)
{
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object);
+ NMClient *self = NM_CLIENT (object);
+ NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self);
- nm_clear_g_cancellable (&priv->new_object_manager_cancellable);
+ nm_assert (!priv->init_data);
- if (priv->manager) {
- g_signal_handlers_disconnect_by_data (priv->manager, object);
- g_clear_object (&priv->manager);
- }
+ self->obj_base.is_disposing = TRUE;
- if (priv->settings) {
- g_signal_handlers_disconnect_by_data (priv->settings, object);
- g_clear_object (&priv->settings);
- }
+ nm_clear_g_cancellable (&priv->name_owner_get_cancellable);
- if (priv->dns_manager) {
- g_signal_handlers_disconnect_by_data (priv->dns_manager, object);
- g_clear_object (&priv->dns_manager);
- }
+ nm_clear_g_dbus_connection_signal (priv->dbus_connection,
+ &priv->name_owner_changed_id);
- if (priv->object_manager) {
- GList *objects, *iter;
+ nm_clear_g_free (&priv->name_owner);
- /* Unhook the NM objects. */
- objects = g_dbus_object_manager_get_objects (priv->object_manager);
- for (iter = objects; iter; iter = iter->next)
- g_object_set_qdata (G_OBJECT (iter->data), _nm_object_obj_nm_quark (), NULL);
- g_list_free_full (objects, g_object_unref);
+ _init_release_all (self);
- g_signal_handlers_disconnect_by_data (priv->object_manager, object);
- g_clear_object (&priv->object_manager);
- }
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_watched_only));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_on_dbus));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_not_ready));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_maybe_ready));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_visible));
+ nm_assert (c_list_is_empty (&priv->dbus_objects_lst_head_with_nmobj_hidden));
+
+ nm_assert (c_list_is_empty (&priv->queue_notify_lst_head));
+ nm_assert (c_list_is_empty (&priv->notify_event_lst_head));
+ nm_assert (c_list_is_empty (&self->obj_base.queue_notify_lst));
+ nm_assert (!priv->dbus_objects || g_hash_table_size (priv->dbus_objects) == 0);
+
+ nml_dbus_property_o_clear (&priv->nm.activating_connection, NULL);
+ nml_dbus_property_o_clear (&priv->nm.primary_connection, NULL);
+ nml_dbus_property_ao_clear (&priv->nm.devices, NULL);
+ nml_dbus_property_ao_clear (&priv->nm.all_devices, NULL);
+ nml_dbus_property_ao_clear (&priv->nm.active_connections, NULL);
+ nml_dbus_property_ao_clear (&priv->nm.checkpoints, NULL);
+
+ nm_clear_g_free (&priv->nm.connectivity_check_uri);
+ nm_clear_g_free (&priv->nm.version);
+
+ nml_dbus_property_ao_clear (&priv->settings.connections, NULL);
+ nm_clear_g_free (&priv->settings.hostname);
+
+ nm_clear_pointer (&priv->dns_manager.configuration, g_ptr_array_unref);
+ nm_clear_g_free (&priv->dns_manager.mode);
+ nm_clear_g_free (&priv->dns_manager.rc_manager);
+
+ nm_clear_pointer (&priv->dbus_objects, g_hash_table_destroy);
G_OBJECT_CLASS (nm_client_parent_class)->dispose (object);
nm_clear_pointer (&priv->udev, udev_unref);
+ nm_clear_pointer (&priv->dbus_context_integration, nm_g_source_destroy_and_unref);
+ nm_clear_pointer (&priv->dbus_context, g_main_context_unref);
nm_clear_pointer (&priv->main_context, g_main_context_unref);
+ nm_clear_pointer (&priv->permissions, g_hash_table_unref);
+
g_clear_object (&priv->dbus_connection);
- nm_clear_g_free (&priv->name_owner_cached);
+ nm_clear_g_free (&priv->name_owner);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager = NML_DBUS_META_IFACE_INIT (
+ NM_DBUS_INTERFACE_AGENT_MANAGER,
+ NULL,
+ NML_DBUS_META_INTERFACE_PRIO_NONE,
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE,
+ nm_client_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("ActivatingConnection", PROP_ACTIVATING_CONNECTION, NMClient, _priv.nm.activating_connection, nm_active_connection_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("ActiveConnections", PROP_ACTIVE_CONNECTIONS, NMClient, _priv.nm.active_connections, nm_active_connection_get_type, .notify_changed_ao = _property_ao_notify_changed_active_connections_cb ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("AllDevices", PROP_ALL_DEVICES, NMClient, _priv.nm.all_devices, nm_device_get_type, .notify_changed_ao = _property_ao_notify_changed_all_devices_cb ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("Capabilities", "au" ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Checkpoints", PROP_CHECKPOINTS, NMClient, _priv.nm.checkpoints, nm_checkpoint_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Connectivity", PROP_CONNECTIVITY, NMClient, _priv.nm.connectivity ),
+ NML_DBUS_META_PROPERTY_INIT_B ("ConnectivityCheckAvailable", PROP_CONNECTIVITY_CHECK_AVAILABLE, NMClient, _priv.nm.connectivity_check_available ),
+ NML_DBUS_META_PROPERTY_INIT_B ("ConnectivityCheckEnabled", PROP_CONNECTIVITY_CHECK_ENABLED, NMClient, _priv.nm.connectivity_check_enabled ),
+ NML_DBUS_META_PROPERTY_INIT_S ("ConnectivityCheckUri", PROP_CONNECTIVITY_CHECK_URI, NMClient, _priv.nm.connectivity_check_uri ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Devices", PROP_DEVICES, NMClient, _priv.nm.devices, nm_device_get_type, .notify_changed_ao = _property_ao_notify_changed_devices_cb ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("GlobalDnsConfiguration", "a{sv}" ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Metered", PROP_METERED, NMClient, _priv.nm.metered ),
+ NML_DBUS_META_PROPERTY_INIT_B ("NetworkingEnabled", PROP_NETWORKING_ENABLED, NMClient, _priv.nm.networking_enabled ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("PrimaryConnection", PROP_PRIMARY_CONNECTION, NMClient, _priv.nm.primary_connection, nm_active_connection_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("PrimaryConnectionType", "s" ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Startup", PROP_STARTUP, NMClient, _priv.nm.startup ),
+ NML_DBUS_META_PROPERTY_INIT_U ("State", PROP_STATE, NMClient, _priv.nm.state ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Version", PROP_VERSION, NMClient, _priv.nm.version ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("WimaxEnabled", "b" ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("WimaxHardwareEnabled", "b" ),
+ NML_DBUS_META_PROPERTY_INIT_B ("WirelessEnabled", PROP_WIRELESS_ENABLED, NMClient, _priv.nm.wireless_enabled ),
+ NML_DBUS_META_PROPERTY_INIT_B ("WirelessHardwareEnabled", PROP_WIRELESS_HARDWARE_ENABLED, NMClient, _priv.nm.wireless_hardware_enabled ),
+ NML_DBUS_META_PROPERTY_INIT_B ("WwanEnabled", PROP_WWAN_ENABLED, NMClient, _priv.nm.wwan_enabled ),
+ NML_DBUS_META_PROPERTY_INIT_B ("WwanHardwareEnabled", PROP_WWAN_HARDWARE_ENABLED, NMClient, _priv.nm.wwan_hardware_enabled ),
+ ),
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_SETTINGS,
+ nm_client_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("CanModify", PROP_CAN_MODIFY, NMClient, _priv.settings.can_modify ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Connections", PROP_CONNECTIONS, NMClient, _priv.settings.connections, nm_remote_connection_get_type, .notify_changed_ao = _property_ao_notify_changed_connections_cb, .check_nmobj_visible_fcn = (gboolean (*) (GObject *)) nm_remote_connection_get_visible ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Hostname", PROP_HOSTNAME, NMClient, _priv.settings.hostname ),
+ ),
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dnsmanager = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DNS_MANAGER,
+ nm_client_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Configuration", PROP_DNS_CONFIGURATION, "aa{sv}", _notify_update_prop_dns_manager_configuration ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Mode", PROP_DNS_MODE, NMClient, _priv.dns_manager.mode ),
+ NML_DBUS_META_PROPERTY_INIT_S ("RcManager", PROP_DNS_RC_MANAGER, NMClient, _priv.dns_manager.rc_manager ),
+ ),
+);
+
static void
nm_client_class_init (NMClientClass *client_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (client_class);
+ _dbus_path_nm = nm_ref_string_new (NM_DBUS_PATH);
+ _dbus_path_settings = nm_ref_string_new (NM_DBUS_PATH_SETTINGS);
+ _dbus_path_dns_manager = nm_ref_string_new (NM_DBUS_PATH_DNS_MANAGER);
+
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->constructed = constructed;
@@ -4081,6 +7199,19 @@ nm_client_class_init (NMClientClass *client_class)
G_PARAM_STATIC_STRINGS);
/**
+ * NMClient:connectivity-check-uri:
+ *
+ * The used URI for connectivity checking.
+ *
+ * Since: 1.22
+ **/
+ obj_properties[PROP_CONNECTIVITY_CHECK_URI] =
+ g_param_spec_string (NM_CLIENT_CONNECTIVITY_CHECK_URI, "", "",
+ NULL,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
* NMClient:primary-connection:
*
* The #NMActiveConnection of the device with the default route;
@@ -4230,7 +7361,9 @@ nm_client_class_init (NMClientClass *client_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm,
+ &_nml_dbus_meta_iface_nm_settings,
+ &_nml_dbus_meta_iface_nm_dnsmanager);
/**
* NMClient::device-added:
diff --git a/libnm/nm-client.h b/libnm/nm-client.h
index 41481f11f7..4c1436f495 100644
--- a/libnm/nm-client.h
+++ b/libnm/nm-client.h
@@ -45,6 +45,7 @@ _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY
#define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections"
#define NM_CLIENT_CONNECTIVITY "connectivity"
+#define NM_CLIENT_CONNECTIVITY_CHECK_URI "connectivity-check-uri"
#define NM_CLIENT_CONNECTIVITY_CHECK_AVAILABLE "connectivity-check-available"
_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY
@@ -224,6 +225,9 @@ NMState nm_client_get_state (NMClient *client);
gboolean nm_client_get_startup (NMClient *client);
gboolean nm_client_get_nm_running (NMClient *client);
+NM_AVAILABLE_IN_1_22
+NMMetered nm_client_get_metered (NMClient *client);
+
gboolean nm_client_networking_get_enabled (NMClient *client);
_NM_DEPRECATED_SYNC_METHOD
diff --git a/libnm/nm-dbus-helpers.c b/libnm/nm-dbus-helpers.c
index 6272dd5820..a27b7e8682 100644
--- a/libnm/nm-dbus-helpers.c
+++ b/libnm/nm-dbus-helpers.c
@@ -27,65 +27,6 @@ _nm_dbus_bus_type (void)
return v;
}
-/* D-Bus has an upper limit on number of Match rules and it's rather easy
- * to hit as the proxy likes to add one for each object. Let's remove the Match
- * rule the proxy added and ensure a less granular rule is present instead.
- *
- * Also, don't do this immediately since it has a performance penalty.
- * Still better than losing the signals altogether.
- *
- * Ideally, we should be able to tell glib not to hook its rules:
- * https://bugzilla.gnome.org/show_bug.cgi?id=758749
- */
-void
-_nm_dbus_proxy_replace_match (GDBusProxy *proxy)
-{
- GDBusConnection *connection = g_dbus_proxy_get_connection (proxy);
- static unsigned match_counter = 1024;
- char *match;
-
- if (match_counter == 1) {
- /* If we hit the low matches watermark, install a
- * less granular one. */
- g_dbus_connection_call (connection,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "AddMatch",
- g_variant_new ("(s)", "type='signal',sender='" NM_DBUS_SERVICE "'"),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL,
- NULL);
- }
-
- if (match_counter)
- match_counter--;
- if (match_counter)
- return;
-
- /* Remove what this proxy added. */
- match = g_strdup_printf ("type='signal',sender='" NM_DBUS_SERVICE "',"
- "interface='%s',path='%s'",
- g_dbus_proxy_get_interface_name (proxy),
- g_dbus_proxy_get_object_path (proxy));
- g_dbus_connection_call (connection,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus",
- "RemoveMatch",
- g_variant_new ("(s)", match),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- -1,
- NULL,
- NULL,
- NULL);
- g_free (match);
-}
-
/* Binds the properties on a generated server-side GDBus object to the
* corresponding properties on the public object.
*/
diff --git a/libnm/nm-dbus-helpers.h b/libnm/nm-dbus-helpers.h
index 5a0fb756ab..f83f2b0d9e 100644
--- a/libnm/nm-dbus-helpers.h
+++ b/libnm/nm-dbus-helpers.h
@@ -16,8 +16,6 @@
GBusType _nm_dbus_bus_type (void);
-void _nm_dbus_proxy_replace_match (GDBusProxy *proxy);
-
void _nm_dbus_bind_properties (gpointer object,
gpointer skeleton);
diff --git a/libnm/nm-device-6lowpan.c b/libnm/nm-device-6lowpan.c
index 25f3932979..5899df3044 100644
--- a/libnm/nm-device-6lowpan.c
+++ b/libnm/nm-device-6lowpan.c
@@ -17,7 +17,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NMDevice *parent;
+ NMLDBusPropertyO parent;
char *hw_address;
} NMDevice6LowpanPrivate;
@@ -49,7 +49,7 @@ nm_device_6lowpan_get_parent (NMDevice6Lowpan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_6LOWPAN (device), NULL);
- return NM_DEVICE_6LOWPAN_GET_PRIVATE (device)->parent;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_6LOWPAN_GET_PRIVATE (device)->parent);
}
/**
@@ -77,7 +77,7 @@ get_hw_address (NMDevice *device)
return nm_device_6lowpan_get_hw_address (NM_DEVICE_6LOWPAN (device));
}
-/***********************************************************/
+/*****************************************************************************/
static void
nm_device_6lowpan_init (NMDevice6Lowpan *device)
@@ -85,31 +85,13 @@ nm_device_6lowpan_init (NMDevice6Lowpan *device)
}
static void
-init_dbus (NMObject *object)
+dispose (GObject *object)
{
NMDevice6LowpanPrivate *priv = NM_DEVICE_6LOWPAN_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_6LOWPAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_6LOWPAN_HW_ADDRESS, &priv->hw_address },
- { NULL },
- };
- NM_OBJECT_CLASS (nm_device_6lowpan_parent_class)->init_dbus (object);
+ G_OBJECT_CLASS (nm_device_6lowpan_parent_class)->dispose (object);
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_6LOWPAN,
- property_info);
-}
-
-static void
-finalize (GObject *object)
-{
- NMDevice6LowpanPrivate *priv = NM_DEVICE_6LOWPAN_GET_PRIVATE (object);
-
- g_free (priv->hw_address);
- g_clear_object (&priv->parent);
-
- G_OBJECT_CLASS (nm_device_6lowpan_parent_class)->finalize (object);
+ nm_clear_g_free (&priv->hw_address);
}
static void
@@ -133,6 +115,16 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_lowpan = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_6LOWPAN,
+ nm_device_6lowpan_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDevice6Lowpan, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDevice6Lowpan, _priv.parent, nm_device_get_type ),
+ ),
+);
+
static void
nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass)
{
@@ -141,9 +133,11 @@ nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass)
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->finalize = finalize;
+ object_class->dispose = dispose;
+
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDevice6Lowpan);
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDevice6LowpanPrivate, parent);
device_class->get_hw_address = get_hw_address;
@@ -173,5 +167,5 @@ nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_lowpan);
}
diff --git a/libnm/nm-device-adsl.c b/libnm/nm-device-adsl.c
index 08174d4063..56ab49edb7 100644
--- a/libnm/nm-device-adsl.c
+++ b/libnm/nm-device-adsl.c
@@ -19,7 +19,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- gboolean carrier;
+ bool carrier;
} NMDeviceAdslPrivate;
struct _NMDeviceAdsl {
@@ -82,22 +82,6 @@ nm_device_adsl_init (NMDeviceAdsl *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_ADSL_CARRIER, &priv->carrier },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_adsl_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_ADSL,
- property_info);
-}
-
-static void
get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -115,17 +99,23 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_adsl = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_ADSL,
+ nm_device_adsl_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceAdsl, _priv.carrier),
+ ),
+);
+
static void
nm_device_adsl_class_init (NMDeviceAdslClass *adsl_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (adsl_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (adsl_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (adsl_class);
object_class->get_property = get_property;
- nm_object_class->init_dbus = init_dbus;
-
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -140,5 +130,5 @@ nm_device_adsl_class_init (NMDeviceAdslClass *adsl_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_adsl);
}
diff --git a/libnm/nm-device-bond.c b/libnm/nm-device-bond.c
index 880c4f94b8..66c1bf8331 100644
--- a/libnm/nm-device-bond.c
+++ b/libnm/nm-device-bond.c
@@ -22,9 +22,9 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ NMLDBusPropertyAO slaves;
char *hw_address;
- gboolean carrier;
- GPtrArray *slaves;
+ bool carrier;
} NMDeviceBondPrivate;
struct _NMDeviceBond {
@@ -90,7 +90,7 @@ nm_device_bond_get_slaves (NMDeviceBond *device)
{
g_return_val_if_fail (NM_IS_DEVICE_BOND (device), FALSE);
- return NM_DEVICE_BOND_GET_PRIVATE (device)->slaves;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_BOND_GET_PRIVATE (device)->slaves);
}
static gboolean
@@ -127,37 +127,6 @@ get_hw_address (NMDevice *device)
static void
nm_device_bond_init (NMDeviceBond *device)
{
- NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (device);
-
- priv->slaves = g_ptr_array_new ();
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_BOND_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_BOND_CARRIER, &priv->carrier },
- { NM_DEVICE_BOND_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_bond_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_BOND,
- property_info);
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceBondPrivate *priv = NM_DEVICE_BOND_GET_PRIVATE (object);
-
- g_clear_pointer (&priv->slaves, g_ptr_array_unref);
-
- G_OBJECT_CLASS (nm_device_bond_parent_class)->dispose (object);
}
static void
@@ -194,18 +163,30 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bond = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_BOND,
+ nm_device_bond_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceBond, _priv.carrier ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceBond, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceBond, _priv.slaves, nm_device_get_type ),
+ ),
+);
+
static void
-nm_device_bond_class_init (NMDeviceBondClass *bond_class)
+nm_device_bond_class_init (NMDeviceBondClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (bond_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bond_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (bond_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceBond);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceBondPrivate, slaves);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -244,5 +225,5 @@ nm_device_bond_class_init (NMDeviceBondClass *bond_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_bond);
}
diff --git a/libnm/nm-device-bridge.c b/libnm/nm-device-bridge.c
index 8c3db03e9c..f50054d4b2 100644
--- a/libnm/nm-device-bridge.c
+++ b/libnm/nm-device-bridge.c
@@ -22,9 +22,9 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ NMLDBusPropertyAO slaves;
char *hw_address;
- gboolean carrier;
- GPtrArray *slaves;
+ bool carrier;
} NMDeviceBridgePrivate;
struct _NMDeviceBridge {
@@ -90,7 +90,7 @@ nm_device_bridge_get_slaves (NMDeviceBridge *device)
{
g_return_val_if_fail (NM_IS_DEVICE_BRIDGE (device), FALSE);
- return NM_DEVICE_BRIDGE_GET_PRIVATE (device)->slaves;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_BRIDGE_GET_PRIVATE (device)->slaves);
}
static gboolean
@@ -132,37 +132,6 @@ get_hw_address (NMDevice *device)
static void
nm_device_bridge_init (NMDeviceBridge *device)
{
- NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (device);
-
- priv->slaves = g_ptr_array_new ();
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_BRIDGE_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_BRIDGE_CARRIER, &priv->carrier },
- { NM_DEVICE_BRIDGE_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_bridge_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_BRIDGE,
- property_info);
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceBridgePrivate *priv = NM_DEVICE_BRIDGE_GET_PRIVATE (object);
-
- g_clear_pointer (&priv->slaves, g_ptr_array_unref);
-
- G_OBJECT_CLASS (nm_device_bridge_parent_class)->dispose (object);
}
static void
@@ -199,18 +168,30 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bridge = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_BRIDGE,
+ nm_device_bridge_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceBridge, _priv.carrier ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceBridge, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceBridge, _priv.slaves, nm_device_get_type ),
+ ),
+);
+
static void
-nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class)
+nm_device_bridge_class_init (NMDeviceBridgeClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (bridge_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bridge_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (bridge_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
- object_class->dispose = dispose;
object_class->finalize = finalize;
object_class->get_property = get_property;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceBridge);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceBridgePrivate, slaves);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -249,5 +230,5 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *bridge_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_bridge);
}
diff --git a/libnm/nm-device-bt.c b/libnm/nm-device-bt.c
index d1600a4277..150b5d84cb 100644
--- a/libnm/nm-device-bt.c
+++ b/libnm/nm-device-bt.c
@@ -184,24 +184,6 @@ nm_device_bt_init (NMDeviceBt *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_BT_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_BT_NAME, &priv->name },
- { NM_DEVICE_BT_CAPABILITIES, &priv->bt_capabilities },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_bt_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_BLUETOOTH,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object);
@@ -236,18 +218,26 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bluetooth = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_BLUETOOTH,
+ nm_device_bt_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_U ("BtCapabilities", PROP_BT_CAPABILITIES, NMDeviceBt, _priv.bt_capabilities ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceBt, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Name", PROP_NAME, NMDeviceBt, _priv.name ),
+ ),
+);
+
static void
nm_device_bt_class_init (NMDeviceBtClass *bt_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (bt_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bt_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (bt_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
@@ -286,5 +276,5 @@ nm_device_bt_class_init (NMDeviceBtClass *bt_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_bluetooth);
}
diff --git a/libnm/nm-device-dummy.c b/libnm/nm-device-dummy.c
index a7f375fdf1..4916cc7d9f 100644
--- a/libnm/nm-device-dummy.c
+++ b/libnm/nm-device-dummy.c
@@ -99,29 +99,13 @@ nm_device_dummy_init (NMDeviceDummy *device)
}
static void
-init_dbus (NMObject *object)
+finalize (GObject *object)
{
NMDeviceDummyPrivate *priv = NM_DEVICE_DUMMY_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_DUMMY_HW_ADDRESS, &priv->hw_address },
- { NULL },
- };
- NM_OBJECT_CLASS (nm_device_dummy_parent_class)->init_dbus (object);
+ g_free (priv->hw_address);
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_DUMMY,
- property_info);
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceDummyPrivate *priv = NM_DEVICE_DUMMY_GET_PRIVATE (object);
-
- g_clear_pointer (&priv->hw_address, g_free);
-
- G_OBJECT_CLASS (nm_device_dummy_parent_class)->dispose (object);
+ G_OBJECT_CLASS (nm_device_dummy_parent_class)->finalize (object);
}
static void
@@ -142,17 +126,23 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_DUMMY,
+ nm_device_dummy_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceDummy, _priv.hw_address ),
+ ),
+);
+
static void
nm_device_dummy_class_init (NMDeviceDummyClass *dummy_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (dummy_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (dummy_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (dummy_class);
object_class->get_property = get_property;
- object_class->dispose = dispose;
-
- nm_object_class->init_dbus = init_dbus;
+ object_class->finalize = finalize;
device_class->connection_compatible = connection_compatible;
device_class->get_hw_address = get_hw_address;
@@ -171,5 +161,5 @@ nm_device_dummy_class_init (NMDeviceDummyClass *dummy_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_dummy);
}
diff --git a/libnm/nm-device-ethernet.c b/libnm/nm-device-ethernet.c
index 94ec318ed6..7cd5b89fc1 100644
--- a/libnm/nm-device-ethernet.c
+++ b/libnm/nm-device-ethernet.c
@@ -25,11 +25,11 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ char **s390_subchannels;
char *hw_address;
char *perm_hw_address;
guint32 speed;
- gboolean carrier;
- char **s390_subchannels;
+ bool carrier;
} NMDeviceEthernetPrivate;
struct _NMDeviceEthernet {
@@ -124,24 +124,12 @@ nm_device_ethernet_get_carrier (NMDeviceEthernet *device)
*
* Since: 1.2
**/
-const char * const *
+const char *const*
nm_device_ethernet_get_s390_subchannels (NMDeviceEthernet *device)
{
g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
- return (const char * const *) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->s390_subchannels;
-}
-
-static guint32
-_subchannels_count_num (const char * const *array)
-{
- int i;
-
- if (!array)
- return 0;
- for (i = 0; array[i]; i++)
- /* NOP */;
- return i;
+ return (const char *const*) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->s390_subchannels;
}
static gboolean
@@ -149,14 +137,14 @@ match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_m
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
const char * const *subchans;
- guint32 num1, num2;
- int i, j;
+ gsize num1, num2;
+ gsize i, j;
*try_mac = TRUE;
subchans = nm_setting_wired_get_s390_subchannels (s_wired);
- num1 = _subchannels_count_num (subchans);
- num2 = _subchannels_count_num ((const char * const *) priv->s390_subchannels);
+ num1 = NM_PTRARRAY_LEN (subchans);
+ num2 = NM_PTRARRAY_LEN (priv->s390_subchannels);
/* connection has no subchannels */
if (num1 == 0)
return TRUE;
@@ -277,26 +265,6 @@ nm_device_ethernet_init (NMDeviceEthernet *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_ETHERNET_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, &priv->perm_hw_address },
- { NM_DEVICE_ETHERNET_SPEED, &priv->speed },
- { NM_DEVICE_ETHERNET_CARRIER, &priv->carrier },
- { NM_DEVICE_ETHERNET_S390_SUBCHANNELS, &priv->s390_subchannels },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_ethernet_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_WIRED,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
@@ -339,18 +307,35 @@ get_property (GObject *object,
}
}
+/* TODO: implemented Veth. */
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth = NML_DBUS_META_IFACE_INIT (
+ NM_DBUS_INTERFACE_DEVICE_VETH,
+ NULL,
+ NML_DBUS_META_INTERFACE_PRIO_NONE,
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_WIRED,
+ nm_device_ethernet_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceEthernet, _priv.carrier ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceEthernet, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_S ("PermHwAddress", PROP_PERM_HW_ADDRESS, NMDeviceEthernet, _priv.perm_hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_AS ("S390Subchannels", PROP_S390_SUBCHANNELS, NMDeviceEthernet, _priv.s390_subchannels ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Speed", PROP_SPEED, NMDeviceEthernet, _priv.speed ),
+ ),
+);
+
static void
nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (eth_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (eth_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (eth_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
@@ -413,5 +398,5 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_wired);
}
diff --git a/libnm/nm-device-generic.c b/libnm/nm-device-generic.c
index f8c4d25737..b1c784757f 100644
--- a/libnm/nm-device-generic.c
+++ b/libnm/nm-device-generic.c
@@ -109,23 +109,6 @@ nm_device_generic_init (NMDeviceGeneric *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_GENERIC_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_GENERIC_TYPE_DESCRIPTION, &priv->type_description },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_generic_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_GENERIC,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceGenericPrivate *priv = NM_DEVICE_GENERIC_GET_PRIVATE (object);
@@ -158,18 +141,25 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_GENERIC,
+ nm_device_generic_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceGeneric, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_S ("TypeDescription", PROP_TYPE_DESCRIPTION, NMDeviceGeneric, _priv.type_description ),
+ ),
+);
+
static void
nm_device_generic_class_init (NMDeviceGenericClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->get_type_description = get_type_description;
device_class->get_hw_address = get_hw_address;
device_class->connection_compatible = connection_compatible;
@@ -198,5 +188,5 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_generic);
}
diff --git a/libnm/nm-device-infiniband.c b/libnm/nm-device-infiniband.c
index b48431a91c..c3e57c9596 100644
--- a/libnm/nm-device-infiniband.c
+++ b/libnm/nm-device-infiniband.c
@@ -21,7 +21,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
typedef struct {
char *hw_address;
- gboolean carrier;
+ bool carrier;
} NMDeviceInfinibandPrivate;
struct _NMDeviceInfiniband {
@@ -127,23 +127,6 @@ nm_device_infiniband_init (NMDeviceInfiniband *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_INFINIBAND_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_INFINIBAND_CARRIER, &priv->carrier },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_infiniband_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_INFINIBAND,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceInfinibandPrivate *priv = NM_DEVICE_INFINIBAND_GET_PRIVATE (object);
@@ -174,18 +157,25 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_INFINIBAND,
+ nm_device_infiniband_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceInfiniband, _priv.carrier ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceInfiniband, _priv.hw_address ),
+ ),
+);
+
static void
nm_device_infiniband_class_init (NMDeviceInfinibandClass *ib_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ib_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ib_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (ib_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
@@ -212,5 +202,5 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *ib_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_infiniband);
}
diff --git a/libnm/nm-device-ip-tunnel.c b/libnm/nm-device-ip-tunnel.c
index 3408dd28f0..2990e204a6 100644
--- a/libnm/nm-device-ip-tunnel.c
+++ b/libnm/nm-device-ip-tunnel.c
@@ -31,18 +31,18 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NMIPTunnelMode mode;
- NMDevice *parent;
+ NMLDBusPropertyO parent;
char *local;
char *remote;
- guint8 ttl;
- guint8 tos;
- gboolean path_mtu_discovery;
char *input_key;
char *output_key;
- guint8 encap_limit;
+ guint32 mode;
guint32 flow_label;
guint32 flags;
+ guint8 ttl;
+ guint8 tos;
+ guint8 encapsulation_limit;
+ bool path_mtu_discovery;
} NMDeviceIPTunnelPrivate;
struct _NMDeviceIPTunnel {
@@ -89,7 +89,7 @@ nm_device_ip_tunnel_get_parent (NMDeviceIPTunnel *device)
{
g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), NULL);
- return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->parent;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->parent);
}
/**
@@ -218,7 +218,7 @@ nm_device_ip_tunnel_get_encapsulation_limit (NMDeviceIPTunnel *device)
{
g_return_val_if_fail (NM_IS_DEVICE_IP_TUNNEL (device), 0);
- return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->encap_limit;
+ return NM_DEVICE_IP_TUNNEL_GET_PRIVATE (device)->encapsulation_limit;
}
/**
@@ -282,33 +282,6 @@ nm_device_ip_tunnel_init (NMDeviceIPTunnel *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_IP_TUNNEL_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_IP_TUNNEL_MODE, &priv->mode },
- { NM_DEVICE_IP_TUNNEL_LOCAL, &priv->local },
- { NM_DEVICE_IP_TUNNEL_REMOTE, &priv->remote },
- { NM_DEVICE_IP_TUNNEL_TTL, &priv->ttl },
- { NM_DEVICE_IP_TUNNEL_TOS, &priv->tos },
- { NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY, &priv->path_mtu_discovery },
- { NM_DEVICE_IP_TUNNEL_INPUT_KEY, &priv->input_key },
- { NM_DEVICE_IP_TUNNEL_OUTPUT_KEY, &priv->output_key },
- { NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT, &priv->encap_limit },
- { NM_DEVICE_IP_TUNNEL_FLOW_LABEL, &priv->flow_label },
- { NM_DEVICE_IP_TUNNEL_FLAGS, &priv->flags },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (object);
@@ -317,7 +290,6 @@ finalize (GObject *object)
g_free (priv->remote);
g_free (priv->input_key);
g_free (priv->output_key);
- g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->finalize (object);
}
@@ -373,17 +345,39 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_iptunnel = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL,
+ nm_device_ip_tunnel_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_Y ("EncapsulationLimit", PROP_ENCAPSULATION_LIMIT, NMDeviceIPTunnel, _priv.encapsulation_limit ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Flags", PROP_FLAGS, NMDeviceIPTunnel, _priv.flags ),
+ NML_DBUS_META_PROPERTY_INIT_U ("FlowLabel", PROP_FLOW_LABEL, NMDeviceIPTunnel, _priv.flow_label ),
+ NML_DBUS_META_PROPERTY_INIT_S ("InputKey", PROP_INPUT_KEY, NMDeviceIPTunnel, _priv.input_key ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Local", PROP_LOCAL, NMDeviceIPTunnel, _priv.local ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Mode", PROP_MODE, NMDeviceIPTunnel, _priv.mode ),
+ NML_DBUS_META_PROPERTY_INIT_S ("OutputKey", PROP_OUTPUT_KEY, NMDeviceIPTunnel, _priv.output_key ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceIPTunnel, _priv.parent, nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_B ("PathMtuDiscovery", PROP_PATH_MTU_DISCOVERY, NMDeviceIPTunnel, _priv.path_mtu_discovery ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Remote", PROP_REMOTE, NMDeviceIPTunnel, _priv.remote ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("Tos", PROP_TOS, NMDeviceIPTunnel, _priv.tos ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("Ttl", PROP_TTL, NMDeviceIPTunnel, _priv.ttl ),
+ ),
+);
+
static void
-nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *bond_class)
+nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (bond_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (bond_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (bond_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceIPTunnel);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceIPTunnelPrivate, parent);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -549,5 +543,5 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *bond_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_iptunnel);
}
diff --git a/libnm/nm-device-macsec.c b/libnm/nm-device-macsec.c
index 59923a8c60..194261f07e 100644
--- a/libnm/nm-device-macsec.c
+++ b/libnm/nm-device-macsec.c
@@ -31,20 +31,20 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NMDevice *parent;
+ NMLDBusPropertyO parent;
char *hw_address;
+ char *validation;
guint64 sci;
guint64 cipher_suite;
- guint8 icv_length;
guint32 window;
+ guint8 icv_length;
guint8 encoding_sa;
- gboolean encrypt;
- gboolean protect;
- gboolean include_sci;
- gboolean es;
- gboolean scb;
- gboolean replay_protect;
- char *validation;
+ bool encrypt;
+ bool protect;
+ bool include_sci;
+ bool es;
+ bool scb;
+ bool replay_protect;
} NMDeviceMacsecPrivate;
struct _NMDeviceMacsec {
@@ -75,7 +75,7 @@ nm_device_macsec_get_parent (NMDeviceMacsec *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACSEC (device), NULL);
- return NM_DEVICE_MACSEC_GET_PRIVATE (device)->parent;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_MACSEC_GET_PRIVATE (device)->parent);
}
/**
@@ -332,42 +332,12 @@ nm_device_macsec_init (NMDeviceMacsec *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_MACSEC_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_MACSEC_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_MACSEC_SCI, &priv->sci },
- { NM_DEVICE_MACSEC_CIPHER_SUITE, &priv->cipher_suite },
- { NM_DEVICE_MACSEC_ICV_LENGTH, &priv->icv_length },
- { NM_DEVICE_MACSEC_WINDOW, &priv->window },
- { NM_DEVICE_MACSEC_ENCODING_SA, &priv->encoding_sa },
- { NM_DEVICE_MACSEC_ENCRYPT, &priv->encrypt },
- { NM_DEVICE_MACSEC_PROTECT, &priv->protect },
- { NM_DEVICE_MACSEC_INCLUDE_SCI, &priv->include_sci },
- { NM_DEVICE_MACSEC_ES, &priv->es },
- { NM_DEVICE_MACSEC_SCB, &priv->scb },
- { NM_DEVICE_MACSEC_REPLAY_PROTECT, &priv->replay_protect },
- { NM_DEVICE_MACSEC_VALIDATION, &priv->validation },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_macsec_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_MACSEC,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (object);
g_free (priv->validation);
g_free (priv->hw_address);
- g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_macsec_parent_class)->finalize (object);
}
@@ -429,17 +399,40 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macsec = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_MACSEC,
+ nm_device_macsec_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_T ("CipherSuite", PROP_CIPHER_SUITE, NMDeviceMacsec, _priv.cipher_suite ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("EncodingSa", PROP_ENCODING_SA, NMDeviceMacsec, _priv.encoding_sa ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Encrypt", PROP_ENCRYPT, NMDeviceMacsec, _priv.encrypt ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Es", PROP_ES, NMDeviceMacsec, _priv.es ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("IcvLength", PROP_ICV_LENGTH, NMDeviceMacsec, _priv.icv_length ),
+ NML_DBUS_META_PROPERTY_INIT_B ("IncludeSci", PROP_INCLUDE_SCI, NMDeviceMacsec, _priv.include_sci ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceMacsec, _priv.parent, nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Protect", PROP_PROTECT, NMDeviceMacsec, _priv.protect ),
+ NML_DBUS_META_PROPERTY_INIT_B ("ReplayProtect", PROP_REPLAY_PROTECT, NMDeviceMacsec, _priv.replay_protect ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Scb", PROP_SCB, NMDeviceMacsec, _priv.scb ),
+ NML_DBUS_META_PROPERTY_INIT_T ("Sci", PROP_SCI, NMDeviceMacsec, _priv.sci ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Validation", PROP_VALIDATION, NMDeviceMacsec, _priv.validation ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Window", PROP_WINDOW, NMDeviceMacsec, _priv.window ),
+ ),
+);
+
static void
-nm_device_macsec_class_init (NMDeviceMacsecClass *macsec_class)
+nm_device_macsec_class_init (NMDeviceMacsecClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (macsec_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (macsec_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (macsec_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceMacsec);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceMacsecPrivate, parent);
device_class->get_hw_address = get_hw_address;
@@ -630,5 +623,5 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *macsec_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_macsec);
}
diff --git a/libnm/nm-device-macvlan.c b/libnm/nm-device-macvlan.c
index 59565b64a1..e703cb5ccf 100644
--- a/libnm/nm-device-macvlan.c
+++ b/libnm/nm-device-macvlan.c
@@ -24,10 +24,10 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NMDevice *parent;
+ NMLDBusPropertyO parent;
char *mode;
- gboolean no_promisc;
- gboolean tap;
+ bool no_promisc;
+ bool tap;
} NMDeviceMacvlanPrivate;
struct _NMDeviceMacvlan {
@@ -58,7 +58,7 @@ nm_device_macvlan_get_parent (NMDeviceMacvlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
- return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->parent;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_MACVLAN_GET_PRIVATE (device)->parent);
}
/**
@@ -181,31 +181,11 @@ nm_device_macvlan_init (NMDeviceMacvlan *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_MACVLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_MACVLAN_MODE, &priv->mode },
- { NM_DEVICE_MACVLAN_NO_PROMISC, &priv->no_promisc },
- { NM_DEVICE_MACVLAN_TAP, &priv->tap },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_macvlan_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_MACVLAN,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
g_free (priv->mode);
- g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_macvlan_parent_class)->finalize (object);
}
@@ -240,17 +220,31 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macvlan = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_MACVLAN,
+ nm_device_macvlan_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("Mode", PROP_MODE, NMDeviceMacvlan, _priv.mode ),
+ NML_DBUS_META_PROPERTY_INIT_B ("NoPromisc", PROP_NO_PROMISC, NMDeviceMacvlan, _priv.no_promisc ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceMacvlan, _priv.parent, nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Tap", PROP_TAP, NMDeviceMacvlan, _priv.tap ),
+ ),
+);
+
static void
-nm_device_macvlan_class_init (NMDeviceMacvlanClass *gre_class)
+nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (gre_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (gre_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (gre_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceMacvlan);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceMacvlanPrivate, parent);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -323,5 +317,5 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *gre_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_macvlan);
}
diff --git a/libnm/nm-device-modem.c b/libnm/nm-device-modem.c
index a56eeb4ada..5e7b064b78 100644
--- a/libnm/nm-device-modem.c
+++ b/libnm/nm-device-modem.c
@@ -25,11 +25,11 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NMDeviceModemCapabilities caps;
- NMDeviceModemCapabilities current_caps;
char *device_id;
char *operator_code;
char *apn;
+ guint32 modem_capabilities;
+ guint32 current_capabilities;
} NMDeviceModemPrivate;
struct _NMDeviceModem {
@@ -62,7 +62,7 @@ nm_device_modem_get_modem_capabilities (NMDeviceModem *self)
{
g_return_val_if_fail (NM_IS_DEVICE_MODEM (self), NM_DEVICE_MODEM_CAPABILITY_NONE);
- return NM_DEVICE_MODEM_GET_PRIVATE (self)->caps;
+ return NM_DEVICE_MODEM_GET_PRIVATE (self)->modem_capabilities;
}
/**
@@ -81,7 +81,7 @@ nm_device_modem_get_current_capabilities (NMDeviceModem *self)
{
g_return_val_if_fail (NM_IS_DEVICE_MODEM (self), NM_DEVICE_MODEM_CAPABILITY_NONE);
- return NM_DEVICE_MODEM_GET_PRIVATE (self)->current_caps;
+ return NM_DEVICE_MODEM_GET_PRIVATE (self)->current_capabilities;
}
/**
@@ -216,26 +216,6 @@ nm_device_modem_init (NMDeviceModem *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_MODEM_MODEM_CAPABILITIES, &priv->caps },
- { NM_DEVICE_MODEM_CURRENT_CAPABILITIES, &priv->current_caps },
- { NM_DEVICE_MODEM_DEVICE_ID, &priv->device_id },
- { NM_DEVICE_MODEM_OPERATOR_CODE, &priv->operator_code },
- { NM_DEVICE_MODEM_APN, &priv->apn },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_modem_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_MODEM,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (object);
@@ -277,18 +257,28 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_modem = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_MODEM,
+ nm_device_modem_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("Apn", PROP_APN, NMDeviceModem, _priv.apn ),
+ NML_DBUS_META_PROPERTY_INIT_U ("CurrentCapabilities", PROP_CURRENT_CAPABILITIES, NMDeviceModem, _priv.current_capabilities ),
+ NML_DBUS_META_PROPERTY_INIT_S ("DeviceId", PROP_DEVICE_ID, NMDeviceModem, _priv.device_id ),
+ NML_DBUS_META_PROPERTY_INIT_U ("ModemCapabilities", PROP_MODEM_CAPABILITIES, NMDeviceModem, _priv.modem_capabilities ),
+ NML_DBUS_META_PROPERTY_INIT_S ("OperatorCode", PROP_OPERATOR_CODE, NMDeviceModem, _priv.operator_code ),
+ ),
+);
+
static void
nm_device_modem_class_init (NMDeviceModemClass *modem_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (modem_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (modem_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (modem_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->get_type_description = get_type_description;
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -354,5 +344,5 @@ nm_device_modem_class_init (NMDeviceModemClass *modem_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_modem);
}
diff --git a/libnm/nm-device-olpc-mesh.c b/libnm/nm-device-olpc-mesh.c
index 4d81abcc53..1ad320bf86 100644
--- a/libnm/nm-device-olpc-mesh.c
+++ b/libnm/nm-device-olpc-mesh.c
@@ -21,8 +21,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ NMLDBusPropertyO companion;
char *hw_address;
- NMDeviceWifi *companion;
guint32 active_channel;
} NMDeviceOlpcMeshPrivate;
@@ -71,7 +71,7 @@ nm_device_olpc_mesh_get_companion (NMDeviceOlpcMesh *device)
{
g_return_val_if_fail (NM_IS_DEVICE_OLPC_MESH (device), NULL);
- return NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->companion;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_OLPC_MESH_GET_PRIVATE (device)->companion);
}
/**
@@ -125,34 +125,6 @@ nm_device_olpc_mesh_init (NMDeviceOlpcMesh *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_OLPC_MESH_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_OLPC_MESH_COMPANION, &priv->companion, NULL, NM_TYPE_DEVICE_WIFI },
- { NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL, &priv->active_channel },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_OLPC_MESH,
- property_info);
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object);
-
- g_clear_object (&priv->companion);
-
- G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object);
@@ -186,18 +158,30 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_olpcmesh = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_OLPC_MESH,
+ nm_device_olpc_mesh_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_U ("ActiveChannel", PROP_ACTIVE_CHANNEL, NMDeviceOlpcMesh, _priv.active_channel ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Companion", PROP_COMPANION, NMDeviceOlpcMesh, _priv.companion, nm_device_wifi_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceOlpcMesh, _priv.hw_address ),
+ ),
+);
+
static void
-nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class)
+nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (olpc_mesh_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (olpc_mesh_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (olpc_mesh_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceOlpcMesh);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceOlpcMeshPrivate, companion);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -236,5 +220,5 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *olpc_mesh_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_olpcmesh);
}
diff --git a/libnm/nm-device-ovs-bridge.c b/libnm/nm-device-ovs-bridge.c
index b37743f361..4b946fca7d 100644
--- a/libnm/nm-device-ovs-bridge.c
+++ b/libnm/nm-device-ovs-bridge.c
@@ -20,7 +20,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- GPtrArray *slaves;
+ NMLDBusPropertyAO slaves;
} NMDeviceOvsBridgePrivate;
struct _NMDeviceOvsBridge {
@@ -55,7 +55,7 @@ nm_device_ovs_bridge_get_slaves (NMDeviceOvsBridge *device)
{
g_return_val_if_fail (NM_IS_DEVICE_OVS_BRIDGE (device), FALSE);
- return NM_DEVICE_OVS_BRIDGE_GET_PRIVATE (device)->slaves;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_OVS_BRIDGE_GET_PRIVATE (device)->slaves);
}
static const char *
@@ -97,22 +97,6 @@ get_setting_type (NMDevice *device)
/*****************************************************************************/
static void
-init_dbus (NMObject *object)
-{
- NMDeviceOvsBridge *device = NM_DEVICE_OVS_BRIDGE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_OVS_BRIDGE_SLAVES, &device->_priv.slaves, NULL, NM_TYPE_DEVICE },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_ovs_bridge_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE,
- property_info);
-}
-
-static void
get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -130,32 +114,34 @@ get_property (GObject *object,
}
}
+/*****************************************************************************/
+
static void
nm_device_ovs_bridge_init (NMDeviceOvsBridge *device)
{
}
-static void
-dispose (GObject *object)
-{
- NMDeviceOvsBridgePrivate *priv = NM_DEVICE_OVS_BRIDGE_GET_PRIVATE (object);
-
- g_clear_pointer (&priv->slaves, g_ptr_array_unref);
-
- G_OBJECT_CLASS (nm_device_ovs_bridge_parent_class)->dispose (object);
-}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsbridge = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE,
+ nm_device_ovs_bridge_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceOvsBridge, _priv.slaves, nm_device_get_type ),
+ ),
+);
static void
-nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *ovs_bridge_class)
+nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (ovs_bridge_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ovs_bridge_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (ovs_bridge_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceOvsBridge);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceOvsBridgePrivate, slaves);
device_class->get_type_description = get_type_description;
device_class->connection_compatible = connection_compatible;
@@ -174,5 +160,5 @@ nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *ovs_bridge_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_ovsbridge);
}
diff --git a/libnm/nm-device-ovs-interface.c b/libnm/nm-device-ovs-interface.c
index c205dd5e7b..a2e3b2cf65 100644
--- a/libnm/nm-device-ovs-interface.c
+++ b/libnm/nm-device-ovs-interface.c
@@ -69,6 +69,12 @@ nm_device_ovs_interface_init (NMDeviceOvsInterface *device)
{
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsinterface = NML_DBUS_META_IFACE_INIT (
+ NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE,
+ nm_device_ovs_interface_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+);
+
static void
nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *ovs_interface_class)
{
diff --git a/libnm/nm-device-ovs-port.c b/libnm/nm-device-ovs-port.c
index ab39ff7100..f8b963b175 100644
--- a/libnm/nm-device-ovs-port.c
+++ b/libnm/nm-device-ovs-port.c
@@ -20,7 +20,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- GPtrArray *slaves;
+ NMLDBusPropertyAO slaves;
} NMDeviceOvsPortPrivate;
struct _NMDeviceOvsPort {
@@ -55,7 +55,7 @@ nm_device_ovs_port_get_slaves (NMDeviceOvsPort *device)
{
g_return_val_if_fail (NM_IS_DEVICE_OVS_PORT (device), FALSE);
- return NM_DEVICE_OVS_PORT_GET_PRIVATE (device)->slaves;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_OVS_PORT_GET_PRIVATE (device)->slaves);
}
static const char *
@@ -97,23 +97,6 @@ get_setting_type (NMDevice *device)
/*****************************************************************************/
static void
-init_dbus (NMObject *object)
-{
- NMDeviceOvsPort *device = NM_DEVICE_OVS_PORT (object);
- NMDeviceOvsPortPrivate *priv = NM_DEVICE_OVS_PORT_GET_PRIVATE (device);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_OVS_PORT_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_ovs_port_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_OVS_PORT,
- property_info);
-}
-
-static void
get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -131,32 +114,34 @@ get_property (GObject *object,
}
}
+/*****************************************************************************/
+
static void
nm_device_ovs_port_init (NMDeviceOvsPort *device)
{
}
-static void
-dispose (GObject *object)
-{
- NMDeviceOvsPortPrivate *priv = NM_DEVICE_OVS_PORT_GET_PRIVATE (object);
-
- g_clear_pointer (&priv->slaves, g_ptr_array_unref);
-
- G_OBJECT_CLASS (nm_device_ovs_port_parent_class)->dispose (object);
-}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsport = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_OVS_PORT,
+ nm_device_ovs_port_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceOvsPort, _priv.slaves, nm_device_get_type ),
+ ),
+);
static void
-nm_device_ovs_port_class_init (NMDeviceOvsPortClass *ovs_port_class)
+nm_device_ovs_port_class_init (NMDeviceOvsPortClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (ovs_port_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (ovs_port_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (ovs_port_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceOvsPort);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceOvsPortPrivate, slaves);
device_class->get_type_description = get_type_description;
device_class->connection_compatible = connection_compatible;
@@ -175,5 +160,5 @@ nm_device_ovs_port_class_init (NMDeviceOvsPortClass *ovs_port_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_ovsport);
}
diff --git a/libnm/nm-device-ppp.c b/libnm/nm-device-ppp.c
index a4ec672310..0484546e58 100644
--- a/libnm/nm-device-ppp.c
+++ b/libnm/nm-device-ppp.c
@@ -6,6 +6,7 @@
#include "nm-default.h"
#include "nm-device-ppp.h"
+
#include "nm-device.h"
/*****************************************************************************/
@@ -27,6 +28,12 @@ nm_device_ppp_init (NMDevicePpp *device)
{
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ppp = NML_DBUS_META_IFACE_INIT (
+ NM_DBUS_INTERFACE_DEVICE_PPP,
+ nm_device_ppp_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+);
+
static void
nm_device_ppp_class_init (NMDevicePppClass *klass)
{
diff --git a/libnm/nm-device-team.c b/libnm/nm-device-team.c
index 08b3b082c1..a1c04c18f8 100644
--- a/libnm/nm-device-team.c
+++ b/libnm/nm-device-team.c
@@ -23,10 +23,10 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ NMLDBusPropertyAO slaves;
char *hw_address;
- gboolean carrier;
- GPtrArray *slaves;
char *config;
+ bool carrier;
} NMDeviceTeamPrivate;
struct _NMDeviceTeam {
@@ -92,7 +92,7 @@ nm_device_team_get_slaves (NMDeviceTeam *device)
{
g_return_val_if_fail (NM_IS_DEVICE_TEAM (device), FALSE);
- return NM_DEVICE_TEAM_GET_PRIVATE (device)->slaves;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_TEAM_GET_PRIVATE (device)->slaves);
}
/**
@@ -148,38 +148,6 @@ get_setting_type (NMDevice *device)
static void
nm_device_team_init (NMDeviceTeam *device)
{
- NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (device);
-
- priv->slaves = g_ptr_array_new ();
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_TEAM_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_TEAM_CARRIER, &priv->carrier },
- { NM_DEVICE_TEAM_SLAVES, &priv->slaves, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_TEAM_CONFIG, &priv->config },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_team_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_TEAM,
- property_info);
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (object);
-
- g_clear_pointer (&priv->slaves, g_ptr_array_unref);
-
- G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object);
}
static void
@@ -220,18 +188,31 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_team = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_TEAM,
+ nm_device_team_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceTeam, _priv.carrier ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Config", PROP_CONFIG, NMDeviceTeam, _priv.config ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceTeam, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Slaves", PROP_SLAVES, NMDeviceTeam, _priv.slaves, nm_device_get_type ),
+ ),
+);
+
static void
-nm_device_team_class_init (NMDeviceTeamClass *team_class)
+nm_device_team_class_init (NMDeviceTeamClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (team_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (team_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (team_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceTeam);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceTeamPrivate, slaves);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -283,5 +264,5 @@ nm_device_team_class_init (NMDeviceTeamClass *team_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_team);
}
diff --git a/libnm/nm-device-tun.c b/libnm/nm-device-tun.c
index 220c9a2980..cc84774bca 100644
--- a/libnm/nm-device-tun.c
+++ b/libnm/nm-device-tun.c
@@ -31,9 +31,9 @@ typedef struct {
char *mode;
gint64 owner;
gint64 group;
- gboolean no_pi;
- gboolean vnet_hdr;
- gboolean multi_queue;
+ bool no_pi;
+ bool vnet_hdr;
+ bool multi_queue;
} NMDeviceTunPrivate;
struct _NMDeviceTun {
@@ -235,28 +235,6 @@ nm_device_tun_init (NMDeviceTun *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_TUN_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_TUN_MODE, &priv->mode },
- { NM_DEVICE_TUN_OWNER, &priv->owner },
- { NM_DEVICE_TUN_GROUP, &priv->group },
- { NM_DEVICE_TUN_NO_PI, &priv->no_pi },
- { NM_DEVICE_TUN_VNET_HDR, &priv->vnet_hdr },
- { NM_DEVICE_TUN_MULTI_QUEUE, &priv->multi_queue },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_tun_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_TUN,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (object);
@@ -304,18 +282,30 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_tun = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_TUN,
+ nm_device_tun_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_X ("Group", PROP_GROUP, NMDeviceTun, _priv.group ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceTun, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Mode", PROP_MODE, NMDeviceTun, _priv.mode ),
+ NML_DBUS_META_PROPERTY_INIT_B ("MultiQueue", PROP_MULTI_QUEUE, NMDeviceTun, _priv.multi_queue ),
+ NML_DBUS_META_PROPERTY_INIT_B ("NoPi", PROP_NO_PI, NMDeviceTun, _priv.no_pi ),
+ NML_DBUS_META_PROPERTY_INIT_X ("Owner", PROP_OWNER, NMDeviceTun, _priv.owner ),
+ NML_DBUS_META_PROPERTY_INIT_B ("VnetHdr", PROP_VNET_HDR, NMDeviceTun, _priv.vnet_hdr ),
+ ),
+);
+
static void
nm_device_tun_class_init (NMDeviceTunClass *gre_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (gre_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (gre_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (gre_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
@@ -415,5 +405,5 @@ nm_device_tun_class_init (NMDeviceTunClass *gre_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_tun);
}
diff --git a/libnm/nm-device-vlan.c b/libnm/nm-device-vlan.c
index ebe9f00cbe..ee57d0f43f 100644
--- a/libnm/nm-device-vlan.c
+++ b/libnm/nm-device-vlan.c
@@ -23,10 +23,10 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ NMLDBusPropertyO parent;
char *hw_address;
- gboolean carrier;
- NMDevice *parent;
- guint vlan_id;
+ guint32 vlan_id;
+ bool carrier;
} NMDeviceVlanPrivate;
struct _NMDeviceVlan {
@@ -88,7 +88,7 @@ nm_device_vlan_get_parent (NMDeviceVlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
- return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_VLAN_GET_PRIVATE (device)->parent);
}
/**
@@ -167,31 +167,11 @@ nm_device_vlan_init (NMDeviceVlan *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_VLAN_CARRIER, &priv->carrier },
- { NM_DEVICE_VLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_VLAN_VLAN_ID, &priv->vlan_id },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_vlan_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_VLAN,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
g_free (priv->hw_address);
- g_clear_object (&priv->parent);
G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object);
}
@@ -223,17 +203,31 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vlan = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_VLAN,
+ nm_device_vlan_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_B ("Carrier", PROP_CARRIER, NMDeviceVlan, _priv.carrier ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceVlan, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceVlan, _priv.parent, nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_U ("VlanId", PROP_VLAN_ID, NMDeviceVlan, _priv.vlan_id ),
+ ),
+);
+
static void
-nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
+nm_device_vlan_class_init (NMDeviceVlanClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (vlan_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (vlan_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (vlan_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceVlan);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceVlanPrivate, parent);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -283,5 +277,5 @@ nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_vlan);
}
diff --git a/libnm/nm-device-vxlan.c b/libnm/nm-device-vxlan.c
index 27d7db1d7e..4397977c3f 100644
--- a/libnm/nm-device-vxlan.c
+++ b/libnm/nm-device-vxlan.c
@@ -36,23 +36,23 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
- NMDevice *parent;
+ NMLDBusPropertyO parent;
char *hw_address;
- guint id;
char *group;
char *local;
- guint src_port_min;
- guint src_port_max;
- guint dst_port;
- guint tos;
- guint ttl;
- guint limit;
- gboolean learning;
- guint ageing;
- gboolean proxy;
- gboolean rsc;
- gboolean l2miss;
- gboolean l3miss;
+ guint32 id;
+ guint32 limit;
+ guint32 ageing;
+ guint16 src_port_min;
+ guint16 src_port_max;
+ guint16 dst_port;
+ guint8 tos;
+ guint8 ttl;
+ bool learning;
+ bool proxy;
+ bool rsc;
+ bool l2miss;
+ bool l3miss;
} NMDeviceVxlanPrivate;
struct _NMDeviceVxlan {
@@ -123,7 +123,7 @@ nm_device_vxlan_get_parent (NMDeviceVxlan *device)
{
g_return_val_if_fail (NM_IS_DEVICE_VXLAN (device), NULL);
- return NM_DEVICE_VXLAN_GET_PRIVATE (device)->parent;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_VXLAN_GET_PRIVATE (device)->parent);
}
/**
@@ -412,44 +412,11 @@ nm_device_vxlan_init (NMDeviceVxlan *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_VXLAN_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_VXLAN_PARENT, &priv->parent, NULL, NM_TYPE_DEVICE },
- { NM_DEVICE_VXLAN_ID, &priv->id },
- { NM_DEVICE_VXLAN_GROUP, &priv->group },
- { NM_DEVICE_VXLAN_LOCAL, &priv->local },
- { NM_DEVICE_VXLAN_SRC_PORT_MIN, &priv->src_port_min },
- { NM_DEVICE_VXLAN_SRC_PORT_MAX, &priv->src_port_max },
- { NM_DEVICE_VXLAN_DST_PORT, &priv->dst_port },
- { NM_DEVICE_VXLAN_TOS, &priv->tos },
- { NM_DEVICE_VXLAN_TTL, &priv->ttl },
- { NM_DEVICE_VXLAN_LIMIT, &priv->limit },
- { NM_DEVICE_VXLAN_LEARNING, &priv->learning },
- { NM_DEVICE_VXLAN_AGEING, &priv->ageing },
- { NM_DEVICE_VXLAN_PROXY, &priv->proxy },
- { NM_DEVICE_VXLAN_RSC, &priv->rsc },
- { NM_DEVICE_VXLAN_L2MISS, &priv->l2miss },
- { NM_DEVICE_VXLAN_L3MISS, &priv->l3miss },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_vxlan_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_VXLAN,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE (object);
g_free (priv->hw_address);
- g_clear_object (&priv->parent);
g_free (priv->group);
g_free (priv->local);
@@ -525,17 +492,44 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vxlan = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_VXLAN,
+ nm_device_vxlan_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_U ("Ageing", PROP_AGEING, NMDeviceVxlan, _priv.ageing ),
+ NML_DBUS_META_PROPERTY_INIT_Q ("DstPort", PROP_DST_PORT, NMDeviceVxlan, _priv.dst_port ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Group", PROP_GROUP, NMDeviceVxlan, _priv.group ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceVxlan, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Id", PROP_ID, NMDeviceVxlan, _priv.id ),
+ NML_DBUS_META_PROPERTY_INIT_B ("L2miss", PROP_L2MISS, NMDeviceVxlan, _priv.l2miss ),
+ NML_DBUS_META_PROPERTY_INIT_B ("L3miss", PROP_L3MISS, NMDeviceVxlan, _priv.l3miss ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Learning", PROP_LEARNING, NMDeviceVxlan, _priv.learning ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Limit", PROP_LIMIT, NMDeviceVxlan, _priv.limit ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Local", PROP_LOCAL, NMDeviceVxlan, _priv.local ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Parent", PROP_PARENT, NMDeviceVxlan, _priv.parent, nm_device_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Proxy", PROP_PROXY, NMDeviceVxlan, _priv.proxy ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Rsc", PROP_RSC, NMDeviceVxlan, _priv.rsc ),
+ NML_DBUS_META_PROPERTY_INIT_Q ("SrcPortMax", PROP_SRC_PORT_MAX, NMDeviceVxlan, _priv.src_port_max ),
+ NML_DBUS_META_PROPERTY_INIT_Q ("SrcPortMin", PROP_SRC_PORT_MIN, NMDeviceVxlan, _priv.src_port_min ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("Tos", PROP_TOS, NMDeviceVxlan, _priv.tos ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("Ttl", PROP_TTL, NMDeviceVxlan, _priv.ttl ),
+ ),
+);
+
static void
-nm_device_vxlan_class_init (NMDeviceVxlanClass *vxlan_class)
+nm_device_vxlan_class_init (NMDeviceVxlanClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (vxlan_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (vxlan_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (vxlan_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceVxlan);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceVxlanPrivate, parent);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
@@ -783,5 +777,5 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *vxlan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_vxlan);
}
diff --git a/libnm/nm-device-wifi-p2p.c b/libnm/nm-device-wifi-p2p.c
index 92652b3841..191d30eb37 100644
--- a/libnm/nm-device-wifi-p2p.c
+++ b/libnm/nm-device-wifi-p2p.c
@@ -16,8 +16,6 @@
#include "nm-core-internal.h"
#include "nm-dbus-helpers.h"
-#include "introspection/org.freedesktop.NetworkManager.Device.WifiP2P.h"
-
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
@@ -35,11 +33,8 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
- NMDBusDeviceWifiP2P *proxy;
-
+ NMLDBusPropertyAO peers;
char *hw_address;
-
- GPtrArray *peers;
} NMDeviceWifiP2PPrivate;
struct _NMDeviceWifiP2P {
@@ -93,7 +88,7 @@ nm_device_wifi_p2p_get_peers (NMDeviceWifiP2P *device)
{
g_return_val_if_fail (NM_IS_DEVICE_WIFI_P2P (device), NULL);
- return NM_DEVICE_WIFI_P2P_GET_PRIVATE (device)->peers;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_WIFI_P2P_GET_PRIVATE (device)->peers);
}
/**
@@ -164,7 +159,8 @@ nm_device_wifi_p2p_start_find (NMDeviceWifiP2P *device,
if (!options)
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_wifi_p2p_start_find,
cancellable,
callback,
@@ -222,7 +218,8 @@ nm_device_wifi_p2p_stop_find (NMDeviceWifiP2P *device,
g_return_if_fail (NM_IS_DEVICE_WIFI_P2P (device));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_wifi_p2p_stop_find,
cancellable,
callback,
@@ -260,21 +257,6 @@ nm_device_wifi_p2p_stop_find_finish (NMDeviceWifiP2P *device,
return g_task_propagate_boolean (G_TASK (result), error);
}
-static void
-clean_up_peers (NMDeviceWifiP2P *self)
-{
- NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (self);
-
- while (priv->peers->len > 0) {
- NMWifiP2PPeer *peer;
-
- peer = priv->peers->pdata[priv->peers->len - 1];
- g_ptr_array_remove_index (priv->peers, priv->peers->len - 1);
-
- g_signal_emit (self, signals[PEER_REMOVED], 0, peer);
- }
-}
-
static gboolean
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
{
@@ -311,6 +293,24 @@ get_type_description (NMDevice *device)
/*****************************************************************************/
static void
+_property_ao_notify_changed_peers_cb (NMLDBusPropertyAO *pr_ao,
+ NMClient *client,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */)
+{
+ _nm_client_notify_event_queue_emit_obj_signal (client,
+ G_OBJECT (pr_ao->owner_dbobj->nmobj),
+ nmobj,
+ is_added,
+ 10,
+ is_added
+ ? signals[PEER_ADDED]
+ : signals[PEER_REMOVED]);
+}
+
+/*****************************************************************************/
+
+static void
get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -331,38 +331,11 @@ get_property (GObject *object,
}
}
-static void
-nm_device_wifi_p2p_init (NMDeviceWifiP2P *device)
-{
- NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (device);
-
- priv->peers = g_ptr_array_new ();
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_WIFI_P2P_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_WIFI_P2P_PEERS, &priv->peers, NULL, NM_TYPE_WIFI_P2P_PEER, "peer" },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->init_dbus (object);
-
- priv->proxy = NMDBUS_DEVICE_WIFI_P2P (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE_WIFI_P2P));
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_WIFI_P2P,
- property_info);
-}
+/*****************************************************************************/
static void
-dispose (GObject *object)
+nm_device_wifi_p2p_init (NMDeviceWifiP2P *device)
{
- clean_up_peers (NM_DEVICE_WIFI_P2P (object));
-
- G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->dispose (object);
}
static void
@@ -370,32 +343,40 @@ finalize (GObject *object)
{
NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE (object);
- g_clear_object (&priv->proxy);
g_free (priv->hw_address);
- if (priv->peers)
- g_ptr_array_unref (priv->peers);
G_OBJECT_CLASS (nm_device_wifi_p2p_parent_class)->finalize (object);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wifip2p = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_WIFI_P2P,
+ nm_device_wifi_p2p_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceWifiP2P, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Peers", PROP_PEERS, NMDeviceWifiP2P, _priv.peers, nm_wifi_p2p_peer_get_type, .notify_changed_ao = _property_ao_notify_changed_peers_cb ),
+ ),
+);
+
static void
-nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *wifi_class)
+nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wifi_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (wifi_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
object_class->finalize = finalize;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceWifiP2P);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceWifiP2PPrivate, peers);
+
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
device_class->get_type_description = get_type_description;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMDeviceWifiP2P:hw-address:
*
@@ -422,7 +403,7 @@ nm_device_wifi_p2p_class_init (NMDeviceWifiP2PClass *wifi_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_wifip2p);
/**
* NMDeviceWifiP2P::peer-added:
diff --git a/libnm/nm-device-wifi.c b/libnm/nm-device-wifi.c
index 36b26561c2..5d8f742c5b 100644
--- a/libnm/nm-device-wifi.c
+++ b/libnm/nm-device-wifi.c
@@ -18,8 +18,6 @@
#include "nm-core-internal.h"
#include "nm-dbus-helpers.h"
-#include "introspection/org.freedesktop.NetworkManager.Device.Wireless.h"
-
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
@@ -27,23 +25,21 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_PERM_HW_ADDRESS,
PROP_MODE,
PROP_BITRATE,
+ PROP_ACCESS_POINTS,
PROP_ACTIVE_ACCESS_POINT,
PROP_WIRELESS_CAPABILITIES,
- PROP_ACCESS_POINTS,
PROP_LAST_SCAN,
);
typedef struct {
- NMDBusDeviceWifi *proxy;
-
+ NMLDBusPropertyAO access_points;
+ NMLDBusPropertyO active_access_point;
char *hw_address;
char *perm_hw_address;
- NM80211Mode mode;
- guint32 rate;
- NMAccessPoint *active_ap;
- NMDeviceWifiCapabilities wireless_caps;
- GPtrArray *aps;
gint64 last_scan;
+ guint32 mode;
+ guint32 bitrate;
+ guint32 wireless_capabilities;
} NMDeviceWifiPrivate;
enum {
@@ -55,7 +51,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-
struct _NMDeviceWifi {
NMDevice parent;
NMDeviceWifiPrivate _priv;
@@ -63,8 +58,6 @@ struct _NMDeviceWifi {
struct _NMDeviceWifiClass {
NMDeviceClass parent;
-
- void (*access_point_removed) (NMDeviceWifi *device, NMAccessPoint *ap);
};
G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
@@ -73,11 +66,6 @@ G_DEFINE_TYPE (NMDeviceWifi, nm_device_wifi, NM_TYPE_DEVICE)
/*****************************************************************************/
-void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
-static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data);
-
-/*****************************************************************************/
-
/**
* nm_device_wifi_get_hw_address:
* @device: a #NMDeviceWifi
@@ -155,7 +143,7 @@ nm_device_wifi_get_bitrate (NMDeviceWifi *device)
return 0;
}
- return NM_DEVICE_WIFI_GET_PRIVATE (device)->rate;
+ return NM_DEVICE_WIFI_GET_PRIVATE (device)->bitrate;
}
/**
@@ -171,7 +159,7 @@ nm_device_wifi_get_capabilities (NMDeviceWifi *device)
{
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), 0);
- return NM_DEVICE_WIFI_GET_PRIVATE (device)->wireless_caps;
+ return NM_DEVICE_WIFI_GET_PRIVATE (device)->wireless_capabilities;
}
/**
@@ -185,27 +173,9 @@ nm_device_wifi_get_capabilities (NMDeviceWifi *device)
NMAccessPoint *
nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
{
- NMDeviceState state;
-
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
- state = nm_device_get_state (NM_DEVICE (device));
- switch (state) {
- case NM_DEVICE_STATE_PREPARE:
- case NM_DEVICE_STATE_CONFIG:
- case NM_DEVICE_STATE_NEED_AUTH:
- case NM_DEVICE_STATE_IP_CONFIG:
- case NM_DEVICE_STATE_IP_CHECK:
- case NM_DEVICE_STATE_SECONDARIES:
- case NM_DEVICE_STATE_ACTIVATED:
- case NM_DEVICE_STATE_DEACTIVATING:
- break;
- default:
- return NULL;
- break;
- }
-
- return NM_DEVICE_WIFI_GET_PRIVATE (device)->active_ap;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_WIFI_GET_PRIVATE (device)->active_access_point);
}
/**
@@ -223,7 +193,7 @@ nm_device_wifi_get_access_points (NMDeviceWifi *device)
{
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
- return NM_DEVICE_WIFI_GET_PRIVATE (device)->aps;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_WIFI_GET_PRIVATE (device)->access_points);
}
/**
@@ -342,9 +312,9 @@ nm_device_wifi_request_scan_options (NMDeviceWifi *device,
if (!options)
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
- return _nm_object_dbus_call_sync_void (device,
+ return _nm_client_dbus_call_sync_void (_nm_object_get_client (device),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
"RequestScan",
g_variant_new ("(@a{sv})", options),
@@ -412,12 +382,13 @@ nm_device_wifi_request_scan_options_async (NMDeviceWifi *device,
if (!options)
options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_wifi_request_scan_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_WIFI_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
"RequestScan",
g_variant_new ("(@a{sv})", options),
@@ -454,53 +425,6 @@ nm_device_wifi_request_scan_finish (NMDeviceWifi *device,
return g_task_propagate_boolean (G_TASK (result), error);
}
-static void
-clean_up_aps (NMDeviceWifi *self, gboolean in_dispose)
-{
- NMDeviceWifiPrivate *priv;
- GPtrArray *aps;
- int i;
-
- g_return_if_fail (NM_IS_DEVICE_WIFI (self));
-
- priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- g_clear_object (&priv->active_ap);
-
- aps = priv->aps;
-
- if (in_dispose)
- priv->aps = NULL;
- else {
- priv->aps = g_ptr_array_new ();
-
- for (i = 0; i < aps->len; i++) {
- NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
-
- g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap);
- }
- }
-
- g_ptr_array_unref (aps);
-}
-
-/**
- * _nm_device_wifi_set_wireless_enabled:
- * @device: a #NMDeviceWifi
- * @enabled: %TRUE to enable the device
- *
- * Enables or disables the wireless device.
- **/
-void
-_nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device,
- gboolean enabled)
-{
- g_return_if_fail (NM_IS_DEVICE_WIFI (device));
-
- if (!enabled)
- clean_up_aps (device, FALSE);
-}
-
#define WPA_CAPS (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | \
NM_WIFI_DEVICE_CAP_CIPHER_CCMP | \
NM_WIFI_DEVICE_CAP_WPA | \
@@ -600,16 +524,28 @@ get_hw_address (NMDevice *device)
/*****************************************************************************/
static void
+_property_ao_notify_changed_access_points_cb (NMLDBusPropertyAO *pr_ao,
+ NMClient *client,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */)
+{
+ _nm_client_notify_event_queue_emit_obj_signal (client,
+ G_OBJECT (pr_ao->owner_dbobj->nmobj),
+ nmobj,
+ is_added,
+ 10,
+ is_added
+ ? signals[ACCESS_POINT_ADDED]
+ : signals[ACCESS_POINT_REMOVED]);
+}
+
+/*****************************************************************************/
+
+static void
nm_device_wifi_init (NMDeviceWifi *device)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
- g_signal_connect (device,
- "notify::" NM_DEVICE_STATE,
- G_CALLBACK (state_changed_cb),
- NULL);
-
- priv->aps = g_ptr_array_new ();
priv->last_scan = -1;
}
@@ -653,80 +589,6 @@ get_property (GObject *object,
}
static void
-state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data)
-{
- NMDeviceWifi *self = NM_DEVICE_WIFI (device);
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- switch (nm_device_get_state (device)) {
- case NM_DEVICE_STATE_UNKNOWN:
- case NM_DEVICE_STATE_UNMANAGED:
- case NM_DEVICE_STATE_UNAVAILABLE:
- case NM_DEVICE_STATE_DISCONNECTED:
- case NM_DEVICE_STATE_FAILED:
- /* Just clear active AP; don't clear the AP list unless wireless is disabled completely */
- g_clear_object (&priv->active_ap);
- _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
- priv->rate = 0;
- _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_BITRATE);
- break;
- default:
- break;
- }
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_WIFI_HW_ADDRESS, &priv->hw_address },
- { NM_DEVICE_WIFI_PERMANENT_HW_ADDRESS, &priv->perm_hw_address },
- { NM_DEVICE_WIFI_MODE, &priv->mode },
- { NM_DEVICE_WIFI_BITRATE, &priv->rate },
- { NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT, &priv->active_ap, NULL, NM_TYPE_ACCESS_POINT },
- { NM_DEVICE_WIFI_CAPABILITIES, &priv->wireless_caps },
- { NM_DEVICE_WIFI_ACCESS_POINTS, &priv->aps, NULL, NM_TYPE_ACCESS_POINT, "access-point" },
- { NM_DEVICE_WIFI_LAST_SCAN, &priv->last_scan },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_wifi_parent_class)->init_dbus (object);
-
- priv->proxy = NMDBUS_DEVICE_WIFI (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE_WIRELESS));
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_WIRELESS,
- property_info);
-}
-
-static void
-access_point_removed (NMDeviceWifi *self, NMAccessPoint *ap)
-{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
-
- if (ap == priv->active_ap) {
- g_clear_object (&priv->active_ap);
- _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
-
- priv->rate = 0;
- _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
- }
-}
-
-static void
-dispose (GObject *object)
-{
- NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
-
- if (priv->aps)
- clean_up_aps (NM_DEVICE_WIFI (object), TRUE);
-
- g_clear_object (&priv->proxy);
-
- G_OBJECT_CLASS (nm_device_wifi_parent_class)->dispose (object);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
@@ -737,25 +599,41 @@ finalize (GObject *object)
G_OBJECT_CLASS (nm_device_wifi_parent_class)->finalize (object);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireless = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_WIRELESS,
+ nm_device_wifi_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("AccessPoints", PROP_ACCESS_POINTS, NMDeviceWifi, _priv.access_points, nm_access_point_get_type, .notify_changed_ao = _property_ao_notify_changed_access_points_cb ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("ActiveAccessPoint", PROP_ACTIVE_ACCESS_POINT, NMDeviceWifi, _priv.active_access_point, nm_access_point_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Bitrate", PROP_BITRATE, NMDeviceWifi, _priv.bitrate ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceWifi, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_X ("LastScan", PROP_LAST_SCAN, NMDeviceWifi, _priv.last_scan ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Mode", PROP_MODE, NMDeviceWifi, _priv.mode ),
+ NML_DBUS_META_PROPERTY_INIT_S ("PermHwAddress", PROP_PERM_HW_ADDRESS, NMDeviceWifi, _priv.perm_hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_U ("WirelessCapabilities", PROP_WIRELESS_CAPABILITIES, NMDeviceWifi, _priv.wireless_capabilities ),
+ ),
+);
+
static void
-nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
+nm_device_wifi_class_init (NMDeviceWifiClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (wifi_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wifi_class);
- NMDeviceClass *device_class = NM_DEVICE_CLASS (wifi_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
object_class->get_property = get_property;
- object_class->dispose = dispose;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT (nm_object_class, NMDeviceWifi);
+
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1 (nm_object_class, NMDeviceWifiPrivate, active_access_point);
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDeviceWifiPrivate, access_points);
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
- wifi_class->access_point_removed = access_point_removed;
-
/**
* NMDeviceWifi:hw-address:
*
@@ -850,7 +728,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_wireless);
/**
* NMDeviceWifi::access-point-added:
@@ -879,8 +757,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *wifi_class)
g_signal_new ("access-point-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMDeviceWifiClass, access_point_removed),
- NULL, NULL,
+ 0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
diff --git a/libnm/nm-device-wireguard.c b/libnm/nm-device-wireguard.c
index 825095eaa5..b4e2f350f4 100644
--- a/libnm/nm-device-wireguard.c
+++ b/libnm/nm-device-wireguard.c
@@ -19,8 +19,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
typedef struct {
GBytes *public_key;
- guint listen_port;
- guint fwmark;
+ guint32 fwmark;
+ guint16 listen_port;
} NMDeviceWireGuardPrivate;
struct _NMDeviceWireGuard {
@@ -126,24 +126,6 @@ nm_device_wireguard_init (NMDeviceWireGuard *device)
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_WIREGUARD_PUBLIC_KEY, &priv->public_key },
- { NM_DEVICE_WIREGUARD_LISTEN_PORT, &priv->listen_port },
- { NM_DEVICE_WIREGUARD_FWMARK, &priv->fwmark },
- { NULL }
- };
-
- NM_OBJECT_CLASS (nm_device_wireguard_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_WIREGUARD,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (object);
@@ -153,17 +135,25 @@ finalize (GObject *object)
G_OBJECT_CLASS (nm_device_wireguard_parent_class)->finalize (object);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireguard = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_WIREGUARD,
+ nm_device_wireguard_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_U ("FwMark", PROP_FWMARK, NMDeviceWireGuard, _priv.fwmark ),
+ NML_DBUS_META_PROPERTY_INIT_Q ("ListenPort", PROP_LISTEN_PORT, NMDeviceWireGuard, _priv.listen_port ),
+ NML_DBUS_META_PROPERTY_INIT_AY ("PublicKey", PROP_PUBLIC_KEY, NMDeviceWireGuard, _priv.public_key ),
+ ),
+);
+
static void
nm_device_wireguard_class_init (NMDeviceWireGuardClass *wireguard_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (wireguard_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wireguard_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMDeviceWireGuard:public-key:
*
@@ -203,5 +193,5 @@ nm_device_wireguard_class_init (NMDeviceWireGuardClass *wireguard_class)
0, G_MAXUINT32, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_wireguard);
}
diff --git a/libnm/nm-device-wpan.c b/libnm/nm-device-wpan.c
index 3dfa8f267c..5ddd8af37b 100644
--- a/libnm/nm-device-wpan.c
+++ b/libnm/nm-device-wpan.c
@@ -48,9 +48,9 @@ G_DEFINE_TYPE (NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE)
const char *
nm_device_wpan_get_hw_address (NMDeviceWpan *device)
{
- g_return_val_if_fail (NM_IS_DEVICE_WPAN (device), NULL);
+ g_return_val_if_fail (NM_IS_DEVICE_WPAN (device), NULL);
- return _nml_coerce_property_str_not_empty (NM_DEVICE_WPAN_GET_PRIVATE (device)->hw_address);
+ return _nml_coerce_property_str_not_empty (NM_DEVICE_WPAN_GET_PRIVATE (device)->hw_address);
}
static gboolean
@@ -95,49 +95,41 @@ get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
}
}
+/*****************************************************************************/
+
static void
nm_device_wpan_init (NMDeviceWpan *device)
{
}
static void
-init_dbus (NMObject *object)
-{
- NMDeviceWpanPrivate *priv = NM_DEVICE_WPAN_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_WPAN_HW_ADDRESS, &priv->hw_address },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_wpan_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE_WPAN,
- property_info);
-}
-
-static void
finalize (GObject *object)
{
- NMDeviceWpanPrivate *priv = NM_DEVICE_WPAN_GET_PRIVATE (object);
+ NMDeviceWpanPrivate *priv = NM_DEVICE_WPAN_GET_PRIVATE (object);
- g_free (priv->hw_address);
+ g_free (priv->hw_address);
- G_OBJECT_CLASS (nm_device_wpan_parent_class)->finalize (object);
+ G_OBJECT_CLASS (nm_device_wpan_parent_class)->finalize (object);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wpan = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE_WPAN,
+ nm_device_wpan_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMDeviceWpan, _priv.hw_address ),
+ ),
+);
+
static void
nm_device_wpan_class_init (NMDeviceWpanClass *wpan_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (wpan_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wpan_class);
NMDeviceClass *device_class = NM_DEVICE_CLASS (wpan_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
device_class->connection_compatible = connection_compatible;
device_class->get_setting_type = get_setting_type;
device_class->get_hw_address = get_hw_address;
@@ -153,5 +145,5 @@ nm_device_wpan_class_init (NMDeviceWpanClass *wpan_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device_wpan);
}
diff --git a/libnm/nm-device.c b/libnm/nm-device.c
index 8344f2a037..1db1c17051 100644
--- a/libnm/nm-device.c
+++ b/libnm/nm-device.c
@@ -27,11 +27,9 @@
#include "nm-setting-connection.h"
#include "nm-udev-aux/nm-udev-utils.h"
-#include "introspection/org.freedesktop.NetworkManager.Device.h"
-
/*****************************************************************************/
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
PROP_INTERFACE,
PROP_UDI,
PROP_DRIVER,
@@ -71,45 +69,50 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-typedef struct _NMDevicePrivate {
- NMDBusDevice *proxy;
+enum {
+ PROPERTY_O_IDX_ACTIVE_CONNECTION,
+ PROPERTY_O_IDX_IP4_CONFIG,
+ PROPERTY_O_IDX_IP6_CONFIG,
+ PROPERTY_O_IDX_DHCP4_CONFIG,
+ PROPERTY_O_IDX_DHCP6_CONFIG,
+ _PROPERTY_O_IDX_NUM,
+};
- char *iface;
- char *ip_iface;
- NMDeviceType device_type;
- char *udi;
+typedef struct _NMDevicePrivate {
+ NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NUM];
+ NMLDBusPropertyAO available_connections;
+ GPtrArray *lldp_neighbors;
char *driver;
char *driver_version;
+ char *interface;
+ char *ip_interface;
char *firmware_version;
- char *type_description;
- NMMetered metered;
- NMDeviceCapabilities capabilities;
- gboolean real;
- gboolean managed;
- gboolean firmware_missing;
- gboolean nm_plugin_missing;
- gboolean autoconnect;
- NMIPConfig *ip4_config;
- NMDhcpConfig *dhcp4_config;
- NMIPConfig *ip6_config;
- NMDhcpConfig *dhcp6_config;
- NMConnectivityState ip4_connectivity;
- NMConnectivityState ip6_connectivity;
- NMDeviceState state;
- NMDeviceState last_seen_state;
- NMDeviceStateReason reason;
-
- NMActiveConnection *active_connection;
- GPtrArray *available_connections;
+ char *physical_port_id;
+ char *udi;
+ guint32 capabilities;
+ guint32 device_type;
+ guint32 ip4_connectivity;
+ guint32 ip6_connectivity;
+ guint32 metered;
+ guint32 mtu;
+ guint32 state;
+ guint32 state_reason;
+ bool firmware_missing;
+ bool nm_plugin_missing;
+ bool autoconnect;
+ bool managed;
+ bool real;
+
+ guint32 old_state;
struct udev *udev;
+ char *type_description;
char *product;
- char *vendor, *short_vendor;
- char *description, *bus_name;
+ char *vendor;
+ char *short_vendor;
+ char *description;
+ char *bus_name;
- char *physical_port_id;
- guint32 mtu;
- GPtrArray *lldp_neighbors;
} NMDevicePrivate;
G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_OBJECT);
@@ -130,6 +133,8 @@ struct _NMLldpNeighbor {
G_DEFINE_BOXED_TYPE (NMLldpNeighbor, nm_lldp_neighbor, nm_lldp_neighbor_dup, nm_lldp_neighbor_unref)
+/*****************************************************************************/
+
static void
nm_device_init (NMDevice *self)
{
@@ -139,119 +144,121 @@ nm_device_init (NMDevice *self)
self->_priv = priv;
- priv->ip4_connectivity = NM_CONNECTIVITY_UNKNOWN;
- priv->ip6_connectivity = NM_CONNECTIVITY_UNKNOWN;
- priv->state = NM_DEVICE_STATE_UNKNOWN;
- priv->reason = NM_DEVICE_STATE_REASON_NONE;
- priv->lldp_neighbors = g_ptr_array_new ();
+ priv->old_state = NM_DEVICE_STATE_UNKNOWN;
}
-static gboolean
-demarshal_state_reason (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
-{
- guint32 *reason_field = field;
-
- g_variant_get (value, "(uu)", NULL, reason_field);
- _nm_object_queue_notify (object, NM_DEVICE_STATE_REASON);
- return TRUE;
-}
+/*****************************************************************************/
-static gboolean
-demarshal_lldp_neighbors (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
+static void
+_notify_event_state_changed (NMClient *client,
+ NMClientNotifyEventWithPtr *notify_event)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
- GVariantIter iter, attrs_iter;
- GVariant *variant, *attr_variant;
- const char *attr_name;
+ gs_unref_object NMDevice *self = notify_event->user_data;
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
- g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE);
+ NML_NMCLIENT_LOG_T (_nm_object_get_client (self),
+ "[%s] emit Device's StateChanged signal %u -> %u, reason: %u",
+ _nm_object_get_path (self),
+ (guint) priv->old_state,
+ (guint) priv->state,
+ (guint) priv->state_reason);
+
+ g_signal_emit (self,
+ signals[STATE_CHANGED],
+ 0,
+ (guint) priv->state,
+ (guint) priv->old_state,
+ (guint) priv->state_reason);
+}
+
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_state_reason (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
+{
+ NMDevice *self = NM_DEVICE (dbobj->nmobj);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ guint32 new_state = NM_DEVICE_STATE_UNKNOWN;
+ guint32 reason = NM_DEVICE_STATE_REASON_NONE;
- g_ptr_array_unref (priv->lldp_neighbors);
- priv->lldp_neighbors = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_lldp_neighbor_unref);
- g_variant_iter_init (&iter, value);
+ /* We ignore the "State" property and the "StateChanged" signal of the device.
+ * This information is redundant to the "StateReason" property, and we rely
+ * on that one alone. In the best case, the information is identical. If it
+ * would not be, then we stick to the information from "StateReason" property. */
- while (g_variant_iter_next (&iter, "@a{sv}", &variant)) {
- NMLldpNeighbor *neigh;
+ if (value)
+ g_variant_get (value, "(uu)", &new_state, &reason);
- neigh = nm_lldp_neighbor_new ();
- g_variant_iter_init (&attrs_iter, variant);
+ if ( priv->state == new_state
+ && priv->state_reason == reason) {
+ /* no changes. */
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+ }
- while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_variant))
- g_hash_table_insert (neigh->attrs, g_strdup (attr_name), attr_variant);
+ if (priv->state != new_state) {
+ priv->old_state = priv->state;
+ priv->state = new_state;
+ _nm_client_queue_notify_object (client,
+ self,
+ obj_properties[PROP_STATE]);
+ }
- g_variant_unref (variant);
- g_ptr_array_add (priv->lldp_neighbors, neigh);
+ if (priv->state_reason != reason) {
+ priv->state_reason = reason;
+ _nm_client_queue_notify_object (client,
+ self,
+ obj_properties[PROP_STATE_REASON]);
}
- _nm_object_queue_notify (object, NM_DEVICE_LLDP_NEIGHBORS);
+ _nm_client_notify_event_queue_with_ptr (client,
+ NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP + 1,
+ _notify_event_state_changed,
+ g_object_ref (self));
- return TRUE;
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
}
-static void
-device_state_reason_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
-
-static void
-init_dbus (NMObject *object)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_lldp_neighbors (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DEVICE_UDI, &priv->udi },
- { NM_DEVICE_INTERFACE, &priv->iface },
- { NM_DEVICE_DEVICE_TYPE, &priv->device_type },
- { NM_DEVICE_IP_INTERFACE, &priv->ip_iface },
- { NM_DEVICE_DRIVER, &priv->driver },
- { NM_DEVICE_DRIVER_VERSION, &priv->driver_version },
- { NM_DEVICE_FIRMWARE_VERSION, &priv->firmware_version },
- { NM_DEVICE_CAPABILITIES, &priv->capabilities },
- { NM_DEVICE_REAL, &priv->real },
- { NM_DEVICE_MANAGED, &priv->managed },
- { NM_DEVICE_AUTOCONNECT, &priv->autoconnect },
- { NM_DEVICE_FIRMWARE_MISSING, &priv->firmware_missing },
- { NM_DEVICE_NM_PLUGIN_MISSING, &priv->nm_plugin_missing },
- { NM_DEVICE_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG },
- { NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG },
- { NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG },
- { NM_DEVICE_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG },
- { NM_DEVICE_IP4_CONNECTIVITY, &priv->ip4_connectivity },
- { NM_DEVICE_IP6_CONNECTIVITY, &priv->ip6_connectivity },
- { NM_DEVICE_STATE, &priv->state },
- { NM_DEVICE_STATE_REASON, &priv->reason, demarshal_state_reason },
- { NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
- { NM_DEVICE_AVAILABLE_CONNECTIONS, &priv->available_connections, NULL, NM_TYPE_REMOTE_CONNECTION },
- { NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id },
- { NM_DEVICE_MTU, &priv->mtu },
- { NM_DEVICE_METERED, &priv->metered },
- { NM_DEVICE_LLDP_NEIGHBORS, &priv->lldp_neighbors, demarshal_lldp_neighbors },
-
- /* Properties that exist in D-Bus but that we don't track */
- { "ip4-address", NULL },
-
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_device_parent_class)->init_dbus (object);
-
- priv->proxy = NMDBUS_DEVICE (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DEVICE));
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DEVICE,
- property_info);
-
- g_signal_connect (priv->proxy, "notify::state-reason",
- G_CALLBACK (device_state_reason_changed), object);
-}
-
-static void
-device_state_reason_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
-{
- NMDevice *self = NM_DEVICE (user_data);
+ NMDevice *self = NM_DEVICE (dbobj->nmobj);
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
+ gs_unref_ptrarray GPtrArray *old = NULL;
+ gs_unref_ptrarray GPtrArray *new = NULL;
+ GVariantIter *attrs_iter;
+ GVariantIter iter;
+
+ new = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_lldp_neighbor_unref);
+
+ if (value) {
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "a{sv}", &attrs_iter)) {
+ GVariant *attr_variant;
+ const char *attr_name;
+ NMLldpNeighbor *neigh;
+
+ neigh = nm_lldp_neighbor_new ();
+ while (g_variant_iter_next (attrs_iter, "{&sv}", &attr_name, &attr_variant))
+ g_hash_table_insert (neigh->attrs, g_strdup (attr_name), attr_variant);
+ g_ptr_array_add (new, neigh);
+
+ g_variant_iter_free (attrs_iter);
+ }
+ }
- g_signal_emit (self, signals[STATE_CHANGED], 0,
- priv->state, priv->last_seen_state, priv->reason);
- priv->last_seen_state = priv->state;
+ old = g_steal_pointer (&priv->lldp_neighbors);
+ priv->lldp_neighbors = g_steal_pointer (&new);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
+/*****************************************************************************/
+
static NMDeviceType
coerce_type (NMDeviceType type)
{
@@ -292,37 +299,33 @@ coerce_type (NMDeviceType type)
return NM_DEVICE_TYPE_UNKNOWN;
}
+/*****************************************************************************/
+
static void
-dispose (GObject *object)
+register_client (NMObject *nmobj,
+ NMClient *client,
+ NMLDBusObject *dbobj)
{
- NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
+ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (nmobj);
- g_clear_object (&priv->ip4_config);
- g_clear_object (&priv->dhcp4_config);
- g_clear_object (&priv->ip6_config);
- g_clear_object (&priv->dhcp6_config);
- g_clear_object (&priv->active_connection);
+ priv->udev = _nm_client_get_udev (client);
+ if (priv->udev)
+ udev_ref (priv->udev);
- udev_unref (priv->udev);
- priv->udev = NULL;
-
- g_clear_pointer (&priv->available_connections, g_ptr_array_unref);
- g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
-
- if (priv->proxy)
- g_signal_handlers_disconnect_by_func (priv->proxy, device_state_reason_changed, object);
- g_clear_object (&priv->proxy);
-
- G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
+ NM_OBJECT_CLASS (nm_device_parent_class)->register_client (nmobj, client, dbobj);
}
+/*****************************************************************************/
+
static void
finalize (GObject *object)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
- g_free (priv->iface);
- g_free (priv->ip_iface);
+ g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
+
+ g_free (priv->interface);
+ g_free (priv->ip_interface);
g_free (priv->udi);
g_free (priv->driver);
g_free (priv->driver_version);
@@ -335,6 +338,8 @@ finalize (GObject *object)
g_free (priv->type_description);
g_free (priv->physical_port_id);
+ nm_clear_pointer (&priv->udev, udev_unref);
+
G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
}
@@ -462,22 +467,75 @@ set_property (GObject *object,
}
}
+/* TODO: statistics interface not yet implemented. */
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_statistics = NML_DBUS_META_IFACE_INIT (
+ NM_DBUS_INTERFACE_DEVICE_STATISTICS,
+ NULL,
+ NML_DBUS_META_INTERFACE_PRIO_NONE,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_TODO ("RefreshRateMs", "u" ),
+ NML_DBUS_META_PROPERTY_INIT_TODO ("RxBytes", "t" ),
+ NML_DBUS_META_PROPERTY_INIT_TODO ("TxBytes", "t" ),
+ ),
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DEVICE,
+ nm_device_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("ActiveConnection", PROP_ACTIVE_CONNECTION, NMDevicePrivate, property_o[PROPERTY_O_IDX_ACTIVE_CONNECTION], nm_active_connection_get_type, .ready_without_visible = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Autoconnect", PROP_AUTOCONNECT, NMDevicePrivate, autoconnect ),
+ NML_DBUS_META_PROPERTY_INIT_AO_PROP ("AvailableConnections", PROP_AVAILABLE_CONNECTIONS, NMDevicePrivate, available_connections, nm_remote_connection_get_type, .ready_without_visible = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Capabilities", PROP_CAPABILITIES, NMDevicePrivate, capabilities ),
+ NML_DBUS_META_PROPERTY_INIT_U ("DeviceType", PROP_DEVICE_TYPE, NMDevicePrivate, device_type ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Dhcp4Config", PROP_DHCP4_CONFIG, NMDevicePrivate, property_o[PROPERTY_O_IDX_DHCP4_CONFIG], nm_dhcp4_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Dhcp6Config", PROP_DHCP6_CONFIG, NMDevicePrivate, property_o[PROPERTY_O_IDX_DHCP6_CONFIG], nm_dhcp6_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Driver", PROP_DRIVER, NMDevicePrivate, driver ),
+ NML_DBUS_META_PROPERTY_INIT_S ("DriverVersion", PROP_DRIVER_VERSION, NMDevicePrivate, driver_version ),
+ NML_DBUS_META_PROPERTY_INIT_B ("FirmwareMissing", PROP_FIRMWARE_MISSING, NMDevicePrivate, firmware_missing ),
+ NML_DBUS_META_PROPERTY_INIT_S ("FirmwareVersion", PROP_FIRMWARE_VERSION, NMDevicePrivate, firmware_version ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Interface", PROP_INTERFACE, NMDevicePrivate, interface ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("Ip4Address", "u" ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Ip4Config", PROP_IP4_CONFIG, NMDevicePrivate, property_o[PROPERTY_O_IDX_IP4_CONFIG], nm_ip4_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Ip4Connectivity", PROP_IP4_CONNECTIVITY, NMDevicePrivate, ip4_connectivity ),
+ NML_DBUS_META_PROPERTY_INIT_O_PROP ("Ip6Config", PROP_IP6_CONFIG, NMDevicePrivate, property_o[PROPERTY_O_IDX_IP6_CONFIG], nm_ip6_config_get_type ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Ip6Connectivity", PROP_IP6_CONNECTIVITY, NMDevicePrivate, ip6_connectivity ),
+ NML_DBUS_META_PROPERTY_INIT_S ("IpInterface", PROP_IP_INTERFACE, NMDevicePrivate, ip_interface ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("LldpNeighbors", PROP_LLDP_NEIGHBORS, "aa{sv}", _notify_update_prop_lldp_neighbors ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Managed", PROP_MANAGED, NMDevicePrivate, managed ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Metered", PROP_METERED, NMDevicePrivate, metered ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Mtu", PROP_MTU, NMDevicePrivate, mtu ),
+ NML_DBUS_META_PROPERTY_INIT_B ("NmPluginMissing", PROP_NM_PLUGIN_MISSING, NMDevicePrivate, nm_plugin_missing ),
+ NML_DBUS_META_PROPERTY_INIT_S ("PhysicalPortId", PROP_PHYSICAL_PORT_ID, NMDevicePrivate, physical_port_id ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Real", PROP_REAL, NMDevicePrivate, real ),
+ NML_DBUS_META_PROPERTY_INIT_IGNORE ("State", "u" ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("StateReason", PROP_STATE_REASON, "(uu)", _notify_update_prop_state_reason ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Udi", PROP_UDI, NMDevicePrivate, udi ),
+ ),
+ .base_struct_offset = G_STRUCT_OFFSET (NMDevice, _priv),
+);
+
static void
-nm_device_class_init (NMDeviceClass *device_class)
+nm_device_class_init (NMDeviceClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (device_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (device_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
- g_type_class_add_private (device_class, sizeof (NMDevicePrivate));
+ g_type_class_add_private (klass, sizeof (NMDevicePrivate));
object_class->get_property = get_property;
object_class->set_property = set_property;
- object_class->dispose = dispose;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ nm_object_class->register_client = register_client;
+
+ _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT (nm_object_class, NMDevice);
- device_class->connection_compatible = connection_compatible;
+ _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N (nm_object_class, NMDevicePrivate, property_o);
+ _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1 (nm_object_class, NMDevicePrivate, available_connections);
+
+ klass->connection_compatible = connection_compatible;
/**
* NMDevice:interface:
@@ -825,7 +883,7 @@ nm_device_class_init (NMDeviceClass *device_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_device);
/**
* NMDevice::state-changed:
@@ -840,8 +898,7 @@ nm_device_class_init (NMDeviceClass *device_class)
g_signal_new ("state-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMDeviceClass, state_changed),
- NULL, NULL, NULL,
+ 0, NULL, NULL, NULL,
G_TYPE_NONE, 3,
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
}
@@ -860,7 +917,7 @@ nm_device_get_iface (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return _nml_coerce_property_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->iface);
+ return _nml_coerce_property_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->interface);
}
/**
@@ -878,7 +935,7 @@ nm_device_get_ip_iface (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return _nml_coerce_property_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->ip_iface);
+ return _nml_coerce_property_str_not_empty (NM_DEVICE_GET_PRIVATE (device)->ip_interface);
}
/**
@@ -1082,10 +1139,12 @@ nm_device_set_managed (NMDevice *device, gboolean managed)
NM_DEVICE_GET_PRIVATE (device)->managed = managed;
- _nm_object_set_property (NM_OBJECT (device),
- NM_DBUS_INTERFACE_DEVICE,
- "Managed",
- "b", managed);
+ _nm_client_set_property_sync_legacy (_nm_object_get_client (device),
+ _nm_object_get_path (device),
+ NM_DBUS_INTERFACE_DEVICE,
+ "Managed",
+ "b",
+ managed);
}
/**
@@ -1125,10 +1184,12 @@ nm_device_set_autoconnect (NMDevice *device, gboolean autoconnect)
NM_DEVICE_GET_PRIVATE (device)->autoconnect = autoconnect;
- _nm_object_set_property (NM_OBJECT (device),
- NM_DBUS_INTERFACE_DEVICE,
- "Autoconnect",
- "b", autoconnect);
+ _nm_client_set_property_sync_legacy (_nm_object_get_client (device),
+ _nm_object_get_path (device),
+ NM_DBUS_INTERFACE_DEVICE,
+ "AutoConnect",
+ "b",
+ autoconnect);
}
/**
@@ -1184,7 +1245,7 @@ nm_device_get_ip4_config (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->ip4_config;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_GET_PRIVATE (device)->property_o[PROPERTY_O_IDX_IP4_CONFIG]);
}
/**
@@ -1204,7 +1265,7 @@ nm_device_get_dhcp4_config (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->dhcp4_config;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_GET_PRIVATE (device)->property_o[PROPERTY_O_IDX_DHCP4_CONFIG]);
}
/**
@@ -1223,7 +1284,7 @@ nm_device_get_ip6_config (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->ip6_config;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_GET_PRIVATE (device)->property_o[PROPERTY_O_IDX_IP6_CONFIG]);
}
/**
@@ -1243,7 +1304,7 @@ nm_device_get_dhcp6_config (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_GET_PRIVATE (device)->property_o[PROPERTY_O_IDX_DHCP6_CONFIG]);
}
/**
@@ -1305,7 +1366,7 @@ nm_device_get_state_reason (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_REASON_UNKNOWN);
- return NM_DEVICE_GET_PRIVATE (device)->reason;
+ return NM_DEVICE_GET_PRIVATE (device)->state_reason;
}
/**
@@ -1322,7 +1383,7 @@ nm_device_get_active_connection (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->active_connection;
+ return nml_dbus_property_o_get_obj (&NM_DEVICE_GET_PRIVATE (device)->property_o[PROPERTY_O_IDX_ACTIVE_CONNECTION]);
}
/**
@@ -1341,7 +1402,7 @@ nm_device_get_available_connections (NMDevice *device)
{
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->available_connections;
+ return nml_dbus_property_ao_get_objs_as_ptrarray (&NM_DEVICE_GET_PRIVATE (device)->available_connections);
}
static const char *
@@ -1444,7 +1505,8 @@ get_bus_name (NMDevice *device)
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
struct udev_device *udevice;
- const char *ifname, *bus;
+ const char *ifname;
+ const char *bus;
if (priv->bus_name)
goto out;
@@ -1482,31 +1544,18 @@ out:
return NULL;
}
-void
-_nm_device_set_udev (NMDevice *device, struct udev *udev)
-{
- NMDevicePrivate *priv;
-
- nm_assert (NM_IS_DEVICE (device));
- nm_assert (udev);
-
- priv = NM_DEVICE_GET_PRIVATE (device);
-
- nm_assert (!priv->udev);
-
- priv->udev = udev_ref (udev);
-}
-
static char *
_get_udev_property (NMDevice *device,
const char *enc_prop, /* ID_XXX_ENC */
const char *db_prop) /* ID_XXX_FROM_DATABASE */
{
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
- struct udev_device *udev_device, *tmpdev;
+ struct udev_device *udev_device;
+ struct udev_device *tmpdev;
const char *ifname;
guint32 count = 0;
- char *enc_value = NULL, *db_value = NULL;
+ char *enc_value = NULL;
+ char *db_value = NULL;
if (!priv->udev)
return NULL;
@@ -1923,9 +1972,14 @@ NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_device_get_metered, (NMDevice *de
GPtrArray *
nm_device_get_lldp_neighbors (NMDevice *device)
{
- g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+ NMDevicePrivate *priv;
+
+ g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
- return NM_DEVICE_GET_PRIVATE (device)->lldp_neighbors;
+ priv = NM_DEVICE_GET_PRIVATE (device);
+ if (!priv->lldp_neighbors)
+ priv->lldp_neighbors = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_lldp_neighbor_unref);
+ return priv->lldp_neighbors;
}
/**
@@ -2003,9 +2057,9 @@ nm_device_reapply (NMDevice *device,
if (!arg_connection)
arg_connection = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
- return _nm_object_dbus_call_sync_void (device,
+ return _nm_client_dbus_call_sync_void (_nm_object_get_client (device),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"Reapply",
g_variant_new ("(@a{sa{sv}}tu)",
@@ -2057,12 +2111,13 @@ nm_device_reapply_async (NMDevice *device,
if (!arg_connection)
arg_connection = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_reapply_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"Reapply",
g_variant_new ("(@a{sa{sv}}tu)",
@@ -2138,9 +2193,9 @@ nm_device_get_applied_connection (NMDevice *device,
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
g_return_val_if_fail (!error || !*error, NULL);
- ret = _nm_object_dbus_call_sync (device,
+ ret = _nm_client_dbus_call_sync (_nm_object_get_client (device),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"GetAppliedConnection",
g_variant_new ("(u)", flags),
@@ -2187,12 +2242,13 @@ nm_device_get_applied_connection_async (NMDevice *device,
g_return_if_fail (NM_IS_DEVICE (device));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_get_applied_connection_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"GetAppliedConnection",
g_variant_new ("(u)", flags),
@@ -2277,9 +2333,9 @@ nm_device_disconnect (NMDevice *device,
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
- return _nm_object_dbus_call_sync_void (device,
+ return _nm_client_dbus_call_sync_void (_nm_object_get_client (device),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"Disconnect",
g_variant_new ("()"),
@@ -2309,12 +2365,13 @@ nm_device_disconnect_async (NMDevice *device,
g_return_if_fail (NM_IS_DEVICE (device));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_disconnect_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"Disconnect",
g_variant_new ("()"),
@@ -2368,9 +2425,9 @@ nm_device_delete (NMDevice *device,
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
- return _nm_object_dbus_call_sync_void (device,
+ return _nm_client_dbus_call_sync_void (_nm_object_get_client (device),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"Delete",
g_variant_new ("()"),
@@ -2399,12 +2456,13 @@ nm_device_delete_async (NMDevice *device,
g_return_if_fail (NM_IS_DEVICE (device));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (device,
+ _nm_client_dbus_call (_nm_object_get_client (device),
+ device,
nm_device_delete_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_DEVICE_GET_PRIVATE (device)->proxy)),
+ _nm_object_get_path (device),
NM_DBUS_INTERFACE_DEVICE,
"Delete",
g_variant_new ("()"),
diff --git a/libnm/nm-dhcp-config.c b/libnm/nm-dhcp-config.c
index df171690b1..fcafceccc7 100644
--- a/libnm/nm-dhcp-config.c
+++ b/libnm/nm-dhcp-config.c
@@ -16,7 +16,7 @@
/*****************************************************************************/
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+NM_GOBJECT_PROPERTIES_DEFINE (NMDhcpConfig,
PROP_FAMILY,
PROP_OPTIONS,
);
@@ -31,54 +31,46 @@ G_DEFINE_ABSTRACT_TYPE (NMDhcpConfig, nm_dhcp_config, NM_TYPE_OBJECT)
/*****************************************************************************/
-static void
-nm_dhcp_config_init (NMDhcpConfig *self)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_options (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- NMDhcpConfigPrivate *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DHCP_CONFIG, NMDhcpConfigPrivate);
-
- self->_priv = priv;
-
- priv->options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
-}
-
-static gboolean
-demarshal_dhcp_options (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
-{
- NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (object);
- GVariantIter iter;
- const char *key;
- GVariant *opt;
+ NMDhcpConfig *self = NM_DHCP_CONFIG (dbobj->nmobj);
+ NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (self);
g_hash_table_remove_all (priv->options);
- g_variant_iter_init (&iter, value);
- while (g_variant_iter_next (&iter, "{&sv}", &key, &opt)) {
- g_hash_table_insert (priv->options, g_strdup (key), g_variant_dup_string (opt, NULL));
- g_variant_unref (opt);
+ if (value) {
+ GVariantIter iter;
+ const char *key;
+ GVariant *opt;
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "{&sv}", &key, &opt)) {
+ if (g_variant_is_of_type (opt, G_VARIANT_TYPE_STRING))
+ g_hash_table_insert (priv->options, g_strdup (key), g_variant_dup_string (opt, NULL));
+ g_variant_unref (opt);
+ }
}
- _nm_object_queue_notify (object, NM_DHCP_CONFIG_OPTIONS);
- return TRUE;
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
+/*****************************************************************************/
+
static void
-init_dbus (NMObject *object)
+nm_dhcp_config_init (NMDhcpConfig *self)
{
- NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DHCP_CONFIG_OPTIONS, &priv->options, demarshal_dhcp_options },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_dhcp_config_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- (NM_IS_DHCP4_CONFIG (object) ?
- NM_DBUS_INTERFACE_DHCP4_CONFIG :
- NM_DBUS_INTERFACE_DHCP6_CONFIG),
- property_info);
+ NMDhcpConfigPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_DHCP_CONFIG, NMDhcpConfigPrivate);
+
+ self->_priv = priv;
+
+ priv->options = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
}
static void
@@ -86,8 +78,7 @@ finalize (GObject *object)
{
NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE (object);
- if (priv->options)
- g_hash_table_destroy (priv->options);
+ g_hash_table_destroy (priv->options);
G_OBJECT_CLASS (nm_dhcp_config_parent_class)->finalize (object);
}
@@ -113,19 +104,36 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp4config = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DHCP4_CONFIG,
+ nm_dhcp4_config_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Options", PROP_OPTIONS, "a{sv}", _notify_update_prop_options ),
+ ),
+ .base_struct_offset = G_STRUCT_OFFSET (NMDhcpConfig, _priv),
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp6config = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_DHCP6_CONFIG,
+ nm_dhcp6_config_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Options", PROP_OPTIONS, "a{sv}", _notify_update_prop_options ),
+ ),
+ .base_struct_offset = G_STRUCT_OFFSET (NMDhcpConfig, _priv),
+);
+
static void
nm_dhcp_config_class_init (NMDhcpConfigClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class);
g_type_class_add_private (config_class, sizeof (NMDhcpConfigPrivate));
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMDhcpConfig:family:
*
@@ -149,7 +157,8 @@ nm_dhcp_config_class_init (NMDhcpConfigClass *config_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_dhcp4config,
+ &_nml_dbus_meta_iface_nm_dhcp6config);
}
/**
diff --git a/libnm/nm-dns-manager.c b/libnm/nm-dns-manager.c
index 4204cd138b..9fe759d384 100644
--- a/libnm/nm-dns-manager.c
+++ b/libnm/nm-dns-manager.c
@@ -14,25 +14,6 @@
#include "nm-dbus-helpers.h"
#include "nm-core-internal.h"
-#include "introspection/org.freedesktop.NetworkManager.DnsManager.h"
-
-G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, NM_TYPE_OBJECT)
-
-#define NM_DNS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DNS_MANAGER, NMDnsManagerPrivate))
-
-typedef struct {
- NMDBusDnsManager *proxy;
- char *mode;
- char *rc_manager;
- GPtrArray *configuration;
-} NMDnsManagerPrivate;
-
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
- PROP_MODE,
- PROP_RC_MANAGER,
- PROP_CONFIGURATION,
-);
-
/*****************************************************************************
* NMDnsEntry
*****************************************************************************/
@@ -234,192 +215,3 @@ nm_dns_entry_get_priority (NMDnsEntry *entry)
return entry->priority;
}
-
-/*****************************************************************************/
-
-static gboolean
-demarshal_dns_configuration (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
- GVariant *entry_var;
- GVariantIter iter, *iterp;
- NMDnsEntry *entry;
- GPtrArray *array;
-
- g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE);
-
- g_variant_iter_init (&iter, value);
- g_ptr_array_unref (priv->configuration);
- priv->configuration = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_dns_entry_unref);
-
- while (g_variant_iter_next (&iter, "@a{sv}", &entry_var)) {
- char **nameservers = NULL, **domains = NULL;
- gboolean vpn = FALSE;
- char *interface = NULL, *str;
- int priority;
-
- if ( !g_variant_lookup (entry_var, "nameservers", "as", &iterp)
- || !g_variant_lookup (entry_var, "priority", "i", &priority)) {
- g_warning ("Ignoring invalid DNS configuration");
- g_variant_unref (entry_var);
- continue;
- }
-
- array = g_ptr_array_new ();
- while (g_variant_iter_next (iterp, "&s", &str))
- g_ptr_array_add (array, str);
- g_ptr_array_add (array, NULL);
- nameservers = (char **) g_ptr_array_free (array, FALSE);
- g_variant_iter_free (iterp);
-
- if (g_variant_lookup (entry_var, "domains", "as", &iterp)) {
- array = g_ptr_array_new ();
- while (g_variant_iter_next (iterp, "&s", &str))
- g_ptr_array_add (array, str);
- g_ptr_array_add (array, NULL);
- domains = (char **) g_ptr_array_free (array, FALSE);
- g_variant_iter_free (iterp);
- }
-
- g_variant_lookup (entry_var, "interface", "&s", &interface);
- g_variant_lookup (entry_var, "priority", "i", &priority);
- g_variant_lookup (entry_var, "vpn", "b", &vpn);
-
- entry = nm_dns_entry_new (interface,
- (const char * const *) nameservers,
- (const char * const *) domains,
- priority,
- vpn);
- g_free (domains);
- g_free (nameservers);
- g_variant_unref (entry_var);
- if (!entry) {
- g_warning ("Ignoring invalid DNS entry");
- continue;
- }
-
- g_ptr_array_add (priv->configuration, entry);
- }
-
- _nm_object_queue_notify (object, NM_DNS_MANAGER_CONFIGURATION);
-
- return TRUE;
-}
-
-/*****************************************************************************/
-const char *
-nm_dns_manager_get_mode (NMDnsManager *manager)
-{
- return NM_DNS_MANAGER_GET_PRIVATE (manager)->mode;
-}
-
-const char *
-nm_dns_manager_get_rc_manager (NMDnsManager *manager)
-{
- return NM_DNS_MANAGER_GET_PRIVATE (manager)->rc_manager;
-}
-
-const GPtrArray *
-nm_dns_manager_get_configuration (NMDnsManager *manager)
-{
- return NM_DNS_MANAGER_GET_PRIVATE (manager)->configuration;
-}
-/*****************************************************************************/
-
-static void
-nm_dns_manager_init (NMDnsManager *self)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- priv->configuration = g_ptr_array_new ();
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_DNS_MANAGER_MODE, &priv->mode },
- { NM_DNS_MANAGER_RC_MANAGER, &priv->rc_manager },
- { NM_DNS_MANAGER_CONFIGURATION, &priv->configuration, demarshal_dns_configuration },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_dns_manager_parent_class)->init_dbus (object);
-
- priv->proxy = NMDBUS_DNS_MANAGER (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_DNS_MANAGER));
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_DNS_MANAGER,
- property_info);
-}
-
-static void
-dispose (GObject *object)
-{
- NMDnsManager *self = NM_DNS_MANAGER (object);
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
-
- g_clear_pointer (&priv->mode, g_free);
- g_clear_pointer (&priv->rc_manager, g_free);
- g_clear_pointer (&priv->configuration, g_ptr_array_unref);
-
- G_OBJECT_CLASS (nm_dns_manager_parent_class)->dispose (object);
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_MODE:
- g_value_set_string (value, priv->mode);
- break;
- case PROP_RC_MANAGER:
- g_value_set_string (value, priv->rc_manager);
- break;
- case PROP_CONFIGURATION:
- g_value_take_boxed (value, _nm_utils_copy_array (priv->configuration,
- (NMUtilsCopyFunc) nm_dns_entry_dup,
- (GDestroyNotify) nm_dns_entry_unref));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_dns_manager_class_init (NMDnsManagerClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (class);
-
- g_type_class_add_private (class, sizeof (NMDnsManagerPrivate));
-
- object_class->get_property = get_property;
- object_class->dispose = dispose;
-
- nm_object_class->init_dbus = init_dbus;
-
- obj_properties[PROP_MODE] =
- g_param_spec_string (NM_DNS_MANAGER_MODE, "", "",
- NULL,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_RC_MANAGER] =
- g_param_spec_string (NM_DNS_MANAGER_RC_MANAGER, "", "",
- NULL,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_CONFIGURATION] =
- g_param_spec_boxed (NM_DNS_MANAGER_CONFIGURATION, "", "",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-}
diff --git a/libnm/nm-dns-manager.h b/libnm/nm-dns-manager.h
index 165f47653c..c645e43488 100644
--- a/libnm/nm-dns-manager.h
+++ b/libnm/nm-dns-manager.h
@@ -10,45 +10,13 @@
#error Cannot use this header.
#endif
-#include "nm-object.h"
#include "nm-client.h"
-#define NM_TYPE_DNS_MANAGER (nm_dns_manager_get_type ())
-#define NM_DNS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DNS_MANAGER, NMDnsManager))
-#define NM_DNS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DNS_MANAGER, NMDnsManagerClass))
-#define NM_IS_DNS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DNS_MANAGER))
-#define NM_IS_DNS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DNS_MANAGER))
-#define NM_DNS_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DNS_MANAGER, NMDnsManagerClass))
-
-#define NM_DNS_MANAGER_MODE "mode"
-#define NM_DNS_MANAGER_RC_MANAGER "rc-manager"
-#define NM_DNS_MANAGER_CONFIGURATION "configuration"
-
-typedef struct _NMDnsManager NMDnsManager;
-typedef struct _NMDnsManagerClass NMDnsManagerClass;
-
-/**
- * NMDnsManager:
- */
-struct _NMDnsManager {
- NMObject parent;
-};
-
-struct _NMDnsManagerClass {
- NMObjectClass parent;
-};
-
-GType nm_dns_manager_get_type (void);
-
-const char *nm_dns_manager_get_mode (NMDnsManager *manager);
-const char *nm_dns_manager_get_rc_manager (NMDnsManager *manager);
-const GPtrArray *nm_dns_manager_get_configuration (NMDnsManager *manager);
-
-NMDnsEntry * nm_dns_entry_new (const char *interface,
- const char * const *nameservers,
- const char * const *domains,
- int priority,
- gboolean vpn);
-NMDnsEntry * nm_dns_entry_dup (NMDnsEntry *entry);
+NMDnsEntry *nm_dns_entry_new (const char *interface,
+ const char * const *nameservers,
+ const char * const *domains,
+ int priority,
+ gboolean vpn);
+NMDnsEntry *nm_dns_entry_dup (NMDnsEntry *entry);
#endif /* __NM_DNS_MANAGER_H__ */
diff --git a/libnm/nm-ip-config.c b/libnm/nm-ip-config.c
index 19e008ed05..f214cdc43b 100644
--- a/libnm/nm-ip-config.c
+++ b/libnm/nm-ip-config.c
@@ -18,7 +18,7 @@
/*****************************************************************************/
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+NM_GOBJECT_PROPERTIES_DEFINE (NMIPConfig,
PROP_FAMILY,
PROP_GATEWAY,
PROP_ADDRESSES,
@@ -30,15 +30,18 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct _NMIPConfigPrivate {
- char *gateway;
GPtrArray *addresses;
GPtrArray *routes;
char **nameservers;
char **domains;
char **searches;
- char **wins;
+ char **wins_servers;
+ char *gateway;
- gboolean new_style_data;
+ bool addresses_new_style:1;
+ bool routes_new_style:1;
+ bool nameservers_new_style:1;
+ bool wins_servers_new_style:1;
} NMIPConfigPrivate;
G_DEFINE_ABSTRACT_TYPE (NMIPConfig, nm_ip_config, NM_TYPE_OBJECT)
@@ -47,156 +50,191 @@ G_DEFINE_ABSTRACT_TYPE (NMIPConfig, nm_ip_config, NM_TYPE_OBJECT)
/*****************************************************************************/
-static void
-nm_ip_config_init (NMIPConfig *self)
-{
- NMIPConfigPrivate *priv;
-
- priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_IP_CONFIG, NMIPConfigPrivate);
-
- self->_priv = priv;
-
- priv->addresses = g_ptr_array_new ();
- priv->routes = g_ptr_array_new ();
- priv->nameservers = g_new0 (char *, 1);
- priv->domains = g_new0 (char *, 1);
- priv->searches = g_new0 (char *, 1);
- priv->wins = g_new0 (char *, 1);
-}
-
-static gboolean
-demarshal_ip_addresses (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_addresses (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
-
- if (priv->new_style_data)
- return TRUE;
-
- g_ptr_array_unref (priv->addresses);
- if (NM_IS_IP4_CONFIG (object))
- priv->addresses = nm_utils_ip4_addresses_from_variant (value, NULL);
- else
- priv->addresses = nm_utils_ip6_addresses_from_variant (value, NULL);
- _nm_object_queue_notify (object, NM_IP_CONFIG_ADDRESSES);
-
- return TRUE;
-}
-
-static gboolean
-demarshal_ip_address_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
-{
- NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
-
- priv->new_style_data = TRUE;
-
- g_ptr_array_unref (priv->addresses);
- if (NM_IS_IP4_CONFIG (object))
- priv->addresses = nm_utils_ip_addresses_from_variant (value, AF_INET);
- else
- priv->addresses = nm_utils_ip_addresses_from_variant (value, AF_INET6);
- _nm_object_queue_notify (object, NM_IP_CONFIG_ADDRESSES);
+ NMIPConfig *self = NM_IP_CONFIG (dbobj->nmobj);
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (self);
+ gs_unref_ptrarray GPtrArray *addresses_old = NULL;
+ gs_unref_ptrarray GPtrArray *addresses_new = NULL;
+ int addr_family = meta_iface == &_nml_dbus_meta_iface_nm_ip4config
+ ? AF_INET : AF_INET6;
+ gboolean new_style;
+
+ new_style = (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[2] == '{');
+
+ if (priv->addresses_new_style) {
+ if (!new_style)
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+ } else
+ priv->addresses_new_style = new_style;
+
+ if (value) {
+ if (new_style)
+ addresses_new = nm_utils_ip_addresses_from_variant (value, addr_family);
+ else if (addr_family == AF_INET)
+ addresses_new = nm_utils_ip4_addresses_from_variant (value, NULL);
+ else
+ addresses_new = nm_utils_ip6_addresses_from_variant (value, NULL);
+ nm_assert (addresses_new);
+ }
+ if (!addresses_new)
+ addresses_new = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
- return TRUE;
+ addresses_old = priv->addresses;
+ priv->addresses = g_steal_pointer (&addresses_new);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
-static gboolean
-demarshal_ip_array (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_routes (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- char ***obj_field;
-
- obj_field = field;
- if (*obj_field)
- g_strfreev (*obj_field);
-
- if (NM_IS_IP4_CONFIG (object))
- *obj_field = nm_utils_ip4_dns_from_variant (value);
- else
- *obj_field = nm_utils_ip6_dns_from_variant (value);
+ NMIPConfig *self = NM_IP_CONFIG (dbobj->nmobj);
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (self);
+ gs_unref_ptrarray GPtrArray *routes_old = NULL;
+ gs_unref_ptrarray GPtrArray *routes_new = NULL;
+ int addr_family = meta_iface == &_nml_dbus_meta_iface_nm_ip4config
+ ? AF_INET : AF_INET6;
+ gboolean new_style;
+
+ new_style = (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[2] == '{');
+
+ if (priv->routes_new_style) {
+ if (!new_style)
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+ } else
+ priv->routes_new_style = new_style;
+
+ if (value) {
+ if (new_style)
+ routes_new = nm_utils_ip_routes_from_variant (value, addr_family);
+ else if (addr_family == AF_INET)
+ routes_new = nm_utils_ip4_routes_from_variant (value);
+ else
+ routes_new = nm_utils_ip6_routes_from_variant (value);
+ nm_assert (routes_new);
+ }
+ if (!routes_new)
+ routes_new = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref);
- _nm_object_queue_notify (object, pspec->name);
- return TRUE;
+ routes_old = priv->routes;
+ priv->routes = g_steal_pointer (&routes_new);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
-static gboolean
-demarshal_ip_routes (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_nameservers (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
-
- if (priv->new_style_data)
- return TRUE;
+ NMIPConfig *self = NM_IP_CONFIG (dbobj->nmobj);
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (self);
+ gs_strfreev char **nameservers_new = NULL;
+ gboolean new_style = TRUE;
+ int addr_family = meta_iface == &_nml_dbus_meta_iface_nm_ip4config
+ ? AF_INET : AF_INET6;
+
+ if (addr_family == AF_INET) {
+ new_style = (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[1] == 'a');
+
+ if (priv->nameservers_new_style) {
+ if (!new_style)
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+ } else
+ priv->nameservers_new_style = new_style;
+ }
- g_ptr_array_unref (priv->routes);
- if (NM_IS_IP4_CONFIG (object))
- priv->routes = nm_utils_ip4_routes_from_variant (value);
- else
- priv->routes = nm_utils_ip6_routes_from_variant (value);
- _nm_object_queue_notify (object, NM_IP_CONFIG_ROUTES);
+ if (value) {
+ if (addr_family == AF_INET6)
+ nameservers_new = nm_utils_ip6_dns_from_variant (value);
+ else if (!new_style)
+ nameservers_new = nm_utils_ip4_dns_from_variant (value);
+ else {
+ GVariantIter iter;
+ GVariantIter *iter_v;
+ gs_unref_ptrarray GPtrArray *arr = NULL;
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "a{sv}", &iter_v)) {
+ const char *key;
+ GVariant *val;
+
+ while (g_variant_iter_next (iter_v, "{&sv}", &key, &val)) {
+ if (nm_streq (key, "address")) {
+ gs_free char *val_str = NULL;
+
+ if (!g_variant_is_of_type (val, G_VARIANT_TYPE_STRING))
+ goto next;
+ if (!nm_utils_parse_inaddr (AF_INET, g_variant_get_string (val, NULL), &val_str))
+ goto next;
+ if (!arr)
+ arr = g_ptr_array_new ();
+ g_ptr_array_add (arr, g_steal_pointer (&val_str));
+ goto next;
+ }
+next:
+ g_variant_unref (val);
+ }
+ g_variant_iter_free (iter_v);
+ }
+ if ( arr
+ && arr->len > 0)
+ nameservers_new = nm_utils_strv_dup (arr->pdata, arr->len, FALSE);
+ else
+ nameservers_new = g_new0 (char *, 1);
+ }
+ nm_assert (nameservers_new);
+ }
- return TRUE;
+ g_strfreev (priv->nameservers);
+ priv->nameservers = g_steal_pointer (&nameservers_new);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
-static gboolean
-demarshal_ip_route_data (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
+static NMLDBusNotifyUpdatePropFlags
+_notify_update_prop_wins_servers (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value)
{
- NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
-
- priv->new_style_data = TRUE;
-
- g_ptr_array_unref (priv->routes);
- if (NM_IS_IP4_CONFIG (object))
- priv->routes = nm_utils_ip_routes_from_variant (value, AF_INET);
- else
- priv->routes = nm_utils_ip_routes_from_variant (value, AF_INET6);
- _nm_object_queue_notify (object, NM_IP_CONFIG_ROUTES);
-
- return TRUE;
-}
+ NMIPConfig *self = NM_IP_CONFIG (dbobj->nmobj);
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (self);
+ gs_strfreev char **wins_servers_new = NULL;
+ gboolean new_style;
+
+ new_style = (((const char *) meta_iface->dbus_properties[dbus_property_idx].dbus_type)[1] == 's');
+
+ if (priv->wins_servers_new_style) {
+ if (!new_style)
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE;
+ } else
+ priv->wins_servers_new_style = new_style;
+
+ if (value) {
+ if (new_style)
+ wins_servers_new = g_variant_dup_strv (value, NULL);
+ else
+ wins_servers_new = nm_utils_ip4_dns_from_variant (value);
+ nm_assert (wins_servers_new);
+ }
-static void
-init_dbus (NMObject *object)
-{
- NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_IP_CONFIG_GATEWAY, &priv->gateway, },
- { NM_IP_CONFIG_ADDRESSES, &priv->addresses, demarshal_ip_addresses },
- { "address-data", &priv->addresses, demarshal_ip_address_data },
- { NM_IP_CONFIG_ROUTES, &priv->routes, demarshal_ip_routes },
- { "route-data", &priv->routes, demarshal_ip_route_data },
- /* Still use deprecated "Nameservers" property instead of "NameserverData" */
- { NM_IP_CONFIG_NAMESERVERS, &priv->nameservers, demarshal_ip_array },
- { NM_IP_CONFIG_DOMAINS, &priv->domains, },
- { NM_IP_CONFIG_SEARCHES, &priv->searches, },
- /* Still use deprecated "WinsServers" property instead of "WinsServerData" */
- { NM_IP_CONFIG_WINS_SERVERS, &priv->wins, demarshal_ip_array },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_ip_config_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- (NM_IS_IP4_CONFIG (object) ?
- NM_DBUS_INTERFACE_IP4_CONFIG :
- NM_DBUS_INTERFACE_IP6_CONFIG),
- property_info);
+ g_strfreev (priv->wins_servers);
+ priv->wins_servers = g_steal_pointer (&wins_servers_new);
+ return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY;
}
-static void
-finalize (GObject *object)
-{
- NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
-
- g_free (priv->gateway);
-
- g_ptr_array_unref (priv->addresses);
- g_ptr_array_unref (priv->routes);
-
- g_strfreev (priv->nameservers);
- g_strfreev (priv->domains);
- g_strfreev (priv->searches);
- g_strfreev (priv->wins);
-
- G_OBJECT_CLASS (nm_ip_config_parent_class)->finalize (object);
-}
+/*****************************************************************************/
static void
get_property (GObject *object,
@@ -241,19 +279,90 @@ get_property (GObject *object,
}
}
+/*****************************************************************************/
+
+static void
+nm_ip_config_init (NMIPConfig *self)
+{
+ NMIPConfigPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_IP_CONFIG, NMIPConfigPrivate);
+
+ self->_priv = priv;
+
+ priv->addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
+ priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE (object);
+
+ g_free (priv->gateway);
+
+ g_ptr_array_unref (priv->routes);
+ g_ptr_array_unref (priv->addresses);
+
+ g_strfreev (priv->nameservers);
+ g_strfreev (priv->domains);
+ g_strfreev (priv->searches);
+ g_strfreev (priv->wins_servers);
+
+ G_OBJECT_CLASS (nm_ip_config_parent_class)->finalize (object);
+}
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip4config = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_IP4_CONFIG,
+ nm_ip4_config_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_FCN ("AddressData", PROP_ADDRESSES, "aa{sv}", _notify_update_prop_addresses ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Addresses", PROP_ADDRESSES, "aau", _notify_update_prop_addresses, .obj_property_no_reverse_idx = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_TODO ("DnsOptions", "as" ),
+ NML_DBUS_META_PROPERTY_INIT_TODO ("DnsPriority", "i" ),
+ NML_DBUS_META_PROPERTY_INIT_AS ("Domains", PROP_DOMAINS, NMIPConfigPrivate, domains ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Gateway", PROP_GATEWAY, NMIPConfigPrivate, gateway ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("NameserverData", PROP_NAMESERVERS, "aa{sv}", _notify_update_prop_nameservers ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Nameservers", PROP_NAMESERVERS, "au", _notify_update_prop_nameservers, .obj_property_no_reverse_idx = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("RouteData", PROP_ROUTES, "aa{sv}", _notify_update_prop_routes ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Routes", PROP_ROUTES, "aau", _notify_update_prop_routes, .obj_property_no_reverse_idx = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_AS ("Searches", PROP_SEARCHES, NMIPConfigPrivate, searches ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("WinsServerData", PROP_WINS_SERVERS, "as", _notify_update_prop_wins_servers ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("WinsServers", PROP_WINS_SERVERS, "au", _notify_update_prop_wins_servers, .obj_property_no_reverse_idx = TRUE ),
+ ),
+ .base_struct_offset = G_STRUCT_OFFSET (NMIPConfig, _priv),
+);
+
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip6config = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_IP6_CONFIG,
+ nm_ip6_config_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_FCN ("AddressData", PROP_ADDRESSES, "aa{sv}", _notify_update_prop_addresses ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Addresses", PROP_ADDRESSES, "a(ayuay)", _notify_update_prop_addresses, .obj_property_no_reverse_idx = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_TODO ("DnsOptions", "as" ),
+ NML_DBUS_META_PROPERTY_INIT_TODO ("DnsPriority", "i" ),
+ NML_DBUS_META_PROPERTY_INIT_AS ("Domains", PROP_DOMAINS, NMIPConfigPrivate, domains ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Gateway", PROP_GATEWAY, NMIPConfigPrivate, gateway ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Nameservers", PROP_NAMESERVERS, "aay", _notify_update_prop_nameservers ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("RouteData", PROP_ROUTES, "aa{sv}", _notify_update_prop_routes ),
+ NML_DBUS_META_PROPERTY_INIT_FCN ("Routes", PROP_ROUTES, "a(ayuayu)", _notify_update_prop_routes, .obj_property_no_reverse_idx = TRUE ),
+ NML_DBUS_META_PROPERTY_INIT_AS ("Searches", PROP_SEARCHES, NMIPConfigPrivate, searches ),
+ ),
+ .base_struct_offset = G_STRUCT_OFFSET (NMIPConfig, _priv),
+);
+
static void
nm_ip_config_class_init (NMIPConfigClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (config_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (config_class);
g_type_class_add_private (config_class, sizeof (NMIPConfigPrivate));
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMIPConfig:family:
*
@@ -344,7 +453,8 @@ nm_ip_config_class_init (NMIPConfigClass *config_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_ip4config,
+ &_nml_dbus_meta_iface_nm_ip6config);
}
/**
@@ -407,12 +517,12 @@ nm_ip_config_get_addresses (NMIPConfig *config)
*
* Returns: (transfer none): the array of nameserver IP addresses
**/
-const char * const *
+const char *const*
nm_ip_config_get_nameservers (NMIPConfig *config)
{
g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL);
- return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->nameservers;
+ return _nml_coerce_property_strv_not_null (NM_IP_CONFIG_GET_PRIVATE (config)->nameservers);
}
/**
@@ -424,12 +534,12 @@ nm_ip_config_get_nameservers (NMIPConfig *config)
* Returns: (transfer none): the array of domains.
* (This is never %NULL, though it may be 0-length).
**/
-const char * const *
+const char *const*
nm_ip_config_get_domains (NMIPConfig *config)
{
g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL);
- return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->domains;
+ return _nml_coerce_property_strv_not_null (NM_IP_CONFIG_GET_PRIVATE (config)->domains);
}
/**
@@ -441,12 +551,12 @@ nm_ip_config_get_domains (NMIPConfig *config)
* Returns: (transfer none): the array of DNS search strings.
* (This is never %NULL, though it may be 0-length).
**/
-const char * const *
+const char *const*
nm_ip_config_get_searches (NMIPConfig *config)
{
g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL);
- return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->searches;
+ return _nml_coerce_property_strv_not_null (NM_IP_CONFIG_GET_PRIVATE (config)->searches);
}
/**
@@ -458,12 +568,12 @@ nm_ip_config_get_searches (NMIPConfig *config)
* Returns: (transfer none): the arry of WINS server IP address strings.
* (This is never %NULL, though it may be 0-length.)
**/
-const char * const *
+const char *const*
nm_ip_config_get_wins_servers (NMIPConfig *config)
{
g_return_val_if_fail (NM_IS_IP_CONFIG (config), NULL);
- return (const char * const *) NM_IP_CONFIG_GET_PRIVATE (config)->wins;
+ return _nml_coerce_property_strv_not_null (NM_IP_CONFIG_GET_PRIVATE (config)->wins_servers);
}
/**
diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c
index 5638d0eae0..73de75e36b 100644
--- a/libnm/nm-libnm-utils.c
+++ b/libnm/nm-libnm-utils.c
@@ -10,6 +10,7 @@
#include "nm-glib-aux/nm-time-utils.h"
#include "nm-libnm-core-intern/nm-common-macros.h"
+#include "nm-object.h"
/*****************************************************************************/
@@ -741,3 +742,205 @@ nm_permission_result_to_client (const char *nm)
return NM_CLIENT_PERMISSION_RESULT_AUTH;
return NM_CLIENT_PERMISSION_RESULT_UNKNOWN;
}
+
+/*****************************************************************************/
+
+const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = {
+ &_nml_dbus_meta_iface_nm,
+ &_nml_dbus_meta_iface_nm_accesspoint,
+ &_nml_dbus_meta_iface_nm_agentmanager,
+ &_nml_dbus_meta_iface_nm_checkpoint,
+ &_nml_dbus_meta_iface_nm_connection_active,
+ &_nml_dbus_meta_iface_nm_dhcp4config,
+ &_nml_dbus_meta_iface_nm_dhcp6config,
+ &_nml_dbus_meta_iface_nm_device,
+ &_nml_dbus_meta_iface_nm_device_adsl,
+ &_nml_dbus_meta_iface_nm_device_bluetooth,
+ &_nml_dbus_meta_iface_nm_device_bond,
+ &_nml_dbus_meta_iface_nm_device_bridge,
+ &_nml_dbus_meta_iface_nm_device_dummy,
+ &_nml_dbus_meta_iface_nm_device_generic,
+ &_nml_dbus_meta_iface_nm_device_iptunnel,
+ &_nml_dbus_meta_iface_nm_device_infiniband,
+ &_nml_dbus_meta_iface_nm_device_lowpan,
+ &_nml_dbus_meta_iface_nm_device_macsec,
+ &_nml_dbus_meta_iface_nm_device_macvlan,
+ &_nml_dbus_meta_iface_nm_device_modem,
+ &_nml_dbus_meta_iface_nm_device_olpcmesh,
+ &_nml_dbus_meta_iface_nm_device_ovsbridge,
+ &_nml_dbus_meta_iface_nm_device_ovsinterface,
+ &_nml_dbus_meta_iface_nm_device_ovsport,
+ &_nml_dbus_meta_iface_nm_device_ppp,
+ &_nml_dbus_meta_iface_nm_device_statistics,
+ &_nml_dbus_meta_iface_nm_device_team,
+ &_nml_dbus_meta_iface_nm_device_tun,
+ &_nml_dbus_meta_iface_nm_device_veth,
+ &_nml_dbus_meta_iface_nm_device_vlan,
+ &_nml_dbus_meta_iface_nm_device_vxlan,
+ &_nml_dbus_meta_iface_nm_device_wifip2p,
+ &_nml_dbus_meta_iface_nm_device_wireguard,
+ &_nml_dbus_meta_iface_nm_device_wired,
+ &_nml_dbus_meta_iface_nm_device_wireless,
+ &_nml_dbus_meta_iface_nm_device_wpan,
+ &_nml_dbus_meta_iface_nm_dnsmanager,
+ &_nml_dbus_meta_iface_nm_ip4config,
+ &_nml_dbus_meta_iface_nm_ip6config,
+ &_nml_dbus_meta_iface_nm_settings,
+ &_nml_dbus_meta_iface_nm_settings_connection,
+ &_nml_dbus_meta_iface_nm_vpn_connection,
+ &_nml_dbus_meta_iface_nm_wifip2ppeer,
+};
+
+#define COMMON_PREFIX "org.freedesktop.NetworkManager"
+
+static int
+_strcmp_common_prefix (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ const NMLDBusMetaIface *iface = a;
+ const char *dbus_iface_name = b;
+
+ nm_assert (g_str_has_prefix (iface->dbus_iface_name, COMMON_PREFIX));
+
+ return strcmp (&iface->dbus_iface_name[NM_STRLEN (COMMON_PREFIX)], dbus_iface_name);
+}
+
+const NMLDBusMetaIface *
+nml_dbus_meta_iface_get (const char *dbus_iface_name)
+{
+ gssize idx;
+
+ nm_assert (dbus_iface_name);
+
+ G_STATIC_ASSERT_EXPR (G_STRUCT_OFFSET (NMLDBusMetaIface, dbus_iface_name) == 0);
+
+ /* we assume that NetworkManager only uses unique interface names. E.g. one
+ * interface name always has one particular meaning (and offers one set of
+ * properties, signals and methods). This is a convenient assumption, and
+ * we sure would never violate it when extending NM's D-Bus API. */
+
+ if (NM_STR_HAS_PREFIX (dbus_iface_name, COMMON_PREFIX)) {
+ /* optimize, that in fact all our interfaces have the same prefix. */
+ idx = nm_utils_ptrarray_find_binary_search ((gconstpointer *) _nml_dbus_meta_ifaces,
+ G_N_ELEMENTS (_nml_dbus_meta_ifaces),
+ &dbus_iface_name[NM_STRLEN (COMMON_PREFIX)],
+ _strcmp_common_prefix,
+ NULL,
+ NULL,
+ NULL);
+ } else
+ return NULL;
+
+ if (idx < 0)
+ return NULL;
+ return _nml_dbus_meta_ifaces[idx];
+}
+
+const NMLDBusMetaProperty *
+nml_dbus_meta_property_get (const NMLDBusMetaIface *meta_iface,
+ const char *dbus_property_name,
+ guint *out_idx)
+{
+ gssize idx;
+
+ nm_assert (meta_iface);
+ nm_assert (dbus_property_name);
+
+ idx = nm_utils_array_find_binary_search (meta_iface->dbus_properties,
+ sizeof (meta_iface->dbus_properties[0]),
+ meta_iface->n_dbus_properties,
+ &dbus_property_name,
+ nm_strcmp_p_with_data,
+ NULL);
+ if (idx < 0) {
+ NM_SET_OUT (out_idx, meta_iface->n_dbus_properties);
+ return NULL;
+ }
+ NM_SET_OUT (out_idx, idx);
+ return &meta_iface->dbus_properties[idx];
+}
+
+void
+_nml_dbus_meta_class_init_with_properties_impl (GObjectClass *object_class,
+ const NMLDBusMetaIface *const*meta_ifaces)
+{
+ int i_iface;
+
+ nm_assert (G_IS_OBJECT_CLASS (object_class));
+ nm_assert (meta_ifaces);
+ nm_assert (meta_ifaces[0]);
+
+ for (i_iface = 0; meta_ifaces[i_iface]; i_iface++) {
+ const NMLDBusMetaIface *meta_iface = meta_ifaces[i_iface];
+ guint8 *reverse_idx;
+ guint8 i;
+
+ nm_assert (g_type_is_a (meta_iface->get_type_fcn (), G_OBJECT_CLASS_TYPE (object_class)));
+ nm_assert (meta_iface->n_obj_properties > 0);
+ nm_assert (meta_iface->obj_properties);
+ nm_assert (meta_iface->obj_properties_reverse_idx[0] == 0);
+ nm_assert (meta_iface->obj_properties == meta_ifaces[0]->obj_properties);
+
+ if (i_iface == 0)
+ g_object_class_install_properties (object_class, meta_iface->n_obj_properties, (GParamSpec **) meta_iface->obj_properties);
+
+ reverse_idx = (guint8 *) meta_iface->obj_properties_reverse_idx;
+
+ for (i = 0; i < meta_iface->n_obj_properties; i++)
+ reverse_idx[i] = 0xFFu;
+ for (i = 0; i < meta_iface->n_dbus_properties; i++) {
+ const NMLDBusMetaProperty *mpr = &meta_iface->dbus_properties[i];
+
+ if ( mpr->obj_properties_idx != 0
+ && !mpr->obj_property_no_reverse_idx) {
+ nm_assert (mpr->obj_properties_idx < meta_iface->n_obj_properties);
+ nm_assert (reverse_idx[mpr->obj_properties_idx] == 0xFFu);
+
+ reverse_idx[mpr->obj_properties_idx] = i;
+ }
+ }
+ }
+}
+
+gboolean
+nm_utils_g_param_spec_is_default (const GParamSpec *pspec)
+{
+ g_return_val_if_fail (pspec, FALSE);
+
+ if (pspec->value_type == G_TYPE_BOOLEAN)
+ return ((((GParamSpecBoolean *) pspec)->default_value) == FALSE);
+ if (pspec->value_type == G_TYPE_UCHAR)
+ return ((((GParamSpecUChar *) pspec)->default_value) == 0u);
+ if (pspec->value_type == G_TYPE_INT)
+ return ((((GParamSpecInt *) pspec)->default_value) == 0);
+ if (pspec->value_type == G_TYPE_UINT)
+ return ((((GParamSpecUInt *) pspec)->default_value) == 0u);
+ if (pspec->value_type == G_TYPE_INT64)
+ return ((((GParamSpecInt64 *) pspec)->default_value) == 0);
+ if (pspec->value_type == G_TYPE_UINT64)
+ return ((((GParamSpecUInt64 *) pspec)->default_value) == 0u);
+ if (g_type_is_a (pspec->value_type, G_TYPE_ENUM))
+ return ((((GParamSpecEnum *) pspec)->default_value) == 0);
+ if (g_type_is_a (pspec->value_type, G_TYPE_FLAGS))
+ return ((((GParamSpecFlags *) pspec)->default_value) == 0u);
+ if (pspec->value_type == G_TYPE_STRING)
+ return ((((GParamSpecString *) pspec)->default_value) == NULL);
+ if (NM_IN_SET (pspec->value_type, G_TYPE_BYTES,
+ G_TYPE_PTR_ARRAY,
+ G_TYPE_HASH_TABLE,
+ G_TYPE_STRV)) {
+ /* boxed types have NULL default. */
+ g_return_val_if_fail (G_IS_PARAM_SPEC_BOXED (pspec), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_BOXED (pspec->value_type), FALSE);
+ return TRUE;
+ }
+ if (g_type_is_a (pspec->value_type, NM_TYPE_OBJECT)) {
+ /* object types have NULL default. */
+ g_return_val_if_fail (G_IS_PARAM_SPEC_OBJECT (pspec), FALSE);
+ g_return_val_if_fail (G_TYPE_IS_OBJECT (pspec->value_type), FALSE);
+ return TRUE;
+ }
+
+ /* This function is only used for asserting/testing. It thus
+ * strictly asserts and only support argument types that we expect. */
+ g_return_val_if_reached (FALSE);
+}
diff --git a/libnm/nm-libnm-utils.h b/libnm/nm-libnm-utils.h
index 484c00396f..9c7959e6be 100644
--- a/libnm/nm-libnm-utils.h
+++ b/libnm/nm-libnm-utils.h
@@ -6,8 +6,10 @@
#ifndef __NM_LIBNM_UTILS_H__
#define __NM_LIBNM_UTILS_H__
-#include "nm-types.h"
+#include "c-list/src/c-list.h"
#include "nm-glib-aux/nm-ref-string.h"
+#include "nm-types.h"
+#include "nm-object.h"
#include "nm-client.h"
/*****************************************************************************/
@@ -18,6 +20,15 @@
/*****************************************************************************/
+char *nm_utils_fixup_vendor_string (const char *desc);
+char *nm_utils_fixup_product_string (const char *desc);
+
+char *nm_utils_wincaps_to_dash (const char *caps);
+
+gboolean nm_utils_g_param_spec_is_default (const GParamSpec *pspec);
+
+/*****************************************************************************/
+
NMClientPermission nm_permission_to_client (const char *nm);
NMClientPermissionResult nm_permission_result_to_client (const char *nm);
@@ -142,35 +153,490 @@ _nml_coerce_property_strv_not_null (char **strv)
/*****************************************************************************/
-char *nm_utils_wincaps_to_dash (const char *caps);
+typedef struct _NMLDBusObject NMLDBusObject;
+typedef struct _NMLDBusObjWatcher NMLDBusObjWatcher;
+typedef struct _NMLDBusObjPropData NMLDBusObjPropData;
+typedef struct _NMLDBusObjIfaceData NMLDBusObjIfaceData;
+typedef struct _NMLDBusMetaIface NMLDBusMetaIface;
+
+typedef enum {
+ NML_DBUS_META_INTERFACE_PRIO_NONE = 0,
+ NML_DBUS_META_INTERFACE_PRIO_NMCLIENT = 1,
+ NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE = 2,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW = 3,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH = 4,
+} NMLDBusMetaInteracePrio;
+
+typedef struct _NMLDBusPropertyO NMLDBusPropertyO;
+typedef struct _NMLDBusPropertyAO NMLDBusPropertyAO;
+
+typedef struct {
+ GType (*get_o_type_fcn) (void);
+
+ /* This is to untangle loops. Device.ActiveConnection and ActiveConnection.Devices
+ * reference each other. One of them must allow to be considered visible without
+ * the other one. */
+ bool ready_without_visible:1;
+
+} NMLDBusPropertVTableO;
+
+typedef struct {
+ GType (*get_o_type_fcn) (void);
+
+ void (*notify_changed_ao) (NMLDBusPropertyAO *pr_ao,
+ NMClient *self,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */);
+
+ gboolean (*check_nmobj_visible_fcn) (GObject *nmobj);
+
+ /* This is to untangle loops. Device.ActiveConnection and ActiveConnection.Devices
+ * reference each other. One of them must allow to be considered visible without
+ * the other one. */
+ bool ready_without_visible:1;
+
+} NMLDBusPropertVTableAO;
+
+struct _NMLDBusPropertyO {
+ NMLDBusObject *owner_dbobj;
+ NMLDBusObjWatcher *obj_watcher;
+ GObject *nmobj;
+ const NMLDBusMetaIface *meta_iface;
+ guint dbus_property_idx;
+ bool is_ready:1;
+};
+
+gpointer nml_dbus_property_o_get_obj (NMLDBusPropertyO *pr_o);
+
+gboolean nml_dbus_property_o_is_ready (const NMLDBusPropertyO *pr_o);
+
+void nml_dbus_property_o_clear (NMLDBusPropertyO *pr_o,
+ NMClient *client);
+
+struct _NMLDBusPropertyAO {
+ CList lst;
+ GHashTable *hash;
+ NMLDBusObject *owner_dbobj;
+ const NMLDBusMetaIface *meta_iface;
+ GPtrArray *arr;
+ guint dbus_property_idx;
+ guint n_not_ready;
+};
+
+const GPtrArray *nml_dbus_property_ao_get_objs_as_ptrarray (NMLDBusPropertyAO *pr_ao);
+
+gboolean nml_dbus_property_ao_is_ready (const NMLDBusPropertyAO *pr_ao);
+
+void nml_dbus_property_ao_clear (NMLDBusPropertyAO *pr_ao,
+ NMClient *client);
+
+typedef enum {
+ NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE = 0,
+ NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY = 0x1,
+} NMLDBusNotifyUpdatePropFlags;
+
+NMLDBusNotifyUpdatePropFlags _nml_dbus_notify_update_prop_ignore (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value);
+
+NMLDBusNotifyUpdatePropFlags _nml_dbus_notify_update_prop_o (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value);
+
+typedef struct {
+ const char *dbus_property_name;
+ const GVariantType *dbus_type;
+
+ guint16 prop_struct_offset;
+
+ guint8 obj_properties_idx;
+
+ bool use_notify_update_prop:1;
+
+ bool obj_property_no_reverse_idx:1;
+
+ union {
+ union {
+ const NMLDBusPropertVTableO *property_vtable_o;
+ const NMLDBusPropertVTableAO *property_vtable_ao;
+ } extra;
+
+ NMLDBusNotifyUpdatePropFlags (*notify_update_prop) (NMClient *client,
+ NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ guint dbus_property_idx,
+ GVariant *value);
+ };
+
+} NMLDBusMetaProperty;
+
+#define NML_DBUS_META_PROPERTY_INIT(v_dbus_property_name, \
+ v_dbus_type, \
+ v_obj_properties_idx, \
+ ...) \
+ { \
+ .dbus_property_name = ""v_dbus_property_name"", \
+ .dbus_type = NM_G_VARIANT_TYPE (""v_dbus_type""), \
+ .obj_properties_idx = v_obj_properties_idx, \
+ ##__VA_ARGS__ \
+ }
+
+#define _NML_DBUS_META_PROPERTY_INIT_DEFAULT(v_dbus_type, \
+ v_exp_type, \
+ v_dbus_property_name, \
+ v_obj_properties_idx, \
+ v_container, \
+ v_field) \
+ NML_DBUS_META_PROPERTY_INIT (v_dbus_property_name, \
+ v_dbus_type, \
+ v_obj_properties_idx, \
+ .prop_struct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE (v_exp_type, v_container, v_field))
+
+#define NML_DBUS_META_PROPERTY_INIT_B(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("b", bool, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_Y(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("y", guint8, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_Q(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("q", guint16, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_I(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("i", gint32, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_U(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("u", guint32, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_X(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("x", gint64, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_T(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("t", guint64, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_S(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("s", char *, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_AS(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("as", char **, __VA_ARGS__)
+#define NML_DBUS_META_PROPERTY_INIT_AY(...) _NML_DBUS_META_PROPERTY_INIT_DEFAULT ("ay", GBytes *, __VA_ARGS__)
+
+#define NML_DBUS_META_PROPERTY_INIT_O(v_dbus_property_name, \
+ v_obj_properties_idx, \
+ v_container, \
+ v_field) \
+ NML_DBUS_META_PROPERTY_INIT (v_dbus_property_name, \
+ "o", \
+ v_obj_properties_idx, \
+ .prop_struct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE (NMRefString *, v_container, v_field), \
+ .use_notify_update_prop = TRUE, \
+ .notify_update_prop = _nml_dbus_notify_update_prop_o)
+
+#define NML_DBUS_META_PROPERTY_INIT_O_PROP(v_dbus_property_name, \
+ v_obj_properties_idx, \
+ v_container, \
+ v_field, \
+ v_get_o_type_fcn, \
+ ...) \
+ NML_DBUS_META_PROPERTY_INIT (v_dbus_property_name, \
+ "o", \
+ v_obj_properties_idx, \
+ .prop_struct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE (NMLDBusPropertyO, v_container, v_field), \
+ .extra.property_vtable_o = &((const NMLDBusPropertVTableO) { \
+ .get_o_type_fcn = (v_get_o_type_fcn), \
+ ##__VA_ARGS__ \
+ }))
+
+#define NML_DBUS_META_PROPERTY_INIT_AO_PROP(v_dbus_property_name, \
+ v_obj_properties_idx, \
+ v_container, \
+ v_field, \
+ v_get_o_type_fcn, \
+ ...) \
+ NML_DBUS_META_PROPERTY_INIT (v_dbus_property_name, \
+ "ao", \
+ v_obj_properties_idx, \
+ .prop_struct_offset = NM_STRUCT_OFFSET_ENSURE_TYPE (NMLDBusPropertyAO, v_container, v_field), \
+ .extra.property_vtable_ao = &((const NMLDBusPropertVTableAO) { \
+ .get_o_type_fcn = (v_get_o_type_fcn), \
+ ##__VA_ARGS__ \
+ }))
+
+#define NML_DBUS_META_PROPERTY_INIT_FCN(v_dbus_property_name, \
+ v_obj_properties_idx, \
+ v_dbus_type, \
+ v_notify_update_prop, \
+ ...) \
+ NML_DBUS_META_PROPERTY_INIT (v_dbus_property_name, \
+ v_dbus_type, \
+ v_obj_properties_idx, \
+ .use_notify_update_prop = TRUE, \
+ .notify_update_prop = (v_notify_update_prop), \
+ ##__VA_ARGS__)
+
+#define NML_DBUS_META_PROPERTY_INIT_IGNORE(v_dbus_property_name, \
+ v_dbus_type) \
+ NML_DBUS_META_PROPERTY_INIT (v_dbus_property_name, \
+ v_dbus_type, \
+ 0, \
+ .use_notify_update_prop = TRUE, \
+ .notify_update_prop = _nml_dbus_notify_update_prop_ignore)
+
+/* "TODO" is like "IGNORE". The difference is that we don't plan to ever implement "IGNORE", but
+ * "TODO" is something we should add support for. */
+#define NML_DBUS_META_PROPERTY_INIT_TODO(...) \
+ NML_DBUS_META_PROPERTY_INIT_IGNORE (__VA_ARGS__)
+
+typedef struct _NMLDBusMetaIface {
+ const char *dbus_iface_name;
+ GType (*get_type_fcn) (void);
+ const GParamSpec *const*obj_properties;
+ const NMLDBusMetaProperty *dbus_properties;
+ const guint8 *obj_properties_reverse_idx;
+ guint8 n_dbus_properties;
+ guint8 n_obj_properties;
+
+ /* The offsets in NMLDBusMetaProperty are based on some base struct.
+ * If this is 0, then the base struct is the GObject pointer itself.
+ * If this is non-null, then we expect at that location a pointer
+ * to the offset. */
+ guint8 base_struct_offset;
+
+ NMLDBusMetaInteracePrio interface_prio:3;
+} NMLDBusMetaIface;
+
+#define NML_DBUS_META_IFACE_OBJ_PROPERTIES() \
+ .obj_properties = (const GParamSpec *const*) (obj_properties), \
+ .n_obj_properties = _PROPERTY_ENUMS_LAST, \
+ .obj_properties_reverse_idx = ((guint8 [_PROPERTY_ENUMS_LAST]) { })
+
+#define NML_DBUS_META_IFACE_DBUS_PROPERTIES(...) \
+ .dbus_properties = ((const NMLDBusMetaProperty []) { __VA_ARGS__ }), \
+ .n_dbus_properties = sizeof ((const NMLDBusMetaProperty []) { __VA_ARGS__ }) / sizeof (NMLDBusMetaProperty) \
+
+#define NML_DBUS_META_IFACE_INIT(v_dbus_iface_name, \
+ v_get_type_fcn, \
+ v_interface_prio, \
+ ...) \
+ { \
+ .dbus_iface_name = ""v_dbus_iface_name"", \
+ .get_type_fcn = v_get_type_fcn, \
+ .interface_prio = v_interface_prio, \
+ ##__VA_ARGS__ \
+ }
+
+#define NML_DBUS_META_IFACE_INIT_PROP(...) \
+ NML_DBUS_META_IFACE_INIT (__VA_ARGS__ \
+ NML_DBUS_META_IFACE_OBJ_PROPERTIES ())
+
+extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[43];
+
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_checkpoint;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_connection_active;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_adsl;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bluetooth;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bond;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bridge;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_iptunnel;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_lowpan;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macsec;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_macvlan;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_modem;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_olpcmesh;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsbridge;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsinterface;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ovsport;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_ppp;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_statistics;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_team;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_tun;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_veth;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vlan;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_vxlan;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wifip2p;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wired;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireguard;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wireless;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_wpan;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp4config;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dhcp6config;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_dnsmanager;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip4config;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_ip6config;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings_connection;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_vpn_connection;
+extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_wifip2ppeer;
+
+const NMLDBusMetaIface *nml_dbus_meta_iface_get (const char *dbus_iface_name);
+
+const NMLDBusMetaProperty *nml_dbus_meta_property_get (const NMLDBusMetaIface *meta_iface,
+ const char *dbus_property_name,
+ guint *out_idx);
+
+void _nml_dbus_meta_class_init_with_properties_impl (GObjectClass *object_class, const NMLDBusMetaIface *const*meta_iface);
+#define _nml_dbus_meta_class_init_with_properties(object_class, ...) \
+ _nml_dbus_meta_class_init_with_properties_impl ((object_class), ((const NMLDBusMetaIface *const[]) { __VA_ARGS__, NULL }))
/*****************************************************************************/
-char *nm_utils_fixup_vendor_string (const char *desc);
-char *nm_utils_fixup_product_string (const char *desc);
+typedef enum {
+ NML_DBUS_OBJ_STATE_UNLINKED = 0,
+ NML_DBUS_OBJ_STATE_WATCHED_ONLY,
+ NML_DBUS_OBJ_STATE_ON_DBUS,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_MAYBE_READY,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE,
+ NML_DBUS_OBJ_STATE_WITH_NMOBJ_HIDDEN,
+} NMLDBusObjState;
+
+struct _NMLDBusObject {
+ NMRefString *dbus_path;
+
+ CList iface_lst_head;
+ CList removed_iface_lst_head;
+ CList changed_obj_lst;
+
+ CList watcher_lst_head;
+
+ CList notify_watchers_lst;
+
+ CList dbus_objects_lst;
+
+ GObject *nmobj;
+ int ref_count;
+
+ NMLDBusObjState obj_state:4;
+};
+
+static inline gboolean
+NML_IS_DBUS_OBJECT (NMLDBusObject *dbobj)
+{
+ nm_assert ( !dbobj
+ || ( NM_IS_REF_STRING (dbobj->dbus_path)
+ && dbobj->ref_count > 0));
+ nm_assert ( !dbobj->nmobj
+ || NM_IS_OBJECT (dbobj->nmobj)
+ || NM_IS_CLIENT (dbobj->nmobj));
+ return !!dbobj;
+}
+
+NMLDBusObject *nml_dbus_object_ref (NMLDBusObject *dbobj);
+
+void nml_dbus_object_unref (NMLDBusObject *dbobj);
+
+NM_AUTO_DEFINE_FCN0 (NMLDBusObject *, _nm_auto_unref_nml_dbusobj, nml_dbus_object_unref)
+#define nm_auto_unref_nml_dbusobj nm_auto (_nm_auto_unref_nml_dbusobj)
+
+NMLDBusObjIfaceData *nml_dbus_object_iface_data_get (NMLDBusObject *dbobj,
+ const char *dbus_iface_name,
+ gboolean allow_create);
+
+gpointer nml_dbus_object_get_property_location (NMLDBusObject *dbobj,
+ const NMLDBusMetaIface *meta_iface,
+ const NMLDBusMetaProperty *meta_property);
/*****************************************************************************/
+/* NMClient is not an NMObject, but in some aspects we want to track it like
+ * an NMObject. For that, both NMClient and NMObject "implement" NMObjectBase,
+ * despite not actually implementing such a GObject type. */
+typedef struct {
+ GObject parent;
+ CList queue_notify_lst;
+ bool is_disposing:1;
+} NMObjectBase;
+
+typedef struct {
+ GObjectClass parent;
+} NMObjectBaseClass;
+
struct _NMObjectPrivate;
struct _NMObject {
- GObject parent;
+ union {
+ GObject parent;
+ NMObjectBase obj_base;
+ };
struct _NMObjectPrivate *_priv;
};
+typedef struct _NMObjectClassFieldInfo {
+ const struct _NMObjectClassFieldInfo *parent;
+ NMObjectClass *klass;
+ guint16 offset;
+ guint16 num;
+} _NMObjectClassFieldInfo;
+
struct _NMObjectClass {
- GObjectClass parent;
+ union {
+ GObjectClass parent;
+ NMObjectBaseClass obj_base;
+ };
+
+ void (*register_client) (NMObject *self,
+ NMClient *client,
+ NMLDBusObject *dbobj);
+
+ void (*unregister_client) (NMObject *self,
+ NMClient *client,
+ NMLDBusObject *dbobj);
+
+ NMLDBusObjState (*is_visible) (NMObject *self);
- void (*init_dbus) (struct _NMObject *object);
+ const _NMObjectClassFieldInfo *property_o_info;
+ const _NMObjectClassFieldInfo *property_ao_info;
- /* The "object-creation-failed" method is PRIVATE for libnm and
- * is not meant for any external usage. It indicates that an error
- * occurred during creation of an object.
- */
- void (*object_creation_failed) (struct _NMObject *master_object,
- const char *failed_path);
+ guint16 priv_ptr_offset;
+
+ bool priv_ptr_indirect:1;
};
+#define _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, type_name) \
+ G_STMT_START { \
+ (nm_object_class)->priv_ptr_offset = NM_STRUCT_OFFSET_ENSURE_TYPE (type_name##Private, type_name, _priv); \
+ (nm_object_class)->priv_ptr_indirect = FALSE; \
+ } G_STMT_END
+
+#define _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT(nm_object_class, type_name) \
+ G_STMT_START { \
+ (nm_object_class)->priv_ptr_offset = NM_STRUCT_OFFSET_ENSURE_TYPE (type_name##Private *, type_name, _priv); \
+ (nm_object_class)->priv_ptr_indirect = TRUE; \
+ } G_STMT_END
+
+#define _NM_OBJECT_CLASS_INIT_FIELD_INFO(_nm_object_class, _field_name, _offset, _num) \
+ G_STMT_START { \
+ (_nm_object_class)->_field_name = ({ \
+ static _NMObjectClassFieldInfo _f; \
+ \
+ _f = (_NMObjectClassFieldInfo) { \
+ .parent = (_nm_object_class)->_field_name, \
+ .klass = (_nm_object_class), \
+ .offset = _offset, \
+ .num = _num, \
+ }; \
+ &_f; \
+ }); \
+ } G_STMT_END
+
+#define _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_1(nm_object_class, type_name, field_name) \
+ _NM_OBJECT_CLASS_INIT_FIELD_INFO (nm_object_class, \
+ property_o_info, \
+ NM_STRUCT_OFFSET_ENSURE_TYPE (NMLDBusPropertyO, type_name, field_name), \
+ 1)
+
+#define _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N(nm_object_class, type_name, field_name) \
+ _NM_OBJECT_CLASS_INIT_FIELD_INFO (nm_object_class, \
+ property_o_info, \
+ NM_STRUCT_OFFSET_ENSURE_TYPE (NMLDBusPropertyO *, type_name, field_name), \
+ G_N_ELEMENTS (((type_name *) NULL)->field_name))
+
+#define _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, type_name, field_name) \
+ _NM_OBJECT_CLASS_INIT_FIELD_INFO (nm_object_class, \
+ property_ao_info, \
+ NM_STRUCT_OFFSET_ENSURE_TYPE (NMLDBusPropertyAO, type_name, field_name), \
+ 1)
+
+#define _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_N(nm_object_class, type_name, field_name) \
+ _NM_OBJECT_CLASS_INIT_FIELD_INFO (nm_object_class, \
+ property_ao_info, \
+ NM_STRUCT_OFFSET_ENSURE_TYPE (NMLDBusPropertyAO *, type_name, field_name), \
+ G_N_ELEMENTS (((type_name *) NULL)->field_name))
+
+
/*****************************************************************************/
struct _NMDevicePrivate;
@@ -183,19 +649,13 @@ struct _NMDevice {
struct _NMDeviceClass {
struct _NMObjectClass parent;
- /* Signals */
- void (*state_changed) (NMDevice *device,
- NMDeviceState new_state,
- NMDeviceState old_state,
- NMDeviceStateReason reason);
-
- /* Methods */
gboolean (*connection_compatible) (NMDevice *device,
NMConnection *connection,
GError **error);
- const char * (*get_type_description) (NMDevice *device);
- const char * (*get_hw_address) (NMDevice *device);
+ const char *(*get_type_description) (NMDevice *device);
+
+ const char *(*get_hw_address) (NMDevice *device);
GType (*get_setting_type) (NMDevice *device);
};
@@ -241,4 +701,154 @@ struct _NMIPConfigClass {
/*****************************************************************************/
+NMLDBusObject *_nm_object_get_dbobj (gpointer self);
+
+const char *_nm_object_get_path (gpointer self);
+
+NMClient *_nm_object_get_client (gpointer self);
+
+GDBusConnection *_nm_client_get_dbus_connection (NMClient *client);
+
+const char *_nm_client_get_dbus_name_owner (NMClient *client);
+
+GMainContext *_nm_client_get_context_main (NMClient *client);
+GMainContext *_nm_client_get_context_dbus (NMClient *client);
+
+void _nm_client_queue_notify_object (NMClient *client,
+ gpointer nmobj,
+ const GParamSpec *pspec);
+
+void _nm_client_notify_object_changed (NMClient *self,
+ NMLDBusObject *dbobj);
+
+struct udev *_nm_client_get_udev (NMClient *self);
+
+/*****************************************************************************/
+
+#define NM_CLIENT_NOTIFY_EVENT_PRIO_BEFORE (-100)
+#define NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP 0
+#define NM_CLIENT_NOTIFY_EVENT_PRIO_AFTER 100
+
+typedef struct _NMClientNotifyEvent NMClientNotifyEvent;
+
+typedef void (*NMClientNotifyEventCb) (NMClient *self,
+ gpointer notify_event);
+
+struct _NMClientNotifyEvent {
+ CList lst;
+ NMClientNotifyEventCb callback;
+ int priority;
+};
+
+gpointer _nm_client_notify_event_queue (NMClient *self,
+ int priority,
+ NMClientNotifyEventCb callback,
+ gsize event_size);
+
+typedef struct _NMClientNotifyEventWithPtr NMClientNotifyEventWithPtr;
+
+typedef void (*NMClientNotifyEventWithPtrCb) (NMClient *self,
+ NMClientNotifyEventWithPtr *notify_event);
+
+struct _NMClientNotifyEventWithPtr {
+ NMClientNotifyEvent parent;
+ gpointer user_data;
+};
+
+NMClientNotifyEventWithPtr *_nm_client_notify_event_queue_with_ptr (NMClient *self,
+ int priority,
+ NMClientNotifyEventWithPtrCb callback,
+ gpointer user_data);
+
+void _nm_client_notify_event_queue_emit_obj_signal (NMClient *self,
+ GObject *source,
+ NMObject *nmobj,
+ gboolean is_added /* or else removed */,
+ int prio_offset,
+ guint signal_id);
+
+/*****************************************************************************/
+
+GError *_nm_client_new_error_nm_not_running (void);
+GError *_nm_client_new_error_nm_not_cached (void);
+
+void _nm_client_dbus_call_simple (NMClient *self,
+ GCancellable *cancellable,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+void _nm_client_dbus_call (NMClient *self,
+ gpointer source_obj,
+ gpointer source_tag,
+ GCancellable *cancellable,
+ GAsyncReadyCallback user_callback,
+ gpointer user_callback_data,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ GAsyncReadyCallback internal_callback);
+
+GVariant *_nm_client_dbus_call_sync (NMClient *self,
+ GCancellable *cancellable,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ const GVariantType *reply_type,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ gboolean strip_dbus_error,
+ GError **error);
+
+gboolean _nm_client_dbus_call_sync_void (NMClient *self,
+ GCancellable *cancellable,
+ const char *object_path,
+ const char *interface_name,
+ const char *method_name,
+ GVariant *parameters,
+ GDBusCallFlags flags,
+ int timeout_msec,
+ gboolean strip_dbus_error,
+ GError **error);
+
+void _nm_client_set_property_sync_legacy (NMClient *self,
+ const char *object_path,
+ const char *interface,
+ const char *prop_name,
+ const char *format_string,
+ ...);
+
+/*****************************************************************************/
+
+void _nm_client_get_settings_call (NMClient *self,
+ NMLDBusObject *dbobj);
+
+GCancellable *_nm_remote_settings_get_settings_prepare (NMRemoteConnection *self);
+
+void _nm_remote_settings_get_settings_commit (NMRemoteConnection *self,
+ GVariant *settings);
+
+/*****************************************************************************/
+
+void _nm_active_connection_state_changed_commit (NMActiveConnection *self,
+ guint32 state,
+ guint32 reason);
+
+void _nm_vpn_connection_state_changed_commit (NMVpnConnection *self,
+ guint32 state,
+ guint32 reason);
+
+/*****************************************************************************/
+
#endif /* __NM_LIBNM_UTILS_H__ */
diff --git a/libnm/nm-manager.c b/libnm/nm-manager.c
deleted file mode 100644
index b88aba098e..0000000000
--- a/libnm/nm-manager.c
+++ /dev/null
@@ -1,1532 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1+
-/*
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2014 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nm-manager.h"
-
-#include "nm-utils.h"
-#include "nm-checkpoint.h"
-#include "nm-libnm-core-intern/nm-common-macros.h"
-#include "nm-device-ethernet.h"
-#include "nm-device-wifi.h"
-#include "nm-core-internal.h"
-#include "nm-object-private.h"
-#include "nm-active-connection.h"
-#include "nm-vpn-connection.h"
-#include "nm-dbus-helpers.h"
-#include "c-list/src/c-list.h"
-
-#include "introspection/org.freedesktop.NetworkManager.h"
-
-void _nm_device_wifi_set_wireless_enabled (NMDeviceWifi *device, gboolean enabled);
-
-static void nm_manager_initable_iface_init (GInitableIface *iface);
-static void nm_manager_async_initable_iface_init (GAsyncInitableIface *iface);
-static GInitableIface *nm_manager_parent_initable_iface;
-static GAsyncInitableIface *nm_manager_parent_async_initable_iface;
-
-G_DEFINE_TYPE_WITH_CODE (NMManager, nm_manager, NM_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_manager_initable_iface_init);
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_manager_async_initable_iface_init);
- )
-
-#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
-
-typedef struct {
- NMDBusManager *proxy;
- GCancellable *props_cancellable;
- char *version;
- NMState state;
- gboolean startup;
- GPtrArray *devices;
- GPtrArray *all_devices;
- GPtrArray *active_connections;
- GPtrArray *checkpoints;
- NMConnectivityState connectivity;
- NMActiveConnection *primary_connection;
- NMActiveConnection *activating_connection;
- NMMetered metered;
-
- GCancellable *perm_call_cancellable;
- GHashTable *permissions;
-
- /* Activations waiting for their NMActiveConnection
- * to appear and then their callback to be called.
- */
- CList wait_for_active_connection_lst_head;
-
- CList wait_for_checkpoint_lst_head;
-
- gboolean networking_enabled;
- gboolean wireless_enabled;
- gboolean wireless_hw_enabled;
-
- gboolean wwan_enabled;
- gboolean wwan_hw_enabled;
-
- gboolean wimax_enabled;
- gboolean wimax_hw_enabled;
-
- gboolean connectivity_check_available;
- gboolean connectivity_check_enabled;
-} NMManagerPrivate;
-
-NM_GOBJECT_PROPERTIES_DEFINE (NMManager,
- PROP_VERSION,
- PROP_STATE,
- PROP_STARTUP,
- PROP_NETWORKING_ENABLED,
- PROP_WIRELESS_ENABLED,
- PROP_WIRELESS_HARDWARE_ENABLED,
- PROP_WWAN_ENABLED,
- PROP_WWAN_HARDWARE_ENABLED,
- PROP_WIMAX_ENABLED,
- PROP_WIMAX_HARDWARE_ENABLED,
- PROP_ACTIVE_CONNECTIONS,
- PROP_CONNECTIVITY,
- PROP_CONNECTIVITY_CHECK_AVAILABLE,
- PROP_CONNECTIVITY_CHECK_ENABLED,
- PROP_PRIMARY_CONNECTION,
- PROP_ACTIVATING_CONNECTION,
- PROP_DEVICES,
- PROP_CHECKPOINTS,
- PROP_METERED,
- PROP_ALL_DEVICES,
-);
-
-enum {
- DEVICE_ADDED,
- DEVICE_REMOVED,
- ANY_DEVICE_ADDED,
- ANY_DEVICE_REMOVED,
- ACTIVE_CONNECTION_ADDED,
- ACTIVE_CONNECTION_REMOVED,
- CHECKPOINT_ADDED,
- CHECKPOINT_REMOVED,
- PERMISSION_CHANGED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/*****************************************************************************/
-
-typedef struct {
- CList lst;
- NMManager *self;
- char *checkpoint_path;
- GTask *task;
- gulong cancelled_id;
-} CheckpointInfo;
-
-static CheckpointInfo *
-_wait_for_checkpoint_find_info (NMManager *manager, const char *path)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- CheckpointInfo *info;
-
- c_list_for_each_entry (info, &priv->wait_for_checkpoint_lst_head, lst) {
- if (nm_streq (path, info->checkpoint_path))
- return info;
- }
-
- return NULL;
-}
-
-static void
-_wait_for_checkpoint_complete (CheckpointInfo *info,
- NMCheckpoint *checkpoint,
- GError *error)
-{
- c_list_unlink_stale (&info->lst);
-
- nm_clear_g_signal_handler (g_task_get_cancellable (info->task), &info->cancelled_id);
-
- if (!checkpoint)
- g_task_return_error (info->task, error);
- else
- g_task_return_pointer (info->task, g_object_ref (checkpoint), g_object_unref);
-
- g_object_unref (info->task);
- g_object_unref (info->self);
- g_free (info->checkpoint_path);
- nm_g_slice_free (info);
-}
-
-static void
-nm_manager_init (NMManager *manager)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-
- c_list_init (&priv->wait_for_active_connection_lst_head);
- c_list_init (&priv->wait_for_checkpoint_lst_head);
-
- priv->state = NM_STATE_UNKNOWN;
- priv->connectivity = NM_CONNECTIVITY_UNKNOWN;
-
- priv->permissions = g_hash_table_new (nm_direct_hash, NULL);
- priv->devices = g_ptr_array_new ();
- priv->all_devices = g_ptr_array_new ();
- priv->active_connections = g_ptr_array_new ();
-}
-
-static void
-poke_wireless_devices_with_rf_status (NMManager *manager)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- int i;
-
- for (i = 0; i < priv->all_devices->len; i++) {
- NMDevice *device = g_ptr_array_index (priv->all_devices, i);
-
- if (NM_IS_DEVICE_WIFI (device))
- _nm_device_wifi_set_wireless_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled);
- }
-}
-
-static void
-wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
-{
- poke_wireless_devices_with_rf_status (NM_MANAGER (object));
-}
-
-static void manager_recheck_permissions (NMDBusManager *proxy, gpointer user_data);
-
-static void
-init_dbus (NMObject *object)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_MANAGER_VERSION, &priv->version },
- { NM_MANAGER_STATE, &priv->state },
- { NM_MANAGER_STARTUP, &priv->startup },
- { NM_MANAGER_NETWORKING_ENABLED, &priv->networking_enabled },
- { NM_MANAGER_WIRELESS_ENABLED, &priv->wireless_enabled },
- { NM_MANAGER_WIRELESS_HARDWARE_ENABLED, &priv->wireless_hw_enabled },
- { NM_MANAGER_WWAN_ENABLED, &priv->wwan_enabled },
- { NM_MANAGER_WWAN_HARDWARE_ENABLED, &priv->wwan_hw_enabled },
- { NM_MANAGER_WIMAX_ENABLED, &priv->wimax_enabled },
- { NM_MANAGER_WIMAX_HARDWARE_ENABLED, &priv->wimax_hw_enabled },
- { NM_MANAGER_ACTIVE_CONNECTIONS, &priv->active_connections, NULL, NM_TYPE_ACTIVE_CONNECTION, "active-connection" },
- { NM_MANAGER_CONNECTIVITY, &priv->connectivity },
- { NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE, &priv->connectivity_check_available },
- { NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, &priv->connectivity_check_enabled },
- { NM_MANAGER_PRIMARY_CONNECTION, &priv->primary_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
- { NM_MANAGER_ACTIVATING_CONNECTION, &priv->activating_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
- { NM_MANAGER_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE, "device" },
- { NM_MANAGER_CHECKPOINTS, &priv->checkpoints, NULL, NM_TYPE_CHECKPOINT, "checkpoint" },
- { NM_MANAGER_METERED, &priv->metered },
- { NM_MANAGER_ALL_DEVICES, &priv->all_devices, NULL, NM_TYPE_DEVICE, "any-device" },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_manager_parent_class)->init_dbus (object);
-
- priv->proxy = NMDBUS_MANAGER (_nm_object_get_proxy (object, NM_DBUS_INTERFACE));
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE,
- property_info);
-
- /* Permissions */
- g_signal_connect_object (priv->proxy, "check-permissions",
- G_CALLBACK (manager_recheck_permissions), object, 0);
-}
-
-static void
-object_creation_failed (NMObject *object, const char *failed_path)
-{
- NMManager *self = NM_MANAGER (object);
- CheckpointInfo *info;
- GError *add_error;
-
- info = _wait_for_checkpoint_find_info (self, failed_path);
- if (info) {
- add_error = g_error_new_literal (NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
- _("Checkpoint was removed before it was initialized"));
- _wait_for_checkpoint_complete (info, NULL, add_error);
- g_error_free (add_error);
- }
-}
-
-static void
-update_permissions (NMManager *self, GVariant *permissions)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- GHashTableIter iter;
- gpointer key, value;
- NMClientPermission perm;
- NMClientPermissionResult perm_result;
- GList *keys, *keys_iter;
-
- /* get list of old permissions for change notification */
- keys = g_hash_table_get_keys (priv->permissions);
- g_hash_table_remove_all (priv->permissions);
-
- if (permissions) {
- GVariantIter viter;
- const char *pkey, *pvalue;
-
- /* Process new permissions */
- g_variant_iter_init (&viter, permissions);
- while (g_variant_iter_next (&viter, "{&s&s}", &pkey, &pvalue)) {
- perm = nm_permission_to_client (pkey);
- perm_result = nm_permission_result_to_client (pvalue);
- if (perm) {
- g_hash_table_insert (priv->permissions,
- GUINT_TO_POINTER (perm),
- GUINT_TO_POINTER (perm_result));
-
- /* Remove this permission from the list of previous permissions
- * we'll be sending NM_CLIENT_PERMISSION_RESULT_UNKNOWN for
- * in the change signal since it is still a known permission.
- */
- keys = g_list_remove (keys, GUINT_TO_POINTER (perm));
- }
- }
- }
-
- /* Signal changes in all updated permissions */
- g_hash_table_iter_init (&iter, priv->permissions);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- g_signal_emit (self, signals[PERMISSION_CHANGED], 0,
- GPOINTER_TO_UINT (key),
- GPOINTER_TO_UINT (value));
- }
-
- /* And signal changes in all permissions that used to be valid but for
- * some reason weren't received in the last request (if any).
- */
- for (keys_iter = keys; keys_iter; keys_iter = g_list_next (keys_iter)) {
- g_signal_emit (self, signals[PERMISSION_CHANGED], 0,
- GPOINTER_TO_UINT (keys_iter->data),
- NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
- }
- g_list_free (keys);
-}
-
-static void
-get_permissions_reply (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- NMManager *self;
- NMManagerPrivate *priv;
- gs_unref_variant GVariant *ret = NULL;
- gs_unref_variant GVariant *permissions = NULL;
- gs_free_error GError *error = NULL;
-
- ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), result, &error);
- if (!ret) {
- if (nm_utils_error_is_cancelled (error, FALSE))
- return;
- } else {
- g_variant_get (ret,
- "(@a{ss})",
- &permissions);
- }
-
- self = user_data;
- priv = NM_MANAGER_GET_PRIVATE (self);
-
- g_clear_object (&priv->perm_call_cancellable);
-
- update_permissions (self, permissions);
-}
-
-static void
-manager_recheck_permissions (NMDBusManager *_unused_proxy, gpointer user_data)
-{
- NMManager *self = NM_MANAGER (user_data);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- const char *name_owner;
-
- /* If a request is already pending, then we cancel it. We anyway
- * need to make a new request, to be sure that we picked up on all
- * the latest changes since the "CheckPermission" signal.
- *
- * However, we cannot accept more than one "GetPermissions" request
- * in flight. That is because NetworkManager needs to ask PolicyKit
- * for each permission individually, and some of these permission
- * requests might be answered before others. Hence, the collection
- * of all permissions is not taken at one point in time. Hence, when
- * we would allow for multiple GetPermissions requests in-flight,
- * we wouldn't know which response reflects the latest state. */
- nm_clear_g_cancellable (&priv->perm_call_cancellable);
-
- name_owner = _nm_object_get_dbus_name_owner (self);
- if (!name_owner)
- return;
-
- priv->perm_call_cancellable = g_cancellable_new ();
- g_dbus_connection_call (_nm_object_get_dbus_connection (self),
- name_owner,
- NM_DBUS_PATH,
- NM_DBUS_INTERFACE,
- "GetPermissions",
- g_variant_new ("()"),
- G_VARIANT_TYPE ("(a{ss})"),
- G_DBUS_CALL_FLAGS_NONE,
- NM_DBUS_DEFAULT_TIMEOUT_MSEC,
- priv->perm_call_cancellable,
- get_permissions_reply,
- self);
-}
-
-const char *
-nm_manager_get_version (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return _nml_coerce_property_str_not_empty (NM_MANAGER_GET_PRIVATE (manager)->version);
-}
-
-NMState
-nm_manager_get_state (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
-
- return NM_MANAGER_GET_PRIVATE (manager)->state;
-}
-
-gboolean
-nm_manager_get_startup (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
-
- return NM_MANAGER_GET_PRIVATE (manager)->startup;
-}
-
-gboolean
-nm_manager_networking_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->networking_enabled;
-}
-
-gboolean
-_nm_manager_networking_set_enabled (GDBusConnection *dbus_connection,
- const char *name_owner,
- gboolean enable,
- GError **error)
-{
- gs_unref_variant GVariant *ret = NULL;
-
- ret = g_dbus_connection_call_sync (dbus_connection,
- name_owner,
- NM_DBUS_PATH,
- NM_DBUS_INTERFACE,
- "Enable",
- g_variant_new ("(b)", enable),
- G_VARIANT_TYPE ("()"),
- G_DBUS_CALL_FLAGS_NONE,
- NM_DBUS_DEFAULT_TIMEOUT_MSEC,
- NULL,
- error);
- if (!ret) {
- if (error)
- g_dbus_error_strip_remote_error (*error);
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-nm_manager_wireless_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->wireless_enabled;
-}
-
-void
-nm_manager_wireless_set_enabled (NMManager *manager, gboolean enabled)
-{
- g_return_if_fail (NM_IS_MANAGER (manager));
-
- _nm_object_set_property (NM_OBJECT (manager),
- NM_DBUS_INTERFACE,
- "WirelessEnabled",
- "b", enabled);
-}
-
-gboolean
-nm_manager_wireless_hardware_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->wireless_hw_enabled;
-}
-
-gboolean
-nm_manager_wwan_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->wwan_enabled;
-}
-
-void
-nm_manager_wwan_set_enabled (NMManager *manager, gboolean enabled)
-{
- g_return_if_fail (NM_IS_MANAGER (manager));
-
- _nm_object_set_property (NM_OBJECT (manager),
- NM_DBUS_INTERFACE,
- "WwanEnabled",
- "b", enabled);
-}
-
-gboolean
-nm_manager_wwan_hardware_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->wwan_hw_enabled;
-}
-
-gboolean
-nm_manager_wimax_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->wimax_enabled;
-}
-
-void
-nm_manager_wimax_set_enabled (NMManager *manager, gboolean enabled)
-{
- g_return_if_fail (NM_IS_MANAGER (manager));
-
- _nm_object_set_property (NM_OBJECT (manager),
- NM_DBUS_INTERFACE,
- "WimaxEnabled",
- "b", enabled);
-}
-
-gboolean
-nm_manager_wimax_hardware_get_enabled (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->wimax_hw_enabled;
-}
-
-gboolean
-nm_manager_connectivity_check_get_available (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
-
- return NM_MANAGER_GET_PRIVATE (manager)->connectivity_check_available;
-}
-
-gboolean
-nm_manager_connectivity_check_get_enabled (NMManager *manager)
-{
- return NM_MANAGER_GET_PRIVATE (manager)->connectivity_check_enabled;
-}
-
-void
-nm_manager_connectivity_check_set_enabled (NMManager *manager, gboolean enabled)
-{
- g_return_if_fail (NM_IS_MANAGER (manager));
-
- _nm_object_set_property (NM_OBJECT (manager),
- NM_DBUS_INTERFACE,
- "ConnectivityCheckEnabled",
- "b", enabled);
-}
-
-const char *
-nm_manager_connectivity_check_get_uri (NMManager *manager)
-{
- return nmdbus_manager_get_connectivity_check_uri (NM_MANAGER_GET_PRIVATE (manager)->proxy);
-}
-
-NMClientPermissionResult
-nm_manager_get_permission_result (NMManager *manager, NMClientPermission permission)
-{
- gpointer result;
-
- g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CLIENT_PERMISSION_RESULT_UNKNOWN);
-
- result = g_hash_table_lookup (NM_MANAGER_GET_PRIVATE (manager)->permissions,
- GUINT_TO_POINTER (permission));
- return GPOINTER_TO_UINT (result);
-}
-
-NMConnectivityState
-nm_manager_get_connectivity (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NM_CONNECTIVITY_UNKNOWN);
-
- return NM_MANAGER_GET_PRIVATE (manager)->connectivity;
-}
-
-void
-_nm_manager_set_connectivity_hack (NMManager *manager,
- guint32 connectivity)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
-
- if ((NMConnectivityState) connectivity != priv->connectivity) {
- priv->connectivity = (NMConnectivityState) connectivity;
- _notify (manager, PROP_CONNECTIVITY);
- }
-}
-
-/*****************************************************************************/
-/* Devices */
-/*****************************************************************************/
-
-const GPtrArray *
-nm_manager_get_devices (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return NM_MANAGER_GET_PRIVATE (manager)->devices;
-}
-
-const GPtrArray *
-nm_manager_get_all_devices (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return NM_MANAGER_GET_PRIVATE (manager)->all_devices;
-}
-
-NMDevice *
-nm_manager_get_device_by_path (NMManager *manager, const char *object_path)
-{
- const GPtrArray *devices;
- guint i;
-
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
- g_return_val_if_fail (object_path, NULL);
-
- devices = nm_manager_get_devices (manager);
- 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)) {
- return candidate;
- }
- }
- return NULL;
-}
-
-static NMCheckpoint *
-get_checkpoint_by_path (NMManager *manager, const char *object_path)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- NMCheckpoint *candidate;
- guint i;
-
- for (i = 0; i < priv->checkpoints->len; i++) {
- candidate = priv->checkpoints->pdata[i];
- if (nm_streq (nm_object_get_path (NM_OBJECT (candidate)), object_path))
- return candidate;
- }
- return NULL;
-}
-
-NMDevice *
-nm_manager_get_device_by_iface (NMManager *manager, const char *iface)
-{
- const GPtrArray *devices;
- int i;
- NMDevice *device = NULL;
-
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
- g_return_val_if_fail (iface, NULL);
-
- devices = nm_manager_get_devices (manager);
- for (i = 0; i < devices->len; i++) {
- NMDevice *candidate = g_ptr_array_index (devices, i);
- if (!strcmp (nm_device_get_iface (candidate), iface)) {
- device = candidate;
- break;
- }
- }
-
- return device;
-}
-
-/*****************************************************************************/
-/* Active Connections */
-/*****************************************************************************/
-
-const GPtrArray *
-nm_manager_get_active_connections (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return NM_MANAGER_GET_PRIVATE (manager)->active_connections;
-}
-
-NMActiveConnection *
-nm_manager_get_primary_connection (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return NM_MANAGER_GET_PRIVATE (manager)->primary_connection;
-}
-
-NMActiveConnection *
-nm_manager_get_activating_connection (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return NM_MANAGER_GET_PRIVATE (manager)->activating_connection;
-}
-
-typedef enum {
- ACTIVATE_TYPE_ACTIVATE_CONNECTION,
- ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION,
- ACTIVATE_TYPE_ADD_AND_ACTIVATE_CONNECTION2,
-} ActivateType;
-
-typedef struct {
- CList lst;
- NMManager *manager;
- GTask *task;
- char *active_path;
- GVariant *add_and_activate_output;
- gulong cancelled_id;
- ActivateType activate_type;
-} ActivateInfo;
-
-_NMActivateResult *
-_nm_activate_result_new (NMActiveConnection *active,
- GVariant *add_and_activate_output)
-{
- _NMActivateResult *r;
-
- nm_assert (!add_and_activate_output || g_variant_is_of_type (add_and_activate_output, G_VARIANT_TYPE ("a{sv}")));
- nm_assert (!add_and_activate_output || !g_variant_is_floating (add_and_activate_output));
-
- r = g_slice_new (_NMActivateResult);
- *r = (_NMActivateResult) {
- .active = g_object_ref (active),
- .add_and_activate_output = g_steal_pointer (&add_and_activate_output),
- };
- return r;
-}
-
-void
-_nm_activate_result_free (_NMActivateResult *result)
-{
- nm_g_object_unref (result->active);
- nm_g_variant_unref (result->add_and_activate_output);
- g_slice_free (_NMActivateResult, result);
-}
-
-static void
-activate_info_complete (ActivateInfo *info,
- NMActiveConnection *active,
- GError *error)
-{
- nm_assert (info);
- nm_assert (info->task);
- nm_assert (G_IS_TASK (info->task));
- nm_assert ((!error) != (!active));
-
- c_list_unlink_stale (&info->lst);
-
- nm_clear_g_signal_handler (g_task_get_cancellable (info->task), &info->cancelled_id);
-
- if (error)
- g_task_return_error (info->task, error);
- else {
- g_task_return_pointer (info->task,
- _nm_activate_result_new (active,
- g_steal_pointer (&info->add_and_activate_output)),
- (GDestroyNotify) _nm_activate_result_free);
- }
-
- nm_g_variant_unref (info->add_and_activate_output);
- g_free (info->active_path);
- g_object_unref (info->task);
- g_slice_free (ActivateInfo, info);
-}
-
-static NMActiveConnection *
-find_active_connection_by_path (NMManager *self, const char *ac_path)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- int i;
-
- for (i = 0; i < priv->active_connections->len; i++) {
- NMActiveConnection *candidate = g_ptr_array_index (priv->active_connections, i);
- const char *candidate_path = nm_object_get_path (NM_OBJECT (candidate));
-
- if (g_strcmp0 (ac_path, candidate_path) == 0)
- return candidate;
- }
-
- return NULL;
-}
-
-static void
-_wait_for_active_connections_check (NMManager *self)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- CList *iter;
- NMActiveConnection *candidate;
- const GPtrArray *devices;
- NMDevice *device;
- GDBusObjectManager *object_manager;
-
- object_manager = _nm_object_get_dbus_object_manager (NM_OBJECT (self));
-
- /* For each pending activation, look for an active connection that has the
- * pending activation's object path, where the active connection and its
- * device have both updated their properties to point to each other, and
- * call the pending connection's callback.
- */
-again:
- c_list_for_each (iter, &priv->wait_for_active_connection_lst_head) {
- ActivateInfo *info = c_list_entry (iter, ActivateInfo, lst);
- gs_unref_object GDBusObject *dbus_obj = NULL;
-
- nm_assert (info->active_path);
-
- /* Check that the object manager still knows about the object.
- * It could be that it vanished before we even learned its name. */
- dbus_obj = g_dbus_object_manager_get_object (object_manager, info->active_path);
- if (!dbus_obj) {
- activate_info_complete (info,
- NULL,
- g_error_new_literal (NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
- _("Active connection removed before it was initialized")));
- goto again;
- }
-
- candidate = find_active_connection_by_path (self, info->active_path);
- if (!candidate)
- continue;
-
- /* Check that the AC and device are both ready */
- devices = nm_active_connection_get_devices (candidate);
- if (devices->len == 0)
- continue;
-
- if (!NM_IS_VPN_CONNECTION (candidate)) {
- device = devices->pdata[0];
- if (nm_device_get_active_connection (device) != candidate)
- continue;
- }
-
- activate_info_complete (info, candidate, NULL);
- goto again;
- }
-}
-
-static void
-_wait_for_active_connection_cancelled_cb (GCancellable *cancellable,
- gpointer user_data)
-{
- ActivateInfo *info = user_data;
- gs_free_error GError *error = NULL;
-
- if (!g_cancellable_set_error_if_cancelled (cancellable, &error))
- return;
-
- activate_info_complete (info, NULL, g_steal_pointer (&error));
-}
-
-void
-nm_manager_wait_for_active_connection (NMManager *self,
- const char *active_path,
- const char *connection_path,
- GVariant *add_and_activate_output_take,
- GTask *task_take)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- gs_unref_object GTask *task = task_take;
- gs_unref_variant GVariant *add_and_activate_output = add_and_activate_output_take;
- ActivateInfo *info;
- GCancellable *cancellable;
-
- nm_assert (NM_IS_MANAGER (self));
- nm_assert (active_path);
- nm_assert (G_IS_TASK (task));
-
- /* FIXME: there is no timeout for how long we wait. But this entire
- * code will be reworked, also that we have a suitable GMainContext
- * where we can schedule the timeout (we shouldn't use g_main_context_default()). */
-
- info = g_slice_new (ActivateInfo);
- *info = (ActivateInfo) {
- .manager = g_object_ref (self),
- .task = g_steal_pointer (&task),
- .active_path = g_strdup (active_path),
- .add_and_activate_output = g_steal_pointer (&add_and_activate_output),
- };
- c_list_link_tail (&priv->wait_for_active_connection_lst_head, &info->lst);
-
- cancellable = g_task_get_cancellable (info->task);
- if (cancellable) {
- info->cancelled_id = g_signal_connect (cancellable,
- "cancelled",
- G_CALLBACK (_wait_for_active_connection_cancelled_cb),
- info);
- if (g_cancellable_is_cancelled (cancellable)) {
- _wait_for_active_connection_cancelled_cb (cancellable, info);
- return;
- }
- }
-
- _wait_for_active_connections_check (self);
-}
-
-static void
-device_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
-{
- _wait_for_active_connections_check (user_data);
-}
-
-static void
-device_added (NMManager *self, NMDevice *device)
-{
- g_signal_connect_object (device, "notify::" NM_DEVICE_ACTIVE_CONNECTION,
- G_CALLBACK (device_ac_changed), self, 0);
-}
-
-static void
-device_removed (NMManager *self, NMDevice *device)
-{
- g_signal_handlers_disconnect_by_func (device, G_CALLBACK (device_ac_changed), self);
-}
-
-static void
-ac_devices_changed (GObject *object, GParamSpec *pspec, gpointer user_data)
-{
- _wait_for_active_connections_check (user_data);
-}
-
-static void
-active_connection_added (NMManager *self, NMActiveConnection *ac)
-{
- g_signal_connect_object (ac, "notify::" NM_ACTIVE_CONNECTION_DEVICES,
- G_CALLBACK (ac_devices_changed), self, 0);
- _wait_for_active_connections_check (self);
-}
-
-static void
-active_connection_removed (NMManager *self, NMActiveConnection *ac)
-{
- g_signal_handlers_disconnect_by_func (ac, G_CALLBACK (ac_devices_changed), self);
- _wait_for_active_connections_check (self);
-}
-
-static void
-checkpoint_added (NMManager *manager, NMCheckpoint *checkpoint)
-{
- CheckpointInfo *info;
-
- info = _wait_for_checkpoint_find_info (manager, nm_object_get_path (NM_OBJECT (checkpoint)));
- if (info)
- _wait_for_checkpoint_complete (info, checkpoint, NULL);
-}
-
-/*****************************************************************************/
-
-static void
-free_active_connections (NMManager *manager)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
- int i;
-
- if (!priv->active_connections)
- return;
-
- /* Break circular refs */
- for (i = 0; i < priv->active_connections->len; i++)
- g_object_run_dispose (G_OBJECT (priv->active_connections->pdata[i]));
- g_ptr_array_unref (priv->active_connections);
- priv->active_connections = NULL;
-}
-
-/*****************************************************************************/
-
-const GPtrArray *
-nm_manager_get_checkpoints (NMManager *manager)
-{
- g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
-
- return NM_MANAGER_GET_PRIVATE (manager)->checkpoints;
-}
-
-static void
-_wait_for_checkpoint_cancelled_cb (GCancellable *cancellable,
- gpointer user_data)
-{
- CheckpointInfo *info = user_data;
- gs_free_error GError *error = NULL;
-
- if (!g_cancellable_set_error_if_cancelled (cancellable, &error))
- return;
-
- _wait_for_checkpoint_complete (info, NULL, g_steal_pointer (&error));
-}
-
-void
-nm_manager_wait_for_checkpoint (NMManager *self,
- const char *checkpoint_path,
- GTask *task_take)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
- gs_unref_object GTask *task = task_take;
- CheckpointInfo *info;
- GCancellable *cancellable;
- NMCheckpoint *checkpoint;
-
- checkpoint = get_checkpoint_by_path (self, checkpoint_path);
- if (checkpoint) {
- g_task_return_pointer (task, g_object_ref (checkpoint), g_object_unref);
- return;
- }
-
- /* FIXME: there is no timeout for how long we wait. But this entire
- * code will be reworked, also that we have a suitable GMainContext
- * where we can schedule the timeout (we shouldn't use g_main_context_default()). */
-
- info = g_slice_new (CheckpointInfo);
- *info = (CheckpointInfo) {
- .self = g_object_ref (self),
- .task = g_steal_pointer (&task),
- .checkpoint_path = g_strdup (checkpoint_path),
- };
- c_list_link_tail (&priv->wait_for_checkpoint_lst_head, &info->lst);
-
- cancellable = g_task_get_cancellable (info->task);
- if (cancellable) {
- info->cancelled_id = g_signal_connect (cancellable,
- "cancelled",
- G_CALLBACK (_wait_for_checkpoint_cancelled_cb),
- info);
- if (g_cancellable_is_cancelled (cancellable)) {
- _wait_for_checkpoint_cancelled_cb (cancellable, info);
- return;
- }
- }
-}
-
-/*****************************************************************************/
-
-static void
-constructed (GObject *object)
-{
- G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object);
-
- g_signal_connect (object, "notify::" NM_MANAGER_WIRELESS_ENABLED,
- G_CALLBACK (wireless_enabled_cb), NULL);
-}
-
-static gboolean
-init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
-{
- NMManager *self = NM_MANAGER (initable);
- gs_unref_variant GVariant *permissions = NULL;
- const char *name_owner;
-
- if (!nm_manager_parent_initable_iface->init (initable, cancellable, error))
- g_return_val_if_reached (FALSE);
-
- name_owner = _nm_object_get_dbus_name_owner (self);
- if (name_owner) {
- gs_unref_variant GVariant *ret = NULL;
-
- ret = g_dbus_connection_call_sync (_nm_object_get_dbus_connection (self),
- name_owner,
- NM_DBUS_PATH,
- NM_DBUS_INTERFACE,
- "GetPermissions",
- g_variant_new ("()"),
- G_VARIANT_TYPE ("(a{ss})"),
- G_DBUS_CALL_FLAGS_NONE,
- NM_DBUS_DEFAULT_TIMEOUT_MSEC,
- cancellable,
- NULL);
- if (ret) {
- g_variant_get (ret,
- "(@a{ss})",
- &permissions);
- }
- }
- update_permissions (self, permissions);
-
- return TRUE;
-}
-
-typedef struct {
- NMManager *manager;
- GCancellable *cancellable;
- GSimpleAsyncResult *result;
-} NMManagerInitData;
-
-static void
-init_async_complete (NMManagerInitData *init_data)
-{
- g_simple_async_result_complete (init_data->result);
- g_object_unref (init_data->result);
- g_clear_object (&init_data->cancellable);
- g_slice_free (NMManagerInitData, init_data);
-}
-
-static void
-init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- NMManagerInitData *init_data = user_data;
- GError *error = NULL;
-
- if (!nm_manager_parent_async_initable_iface->init_finish (G_ASYNC_INITABLE (source), result, &error)) {
- g_simple_async_result_take_error (init_data->result, error);
- init_async_complete (init_data);
- return;
- }
-
- manager_recheck_permissions (NULL, init_data->manager);
-
- init_async_complete (init_data);
-}
-
-static void
-init_async (GAsyncInitable *initable, int io_priority,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
-{
- NMManagerInitData *init_data;
-
- init_data = g_slice_new0 (NMManagerInitData);
- init_data->manager = NM_MANAGER (initable);
- init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
- user_data, init_async);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (init_data->result, cancellable);
- g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
-
- nm_manager_parent_async_initable_iface->init_async (initable, io_priority, cancellable,
- init_async_parent_inited, init_data);
-}
-
-static gboolean
-init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
-{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
-
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
- else
- return TRUE;
-}
-
-static void
-dispose (GObject *object)
-{
- NMManager *manager = NM_MANAGER (object);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
-
- nm_assert (c_list_is_empty (&priv->wait_for_active_connection_lst_head));
- nm_assert (c_list_is_empty (&priv->wait_for_checkpoint_lst_head));
-
- nm_clear_g_cancellable (&priv->perm_call_cancellable);
-
- if (priv->devices) {
- g_ptr_array_unref (priv->devices);
- priv->devices = NULL;
- }
- if (priv->all_devices) {
- g_ptr_array_unref (priv->all_devices);
- priv->all_devices = NULL;
- }
-
- nm_clear_pointer (&priv->checkpoints, g_ptr_array_unref);
-
- free_active_connections (manager);
- g_clear_object (&priv->primary_connection);
- g_clear_object (&priv->activating_connection);
-
- g_clear_object (&priv->proxy);
-
- g_hash_table_destroy (priv->permissions);
- priv->permissions = NULL;
-
- G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
-
- g_free (priv->version);
-
- G_OBJECT_CLASS (nm_manager_parent_class)->finalize (object);
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
- gboolean b;
- const char *name_owner;
-
- switch (prop_id) {
- case PROP_NETWORKING_ENABLED:
- b = g_value_get_boolean (value);
- if (priv->networking_enabled != b) {
- if ((name_owner = _nm_object_get_dbus_name_owner (object))) {
- _nm_manager_networking_set_enabled (_nm_object_get_dbus_connection (object),
- name_owner,
- b,
- NULL);
- }
- /* Let the property value flip when we get the change signal from NM */
- }
- break;
- case PROP_WIRELESS_ENABLED:
- b = g_value_get_boolean (value);
- if (priv->wireless_enabled != b) {
- nm_manager_wireless_set_enabled (NM_MANAGER (object), b);
- /* Let the property value flip when we get the change signal from NM */
- }
- break;
- case PROP_WWAN_ENABLED:
- b = g_value_get_boolean (value);
- if (priv->wwan_enabled != b) {
- nm_manager_wwan_set_enabled (NM_MANAGER (object), b);
- /* Let the property value flip when we get the change signal from NM */
- }
- break;
- case PROP_WIMAX_ENABLED:
- b = g_value_get_boolean (value);
- if (priv->wimax_enabled != b) {
- nm_manager_wimax_set_enabled (NM_MANAGER (object), b);
- /* Let the property value flip when we get the change signal from NM */
- }
- break;
- case PROP_CONNECTIVITY_CHECK_ENABLED:
- b = g_value_get_boolean (value);
- if (priv->connectivity_check_enabled != b) {
- nm_manager_connectivity_check_set_enabled (NM_MANAGER (object), b);
- /* Let the property value flip when we get the change signal from NM */
- }
- 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)
-{
- NMManager *self = NM_MANAGER (object);
- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
-
- switch (prop_id) {
- case PROP_VERSION:
- g_value_set_string (value, nm_manager_get_version (self));
- break;
- case PROP_STATE:
- g_value_set_enum (value, nm_manager_get_state (self));
- break;
- case PROP_STARTUP:
- g_value_set_boolean (value, nm_manager_get_startup (self));
- break;
- case PROP_NETWORKING_ENABLED:
- g_value_set_boolean (value, nm_manager_networking_get_enabled (self));
- 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_WWAN_ENABLED:
- g_value_set_boolean (value, priv->wwan_enabled);
- break;
- case PROP_WWAN_HARDWARE_ENABLED:
- g_value_set_boolean (value, priv->wwan_hw_enabled);
- break;
- case PROP_WIMAX_ENABLED:
- g_value_set_boolean (value, priv->wimax_enabled);
- break;
- case PROP_WIMAX_HARDWARE_ENABLED:
- g_value_set_boolean (value, priv->wimax_hw_enabled);
- break;
- case PROP_ACTIVE_CONNECTIONS:
- g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_active_connections (self)));
- break;
- case PROP_CONNECTIVITY:
- g_value_set_enum (value, priv->connectivity);
- break;
- case PROP_CONNECTIVITY_CHECK_AVAILABLE:
- g_value_set_boolean (value, priv->connectivity_check_available);
- break;
- case PROP_CONNECTIVITY_CHECK_ENABLED:
- g_value_set_boolean (value, priv->connectivity_check_enabled);
- break;
- case PROP_PRIMARY_CONNECTION:
- g_value_set_object (value, priv->primary_connection);
- break;
- case PROP_ACTIVATING_CONNECTION:
- g_value_set_object (value, priv->activating_connection);
- break;
- case PROP_DEVICES:
- g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_devices (self)));
- break;
- case PROP_CHECKPOINTS:
- g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_checkpoints (self)));
- break;
- case PROP_METERED:
- g_value_set_uint (value, priv->metered);
- break;
- case PROP_ALL_DEVICES:
- g_value_take_boxed (value, _nm_utils_copy_object_array (nm_manager_get_all_devices (self)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_manager_class_init (NMManagerClass *manager_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (manager_class);
-
- g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
-
- object_class->constructed = constructed;
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
- object_class->finalize = finalize;
-
- nm_object_class->init_dbus = init_dbus;
- nm_object_class->object_creation_failed = object_creation_failed;
-
- manager_class->device_added = device_added;
- manager_class->device_removed = device_removed;
- manager_class->active_connection_added = active_connection_added;
- manager_class->active_connection_removed = active_connection_removed;
- manager_class->checkpoint_added = checkpoint_added;
-
- obj_properties[PROP_VERSION] =
- g_param_spec_string (NM_MANAGER_VERSION, "", "",
- NULL,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_STATE] =
- g_param_spec_enum (NM_CLIENT_STATE, "", "",
- NM_TYPE_STATE,
- NM_STATE_UNKNOWN,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_STARTUP] =
- g_param_spec_boolean (NM_MANAGER_STARTUP, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_NETWORKING_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_NETWORKING_ENABLED, "", "",
- TRUE,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WIRELESS_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED, "", "",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WIRELESS_HARDWARE_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_WIRELESS_HARDWARE_ENABLED, "", "",
- TRUE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WWAN_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_WWAN_ENABLED, "", "",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WWAN_HARDWARE_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_WWAN_HARDWARE_ENABLED, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WIMAX_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, "", "",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_WIMAX_HARDWARE_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ACTIVE_CONNECTIONS] =
- g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, "", "",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_CONNECTIVITY] =
- g_param_spec_enum (NM_CLIENT_CONNECTIVITY, "", "",
- NM_TYPE_CONNECTIVITY_STATE,
- NM_CONNECTIVITY_UNKNOWN,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_CONNECTIVITY_CHECK_AVAILABLE] =
- g_param_spec_boolean (NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_CONNECTIVITY_CHECK_ENABLED] =
- g_param_spec_boolean (NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, "", "",
- FALSE,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_PRIMARY_CONNECTION] =
- g_param_spec_object (NM_MANAGER_PRIMARY_CONNECTION, "", "",
- NM_TYPE_ACTIVE_CONNECTION,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_ACTIVATING_CONNECTION] =
- g_param_spec_object (NM_MANAGER_ACTIVATING_CONNECTION, "", "",
- NM_TYPE_ACTIVE_CONNECTION,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_DEVICES] =
- g_param_spec_boxed (NM_MANAGER_DEVICES, "", "",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- obj_properties[PROP_CHECKPOINTS] =
- g_param_spec_boxed (NM_MANAGER_CHECKPOINTS, "", "",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
- /**
- * NMManager:metered:
- *
- * Whether the connectivity is metered.
- *
- * Since: 1.2
- **/
- obj_properties[PROP_METERED] =
- g_param_spec_uint (NM_MANAGER_METERED, "", "",
- 0, G_MAXUINT32, NM_METERED_UNKNOWN,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_ALL_DEVICES] =
- g_param_spec_boxed (NM_MANAGER_ALL_DEVICES, "", "",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-
- signals[DEVICE_ADDED] =
- g_signal_new ("device-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, device_added),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[DEVICE_REMOVED] =
- g_signal_new ("device-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, device_removed),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[ANY_DEVICE_ADDED] =
- g_signal_new ("any-device-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[ANY_DEVICE_REMOVED] =
- g_signal_new ("any-device-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[ACTIVE_CONNECTION_ADDED] =
- g_signal_new ("active-connection-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, active_connection_added),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[ACTIVE_CONNECTION_REMOVED] =
- g_signal_new ("active-connection-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, active_connection_removed),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[CHECKPOINT_ADDED] =
- g_signal_new ("checkpoint-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, checkpoint_added),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
- signals[CHECKPOINT_REMOVED] =
- g_signal_new ("checkpoint-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMManagerClass, checkpoint_removed),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
-
- signals[PERMISSION_CHANGED] =
- g_signal_new ("permission-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-}
-
-static void
-nm_manager_initable_iface_init (GInitableIface *iface)
-{
- nm_manager_parent_initable_iface = g_type_interface_peek_parent (iface);
-
- iface->init = init_sync;
-}
-
-static void
-nm_manager_async_initable_iface_init (GAsyncInitableIface *iface)
-{
- nm_manager_parent_async_initable_iface = g_type_interface_peek_parent (iface);
-
- iface->init_async = init_async;
- iface->init_finish = init_finish;
-}
diff --git a/libnm/nm-manager.h b/libnm/nm-manager.h
deleted file mode 100644
index 8c28cbe50d..0000000000
--- a/libnm/nm-manager.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1+
-/*
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2007 - 2014 Red Hat, Inc.
- */
-
-#ifndef __NM_MANAGER_H__
-#define __NM_MANAGER_H__
-
-#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE)
-#error Cannot use this header.
-#endif
-
-#include "nm-object.h"
-#include "nm-client.h"
-
-#define NM_TYPE_MANAGER (nm_manager_get_type ())
-#define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager))
-#define NM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MANAGER, NMManagerClass))
-#define NM_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MANAGER))
-#define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_MANAGER))
-#define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass))
-
-#define NM_MANAGER_VERSION "version"
-#define NM_MANAGER_STATE "state"
-#define NM_MANAGER_STARTUP "startup"
-#define NM_MANAGER_NETWORKING_ENABLED "networking-enabled"
-
-_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY_INTERNAL
-#define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled"
-
-_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY_INTERNAL
-#define NM_MANAGER_WWAN_ENABLED "wwan-enabled"
-
-_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY_INTERNAL
-#define NM_MANAGER_WIMAX_ENABLED "wimax-enabled"
-
-#define NM_MANAGER_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled"
-#define NM_MANAGER_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled"
-#define NM_MANAGER_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled"
-#define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections"
-#define NM_MANAGER_CONNECTIVITY "connectivity"
-#define NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE "connectivity-check-available"
-
-_NM_DEPRECATED_SYNC_WRITABLE_PROPERTY_INTERNAL
-#define NM_MANAGER_CONNECTIVITY_CHECK_ENABLED "connectivity-check-enabled"
-
-#define NM_MANAGER_PRIMARY_CONNECTION "primary-connection"
-#define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection"
-#define NM_MANAGER_DEVICES "devices"
-#define NM_MANAGER_CHECKPOINTS "checkpoints"
-#define NM_MANAGER_METERED "metered"
-#define NM_MANAGER_ALL_DEVICES "all-devices"
-
-/**
- * NMManager:
- */
-typedef struct {
- NMObject parent;
-} NMManager;
-
-typedef struct {
- NMObjectClass parent;
-
- /* Signals */
- void (*device_added) (NMManager *manager, NMDevice *device);
- void (*device_removed) (NMManager *manager, NMDevice *device);
- void (*active_connection_added) (NMManager *manager, NMActiveConnection *ac);
- void (*active_connection_removed) (NMManager *manager, NMActiveConnection *ac);
- void (*checkpoint_added) (NMManager *manager, NMCheckpoint *checkpoint);
- void (*checkpoint_removed) (NMManager *manager, NMCheckpoint *checkpoint);
- void (*permission_changed) (NMManager *manager,
- NMClientPermission permission,
- NMClientPermissionResult result);
-} NMManagerClass;
-
-GType nm_manager_get_type (void);
-
-const char *nm_manager_get_version (NMManager *manager);
-NMState nm_manager_get_state (NMManager *manager);
-gboolean nm_manager_get_startup (NMManager *manager);
-
-gboolean nm_manager_networking_get_enabled (NMManager *manager);
-
-_NM_DEPRECATED_SYNC_METHOD_INTERNAL
-gboolean _nm_manager_networking_set_enabled (GDBusConnection *dbus_connection,
- const char *name_owner,
- gboolean enable,
- GError **error);
-
-gboolean nm_manager_wireless_get_enabled (NMManager *manager);
-
-_NM_DEPRECATED_SYNC_METHOD_INTERNAL
-void nm_manager_wireless_set_enabled (NMManager *manager, gboolean enabled);
-
-gboolean nm_manager_wireless_hardware_get_enabled (NMManager *manager);
-
-gboolean nm_manager_wwan_get_enabled (NMManager *manager);
-void nm_manager_wwan_set_enabled (NMManager *manager, gboolean enabled);
-gboolean nm_manager_wwan_hardware_get_enabled (NMManager *manager);
-
-gboolean nm_manager_wimax_get_enabled (NMManager *manager);
-void nm_manager_wimax_set_enabled (NMManager *manager, gboolean enabled);
-gboolean nm_manager_wimax_hardware_get_enabled (NMManager *manager);
-
-gboolean nm_manager_connectivity_check_get_available (NMManager *manager);
-
-gboolean nm_manager_connectivity_check_get_enabled (NMManager *manager);
-
-void nm_manager_connectivity_check_set_enabled (NMManager *manager,
- gboolean enabled);
-
-const char *nm_manager_connectivity_check_get_uri (NMManager *manager);
-
-NMClientPermissionResult nm_manager_get_permission_result (NMManager *manager,
- NMClientPermission permission);
-
-NMConnectivityState nm_manager_get_connectivity (NMManager *manager);
-
-void _nm_manager_set_connectivity_hack (NMManager *manager,
- guint32 connectivity);
-
-/* Devices */
-
-const GPtrArray *nm_manager_get_devices (NMManager *manager);
-const GPtrArray *nm_manager_get_all_devices(NMManager *manager);
-NMDevice *nm_manager_get_device_by_path (NMManager *manager, const char *object_path);
-NMDevice *nm_manager_get_device_by_iface (NMManager *manager, const char *iface);
-
-/* Active Connections */
-
-const GPtrArray *nm_manager_get_active_connections (NMManager *manager);
-
-NMActiveConnection *nm_manager_get_primary_connection (NMManager *manager);
-NMActiveConnection *nm_manager_get_activating_connection (NMManager *manager);
-
-void nm_manager_wait_for_active_connection (NMManager *self,
- const char *active_path,
- const char *connection_path,
- GVariant *add_and_activate_output_take,
- GTask *task_take);
-
-const GPtrArray *nm_manager_get_checkpoints (NMManager *manager);
-
-void nm_manager_wait_for_checkpoint (NMManager *self,
- const char *checkpoint_path,
- GTask *task_take);
-
-/*****************************************************************************/
-
-typedef struct {
- NMActiveConnection *active;
- GVariant *add_and_activate_output;
-} _NMActivateResult;
-
-_NMActivateResult *_nm_activate_result_new (NMActiveConnection *active,
- GVariant *add_and_activate_output);
-
-void _nm_activate_result_free (_NMActivateResult *result);
-
-NM_AUTO_DEFINE_FCN0 (_NMActivateResult *, _nm_auto_free_activate_result, _nm_activate_result_free)
-#define nm_auto_free_activate_result nm_auto(_nm_auto_free_activate_result)
-
-/*****************************************************************************/
-
-#endif /* __NM_MANAGER_H__ */
diff --git a/libnm/nm-object-private.h b/libnm/nm-object-private.h
index 863b228fae..565329502f 100644
--- a/libnm/nm-object-private.h
+++ b/libnm/nm-object-private.h
@@ -12,86 +12,4 @@
#include "nm-object.h"
-typedef gboolean (*PropertyMarshalFunc) (NMObject *, GParamSpec *, GVariant *, gpointer);
-
-typedef GObject * (*NMObjectCreatorFunc) (GDBusConnection *, const char *);
-
-typedef struct {
- const char *name;
- gpointer field;
- PropertyMarshalFunc func;
- GType object_type;
- const char *signal_prefix;
-} NMPropertiesInfo;
-
-void _nm_object_register_properties (NMObject *object,
- const char *interface,
- const NMPropertiesInfo *info);
-
-void _nm_object_queue_notify (NMObject *object, const char *property);
-
-GDBusObjectManager *_nm_object_get_dbus_object_manager (NMObject *object);
-
-GQuark _nm_object_obj_nm_quark (void);
-
-GDBusConnection *_nm_object_get_dbus_connection (gpointer self);
-
-const char *_nm_object_get_dbus_name_owner (gpointer self);
-
-GDBusConnection *_nm_client_get_dbus_connection (NMClient *client);
-
-const char *_nm_client_get_dbus_name_owner (NMClient *client);
-
-void _nm_object_dbus_call (gpointer self,
- gpointer source_tag,
- GCancellable *cancellable,
- GAsyncReadyCallback user_callback,
- gpointer user_callback_data,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- const GVariantType *reply_type,
- GDBusCallFlags flags,
- int timeout_msec,
- GAsyncReadyCallback internal_callback);
-
-GVariant *_nm_object_dbus_call_sync (gpointer self,
- GCancellable *cancellable,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- const GVariantType *reply_type,
- GDBusCallFlags flags,
- int timeout_msec,
- gboolean strip_dbus_error,
- GError **error);
-
-gboolean _nm_object_dbus_call_sync_void (gpointer self,
- GCancellable *cancellable,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- GDBusCallFlags flags,
- int timeout_msec,
- gboolean strip_dbus_error,
- GError **error);
-
-void _nm_object_set_property (NMObject *object,
- const char *interface,
- const char *prop_name,
- const char *format_string,
- ...);
-
-GDBusProxy *_nm_object_get_proxy (NMObject *object,
- const char *interface);
-
-GError *_nm_object_new_error_nm_not_running (void);
-void _nm_object_set_error_nm_not_running (GError **error);
-
-struct udev;
-void _nm_device_set_udev (NMDevice *device, struct udev *udev);
-
#endif /* __NM_OBJECT_PRIVATE_H__ */
diff --git a/libnm/nm-object.c b/libnm/nm-object.c
index a49a905859..10931a89b9 100644
--- a/libnm/nm-object.c
+++ b/libnm/nm-object.c
@@ -21,72 +21,54 @@
/*****************************************************************************/
-static gboolean debug = FALSE;
-#define dbgmsg(f,...) if (G_UNLIKELY (debug)) { g_message (f, ## __VA_ARGS__ ); }
-
-NM_CACHED_QUARK_FCN ("nm-obj-nm", _nm_object_obj_nm_quark)
-
-/*****************************************************************************/
-
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_PATH,
- PROP_DBUS_CONNECTION,
- PROP_DBUS_OBJECT,
- PROP_DBUS_OBJECT_MANAGER,
);
-typedef struct {
- PropertyMarshalFunc func;
- GType object_type;
- gpointer field;
- const char *signal_prefix;
-} PropertyInfo;
-
typedef struct _NMObjectPrivate {
- GDBusObject *object;
- GDBusObjectManager *object_manager;
-
- GSList *property_tables;
- NMObject *parent;
-
- gboolean inited; /* async init finished? */
- GSList *waiters; /* if async init did not finish, users of this object need
- * to defer their notifications by adding themselves here. */
-
- CList notify_items;
- guint notify_id;
-
- guint reload_remaining;
+ NMClient *client;
+ NMLDBusObject *dbobj;
+} NMObjectPrivate;
- CList pending; /* ordered list of pending property updates. */
- GPtrArray *proxies;
+G_DEFINE_ABSTRACT_TYPE (NMObject, nm_object, G_TYPE_OBJECT);
- char *name_owner_cached;
-} NMObjectPrivate;
+#define NM_OBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMObject, NM_IS_OBJECT)
-typedef struct {
- GSList *interfaces;
-} NMObjectClassPrivate;
+static NMObjectClass *_nm_object_class = NULL;
-static void nm_object_initable_iface_init (GInitableIface *iface);
-static void nm_object_async_initable_iface_init (GAsyncInitableIface *iface);
+/*****************************************************************************/
-G_DEFINE_ABSTRACT_TYPE_WITH_CODE (NMObject, nm_object, G_TYPE_OBJECT,
- g_type_add_class_private (g_define_type_id, sizeof (NMObjectClassPrivate));
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_object_initable_iface_init);
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_object_async_initable_iface_init);
- )
+static gpointer
+_nm_object_get_private (NMObjectClass *klass, NMObject *self, guint16 extra_offset)
+{
+ char *ptr;
-#define NM_OBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMObject, NM_IS_OBJECT)
+ nm_assert (klass->priv_ptr_offset > 0);
-#define NM_OBJECT_CLASS_GET_PRIVATE(k) (G_TYPE_CLASS_GET_PRIVATE ((k), NM_TYPE_OBJECT, NMObjectClassPrivate))
+ ptr = (char *) self;
+ ptr += klass->priv_ptr_offset;
+ if (klass->priv_ptr_indirect)
+ ptr = *((gpointer *) ptr);
+ return ptr + extra_offset;
+}
-/*****************************************************************************/
+NMLDBusObject *
+_nm_object_get_dbobj (gpointer self)
+{
+ return NM_OBJECT_GET_PRIVATE (self)->dbobj;
+}
-static void reload_complete (NMObject *object, gboolean emit_now);
-static gboolean demarshal_generic (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field);
+const char *
+_nm_object_get_path (gpointer self)
+{
+ return NM_OBJECT_GET_PRIVATE (self)->dbobj->dbus_path->str;
+}
-/*****************************************************************************/
+NMClient *
+_nm_object_get_client (gpointer self)
+{
+ return NM_OBJECT_GET_PRIVATE (self)->client;
+}
/**
* nm_object_get_path:
@@ -102,1268 +84,122 @@ nm_object_get_path (NMObject *object)
{
g_return_val_if_fail (NM_IS_OBJECT (object), NULL);
- return g_dbus_object_get_object_path (NM_OBJECT_GET_PRIVATE (object)->object);
-}
-
-/**
- * _nm_object_get_proxy:
- * @object: an #NMObject
- * @interface: a D-Bus interface implemented by @object
- *
- * Gets the D-Bus proxy for @interface on @object.
- *
- * Returns: (transfer none): a D-Bus proxy
- */
-GDBusProxy *
-_nm_object_get_proxy (NMObject *object,
- const char *interface)
-{
- NMObjectPrivate *priv;
- GDBusInterface *proxy;
-
- g_return_val_if_fail (NM_IS_OBJECT (object), NULL);
-
- priv = NM_OBJECT_GET_PRIVATE (object);
- if (priv->object == NULL)
- return NULL;
-
- proxy = g_dbus_object_get_interface (priv->object, interface);
- g_return_val_if_fail (proxy != NULL, NULL);
-
- return G_DBUS_PROXY (proxy);
+ return NM_OBJECT_GET_PRIVATE (object)->dbobj->dbus_path->str;
}
/*****************************************************************************/
-GDBusConnection *
-_nm_object_get_dbus_connection (gpointer self)
-{
- NMObjectPrivate *priv;
-
- nm_assert (NM_IS_OBJECT (self));
-
- priv = NM_OBJECT_GET_PRIVATE (self);
-
- return g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager));
-}
-
-const char *
-_nm_object_get_dbus_name_owner (gpointer self)
+static void
+clear_properties (NMObject *self,
+ NMClient *client)
{
- NMObjectPrivate *priv;
+ NMObjectClass *klass = NM_OBJECT_GET_CLASS (self);
+ const _NMObjectClassFieldInfo *p;
+ guint16 i;
nm_assert (NM_IS_OBJECT (self));
+ nm_assert (!client || NM_IS_CLIENT (client));
- priv = NM_OBJECT_GET_PRIVATE (self);
-
- nm_clear_g_free (&priv->name_owner_cached);
- priv->name_owner_cached = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager));
- return priv->name_owner_cached;
-}
+ for (p = klass->property_o_info; p; p = p->parent) {
+ NMLDBusPropertyO *fields = _nm_object_get_private (p->klass, self, p->offset);
-static gboolean
-_get_dbus_params (gpointer self,
- GDBusConnection **out_dbus_connection,
- const char **out_name_owner)
-{
- const char *name_owner;
- GDBusConnection *dbus_connection = NULL;
-
- if (NM_IS_OBJECT (self)) {
- name_owner = _nm_object_get_dbus_name_owner (self);
- if (name_owner)
- dbus_connection = _nm_object_get_dbus_connection (self);
- } else {
- nm_assert (NM_IS_CLIENT (self));
- name_owner = _nm_client_get_dbus_name_owner (self);
- if (name_owner)
- dbus_connection = _nm_client_get_dbus_connection (self);
+ for (i = 0; i < p->num; i++)
+ nml_dbus_property_o_clear (&fields[i], client);
}
- *out_dbus_connection = dbus_connection;
- *out_name_owner = name_owner;
- return !!name_owner;
-}
-
-void
-_nm_object_dbus_call (gpointer self,
- gpointer source_tag,
- GCancellable *cancellable,
- GAsyncReadyCallback user_callback,
- gpointer user_callback_data,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- const GVariantType *reply_type,
- GDBusCallFlags flags,
- int timeout_msec,
- GAsyncReadyCallback internal_callback)
-{
- gs_unref_object GTask *task = NULL;
- const char *name_owner;
- GDBusConnection *dbus_connection;
-
- nm_assert (G_IS_OBJECT (self));
- nm_assert (source_tag);
- nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
- nm_assert (internal_callback);
- nm_assert (object_path);
- nm_assert (interface_name);
- nm_assert (method_name);
- nm_assert (parameters);
- nm_assert (reply_type);
-
- task = nm_g_task_new (self, cancellable, source_tag, user_callback, user_callback_data);
-
- if (!_get_dbus_params (self, &dbus_connection, &name_owner)) {
- nm_g_variant_unref_floating (parameters);
- g_task_return_error (task, _nm_object_new_error_nm_not_running ());
- return;
- }
-
- g_dbus_connection_call (dbus_connection,
- name_owner,
- object_path,
- interface_name,
- method_name,
- parameters,
- reply_type,
- flags,
- timeout_msec,
- cancellable,
- internal_callback,
- g_steal_pointer (&task));
-}
-
-GVariant *
-_nm_object_dbus_call_sync (gpointer self,
- GCancellable *cancellable,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- const GVariantType *reply_type,
- GDBusCallFlags flags,
- int timeout_msec,
- gboolean strip_dbus_error,
- GError **error)
-{
- gs_unref_variant GVariant *ret = NULL;
- GDBusConnection *dbus_connection;
- const char *name_owner;
-
- nm_assert (G_IS_OBJECT (self));
- nm_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
- nm_assert (!error || !*error);
- nm_assert (object_path);
- nm_assert (interface_name);
- nm_assert (method_name);
- nm_assert (parameters);
- nm_assert (reply_type);
-
- if (!_get_dbus_params (self, &dbus_connection, &name_owner)) {
- nm_g_variant_unref_floating (parameters);
- _nm_object_set_error_nm_not_running (error);
- return NULL;
- }
-
- ret = g_dbus_connection_call_sync (dbus_connection,
- name_owner,
- object_path,
- interface_name,
- method_name,
- parameters,
- reply_type,
- flags,
- timeout_msec,
- cancellable,
- error);
- if (!ret) {
- if (error && strip_dbus_error)
- g_dbus_error_strip_remote_error (*error);
- return NULL;
- }
-
- return g_steal_pointer (&ret);
-}
-
-gboolean
-_nm_object_dbus_call_sync_void (gpointer self,
- GCancellable *cancellable,
- const char *object_path,
- const char *interface_name,
- const char *method_name,
- GVariant *parameters,
- GDBusCallFlags flags,
- int timeout_msec,
- gboolean strip_dbus_error,
- GError **error)
-{
- gs_unref_variant GVariant *ret = NULL;
-
- ret = _nm_object_dbus_call_sync (self,
- cancellable,
- object_path,
- interface_name,
- method_name,
- parameters,
- G_VARIANT_TYPE ("()"),
- flags,
- timeout_msec,
- strip_dbus_error,
- error);
- return !!ret;
-}
-
-/*****************************************************************************/
-
-GError *
-_nm_object_new_error_nm_not_running (void)
-{
- return g_error_new_literal (NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_MANAGER_NOT_RUNNING,
- "NetworkManager is not running");
-}
+ for (p = klass->property_ao_info; p; p = p->parent) {
+ NMLDBusPropertyAO *fields = _nm_object_get_private (p->klass, self, p->offset);
-void
-_nm_object_set_error_nm_not_running (GError **error)
-{
- if (error) {
- if (*error)
- g_return_if_reached ();
- *error = _nm_object_new_error_nm_not_running ();
+ for (i = 0; i < p->num; i++)
+ nml_dbus_property_ao_clear (&fields[i], client);
}
}
/*****************************************************************************/
-typedef enum {
- NOTIFY_SIGNAL_PENDING_NONE,
- NOTIFY_SIGNAL_PENDING_ADDED,
- NOTIFY_SIGNAL_PENDING_REMOVED,
- NOTIFY_SIGNAL_PENDING_ADDED_REMOVED,
-} NotifySignalPending;
-
-typedef struct {
- CList lst;
- const char *property;
- const char *signal_prefix;
- NotifySignalPending pending;
- NMObject *changed;
-} NotifyItem;
-
-static void
-notify_item_free (NotifyItem *item)
-{
- c_list_unlink_stale (&item->lst);
- g_clear_object (&item->changed);
- g_slice_free (NotifyItem, item);
-}
-
-static gboolean
-deferred_notify_cb (gpointer data)
+static NMLDBusObjState
+is_visible (NMObject *self)
{
- NMObject *object = NM_OBJECT (data);
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
- NMObjectClass *object_class = NM_OBJECT_GET_CLASS (object);
- CList props;
- CList *iter, *safe;
-
- priv->notify_id = 0;
-
- /* Wait until all reloads are done before notifying */
- if (priv->reload_remaining)
- return G_SOURCE_REMOVE;
+ NMObjectClass *klass = NM_OBJECT_GET_CLASS (self);
+ NMClient *client = _nm_object_get_client (self);
+ const _NMObjectClassFieldInfo *p;
+ guint16 i;
- /* Clear priv->notify_items early so that an NMObject subclass that
- * listens to property changes can queue up other property changes
- * during the g_object_notify() call separately from the property
- * list we're iterating.
- */
- c_list_link_after (&priv->notify_items, &props);
- c_list_unlink (&priv->notify_items);
+ nm_assert (NM_IS_CLIENT (client));
- g_object_ref (object);
+ for (p = klass->property_o_info; p; p = p->parent) {
+ NMLDBusPropertyO *fields = _nm_object_get_private (p->klass, self, p->offset);
- /* Emit added/removed signals first since some of our internal objects
- * use the added/removed signals for new object processing.
- */
- c_list_for_each (iter, &props) {
- NotifyItem *item = c_list_entry (iter, NotifyItem, lst);
- char buf[50];
- int ret = 0;
-
- switch (item->pending) {
- case NOTIFY_SIGNAL_PENDING_ADDED:
- ret = g_snprintf (buf, sizeof (buf), "%s-added", item->signal_prefix);
- break;
- case NOTIFY_SIGNAL_PENDING_REMOVED:
- ret = g_snprintf (buf, sizeof (buf), "%s-removed", item->signal_prefix);
- break;
- case NOTIFY_SIGNAL_PENDING_ADDED_REMOVED:
- if (object_class->object_creation_failed)
- object_class->object_creation_failed (object, nm_object_get_path (item->changed));
- break;
- case NOTIFY_SIGNAL_PENDING_NONE:
- default:
- break;
- }
- if (ret > 0) {
- g_assert (ret < sizeof (buf));
- g_signal_emit_by_name (object, buf, item->changed);
+ for (i = 0; i < p->num; i++) {
+ if (!nml_dbus_property_o_is_ready (&fields[i]))
+ return NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY;
}
}
- /* Emit property change notifications second */
- c_list_for_each (iter, &props) {
- NotifyItem *item = c_list_entry (iter, NotifyItem, lst);
-
- if (item->property)
- g_object_notify (G_OBJECT (object), item->property);
- }
-
- g_object_unref (object);
-
- c_list_for_each_safe (iter, safe, &props)
- notify_item_free (c_list_entry (iter, NotifyItem, lst));
+ for (p = klass->property_ao_info; p; p = p->parent) {
+ NMLDBusPropertyAO *fields = _nm_object_get_private (p->klass, self, p->offset);
- return G_SOURCE_REMOVE;
-}
-
-static void
-_nm_object_defer_notify (NMObject *object)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-
- if (!priv->notify_id)
- priv->notify_id = g_idle_add_full (G_PRIORITY_LOW, deferred_notify_cb, object, NULL);
-}
-
-static void
-_nm_object_queue_notify_full (NMObject *object,
- const char *property,
- const char *signal_prefix,
- gboolean added,
- NMObject *changed)
-{
- NMObjectPrivate *priv;
- NotifyItem *item;
- CList *iter;
-
- g_return_if_fail (NM_IS_OBJECT (object));
- g_return_if_fail (!signal_prefix != !property);
- g_return_if_fail (!signal_prefix == !changed);
-
- priv = NM_OBJECT_GET_PRIVATE (object);
- _nm_object_defer_notify (object);
-
- property = g_intern_string (property);
- signal_prefix = g_intern_string (signal_prefix);
- c_list_for_each (iter, &priv->notify_items) {
- item = c_list_entry (iter, NotifyItem, lst);
-
- if (property && (property == item->property))
- return;
-
- /* Collapse signals for the same object (such as "added->removed") to
- * ensure we don't emit signals when their sum should have no effect.
- * The "added->removed->removed" sequence requires special handling,
- * hence the addition of the ADDED_REMOVED state to ensure that no
- * signal is emitted in this case:
- *
- * Without the ADDED_REMOVED state:
- * NONE + added -> ADDED
- * ADDED + removed -> NONE
- * NONE + removed -> REMOVED (would emit 'removed' signal)
- *
- * With the ADDED_REMOVED state:
- * NONE | ADDED_REMOVED + added -> ADDED
- * ADDED + removed -> ADDED_REMOVED
- * ADDED_REMOVED + removed -> ADDED_REMOVED (emits no signal)
- */
- if (signal_prefix && (changed == item->changed) && (item->signal_prefix == signal_prefix)) {
- switch (item->pending) {
- case NOTIFY_SIGNAL_PENDING_ADDED:
- if (!added)
- item->pending = NOTIFY_SIGNAL_PENDING_ADDED_REMOVED;
- break;
- case NOTIFY_SIGNAL_PENDING_REMOVED:
- if (added)
- item->pending = NOTIFY_SIGNAL_PENDING_NONE;
- break;
- case NOTIFY_SIGNAL_PENDING_ADDED_REMOVED:
- if (added)
- item->pending = NOTIFY_SIGNAL_PENDING_ADDED;
- break;
- case NOTIFY_SIGNAL_PENDING_NONE:
- item->pending = added ? NOTIFY_SIGNAL_PENDING_ADDED : NOTIFY_SIGNAL_PENDING_REMOVED;
- break;
- default:
- g_assert_not_reached ();
- }
- return;
- }
- }
-
- item = g_slice_new0 (NotifyItem);
- item->property = property;
- if (signal_prefix) {
- item->signal_prefix = signal_prefix;
- item->pending = added ? NOTIFY_SIGNAL_PENDING_ADDED : NOTIFY_SIGNAL_PENDING_REMOVED;
- item->changed = changed ? g_object_ref (changed) : NULL;
- }
- c_list_link_tail (&priv->notify_items, &item->lst);
-}
-
-void
-_nm_object_queue_notify (NMObject *object, const char *property)
-{
- _nm_object_queue_notify_full (object, property, NULL, FALSE, NULL);
-}
-
-typedef struct {
- CList lst_pending;
- NMObject *self;
- PropertyInfo *pi;
-
- GObject **objects;
- int length, remaining;
-
- gboolean array;
- const char *property_name;
-} ObjectCreatedData;
-
-static void
-odata_free (gpointer data)
-{
- ObjectCreatedData *odata = data;
-
- c_list_unlink_stale (&odata->lst_pending);
- g_object_unref (odata->self);
- g_free (odata->objects);
- g_slice_free (ObjectCreatedData, odata);
-}
-
-static void object_property_maybe_complete (NMObject *self);
-
-/* Adds object to array if it's not already there */
-static void
-add_to_object_array_unique (GPtrArray *array, GObject *obj)
-{
- guint i;
-
- g_return_if_fail (array != NULL);
-
- if (obj != NULL) {
- for (i = 0; i < array->len; i++) {
- if (g_ptr_array_index (array, i) == obj) {
- g_object_unref (obj);
- return;
- }
- }
- g_ptr_array_add (array, obj);
- }
-}
-
-/* Places items from 'needles' that are not in 'haystack' into 'diff' */
-static void
-array_diff (GPtrArray *needles, GPtrArray *haystack, GPtrArray *diff)
-{
- guint i, j;
- GObject *obj;
-
- g_assert (needles);
- g_assert (haystack);
- g_assert (diff);
-
- for (i = 0; i < needles->len; i++) {
- obj = g_ptr_array_index (needles, i);
-
- for (j = 0; j < haystack->len; j++) {
- if (g_ptr_array_index (haystack, j) == obj)
- break;
- }
-
- if (j == haystack->len)
- g_ptr_array_add (diff, obj);
- }
-}
-
-static void
-queue_added_removed_signal (NMObject *self,
- const char *signal_prefix,
- NMObject *changed,
- gboolean added)
-{
- _nm_object_queue_notify_full (self, NULL, signal_prefix, added, changed);
-}
-
-static gboolean
-already_awaits (ObjectCreatedData *odata, GObject *object)
-{
- NMObject *self = odata->self;
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- GSList *iter;
-
- if ((GObject *)odata->self == object)
- return TRUE;
-
- for (iter = priv->waiters; iter; iter = g_slist_next (iter)) {
- if (already_awaits (iter->data, object))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-object_property_maybe_complete (NMObject *self)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- /* The odata may hold the last reference. */
- _nm_unused gs_unref_object NMObject *self_keep_alive = g_object_ref (self);
- int i;
- CList *iter, *safe;
-
- c_list_for_each_safe (iter, safe, &priv->pending) {
- ObjectCreatedData *odata = c_list_entry (iter, ObjectCreatedData, lst_pending);
- PropertyInfo *pi = odata->pi;
- gboolean different = TRUE;
-
- if (odata->remaining > 0)
- return;
-
- /* Only complete the array property load when all the objects are initialized. */
- for (i = 0; i < odata->length; i++) {
- GObject *obj = odata->objects[i];
- NMObjectPrivate *obj_priv;
-
- /* Could not load the object. Perhaps it was removed. */
- if (!obj)
- continue;
-
- obj_priv = NM_OBJECT_GET_PRIVATE (obj);
- if (!obj_priv->inited) {
-
- /* The object is not finished because we block its creation. */
- if (already_awaits (odata, obj))
- continue;
-
- if (!g_slist_find (obj_priv->waiters, odata))
- obj_priv->waiters = g_slist_prepend (obj_priv->waiters, odata);
- return;
- }
- }
-
- if (odata->array) {
- GPtrArray *old = *((GPtrArray **) pi->field);
- GPtrArray *new;
-
- /* Build up new array */
- new = g_ptr_array_new_full (odata->length, g_object_unref);
- for (i = 0; i < odata->length; i++)
- add_to_object_array_unique (new, odata->objects[i]);
-
- *((GPtrArray **) pi->field) = new;
-
- if (pi->signal_prefix) {
- GPtrArray *added = g_ptr_array_sized_new (3);
- GPtrArray *removed = g_ptr_array_sized_new (3);
-
- if (old) {
- /* Find objects in 'old' that do not exist in 'new' */
- array_diff (old, new, removed);
-
- /* Find objects in 'new' that do not exist in old */
- array_diff (new, old, added);
- } else {
- for (i = 0; i < new->len; i++)
- g_ptr_array_add (added, g_ptr_array_index (new, i));
- }
-
- /* Emit added & removed */
- for (i = 0; i < removed->len; i++) {
- queue_added_removed_signal (self,
- pi->signal_prefix,
- g_ptr_array_index (removed, i),
- FALSE);
- }
-
- for (i = 0; i < added->len; i++) {
- queue_added_removed_signal (self,
- pi->signal_prefix,
- g_ptr_array_index (added, i),
- TRUE);
- }
-
- different = removed->len || added->len;
- g_ptr_array_unref (added);
- g_ptr_array_unref (removed);
- } else {
- /* No added/removed signals to send, just replace the property with
- * the new values.
- */
- different = TRUE;
- }
-
- /* Free old array last since it will release references, thus freeing
- * any objects in the 'removed' array.
- */
- if (old)
- g_ptr_array_unref (old);
- } else {
- GObject **obj_p = pi->field;
-
- different = (*obj_p != odata->objects[0]);
- if (*obj_p)
- g_object_unref (*obj_p);
- *obj_p = odata->objects[0];
+ for (i = 0; i < p->num; i++) {
+ if (!nml_dbus_property_ao_is_ready (&fields[i]))
+ return NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY;
}
-
- if (different && odata->property_name)
- _nm_object_queue_notify (self, odata->property_name);
-
- if (--priv->reload_remaining == 0)
- reload_complete (self, TRUE);
-
- odata_free (odata);
- }
-}
-
-static void
-object_created (GObject *obj, const char *path, gpointer user_data)
-{
- ObjectCreatedData *odata = user_data;
-
- /* We assume that on error, the creator_func printed something */
-
- if (obj == NULL && g_strcmp0 (path, "/") != 0 ) {
- NMObjectClass *object_class = NM_OBJECT_GET_CLASS (odata->self);
-
- if (object_class->object_creation_failed)
- object_class->object_creation_failed (odata->self, path);
- }
-
- odata->objects[odata->length - odata->remaining--] = obj ? g_object_ref (obj) : NULL;
- object_property_maybe_complete (odata->self);
-}
-
-static gboolean
-handle_object_property (NMObject *self, const char *property_name, GVariant *value,
- PropertyInfo *pi)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- gs_unref_object GDBusObject *object = NULL;
- GObject *obj;
- const char *path;
- ObjectCreatedData *odata;
-
- odata = g_slice_new (ObjectCreatedData);
- odata->self = g_object_ref (self);
- odata->pi = pi;
- odata->objects = g_new0 (GObject *, 1);
- odata->length = odata->remaining = 1;
- odata->array = FALSE;
- odata->property_name = property_name;
-
- c_list_link_tail (&priv->pending, &odata->lst_pending);
-
- priv->reload_remaining++;
-
- path = g_variant_get_string (value, NULL);
-
- if (!strcmp (path, "/")) {
- object_created (NULL, path, odata);
- return TRUE;
- }
-
- object = g_dbus_object_manager_get_object (priv->object_manager, path);
- if (!object) {
- /* This is a server bug -- a dangling object path for an object
- * that does not exist.
- *
- * NOTE: We've ignored this before and the server hits the condition
- * more often that it should. Given we're able to recover from
- * the error, let's lower the severity of the log message to
- * avoid unnecessarily bothering the user. This can be removed
- * once the issue is fixed on the server. */
-#if NM_MORE_ASSERTS
-#define __nm_log_debug g_warning
-#else
-#define __nm_log_debug g_debug
-#endif
- __nm_log_debug ("No object known for %s", path);
-#undef __nm_log_debug
- return FALSE;
}
- obj = g_object_get_qdata (G_OBJECT (object), _nm_object_obj_nm_quark ());
- object_created (obj, path, odata);
-
- return TRUE;
+ return NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE;
}
-static gboolean
-handle_object_array_property (NMObject *self, const char *property_name, GVariant *value,
- PropertyInfo *pi)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- GObject *obj;
- GVariantIter iter;
- gsize npaths;
- const char *path;
- ObjectCreatedData *odata;
-
- npaths = g_variant_n_children (value);
-
- odata = g_slice_new (ObjectCreatedData);
- odata->self = g_object_ref (self);
- odata->pi = pi;
- odata->objects = g_new0 (GObject *, npaths);
- odata->length = odata->remaining = npaths;
- odata->array = TRUE;
- odata->property_name = property_name;
-
- c_list_link_tail (&priv->pending, &odata->lst_pending);
-
- priv->reload_remaining++;
-
- if (npaths == 0) {
- object_property_maybe_complete (self);
- return TRUE;
- }
-
- g_variant_iter_init (&iter, value);
- while (g_variant_iter_next (&iter, "&o", &path)) {
- gs_unref_object GDBusObject *object = NULL;
-
- object = g_dbus_object_manager_get_object (priv->object_manager, path);
- if (object) {
- obj = g_object_get_qdata (G_OBJECT (object), _nm_object_obj_nm_quark ());
- object_created (obj, path, odata);
- } else {
- g_warning ("no object known for %s\n", path);
- odata->remaining--;
- odata->length--;
- object_property_maybe_complete (self);
- }
- }
-
- return TRUE;
-}
+/*****************************************************************************/
static void
-handle_property_changed (NMObject *self, const char *dbus_name, GVariant *value)
+register_client (NMObject *self,
+ NMClient *client,
+ NMLDBusObject *dbobj)
{
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- char *prop_name;
- PropertyInfo *pi;
- GParamSpec *pspec;
- gboolean success = FALSE, found = FALSE;
- GSList *iter;
-
- prop_name = nm_utils_wincaps_to_dash (dbus_name);
- /* Iterate through the object and its parents to find the property */
- for (iter = priv->property_tables; iter; iter = g_slist_next (iter)) {
- pi = g_hash_table_lookup ((GHashTable *) iter->data, prop_name);
- if (pi) {
- if (!pi->field) {
- /* We know about this property but aren't tracking changes on it. */
- goto out;
- }
+ nm_assert (!priv->client);
+ nm_assert (NML_IS_DBUS_OBJECT (dbobj));
+ nm_assert (dbobj->nmobj == G_OBJECT (self));
- found = TRUE;
- break;
- }
- }
-
- if (!found) {
- dbgmsg ("Property '%s' unhandled.", prop_name);
- goto out;
- }
-
- pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name);
- if (!pspec && pi->func == demarshal_generic) {
- dbgmsg ("%s: property '%s' changed but wasn't defined by object type %s.",
- __func__,
- prop_name,
- G_OBJECT_TYPE_NAME (self));
- goto out;
- }
-
- if (G_UNLIKELY (debug)) {
- char *s;
- s = g_variant_print (value, FALSE);
- dbgmsg ("PC: (%p) %s:%s => '%s' (%s%s%s)",
- self, G_OBJECT_TYPE_NAME (self),
- prop_name,
- s,
- g_variant_get_type_string (value),
- pi->object_type ? " / " : "",
- pi->object_type ? g_type_name (pi->object_type) : "");
- g_free (s);
- }
-
- if (pspec && pi->object_type) {
- if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH))
- success = handle_object_property (self, pspec->name, value, pi);
- else if (g_variant_is_of_type (value, G_VARIANT_TYPE ("ao")))
- success = handle_object_array_property (self, pspec->name, value, pi);
- else {
- g_warn_if_reached ();
- goto out;
- }
- } else
- success = (*(pi->func)) (self, pspec, value, pi->field);
-
- if (!success) {
- dbgmsg ("%s: failed to update property '%s' of object type %s.",
- __func__,
- prop_name,
- G_OBJECT_TYPE_NAME (self));
- }
-
-out:
- g_free (prop_name);
+ priv->client = client;
+ priv->dbobj = nml_dbus_object_ref (dbobj);
}
static void
-properties_changed (GDBusProxy *proxy,
- GVariant *changed_properties,
- GStrv invalidated_properties,
- gpointer user_data)
+unregister_client (NMObject *self,
+ NMClient *client,
+ NMLDBusObject *dbobj)
{
- NMObject *self = NM_OBJECT (user_data);
- GVariantIter iter;
- const char *name;
- GVariant *value;
-
- g_variant_iter_init (&iter, changed_properties);
- while (g_variant_iter_next (&iter, "{&sv}", &name, &value)) {
- handle_property_changed (self, name, value);
- g_variant_unref (value);
- }
-}
-
-#define HANDLE_TYPE_CHECK(vtype, ctype, getter) \
- ({ \
- gboolean _success = FALSE; \
- \
- if (g_variant_is_of_type (value, vtype)) { \
- ctype *param = (ctype *) field; \
- ctype newval = getter (value); \
- different = *param != newval; \
- *param = newval; \
- _success = TRUE; \
- } \
- \
- _success; \
- })
-
-#define HANDLE_TYPE(vtype, ctype, getter) \
- G_STMT_START { \
- if (!HANDLE_TYPE_CHECK (vtype, ctype, getter)) {\
- success = FALSE; \
- goto done; \
- } \
- } G_STMT_END
-
-static gboolean
-demarshal_generic (NMObject *object,
- GParamSpec *pspec,
- GVariant *value,
- gpointer field)
-{
- gboolean success = TRUE;
- gboolean different = FALSE;
-
- if (pspec->value_type == G_TYPE_STRING) {
- if (g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) {
- char **param = (char **) field;
- const char *newval = g_variant_get_string (value, NULL);
-
- different = !!g_strcmp0 (*param, newval);
- if (different) {
- g_free (*param);
- *param = g_strdup (newval);
- }
- } else if (g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH)) {
- char **param = (char **) field;
- const char *newval = g_variant_get_string (value, NULL);
-
- /* Handle "NULL" object paths */
- if (g_strcmp0 (newval, "/") == 0)
- newval = NULL;
- different = !!g_strcmp0 (*param, newval);
- if (different) {
- g_free (*param);
- *param = g_strdup (newval);
- }
- } else {
- success = FALSE;
- goto done;
- }
- } else if (pspec->value_type == G_TYPE_STRV) {
- char ***param = (char ***)field;
- const char **newval;
- gsize i;
-
- newval = g_variant_get_strv (value, NULL);
- if (!*param)
- different = TRUE;
- else {
- if (!_nm_utils_strv_equal ((char **) newval, *param)) {
- different = TRUE;
- g_strfreev (*param);
- }
- }
- if (different) {
- for (i = 0; newval[i]; i++)
- newval[i] = g_strdup (newval[i]);
- *param = (char **) newval;
- } else
- g_free (newval);
- } else if (pspec->value_type == G_TYPE_BYTES) {
- GBytes **param = (GBytes **)field;
- gconstpointer val;
- gsize length = 0;
-
- val = g_variant_get_fixed_array (value, &length, 1);
-
- different = !nm_utils_gbytes_equal_mem (*param, val, length);
- if (different) {
- if (*param)
- g_bytes_unref (*param);
- *param = length > 0 ? g_bytes_new (val, length) : NULL;
- }
- } else if (G_IS_PARAM_SPEC_ENUM (pspec)) {
- int *param = (int *) field;
- int newval = 0;
-
- if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32))
- newval = g_variant_get_int32 (value);
- else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
- newval = g_variant_get_uint32 (value);
- else {
- success = FALSE;
- goto done;
- }
- different = *param != newval;
- *param = newval;
- } else if (G_IS_PARAM_SPEC_FLAGS (pspec)) {
- guint *param = (guint *) field;
- guint newval = 0;
-
- if (g_variant_is_of_type (value, G_VARIANT_TYPE_INT32))
- newval = g_variant_get_int32 (value);
- else if (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32))
- newval = g_variant_get_uint32 (value);
- else {
- success = FALSE;
- goto done;
- }
- different = *param != newval;
- *param = newval;
- } else if (pspec->value_type == G_TYPE_BOOLEAN)
- HANDLE_TYPE (G_VARIANT_TYPE_BOOLEAN, gboolean, g_variant_get_boolean);
- else if (pspec->value_type == G_TYPE_UCHAR)
- HANDLE_TYPE (G_VARIANT_TYPE_BYTE, guchar, g_variant_get_byte);
- else if (pspec->value_type == G_TYPE_DOUBLE) {
- NM_PRAGMA_WARNING_DISABLE("-Wfloat-equal")
- HANDLE_TYPE (G_VARIANT_TYPE_DOUBLE, double, g_variant_get_double);
- NM_PRAGMA_WARNING_REENABLE
- } else if (pspec->value_type == G_TYPE_INT)
- HANDLE_TYPE (G_VARIANT_TYPE_INT32, int, g_variant_get_int32);
- else if (pspec->value_type == G_TYPE_UINT) {
- if ( !HANDLE_TYPE_CHECK (G_VARIANT_TYPE_UINT32, guint, g_variant_get_uint32)
- && !HANDLE_TYPE_CHECK (G_VARIANT_TYPE_UINT16, guint, g_variant_get_uint16))
- success = FALSE;
- } else if (pspec->value_type == G_TYPE_INT64)
- HANDLE_TYPE (G_VARIANT_TYPE_INT64, gint64, g_variant_get_int64);
- else if (pspec->value_type == G_TYPE_UINT64)
- HANDLE_TYPE (G_VARIANT_TYPE_UINT64, guint64, g_variant_get_uint64);
- else if (pspec->value_type == G_TYPE_LONG)
- HANDLE_TYPE (G_VARIANT_TYPE_INT64, long, g_variant_get_int64);
- else if (pspec->value_type == G_TYPE_ULONG)
- HANDLE_TYPE (G_VARIANT_TYPE_UINT64, gulong, g_variant_get_uint64);
- 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) {
- if (different)
- _nm_object_queue_notify (object, pspec->name);
- } else {
- dbgmsg ("%s: %s:%s (type %s) couldn't be set from D-Bus type %s.",
- __func__, G_OBJECT_TYPE_NAME (object), pspec->name,
- g_type_name (pspec->value_type), g_variant_get_type_string (value));
- }
- return success;
-}
-
-void
-_nm_object_register_properties (NMObject *object,
- const char *interface,
- const NMPropertiesInfo *info)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
- GDBusProxy *proxy;
- static gsize dval = 0;
- const char *debugstr;
- NMPropertiesInfo *tmp;
- GHashTable *instance;
-
- g_return_if_fail (NM_IS_OBJECT (object));
- g_return_if_fail (interface != NULL);
- g_return_if_fail (info != NULL);
-
- if (g_once_init_enter (&dval)) {
- debugstr = getenv ("LIBNM_GLIB_DEBUG");
- if (debugstr && strstr (debugstr, "properties-changed"))
- debug = TRUE;
- g_once_init_leave (&dval, 1);
- }
-
- proxy = _nm_object_get_proxy (object, interface);
- g_signal_connect (proxy, "g-properties-changed",
- G_CALLBACK (properties_changed), object);
- g_ptr_array_add (priv->proxies, proxy);
-
- instance = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
- priv->property_tables = g_slist_prepend (priv->property_tables, instance);
-
- for (tmp = (NMPropertiesInfo *) info; tmp->name; tmp++) {
- PropertyInfo *pi;
-
- if (!tmp->name || (tmp->func && !tmp->field)) {
- g_warning ("%s: missing field in NMPropertiesInfo", __func__);
- continue;
- }
-
- pi = g_malloc0 (sizeof (PropertyInfo));
- pi->func = tmp->func ?: demarshal_generic;
- pi->object_type = tmp->object_type;
- pi->field = tmp->field;
- pi->signal_prefix = tmp->signal_prefix;
- g_hash_table_insert (instance, g_strdup (tmp->name), pi);
- }
-}
-
-void
-_nm_object_set_property (NMObject *object,
- const char *interface,
- const char *prop_name,
- const char *format_string,
- ...)
-{
- GVariant *val, *ret;
- GDBusProxy *proxy;
- va_list ap;
-
- g_return_if_fail (NM_IS_OBJECT (object));
- g_return_if_fail (interface != NULL);
- g_return_if_fail (prop_name != NULL);
- g_return_if_fail (format_string != NULL);
-
- va_start (ap, format_string);
- val = g_variant_new_va (format_string, NULL, &ap);
- va_end (ap);
- g_return_if_fail (val != NULL);
-
- proxy = _nm_object_get_proxy (object, interface);
- ret = g_dbus_proxy_call_sync (proxy,
- DBUS_INTERFACE_PROPERTIES ".Set",
- g_variant_new ("(ssv)", interface, prop_name, val),
- G_DBUS_CALL_FLAGS_NONE, 2000,
- NULL, NULL);
- /* Ignore errors. */
- if (ret)
- g_variant_unref (ret);
- g_object_unref (proxy);
-}
-
-static void
-reload_complete (NMObject *object, gboolean emit_now)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-
- if (emit_now) {
- nm_clear_g_source (&priv->notify_id);
- deferred_notify_cb (object);
- } else
- _nm_object_defer_notify (object);
-}
-
-GDBusObjectManager *
-_nm_object_get_dbus_object_manager (NMObject *self)
-{
- return NM_OBJECT_GET_PRIVATE (self)->object_manager;
-}
-
-/*****************************************************************************/
-
-static void
-init_dbus (NMObject *object)
-{
-}
-
-static void
-init_if (GDBusProxy *proxy, NMObject *self)
-{
- char **props;
- char **prop;
- GVariant *val;
- char *str;
-
- nm_assert (G_IS_DBUS_PROXY (proxy));
- nm_assert (NM_IS_OBJECT (self));
-
- props = g_dbus_proxy_get_cached_property_names (proxy);
-
- for (prop = props; prop && *prop; prop++) {
- val = g_dbus_proxy_get_cached_property (proxy, *prop);
- str = g_variant_print (val, TRUE);
- handle_property_changed (self, *prop, val);
- g_variant_unref (val);
- g_free (str);
- }
-
- g_strfreev (props);
-}
-
-static gboolean
-init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
-{
- NMObject *self = NM_OBJECT (initable);
NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- GList *interfaces;
-
- g_assert (priv->object && priv->object_manager);
-
- NM_OBJECT_GET_CLASS (self)->init_dbus (self);
-
- priv->reload_remaining++;
-
- interfaces = g_dbus_object_get_interfaces (priv->object);
- g_list_foreach (interfaces, (GFunc) init_if, self);
- g_list_free_full (interfaces, g_object_unref);
-
- priv->inited = TRUE;
-
- if (--priv->reload_remaining == 0)
- reload_complete (self, TRUE);
- /* There are some object properties whose creation couldn't proceed
- * because it depended on this object. */
- while (priv->waiters) {
- ObjectCreatedData *odata = priv->waiters->data;
+ nm_assert (NM_IS_CLIENT (client));
+ nm_assert (priv->client == client);
+ priv->client = NULL;
- priv->waiters = g_slist_remove (priv->waiters, odata);
- object_property_maybe_complete (odata->self);
- }
-
- return TRUE;
+ clear_properties (self, client);
}
/*****************************************************************************/
-typedef struct {
- NMObject *object;
- GSimpleAsyncResult *simple;
- GCancellable *cancellable;
- int proxies_pending;
- GError *error;
-} NMObjectInitData;
-
static void
-init_async_complete (NMObjectInitData *init_data)
-{
- if (init_data->error)
- g_simple_async_result_take_error (init_data->simple, init_data->error);
- else
- g_simple_async_result_set_op_res_gboolean (init_data->simple, TRUE);
- g_simple_async_result_complete_in_idle (init_data->simple);
- g_object_unref (init_data->simple);
- g_clear_object (&init_data->cancellable);
- g_slice_free (NMObjectInitData, init_data);
-}
-
-static void
-init_async (GAsyncInitable *initable, int io_priority,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
-{
- NMObject *self = NM_OBJECT (initable);
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- NMObjectInitData *init_data;
- GList *interfaces;
-
- g_assert (priv->object && priv->object_manager);
-
- NM_OBJECT_GET_CLASS (self)->init_dbus (self);
-
- init_data = g_slice_new0 (NMObjectInitData);
- init_data->object = self;
- init_data->simple = g_simple_async_result_new (G_OBJECT (initable), callback, user_data, init_async);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (init_data->simple, cancellable);
- init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
-
- interfaces = g_dbus_object_get_interfaces (priv->object);
- g_list_foreach (interfaces, (GFunc) init_if, self);
- g_list_free_full (interfaces, g_object_unref);
-
- init_async_complete (init_data);
-}
-
-static gboolean
-init_finish (GAsyncInitable *initable, GAsyncResult *result, GError **error)
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
{
- GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
- NMObject *self = NM_OBJECT (initable);
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
-
- priv->inited = TRUE;
-
- /* There are some object properties whose creation couldn't proceed
- * because it depended on this object. */
- while (priv->waiters) {
- ObjectCreatedData *odata = priv->waiters->data;
+ NMObject *self = NM_OBJECT (object);
- priv->waiters = g_slist_remove (priv->waiters, odata);
- object_property_maybe_complete (odata->self);
+ switch (prop_id) {
+ case PROP_PATH:
+ g_value_set_string (value, nm_object_get_path (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
-
- if (g_simple_async_result_propagate_error (simple, error))
- return FALSE;
- else
- return TRUE;
}
/*****************************************************************************/
static void
-nm_object_initable_iface_init (GInitableIface *iface)
-{
- iface->init = init_sync;
-}
-
-static void
-nm_object_async_initable_iface_init (GAsyncInitableIface *iface)
-{
- iface->init_async = init_async;
- iface->init_finish = init_finish;
-}
-
-static void
nm_object_init (NMObject *object)
{
NMObject *self = NM_OBJECT (object);
@@ -1373,109 +209,43 @@ nm_object_init (NMObject *object)
self->_priv = priv;
- c_list_init (&priv->notify_items);
- c_list_init (&priv->pending);
- priv->proxies = g_ptr_array_new ();
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_DBUS_OBJECT:
- /* construct-only */
- priv->object = g_value_dup_object (value);
- if (!priv->object)
- g_return_if_reached ();
- break;
- case PROP_DBUS_OBJECT_MANAGER:
- /* construct-only */
- priv->object_manager = g_value_dup_object (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)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_PATH:
- g_value_set_string (value, nm_object_get_path (NM_OBJECT (object)));
- break;
- case PROP_DBUS_CONNECTION:
- g_value_set_object (value, g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
+ c_list_init (&self->obj_base.queue_notify_lst);
}
static void
dispose (GObject *object)
{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
- CList *iter, *safe;
- guint i;
-
- nm_clear_g_source (&priv->notify_id);
-
- c_list_for_each_safe (iter, safe, &priv->notify_items)
- notify_item_free (c_list_entry (iter, NotifyItem, lst));
+ NMObject *self = NM_OBJECT (object);
+ NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (self);
- g_slist_free_full (priv->waiters, odata_free);
+ self->obj_base.is_disposing = TRUE;
- g_clear_object (&priv->object);
- g_clear_object (&priv->object_manager);
+ nm_assert (c_list_is_empty (&self->obj_base.queue_notify_lst));
+ nm_assert (!priv->client);
+ nm_assert (!priv->dbobj || !priv->dbobj->nmobj);
- if (priv->proxies) {
- for (i = 0; i < priv->proxies->len; i++) {
- g_signal_handlers_disconnect_by_func (priv->proxies->pdata[i],
- properties_changed,
- object);
- g_object_unref (priv->proxies->pdata[i]);
- }
- g_ptr_array_free (priv->proxies, TRUE);
- priv->proxies = NULL;
- }
+ clear_properties (self, NULL);
G_OBJECT_CLASS (nm_object_parent_class)->dispose (object);
-}
-
-static void
-finalize (GObject *object)
-{
- NMObjectPrivate *priv = NM_OBJECT_GET_PRIVATE (object);
-
- g_slist_free_full (priv->property_tables, (GDestroyNotify) g_hash_table_destroy);
- g_free (priv->name_owner_cached);
-
- G_OBJECT_CLASS (nm_object_parent_class)->finalize (object);
+ nm_clear_pointer (&priv->dbobj, nml_dbus_object_unref);
}
static void
-nm_object_class_init (NMObjectClass *nm_object_class)
+nm_object_class_init (NMObjectClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (nm_object_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ _nm_object_class = klass;
- g_type_class_add_private (nm_object_class, sizeof (NMObjectPrivate));
+ g_type_class_add_private (klass, sizeof (NMObjectPrivate));
object_class->get_property = get_property;
- object_class->set_property = set_property;
object_class->dispose = dispose;
- object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
+ klass->register_client = register_client;
+ klass->unregister_client = unregister_client;
+ klass->is_visible = is_visible;
/**
* NMObject:path:
@@ -1488,40 +258,5 @@ nm_object_class_init (NMObjectClass *nm_object_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- /**
- * NMObject:dbus-connection: (skip)
- *
- * The #GDBusConnection of the object.
- **/
- obj_properties[PROP_DBUS_CONNECTION] =
- g_param_spec_object (NM_OBJECT_DBUS_CONNECTION, "", "",
- G_TYPE_DBUS_CONNECTION,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * NMObject:dbus-object: (skip)
- *
- * The #GDBusObject of the object.
- **/
- obj_properties[PROP_DBUS_OBJECT] =
- g_param_spec_object (NM_OBJECT_DBUS_OBJECT, "", "",
- G_TYPE_DBUS_OBJECT,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
- /**
- * NMObject:dbus-object-manager: (skip)
- *
- * The #GDBusObjectManager of the object.
- **/
- obj_properties[PROP_DBUS_OBJECT_MANAGER] =
- g_param_spec_object (NM_OBJECT_DBUS_OBJECT_MANAGER, "", "",
- G_TYPE_DBUS_OBJECT_MANAGER,
- G_PARAM_WRITABLE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS);
-
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}
diff --git a/libnm/nm-object.h b/libnm/nm-object.h
index d9ee4444c8..88c34a9eb1 100644
--- a/libnm/nm-object.h
+++ b/libnm/nm-object.h
@@ -23,9 +23,6 @@ G_BEGIN_DECLS
#define NM_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_OBJECT, NMObjectClass))
#define NM_OBJECT_PATH "path"
-#define NM_OBJECT_DBUS_CONNECTION "dbus-connection"
-#define NM_OBJECT_DBUS_OBJECT "dbus-object"
-#define NM_OBJECT_DBUS_OBJECT_MANAGER "dbus-object-manager"
/**
* NMObject:
diff --git a/libnm/nm-remote-connection.c b/libnm/nm-remote-connection.c
index c45c7f1fce..294ec5179d 100644
--- a/libnm/nm-remote-connection.c
+++ b/libnm/nm-remote-connection.c
@@ -17,8 +17,6 @@
#include "nm-object-private.h"
#include "nm-dbus-helpers.h"
-#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h"
-
/**
* SECTION:nm-remote-connection
* @short_description: A connection managed by NetworkManager server
@@ -37,13 +35,14 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMRemoteConnection,
);
typedef struct {
- NMDBusSettingsConnection *proxy;
+ GCancellable *get_settings_cancellable;
- gboolean unsaved;
- guint32 flags;
char *filename;
+ guint32 flags;
+ bool unsaved;
- gboolean visible;
+ bool visible:1;
+ bool is_initialized:1;
} NMRemoteConnectionPrivate;
struct _NMRemoteConnection {
@@ -56,20 +55,12 @@ struct _NMRemoteConnectionClass {
};
static void nm_remote_connection_connection_iface_init (NMConnectionInterface *iface);
-static void nm_remote_connection_initable_iface_init (GInitableIface *iface);
-static void nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface);
G_DEFINE_TYPE_WITH_CODE (NMRemoteConnection, nm_remote_connection, NM_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_remote_connection_connection_iface_init);
- G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_remote_connection_initable_iface_init);
- G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, nm_remote_connection_async_initable_iface_init);
)
-#define NM_REMOTE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMRemoteConnection, NM_IS_REMOTE_CONNECTION, NMObject)
-
-/*****************************************************************************/
-static GInitableIface *nm_remote_connection_parent_initable_iface;
-static GAsyncInitableIface *nm_remote_connection_parent_async_initable_iface;
+#define NM_REMOTE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMRemoteConnection, NM_IS_REMOTE_CONNECTION, NMObject)
/*****************************************************************************/
@@ -106,12 +97,13 @@ nm_remote_connection_update2 (NMRemoteConnection *connection,
if (!args)
args = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
- _nm_object_dbus_call (connection,
+ _nm_client_dbus_call (_nm_object_get_client (connection),
+ connection,
nm_remote_connection_update2,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"Update2",
g_variant_new ("(@a{sa{sv}}u@a{sv})",
@@ -185,9 +177,9 @@ nm_remote_connection_commit_changes (NMRemoteConnection *connection,
g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
- ret = _nm_object_dbus_call_sync (connection,
+ ret = _nm_client_dbus_call_sync (_nm_object_get_client (connection),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"Update2",
g_variant_new ("(@a{sa{sv}}u@a{sv})",
@@ -287,9 +279,9 @@ nm_remote_connection_save (NMRemoteConnection *connection,
g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), FALSE);
- return _nm_object_dbus_call_sync_void (connection,
+ return _nm_client_dbus_call_sync_void (_nm_object_get_client (connection),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"Save",
g_variant_new ("()"),
@@ -318,12 +310,13 @@ nm_remote_connection_save_async (NMRemoteConnection *connection,
g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (connection,
+ _nm_client_dbus_call (_nm_object_get_client (connection),
+ connection,
nm_remote_connection_save_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"Save",
g_variant_new ("()"),
@@ -375,9 +368,9 @@ nm_remote_connection_delete (NMRemoteConnection *connection,
{
g_return_val_if_fail (NM_IS_REMOTE_CONNECTION (connection), FALSE);
- return _nm_object_dbus_call_sync_void (connection,
+ return _nm_client_dbus_call_sync_void (_nm_object_get_client (connection),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"Delete",
g_variant_new ("()"),
@@ -405,12 +398,13 @@ nm_remote_connection_delete_async (NMRemoteConnection *connection,
g_return_if_fail (NM_IS_REMOTE_CONNECTION (connection));
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (connection,
+ _nm_client_dbus_call (_nm_object_get_client (connection),
+ connection,
nm_remote_connection_delete_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"Delete",
g_variant_new ("()"),
@@ -469,9 +463,9 @@ nm_remote_connection_get_secrets (NMRemoteConnection *connection,
g_return_val_if_fail (setting_name, NULL);
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
- ret = _nm_object_dbus_call_sync (connection,
+ ret = _nm_client_dbus_call_sync (_nm_object_get_client (connection),
cancellable,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"GetSecrets",
g_variant_new ("(s)", setting_name),
@@ -511,12 +505,13 @@ nm_remote_connection_get_secrets_async (NMRemoteConnection *connection,
g_return_if_fail (setting_name);
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
- _nm_object_dbus_call (connection,
+ _nm_client_dbus_call (_nm_object_get_client (connection),
+ connection,
nm_remote_connection_get_secrets_async,
cancellable,
callback,
user_data,
- g_dbus_proxy_get_object_path (G_DBUS_PROXY (NM_REMOTE_CONNECTION_GET_PRIVATE (connection)->proxy)),
+ _nm_object_get_path (connection),
NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
"GetSecrets",
g_variant_new ("(s)", setting_name),
@@ -633,195 +628,102 @@ nm_remote_connection_get_visible (NMRemoteConnection *connection)
/*****************************************************************************/
-static void
-replace_settings (NMRemoteConnection *self, GVariant *new_settings)
+GCancellable *
+_nm_remote_settings_get_settings_prepare (NMRemoteConnection *self)
{
- GError *error = NULL;
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
- if (!_nm_connection_replace_settings ((NMConnection *) self,
- new_settings,
- NM_SETTING_PARSE_FLAGS_BEST_EFFORT,
- &error))
- g_clear_error (&error);
+ nm_clear_g_cancellable (&priv->get_settings_cancellable);
+ priv->get_settings_cancellable = g_cancellable_new ();
+ return priv->get_settings_cancellable;
}
-static void
-updated_get_settings_cb (GObject *proxy,
- GAsyncResult *result,
- gpointer user_data)
+void
+_nm_remote_settings_get_settings_commit (NMRemoteConnection *self,
+ GVariant *settings)
{
- NMRemoteConnection *self = user_data;
NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
- GVariant *new_settings;
- gboolean visible;
-
- if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &new_settings,
- result, NULL)) {
- /* Connection is no longer visible to this user. */
- nm_connection_clear_settings (NM_CONNECTION (self));
+ GError *error = NULL;
+ gboolean visible = FALSE;
+ gboolean changed = FALSE;
- visible = FALSE;
- } else {
- replace_settings (self, new_settings);
- g_variant_unref (new_settings);
+ g_clear_object (&priv->get_settings_cancellable);
- visible = TRUE;
+ if (!priv->is_initialized) {
+ changed = TRUE;
+ priv->is_initialized = TRUE;
}
- if (visible != priv->visible) {
+ if (settings) {
+ if (!_nm_connection_replace_settings ((NMConnection *) self,
+ settings,
+ NM_SETTING_PARSE_FLAGS_BEST_EFFORT,
+ &error)) {
+ NML_NMCLIENT_LOG_E (_nm_object_get_client (self), "[%s] failure to update settings: %s",
+ _nm_object_get_path (self),
+ error->message);
+ g_clear_error (&error);
+ } else
+ visible = TRUE;
+ } else
+ nm_connection_clear_settings (NM_CONNECTION (self));
+
+ if (priv->visible != visible) {
priv->visible = visible;
- _notify (self, PROP_VISIBLE);
+ _nm_client_queue_notify_object (_nm_object_get_client (self),
+ self,
+ obj_properties[PROP_VISIBLE]);
+ changed = TRUE;
}
- g_object_unref (self);
-}
-
-static void
-updated_cb (NMDBusSettingsConnection *proxy, gpointer user_data)
-{
- NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data);
- NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
-
- /* The connection got updated; request the replacement settings */
- nmdbus_settings_connection_call_get_settings (priv->proxy,
- NULL,
- updated_get_settings_cb,
- g_object_ref (self));
+ if (changed)
+ _nm_client_notify_object_changed (_nm_object_get_client (self), _nm_object_get_dbobj (self));
}
/*****************************************************************************/
-static void
-init_dbus (NMObject *object)
-{
- NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_REMOTE_CONNECTION_UNSAVED, &priv->unsaved },
- { NM_REMOTE_CONNECTION_FLAGS, &priv->flags },
- { NM_REMOTE_CONNECTION_FILENAME, &priv->filename },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_remote_connection_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
- property_info);
-}
-
-static gboolean
-init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
+static NMLDBusObjState
+is_visible (NMObject *nmobj)
{
- NMRemoteConnection *self = NM_REMOTE_CONNECTION (initable);
- NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
- GVariant *settings;
-
- priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (NM_OBJECT (initable), NM_DBUS_INTERFACE_SETTINGS_CONNECTION));
- g_signal_connect_object (priv->proxy, "updated", G_CALLBACK (updated_cb), initable, 0);
-
- if (nmdbus_settings_connection_call_get_settings_sync (priv->proxy,
- &settings,
- cancellable,
- NULL)) {
- priv->visible = TRUE;
- replace_settings (self, settings);
- g_variant_unref (settings);
- }
+ NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (nmobj);
+ NMLDBusObjState obj_state;
- if (!nm_remote_connection_parent_initable_iface->init (initable, cancellable, error))
- return FALSE;
+ if (!priv->is_initialized)
+ return NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY;
- return TRUE;
-}
+ obj_state = NM_OBJECT_CLASS (nm_remote_connection_parent_class)->is_visible (nmobj);
-typedef struct {
- NMRemoteConnection *connection;
- GCancellable *cancellable;
- GSimpleAsyncResult *result;
- GAsyncInitable *initable;
- int io_priority;
-} NMRemoteConnectionInitData;
+ if (obj_state != NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE) {
+ nm_assert (obj_state == NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY);
+ return NML_DBUS_OBJ_STATE_WITH_NMOBJ_NOT_READY;
+ }
-static void
-init_async_complete (NMRemoteConnectionInitData *init_data, GError *error)
-{
- if (error)
- g_simple_async_result_take_error (init_data->result, error);
- else
- g_simple_async_result_set_op_res_gboolean (init_data->result, TRUE);
-
- g_simple_async_result_complete (init_data->result);
- g_object_unref (init_data->result);
- g_clear_object (&init_data->cancellable);
- g_slice_free (NMRemoteConnectionInitData, init_data);
+ return NML_DBUS_OBJ_STATE_WITH_NMOBJ_VISIBLE;
}
-static void
-init_async_parent_inited (GObject *source, GAsyncResult *result, gpointer user_data)
-{
- NMRemoteConnectionInitData *init_data = user_data;
- GError *error = NULL;
-
- init_async_complete (init_data, error);
-}
+/*****************************************************************************/
static void
-init_get_settings_cb (GObject *proxy,
- GAsyncResult *result,
- gpointer user_data)
+register_client (NMObject *nmobj,
+ NMClient *client,
+ NMLDBusObject *dbobj)
{
- NMRemoteConnectionInitData *init_data = user_data;
- NMRemoteConnection *self = NM_REMOTE_CONNECTION (init_data->initable);
- NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
- GVariant *settings;
- GError *error = NULL;
-
- if (!nmdbus_settings_connection_call_get_settings_finish (priv->proxy, &settings,
- result, &error)) {
- g_error_free (error);
- } else {
- priv->visible = TRUE;
- replace_settings (NM_REMOTE_CONNECTION (init_data->initable), settings);
- g_variant_unref (settings);
- }
-
- nm_remote_connection_parent_async_initable_iface->
- init_async (init_data->initable, init_data->io_priority, init_data->cancellable, init_async_parent_inited, init_data);
+ NM_OBJECT_CLASS (nm_remote_connection_parent_class)->register_client (nmobj, client, dbobj);
+ nm_connection_set_path (NM_CONNECTION (nmobj),
+ dbobj->dbus_path->str);
+ _nm_client_get_settings_call (client, dbobj);
}
static void
-init_async (GAsyncInitable *initable, int io_priority,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
+unregister_client (NMObject *nmobj,
+ NMClient *client,
+ NMLDBusObject *dbobj)
{
- NMRemoteConnectionInitData *init_data;
- NMRemoteConnection *self = NM_REMOTE_CONNECTION (initable);
- NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self);
-
- init_data = g_slice_new0 (NMRemoteConnectionInitData);
- init_data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- init_data->result = g_simple_async_result_new (G_OBJECT (initable), callback,
- user_data, init_async);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (init_data->result, cancellable);
- init_data->initable = initable;
- init_data->io_priority = io_priority;
-
- priv->proxy = NMDBUS_SETTINGS_CONNECTION (_nm_object_get_proxy (NM_OBJECT (initable),
- NM_DBUS_INTERFACE_SETTINGS_CONNECTION));
-
- g_signal_connect_object (priv->proxy, "updated",
- G_CALLBACK (updated_cb), initable, 0);
-
- nmdbus_settings_connection_call_get_settings (NM_REMOTE_CONNECTION_GET_PRIVATE (NM_REMOTE_CONNECTION (init_data->initable))->proxy,
- init_data->cancellable,
- init_get_settings_cb, init_data);
+ nm_clear_g_cancellable (&NM_REMOTE_CONNECTION_GET_PRIVATE (nmobj)->get_settings_cancellable);
+ NM_OBJECT_CLASS (nm_remote_connection_parent_class)->unregister_client (nmobj, client, dbobj);
}
-static void
-nm_remote_connection_init (NMRemoteConnection *self)
-{
-}
+/*****************************************************************************/
static void
get_property (GObject *object, guint prop_id,
@@ -846,13 +748,11 @@ get_property (GObject *object, guint prop_id,
}
}
+/*****************************************************************************/
+
static void
-constructed (GObject *object)
+nm_remote_connection_init (NMRemoteConnection *self)
{
- G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructed (object);
-
- nm_connection_set_path (NM_CONNECTION (object),
- nm_object_get_path (NM_OBJECT (object)));
}
static void
@@ -860,23 +760,34 @@ dispose (GObject *object)
{
NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (object);
- g_clear_object (&priv->proxy);
nm_clear_g_free (&priv->filename);
G_OBJECT_CLASS (nm_remote_connection_parent_class)->dispose (object);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_settings_connection = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_SETTINGS_CONNECTION,
+ nm_remote_connection_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("Filename", PROP_FILENAME, NMRemoteConnection, _priv.filename ),
+ NML_DBUS_META_PROPERTY_INIT_U ("Flags", PROP_FLAGS, NMRemoteConnection, _priv.flags ),
+ NML_DBUS_META_PROPERTY_INIT_B ("Unsaved", PROP_UNSAVED, NMRemoteConnection, _priv.unsaved ),
+ ),
+);
+
static void
-nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
+nm_remote_connection_class_init (NMRemoteConnectionClass *klass)
{
- GObjectClass *object_class = G_OBJECT_CLASS (remote_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (remote_class);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
object_class->get_property = get_property;
- object_class->constructed = constructed;
object_class->dispose = dispose;
- nm_object_class->init_dbus = init_dbus;
+ nm_object_class->is_visible = is_visible;
+ nm_object_class->register_client = register_client;
+ nm_object_class->unregister_client = unregister_client;
/**
* NMRemoteConnection:unsaved:
@@ -935,26 +846,10 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_settings_connection);
}
static void
nm_remote_connection_connection_iface_init (NMConnectionInterface *iface)
{
}
-
-static void
-nm_remote_connection_initable_iface_init (GInitableIface *iface)
-{
- nm_remote_connection_parent_initable_iface = g_type_interface_peek_parent (iface);
-
- iface->init = init_sync;
-}
-
-static void
-nm_remote_connection_async_initable_iface_init (GAsyncInitableIface *iface)
-{
- nm_remote_connection_parent_async_initable_iface = g_type_interface_peek_parent (iface);
-
- iface->init_async = init_async;
-}
diff --git a/libnm/nm-remote-settings.c b/libnm/nm-remote-settings.c
deleted file mode 100644
index 7e46cf98d3..0000000000
--- a/libnm/nm-remote-settings.c
+++ /dev/null
@@ -1,479 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1+
-/*
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 - 2012 Red Hat, Inc.
- */
-
-#include "nm-default.h"
-
-#include "nm-remote-settings.h"
-
-#include "c-list/src/c-list.h"
-#include "nm-dbus-interface.h"
-#include "nm-connection.h"
-#include "nm-client.h"
-#include "nm-remote-connection.h"
-#include "nm-remote-connection-private.h"
-#include "nm-object-private.h"
-#include "nm-dbus-helpers.h"
-#include "nm-core-internal.h"
-
-#include "introspection/org.freedesktop.NetworkManager.Settings.h"
-
-G_DEFINE_TYPE (NMRemoteSettings, nm_remote_settings, NM_TYPE_OBJECT)
-
-#define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate))
-
-typedef struct {
- NMDBusSettings *proxy;
- GPtrArray *all_connections;
- GPtrArray *visible_connections;
-
- /* AddConnectionInfo objects that are waiting for the connection to become initialized */
- CList add_lst_head;
-
- char *hostname;
- gboolean can_modify;
-} NMRemoteSettingsPrivate;
-
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
- PROP_CONNECTIONS,
- PROP_HOSTNAME,
- PROP_CAN_MODIFY,
-);
-
-/* Signals */
-enum {
- CONNECTION_ADDED,
- CONNECTION_REMOVED,
-
- LAST_SIGNAL
-};
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/*****************************************************************************/
-
-typedef struct {
- CList add_lst;
- NMRemoteSettings *self;
- GTask *task;
- char *connection_path;
- GVariant *extra_results;
- gulong cancellable_id;
-} AddConnectionInfo;
-
-static AddConnectionInfo *
-_add_connection_info_find (NMRemoteSettings *self, const char *connection_path)
-{
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
- AddConnectionInfo *info;
-
- c_list_for_each_entry (info, &priv->add_lst_head, add_lst) {
- if (nm_streq (info->connection_path, connection_path))
- return info;
- }
- return NULL;
-}
-
-static void
-_add_connection_info_complete (AddConnectionInfo *info,
- NMRemoteConnection *connection,
- GError *error_take)
-{
- nm_assert (info);
-
- c_list_unlink_stale (&info->add_lst);
-
- nm_clear_g_signal_handler (g_task_get_cancellable (info->task), &info->cancellable_id);
-
- if (error_take)
- g_task_return_error (info->task, error_take);
- else {
- NMAddConnectionResultData *result_info;
-
- result_info = g_slice_new (NMAddConnectionResultData);
- *result_info = (NMAddConnectionResultData) {
- .connection = g_object_ref (connection),
- .extra_results = g_steal_pointer (&info->extra_results),
- };
- g_task_return_pointer (info->task, result_info, (GDestroyNotify) nm_add_connection_result_data_free);
- }
-
- g_object_unref (info->task);
- g_object_unref (info->self);
- g_free (info->connection_path);
- nm_g_variant_unref (info->extra_results);
- nm_g_slice_free (info);
-}
-
-static void
-_wait_for_connection_cancelled_cb (GCancellable *cancellable,
- AddConnectionInfo *info)
-{
- _add_connection_info_complete (info,
- NULL,
- g_error_new_literal (G_IO_ERROR,
- G_IO_ERROR_CANCELLED,
- "Operation was cancelled"));
-}
-
-typedef const char * (*ConnectionStringGetter) (NMConnection *);
-
-static NMRemoteConnection *
-get_connection_by_string (NMRemoteSettings *settings,
- const char *string,
- ConnectionStringGetter get_comparison_string)
-{
- NMRemoteSettingsPrivate *priv;
- NMConnection *candidate;
- int i;
-
- priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
-
- for (i = 0; i < priv->visible_connections->len; i++) {
- candidate = priv->visible_connections->pdata[i];
- if (!g_strcmp0 (string, get_comparison_string (candidate)))
- return NM_REMOTE_CONNECTION (candidate);
- }
-
- return NULL;
-}
-
-NMRemoteConnection *
-nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings, const char *id)
-{
- g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
- g_return_val_if_fail (id != NULL, NULL);
-
- return get_connection_by_string (settings, id, nm_connection_get_id);
-}
-
-NMRemoteConnection *
-nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path)
-{
- g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
- g_return_val_if_fail (path != NULL, NULL);
-
- return get_connection_by_string (settings, path, nm_connection_get_path);
-}
-
-NMRemoteConnection *
-nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings, const char *uuid)
-{
- g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
- g_return_val_if_fail (uuid != NULL, NULL);
-
- return get_connection_by_string (settings, uuid, nm_connection_get_uuid);
-}
-
-static void
-connection_visible_changed (GObject *object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- NMRemoteConnection *connection = NM_REMOTE_CONNECTION (object);
- NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data);
-
- if (nm_remote_connection_get_visible (connection))
- g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection);
- else
- g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection);
-}
-
-static void
-cleanup_connection (NMRemoteSettings *self,
- NMRemoteConnection *remote)
-{
- g_signal_handlers_disconnect_by_func (remote, G_CALLBACK (connection_visible_changed), self);
-}
-
-static void
-connection_removed (NMRemoteSettings *self,
- NMRemoteConnection *remote)
-{
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
- gboolean still_exists = FALSE;
- int i;
-
- /* Check if the connection was actually removed or if it just turned invisible. */
- for (i = 0; i < priv->all_connections->len; i++) {
- if (remote == priv->all_connections->pdata[i]) {
- still_exists = TRUE;
- break;
- }
- }
-
- if (!still_exists)
- cleanup_connection (self, remote);
-
- /* Allow the signal to propagate if and only if @remote was in visible_connections */
- if (!g_ptr_array_remove (priv->visible_connections, remote))
- g_signal_stop_emission (self, signals[CONNECTION_REMOVED], 0);
-}
-
-static void
-connection_added (NMRemoteSettings *self,
- NMRemoteConnection *remote)
-{
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
- AddConnectionInfo *info;
- const char *path;
-
- if (!g_signal_handler_find (remote, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL,
- G_CALLBACK (connection_visible_changed), self)) {
- g_signal_connect (remote,
- "notify::" NM_REMOTE_CONNECTION_VISIBLE,
- G_CALLBACK (connection_visible_changed),
- self);
- }
-
- if (nm_remote_connection_get_visible (remote))
- g_ptr_array_add (priv->visible_connections, remote);
- else
- g_signal_stop_emission (self, signals[CONNECTION_ADDED], 0);
-
- /* FIXME: this doesn't look right. Why does it not care about whether the
- * connection is visible? Anyway, this will be reworked. */
- path = nm_connection_get_path (NM_CONNECTION (remote));
- info = path
- ? _add_connection_info_find (self, path)
- : NULL;
- if (info)
- _add_connection_info_complete (info, remote, NULL);
-}
-
-static void
-object_creation_failed (NMObject *object,
- const char *failed_path)
-{
- NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
- AddConnectionInfo *info;
-
- info = _add_connection_info_find (self, failed_path);
- if (!info)
- return;
-
- _add_connection_info_complete (info,
- NULL,
- g_error_new_literal (NM_CLIENT_ERROR,
- NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
- _("Connection removed before it was initialized")));
-}
-
-const GPtrArray *
-nm_remote_settings_get_connections (NMRemoteSettings *settings)
-{
- g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL);
-
- return NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->visible_connections;
-}
-
-void
-nm_remote_settings_wait_for_connection (NMRemoteSettings *self,
- const char *connection_path,
- GVariant *extra_results_take,
- GTask *task_take)
-{
- NMRemoteSettingsPrivate *priv;
- gs_unref_object GTask *task = task_take;
- gs_unref_variant GVariant *extra_results = extra_results_take;
- GCancellable *cancellable;
- AddConnectionInfo *info;
-
- priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
-
- /* FIXME: there is no timeout for how long we wait. But this entire
- * code will be reworked, also that we have a suitable GMainContext
- * where we can schedule the timeout (we shouldn't use g_main_context_default()). */
-
- info = g_slice_new (AddConnectionInfo);
- *info = (AddConnectionInfo) {
- .self = g_object_ref (self),
- .connection_path = g_strdup (connection_path),
- .task = g_steal_pointer (&task),
- .extra_results = g_steal_pointer (&extra_results),
- };
- c_list_link_tail (&priv->add_lst_head, &info->add_lst);
-
- cancellable = g_task_get_cancellable (info->task);
- /* On success, we still have to wait until the connection is fully
- * initialized before calling the callback.
- */
- if (cancellable) {
- gulong id;
-
- id = g_cancellable_connect (cancellable,
- G_CALLBACK (_wait_for_connection_cancelled_cb),
- info,
- NULL);
- if (id == 0) {
- /* the callback was invoked synchronously, which destroyed @info.
- * We must not touch @info anymore. */
- } else
- info->cancellable_id = id;
- }
-
- /* FIXME: OK, we just assume the the connection is here, and that we are bound
- * to get the suitable signal when the connection is fully initalized (or failed).
- * Obviously, that needs reworking. */
-}
-
-/*****************************************************************************/
-
-static void
-nm_remote_settings_init (NMRemoteSettings *self)
-{
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
-
- c_list_init (&priv->add_lst_head);
- priv->all_connections = g_ptr_array_new ();
- priv->visible_connections = g_ptr_array_new ();
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_REMOTE_SETTINGS_CONNECTIONS, &priv->all_connections, NULL, NM_TYPE_REMOTE_CONNECTION, "connection" },
- { NM_REMOTE_SETTINGS_HOSTNAME, &priv->hostname },
- { NM_REMOTE_SETTINGS_CAN_MODIFY, &priv->can_modify },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_remote_settings_parent_class)->init_dbus (object);
-
- priv->proxy = NMDBUS_SETTINGS (_nm_object_get_proxy (object, NM_DBUS_INTERFACE_SETTINGS));
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_SETTINGS,
- property_info);
-}
-
-static GObject *
-constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
-{
- guint i;
- const char *dbus_path;
-
- /* Fill in the right D-Bus path if none was specified */
- for (i = 0; i < n_construct_params; i++) {
- if (strcmp (construct_params[i].pspec->name, NM_OBJECT_PATH) == 0) {
- dbus_path = g_value_get_string (construct_params[i].value);
- if (dbus_path == NULL) {
- g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH_SETTINGS);
- } else {
- if (!g_variant_is_object_path (dbus_path)) {
- g_warning ("Passed D-Bus object path '%s' is invalid; using default '%s' instead",
- dbus_path, NM_DBUS_PATH);
- g_value_set_static_string (construct_params[i].value, NM_DBUS_PATH_SETTINGS);
- }
- }
- break;
- }
- }
-
- return G_OBJECT_CLASS (nm_remote_settings_parent_class)->constructor (type,
- n_construct_params,
- construct_params);
-}
-
-static void
-dispose (GObject *object)
-{
- NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
- guint i;
-
- if (priv->all_connections) {
- for (i = 0; i < priv->all_connections->len; i++)
- cleanup_connection (self, priv->all_connections->pdata[i]);
- g_clear_pointer (&priv->all_connections, g_ptr_array_unref);
- }
-
- g_clear_pointer (&priv->visible_connections, g_ptr_array_unref);
- g_clear_pointer (&priv->hostname, g_free);
- g_clear_object (&priv->proxy);
-
- G_OBJECT_CLASS (nm_remote_settings_parent_class)->dispose (object);
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object);
-
- switch (prop_id) {
- case PROP_CONNECTIONS:
- g_value_take_boxed (value, _nm_utils_copy_object_array (priv->visible_connections));
- break;
- case PROP_HOSTNAME:
- g_value_set_string (value, priv->hostname);
- break;
- case PROP_CAN_MODIFY:
- g_value_set_boolean (value, priv->can_modify);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-nm_remote_settings_class_init (NMRemoteSettingsClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (class);
-
- g_type_class_add_private (class, sizeof (NMRemoteSettingsPrivate));
-
- object_class->get_property = get_property;
- object_class->constructor = constructor;
- object_class->dispose = dispose;
-
- nm_object_class->init_dbus = init_dbus;
- nm_object_class->object_creation_failed = object_creation_failed;
-
- class->connection_added = connection_added;
- class->connection_removed = connection_removed;
-
- obj_properties[PROP_CONNECTIONS] =
- g_param_spec_boxed (NM_REMOTE_SETTINGS_CONNECTIONS, "", "",
- G_TYPE_PTR_ARRAY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_HOSTNAME] =
- g_param_spec_string (NM_REMOTE_SETTINGS_HOSTNAME, "", "",
- NULL,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- obj_properties[PROP_CAN_MODIFY] =
- g_param_spec_boolean (NM_REMOTE_SETTINGS_CAN_MODIFY, "", "",
- FALSE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS);
-
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
-
- signals[CONNECTION_ADDED] =
- g_signal_new (NM_REMOTE_SETTINGS_CONNECTION_ADDED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMRemoteSettingsClass, connection_added),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- NM_TYPE_REMOTE_CONNECTION);
-
- signals[CONNECTION_REMOVED] =
- g_signal_new (NM_REMOTE_SETTINGS_CONNECTION_REMOVED,
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMRemoteSettingsClass, connection_removed),
- NULL, NULL, NULL,
- G_TYPE_NONE, 1,
- NM_TYPE_REMOTE_CONNECTION);
-}
diff --git a/libnm/nm-remote-settings.h b/libnm/nm-remote-settings.h
deleted file mode 100644
index 53d1767b58..0000000000
--- a/libnm/nm-remote-settings.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: LGPL-2.1+
-/*
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 - 2011 Red Hat, Inc.
- */
-
-#ifndef __NM_REMOTE_SETTINGS_H__
-#define __NM_REMOTE_SETTINGS_H__
-
-#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE)
-#error Cannot use this header.
-#endif
-
-#include "nm-object.h"
-
-#define NM_TYPE_REMOTE_SETTINGS (nm_remote_settings_get_type ())
-#define NM_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettings))
-#define NM_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass))
-#define NM_IS_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS))
-#define NM_IS_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_REMOTE_SETTINGS))
-#define NM_REMOTE_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass))
-
-#define NM_REMOTE_SETTINGS_CONNECTIONS "connections"
-#define NM_REMOTE_SETTINGS_HOSTNAME "hostname"
-#define NM_REMOTE_SETTINGS_CAN_MODIFY "can-modify"
-
-#define NM_REMOTE_SETTINGS_CONNECTION_ADDED "connection-added"
-#define NM_REMOTE_SETTINGS_CONNECTION_REMOVED "connection-removed"
-
-typedef struct _NMRemoteSettings NMRemoteSettings;
-typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass;
-
-/**
- * NMRemoteSettings:
- */
-struct _NMRemoteSettings {
- NMObject parent;
-};
-
-struct _NMRemoteSettingsClass {
- NMObjectClass parent;
-
- void (*connection_added) (NMRemoteSettings *settings,
- NMRemoteConnection *connection);
- void (*connection_removed) (NMRemoteSettings *settings,
- NMRemoteConnection *connection);
-};
-
-GType nm_remote_settings_get_type (void);
-
-const GPtrArray *nm_remote_settings_get_connections (NMRemoteSettings *settings);
-
-NMRemoteConnection *nm_remote_settings_get_connection_by_id (NMRemoteSettings *settings,
- const char *id);
-
-NMRemoteConnection *nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings,
- const char *path);
-
-NMRemoteConnection *nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings,
- const char *uuid);
-
-typedef struct {
- NMRemoteConnection *connection;
- GVariant *extra_results;
-} NMAddConnectionResultData;
-
-void nm_add_connection_result_data_free (NMAddConnectionResultData *result_data);
-
-NM_AUTO_DEFINE_FCN0 (NMAddConnectionResultData *, _nm_auto_free_add_connection_result_data, nm_add_connection_result_data_free)
-#define nm_auto_free_add_connection_result_data nm_auto (_nm_auto_free_add_connection_result_data)
-
-void nm_remote_settings_wait_for_connection (NMRemoteSettings *settings,
- const char *connection_path,
- GVariant *extra_results_take,
- GTask *task_take);
-
-#endif /* __NM_REMOTE_SETTINGS_H__ */
diff --git a/libnm/nm-vpn-connection.c b/libnm/nm-vpn-connection.c
index a0d673e913..26980229f3 100644
--- a/libnm/nm-vpn-connection.c
+++ b/libnm/nm-vpn-connection.c
@@ -14,8 +14,6 @@
#include "nm-active-connection.h"
#include "nm-dbus-helpers.h"
-#include "introspection/org.freedesktop.NetworkManager.VPN.Connection.h"
-
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE (NMVpnConnection,
@@ -33,7 +31,8 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
char *banner;
- NMVpnConnectionState vpn_state;
+ guint32 vpn_state;
+ guint32 reason;
} NMVpnConnectionPrivate;
struct _NMVpnConnection {
@@ -86,20 +85,48 @@ nm_vpn_connection_get_vpn_state (NMVpnConnection *vpn)
return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->vpn_state;
}
+/*****************************************************************************/
+
static void
-vpn_state_changed_proxy (NMDBusVpnConnection *proxy,
- guint vpn_state,
- guint reason,
- gpointer user_data)
+_notify_event_state_changed (NMClient *client,
+ NMClientNotifyEventWithPtr *notify_event)
+{
+ gs_unref_object NMVpnConnection *self = notify_event->user_data;
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+
+ /* we expose here the value cache in @priv. In practice, this is the same
+ * value as we received from the signal. In the unexpected case where they
+ * differ, the cached value of the current instance would still be more correct. */
+ g_signal_emit (self,
+ signals[VPN_STATE_CHANGED],
+ 0,
+ (guint) priv->vpn_state,
+ (guint) priv->reason);
+}
+
+void
+_nm_vpn_connection_state_changed_commit (NMVpnConnection *self,
+ guint32 state,
+ guint32 reason)
{
- NMVpnConnection *connection = NM_VPN_CONNECTION (user_data);
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+ NMClient *client;
+ NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
+
+ client = _nm_object_get_client (self);
- if (priv->vpn_state != vpn_state) {
- priv->vpn_state = vpn_state;
- g_signal_emit (connection, signals[VPN_STATE_CHANGED], 0, vpn_state, reason);
- _notify (connection, PROP_VPN_STATE);
+ if (priv->vpn_state != state) {
+ priv->vpn_state = state;
+ _nm_client_queue_notify_object (client,
+ self,
+ obj_properties[PROP_VPN_STATE]);
}
+
+ priv->reason = reason;
+
+ _nm_client_notify_event_queue_with_ptr (client,
+ NM_CLIENT_NOTIFY_EVENT_PRIO_GPROP + 1,
+ _notify_event_state_changed,
+ g_object_ref (self));
}
/*****************************************************************************/
@@ -107,32 +134,6 @@ vpn_state_changed_proxy (NMDBusVpnConnection *proxy,
static void
nm_vpn_connection_init (NMVpnConnection *connection)
{
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
-
- priv->vpn_state = NM_VPN_CONNECTION_STATE_UNKNOWN;
-}
-
-static void
-init_dbus (NMObject *object)
-{
- NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_VPN_CONNECTION_BANNER, &priv->banner },
- { NM_VPN_CONNECTION_VPN_STATE, &priv->vpn_state },
- { NULL },
- };
- GDBusProxy *proxy;
-
- NM_OBJECT_CLASS (nm_vpn_connection_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_VPN_CONNECTION,
- property_info);
-
- proxy = _nm_object_get_proxy (object, NM_DBUS_INTERFACE_VPN_CONNECTION);
- g_signal_connect_object (proxy, "vpn-state-changed",
- G_CALLBACK (vpn_state_changed_proxy), object, 0);
- g_object_unref (proxy);
}
static void
@@ -166,17 +167,24 @@ get_property (GObject *object,
}
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_vpn_connection = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_VPN_CONNECTION,
+ nm_vpn_connection_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_S ("Banner", PROP_BANNER, NMVpnConnection, _priv.banner ),
+ NML_DBUS_META_PROPERTY_INIT_U ("VpnState", PROP_VPN_STATE, NMVpnConnection, _priv.vpn_state ),
+ ),
+);
+
static void
nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (connection_class);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMVpnConnection:vpn-state:
*
@@ -200,7 +208,13 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_vpn_connection);
+
+ /* TODO: the state reason should also be exposed as a property in libnm's NMVpnConnection,
+ * like done for NMDevice's state reason. */
+
+ /* TODO: the D-Bus API should also expose the state-reason as a property instead of
+ * a "VpnStateChanged" signal. Like done for Device's "StateReason". */
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
signals[VPN_STATE_CHANGED] =
diff --git a/libnm/nm-wifi-p2p-peer.c b/libnm/nm-wifi-p2p-peer.c
index 73dc5fc047..509104454c 100644
--- a/libnm/nm-wifi-p2p-peer.c
+++ b/libnm/nm-wifi-p2p-peer.c
@@ -30,20 +30,15 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
);
typedef struct {
+ GBytes *wfd_ies;
char *name;
char *manufacturer;
char *model;
char *model_number;
char *serial;
-
- GBytes *wfd_ies;
-
char *hw_address;
-
- int last_seen;
-
- NM80211ApFlags flags;
-
+ gint32 last_seen;
+ guint32 flags;
guint8 strength;
} NMWifiP2PPeerPrivate;
@@ -340,33 +335,6 @@ nm_wifi_p2p_peer_filter_connections (NMWifiP2PPeer *peer, const GPtrArray *conne
/*****************************************************************************/
static void
-init_dbus (NMObject *object)
-{
- NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE (object);
- const NMPropertiesInfo property_info[] = {
- { NM_WIFI_P2P_PEER_FLAGS, &priv->flags },
- { NM_WIFI_P2P_PEER_NAME, &priv->name },
- { NM_WIFI_P2P_PEER_MANUFACTURER, &priv->manufacturer },
- { NM_WIFI_P2P_PEER_MODEL, &priv->model },
- { NM_WIFI_P2P_PEER_MODEL_NUMBER, &priv->model_number },
- { NM_WIFI_P2P_PEER_SERIAL, &priv->serial },
- { NM_WIFI_P2P_PEER_WFD_IES, &priv->wfd_ies },
- { NM_WIFI_P2P_PEER_HW_ADDRESS, &priv->hw_address },
- { NM_WIFI_P2P_PEER_STRENGTH, &priv->strength },
- { NM_WIFI_P2P_PEER_LAST_SEEN, &priv->last_seen },
- { NULL },
- };
-
- NM_OBJECT_CLASS (nm_wifi_p2p_peer_parent_class)->init_dbus (object);
-
- _nm_object_register_properties (object,
- NM_DBUS_INTERFACE_WIFI_P2P_PEER,
- property_info);
-}
-
-/*****************************************************************************/
-
-static void
get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -429,7 +397,6 @@ finalize (GObject *object)
g_free (priv->model);
g_free (priv->model_number);
g_free (priv->serial);
-
g_free (priv->hw_address);
g_bytes_unref (priv->wfd_ies);
@@ -437,17 +404,31 @@ finalize (GObject *object)
G_OBJECT_CLASS (nm_wifi_p2p_peer_parent_class)->finalize (object);
}
+const NMLDBusMetaIface _nml_dbus_meta_iface_nm_wifip2ppeer = NML_DBUS_META_IFACE_INIT_PROP (
+ NM_DBUS_INTERFACE_WIFI_P2P_PEER,
+ nm_wifi_p2p_peer_get_type,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH,
+ NML_DBUS_META_IFACE_DBUS_PROPERTIES (
+ NML_DBUS_META_PROPERTY_INIT_U ("Flags", PROP_FLAGS, NMWifiP2PPeer, _priv.flags ),
+ NML_DBUS_META_PROPERTY_INIT_S ("HwAddress", PROP_HW_ADDRESS, NMWifiP2PPeer, _priv.hw_address ),
+ NML_DBUS_META_PROPERTY_INIT_I ("LastSeen", PROP_LAST_SEEN, NMWifiP2PPeer, _priv.last_seen ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Manufacturer", PROP_MANUFACTURER, NMWifiP2PPeer, _priv.manufacturer ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Model", PROP_MODEL, NMWifiP2PPeer, _priv.model ),
+ NML_DBUS_META_PROPERTY_INIT_S ("ModelNumber", PROP_MODEL_NUMBER, NMWifiP2PPeer, _priv.model_number ),
+ NML_DBUS_META_PROPERTY_INIT_S ("Serial", PROP_SERIAL, NMWifiP2PPeer, _priv.serial ),
+ NML_DBUS_META_PROPERTY_INIT_Y ("Strength", PROP_STRENGTH, NMWifiP2PPeer, _priv.strength ),
+ NML_DBUS_META_PROPERTY_INIT_AY ("WfdIEs", PROP_WFD_IES, NMWifiP2PPeer, _priv.wfd_ies ),
+ ),
+);
+
static void
nm_wifi_p2p_peer_class_init (NMWifiP2PPeerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
- NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
object_class->get_property = get_property;
object_class->finalize = finalize;
- nm_object_class->init_dbus = init_dbus;
-
/**
* NMWifiP2PPeer:flags:
*
@@ -579,5 +560,5 @@ nm_wifi_p2p_peer_class_init (NMWifiP2PPeerClass *klass)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+ _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm_wifip2ppeer);
}
diff --git a/libnm/tests/test-libnm.c b/libnm/tests/test-libnm.c
index 8af1c28ffa..345fbb07b8 100644
--- a/libnm/tests/test-libnm.c
+++ b/libnm/tests/test-libnm.c
@@ -11,7 +11,16 @@
#include <sys/mman.h>
+#include "NetworkManager.h"
+#include "nm-access-point.h"
+#include "nm-checkpoint.h"
+#include "nm-dhcp4-config.h"
+#include "nm-dhcp6-config.h"
+#include "nm-dns-manager.h"
+#include "nm-ip4-config.h"
+#include "nm-ip6-config.h"
#include "nm-libnm-utils.h"
+#include "nm-object.h"
#include "nm-vpn-service-plugin.h"
#include "nm-utils/nm-test-utils.h"
@@ -2488,7 +2497,6 @@ test_types (void)
G (nm_dhcp6_config_get_type),
G (nm_dhcp_config_get_type),
G (nm_dns_entry_get_type),
- G (nm_dns_manager_get_type),
G (nm_ip4_config_get_type),
G (nm_ip6_config_get_type),
G (nm_ip_address_get_type),
@@ -2500,12 +2508,10 @@ test_types (void)
G (nm_ip_tunnel_mode_get_type),
G (nm_lldp_neighbor_get_type),
G (nm_manager_error_get_type),
- G (nm_manager_get_type),
G (nm_manager_reload_flags_get_type),
G (nm_metered_get_type),
G (nm_object_get_type),
G (nm_remote_connection_get_type),
- G (nm_remote_settings_get_type),
G (nm_secret_agent_capabilities_get_type),
G (nm_secret_agent_error_get_type),
G (nm_secret_agent_get_secrets_flags_get_type),
@@ -2665,6 +2671,401 @@ test_types (void)
/*****************************************************************************/
+static void
+test_nml_dbus_meta (void)
+{
+ const NMLDBusMetaIface *meta_iface;
+ const NMLDBusMetaProperty *meta_property;
+ guint prop_idx;
+ gsize i, j;
+ guint l, m;
+
+ for (i = 0; i < G_N_ELEMENTS (_nml_dbus_meta_ifaces); i++) {
+ const NMLDBusMetaIface *mif = _nml_dbus_meta_ifaces[i];
+ nm_auto_unref_gtypeclass GObjectClass *klass_unref = NULL;
+ GObjectClass *klass;
+ GType gtype;
+
+#define COMMON_PREFIX "org.freedesktop.NetworkManager"
+
+ g_assert (mif);
+ g_assert (mif->dbus_iface_name);
+ g_assert ( g_str_has_prefix (mif->dbus_iface_name, COMMON_PREFIX)
+ && !g_str_has_suffix (mif->dbus_iface_name, ".")
+ && NM_IN_SET (mif->dbus_iface_name[NM_STRLEN (COMMON_PREFIX)], '\0', '.'));
+ for (j = i + 1; j < G_N_ELEMENTS (_nml_dbus_meta_ifaces); j++)
+ g_assert (mif != _nml_dbus_meta_ifaces[j]);
+ if (i > 0) {
+ if (strcmp (_nml_dbus_meta_ifaces[i - 1]->dbus_iface_name, mif->dbus_iface_name) >= 0) {
+ g_error ("meta-ifaces are not properly sorted: [%zu] \"%s\" should be after [%zu] \"%s\"",
+ i - 1, _nml_dbus_meta_ifaces[i - 1]->dbus_iface_name, i, mif->dbus_iface_name);
+ }
+ }
+
+ g_assert ((mif->n_dbus_properties > 0) == (!!mif->dbus_properties));
+
+ if (mif->interface_prio == NML_DBUS_META_INTERFACE_PRIO_NONE) {
+ g_assert (!mif->get_type_fcn);
+ g_assert (!mif->obj_properties);
+ g_assert (mif->n_obj_properties == 0);
+ g_assert (!mif->obj_properties_reverse_idx);
+ if (!NM_IN_STRSET (mif->dbus_iface_name, NM_DBUS_INTERFACE_AGENT_MANAGER,
+ NM_DBUS_INTERFACE_DEVICE_STATISTICS,
+ NM_DBUS_INTERFACE_DEVICE_VETH))
+ g_error ("D-Bus interface \"%s\" is unexpectedly empty", mif->dbus_iface_name);
+ if (mif->n_dbus_properties == 0)
+ continue;
+ gtype = G_TYPE_NONE;
+ klass = NULL;
+ goto check_dbus_properties;
+ }
+
+ g_assert (NM_IN_SET ((NMLDBusMetaInteracePrio) mif->interface_prio, NML_DBUS_META_INTERFACE_PRIO_NMCLIENT,
+ NML_DBUS_META_INTERFACE_PRIO_PARENT_TYPE,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW,
+ NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH));
+
+ g_assert (mif->get_type_fcn);
+ gtype = mif->get_type_fcn ();
+ g_assert (g_type_is_a (gtype, G_TYPE_OBJECT));
+
+ if (mif->interface_prio == NML_DBUS_META_INTERFACE_PRIO_NMCLIENT)
+ g_assert (gtype == NM_TYPE_CLIENT);
+ else
+ g_assert (g_type_is_a (gtype, NM_TYPE_OBJECT));
+
+ /* We only test parts of the types, and avoid initializing all the types.
+ * That is so that other unit tests in this process randomly run with either
+ * the class instance already initialized or not. */
+ if ((nmtst_get_rand_uint () % 5) == 0) {
+ klass = (klass_unref = g_type_class_ref (gtype));
+ g_assert (klass);
+ } else
+ klass = g_type_class_peek (gtype);
+
+ if (klass) {
+ if (NM_IS_OBJECT_CLASS (klass)) {
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (klass);
+ const _NMObjectClassFieldInfo *p_prev;
+ const _NMObjectClassFieldInfo *p;
+
+ p_prev = NULL;
+ for (p = nm_object_class->property_o_info; p; p_prev = p, p = p->parent) {
+ g_assert (p->num > 0);
+ g_assert (NM_IS_OBJECT_CLASS (p->klass));
+ g_assert (g_type_is_a (gtype, G_TYPE_FROM_CLASS (p->klass)));
+ g_assert (p->klass->property_o_info == p);
+ if (p_prev) {
+ g_assert (g_type_is_a (G_TYPE_FROM_CLASS (p_prev->klass), G_TYPE_FROM_CLASS (p->klass)));
+ g_assert (p_prev->klass != p->klass);
+ }
+ }
+ } else
+ g_assert (NM_IS_CLIENT_CLASS (klass));
+ }
+
+ if (!mif->obj_properties) {
+ g_assert_cmpint (mif->n_obj_properties, ==, 0);
+ g_assert (!mif->obj_properties_reverse_idx);
+ } else {
+ g_assert (mif->obj_properties);
+ g_assert (mif->obj_properties[0] == 0);
+ g_assert_cmpint (mif->n_obj_properties, >, 1);
+ if (klass) {
+ for (l = 1; l < mif->n_obj_properties; l++) {
+ const GParamSpec *sp = mif->obj_properties[l];
+
+ g_assert (sp);
+ g_assert (sp->name);
+ g_assert (strlen (sp->name) > 0);
+ }
+ }
+
+ g_assert (mif->obj_properties_reverse_idx);
+ if (klass) {
+ g_assert (mif->obj_properties_reverse_idx[0] == 0xFFu);
+ for (l = 0; l < mif->n_obj_properties; l++) {
+ guint8 ridx = mif->obj_properties_reverse_idx[l];
+
+ if (ridx != 0xFFu) {
+ g_assert_cmpint (ridx, <=, mif->n_dbus_properties);
+ for (m = l + 1; m < mif->n_obj_properties; m++)
+ g_assert_cmpint (ridx, !=, mif->obj_properties_reverse_idx[m]);
+ }
+ }
+ }
+ }
+
+check_dbus_properties:
+ for (l = 0; l < mif->n_dbus_properties; l++) {
+ const NMLDBusMetaProperty *mpr = &mif->dbus_properties[l];
+ gs_free char *obj_property_name = NULL;
+ const struct {
+ const char *dbus_type;
+ GType default_gtype;
+ } *p_expected_type, *p_expected_type_2, expected_types[] = {
+ { "b", G_TYPE_BOOLEAN },
+ { "q", G_TYPE_UINT },
+ { "y", G_TYPE_UCHAR },
+ { "i", G_TYPE_INT },
+ { "u", G_TYPE_UINT },
+ { "x", G_TYPE_INT64 },
+ { "t", G_TYPE_UINT64 },
+ { "s", G_TYPE_STRING },
+ { "o", G_TYPE_STRING },
+ { "ay", G_TYPE_BYTES },
+ { "as", G_TYPE_STRV },
+ { "ao", G_TYPE_PTR_ARRAY },
+ { "a{sv}", G_TYPE_HASH_TABLE },
+ { "aa{sv}", G_TYPE_PTR_ARRAY },
+
+ { "(uu)", G_TYPE_NONE },
+ { "aau", G_TYPE_NONE },
+ { "au", G_TYPE_NONE },
+ { "a(ayuay)", G_TYPE_NONE },
+ { "aay", G_TYPE_NONE },
+ { "a(ayuayu)", G_TYPE_NONE },
+
+ { "u", G_TYPE_FLAGS },
+ { "u", G_TYPE_ENUM },
+ { "o", NM_TYPE_OBJECT },
+ };
+ const GParamSpec *pspec = NULL;
+
+ g_assert (mpr->dbus_property_name);
+ g_assert (g_variant_type_string_is_valid ((const char *) mpr->dbus_type));
+ if (l > 0) {
+ if (strcmp (mif->dbus_properties[l - 1].dbus_property_name, mpr->dbus_property_name) >= 0) {
+ g_error ("meta-ifaces[%s] must have property #%u \"%s\" after #%u \"%s\"",
+ mif->dbus_iface_name, l - 1, mif->dbus_properties[l - 1].dbus_property_name, l, mpr->dbus_property_name);
+ }
+ }
+
+ obj_property_name = nm_utils_wincaps_to_dash (mpr->dbus_property_name);
+ g_assert (obj_property_name);
+
+ for (p_expected_type = &expected_types[0]; TRUE; ) {
+ if (nm_streq ((const char *) mpr->dbus_type, p_expected_type->dbus_type))
+ break;
+ p_expected_type++;
+ if (p_expected_type >= &expected_types[G_N_ELEMENTS (expected_types)]) {
+ g_error ("D-Bus type \"%s\" is not implemented (in property %s.%s)",
+ (const char *) mpr->dbus_type,
+ mif->dbus_iface_name,
+ mpr->dbus_property_name);
+ }
+ }
+
+ if ( klass
+ && mpr->obj_properties_idx > 0) {
+ g_assert_cmpint (mpr->obj_properties_idx, <, mif->n_obj_properties);
+ if (!mpr->obj_property_no_reverse_idx)
+ g_assert_cmpint (mif->obj_properties_reverse_idx[mpr->obj_properties_idx], ==, l);
+ else {
+ g_assert_cmpint (mif->obj_properties_reverse_idx[mpr->obj_properties_idx], !=, l);
+ g_assert_cmpint (mif->obj_properties_reverse_idx[mpr->obj_properties_idx], !=, 0xFFu);
+ }
+ pspec = mif->obj_properties[mpr->obj_properties_idx];
+ }
+
+ if (mpr->use_notify_update_prop) {
+ g_assert (mpr->notify_update_prop);
+ } else {
+ if (klass)
+ g_assert (pspec);
+ }
+
+ if (pspec) {
+ const char *expected_property_name;
+
+ if ( mif == &_nml_dbus_meta_iface_nm_connection_active
+ && nm_streq (pspec->name, NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH)) {
+ g_assert_cmpstr (obj_property_name, ==, "specific-object");
+ expected_property_name = NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH;
+ } else if ( mif == &_nml_dbus_meta_iface_nm_accesspoint
+ && nm_streq (pspec->name, NM_ACCESS_POINT_BSSID)) {
+ g_assert_cmpstr (obj_property_name, ==, "hw-address");
+ expected_property_name = NM_ACCESS_POINT_BSSID;
+ } else if ( mif == &_nml_dbus_meta_iface_nm_device_wireguard
+ && nm_streq (pspec->name, NM_DEVICE_WIREGUARD_FWMARK)) {
+ g_assert_cmpstr (obj_property_name, ==, "fw-mark");
+ expected_property_name = NM_DEVICE_WIREGUARD_FWMARK;
+ } else if ( NM_IN_SET (mif, &_nml_dbus_meta_iface_nm_ip4config,
+ &_nml_dbus_meta_iface_nm_ip6config)
+ && nm_streq (pspec->name, NM_IP_CONFIG_ADDRESSES)) {
+ g_assert (NM_IN_STRSET (obj_property_name, "addresses", "address-data"));
+ expected_property_name = NM_IP_CONFIG_ADDRESSES;
+ } else if ( NM_IN_SET (mif, &_nml_dbus_meta_iface_nm_ip4config,
+ &_nml_dbus_meta_iface_nm_ip6config)
+ && nm_streq (pspec->name, NM_IP_CONFIG_ROUTES)) {
+ g_assert (NM_IN_STRSET (obj_property_name, "routes", "route-data"));
+ expected_property_name = NM_IP_CONFIG_ROUTES;
+ } else if ( NM_IN_SET (mif, &_nml_dbus_meta_iface_nm_ip4config,
+ &_nml_dbus_meta_iface_nm_ip6config)
+ && nm_streq (pspec->name, NM_IP_CONFIG_NAMESERVERS)) {
+ g_assert (NM_IN_STRSET (obj_property_name, "nameservers", "nameserver-data"));
+ expected_property_name = NM_IP_CONFIG_NAMESERVERS;
+ } else if ( mif == &_nml_dbus_meta_iface_nm_ip4config
+ && nm_streq (pspec->name, NM_IP_CONFIG_WINS_SERVERS)) {
+ g_assert (NM_IN_STRSET (obj_property_name, "wins-servers", "wins-server-data"));
+ expected_property_name = NM_IP_CONFIG_WINS_SERVERS;
+ } else if ( mif == &_nml_dbus_meta_iface_nm_dnsmanager
+ && nm_streq (pspec->name, NM_CLIENT_DNS_CONFIGURATION)) {
+ g_assert_cmpstr (obj_property_name, ==, "configuration");
+ expected_property_name = NM_CLIENT_DNS_CONFIGURATION;
+ } else if ( mif == &_nml_dbus_meta_iface_nm_dnsmanager
+ && nm_streq (pspec->name, NM_CLIENT_DNS_MODE)) {
+ g_assert_cmpstr (obj_property_name, ==, "mode");
+ expected_property_name = NM_CLIENT_DNS_MODE;
+ } else if ( mif == &_nml_dbus_meta_iface_nm_dnsmanager
+ && nm_streq (pspec->name, NM_CLIENT_DNS_RC_MANAGER)) {
+ g_assert_cmpstr (obj_property_name, ==, "rc-manager");
+ expected_property_name = NM_CLIENT_DNS_RC_MANAGER;
+ } else
+ expected_property_name = obj_property_name;
+
+ g_assert_cmpstr (expected_property_name, ==, pspec->name);
+
+ if (!mpr->use_notify_update_prop) {
+ for (p_expected_type_2 = &expected_types[0]; p_expected_type_2 < &expected_types[G_N_ELEMENTS (expected_types)]; p_expected_type_2++) {
+ if (!nm_streq ((const char *) mpr->dbus_type, p_expected_type_2->dbus_type))
+ continue;
+ if ( pspec->value_type == p_expected_type_2->default_gtype
+ || ( p_expected_type_2->default_gtype == G_TYPE_ENUM
+ && g_type_is_a (pspec->value_type, G_TYPE_ENUM))
+ || ( p_expected_type_2->default_gtype == G_TYPE_FLAGS
+ && g_type_is_a (pspec->value_type, G_TYPE_FLAGS))
+ || ( p_expected_type_2->default_gtype == NM_TYPE_OBJECT
+ && nm_streq ((const char *) mpr->dbus_type, "o")
+ && g_type_is_a (pspec->value_type, NM_TYPE_OBJECT)))
+ break;
+ }
+ if (p_expected_type_2 >= &expected_types[G_N_ELEMENTS (expected_types)]) {
+ g_error ("D-Bus property \"%s.%s\" (type \"%s\") maps to property \"%s\", but that has an unexpected property type %s (expected %s)",
+ mif->dbus_iface_name,
+ mpr->dbus_property_name,
+ (const char *) mpr->dbus_type,
+ pspec->name,
+ g_type_name (pspec->value_type),
+ g_type_name (p_expected_type->default_gtype));
+ }
+ }
+
+ if (!nm_utils_g_param_spec_is_default (pspec)) {
+ /* We expect our properties to have a default value of zero/NULL.
+ * Except those whitelisted here: */
+ if ( ( mif == &_nml_dbus_meta_iface_nm_accesspoint
+ && nm_streq (pspec->name, NM_ACCESS_POINT_LAST_SEEN))
+ || ( mif == &_nml_dbus_meta_iface_nm_device_vxlan
+ && nm_streq (pspec->name, NM_DEVICE_VXLAN_LEARNING))
+ || ( mif == &_nml_dbus_meta_iface_nm_device_wireless
+ && nm_streq (pspec->name, NM_DEVICE_WIFI_LAST_SCAN))
+ || ( mif == &_nml_dbus_meta_iface_nm_wifip2ppeer
+ && nm_streq (pspec->name, NM_WIFI_P2P_PEER_LAST_SEEN))
+ || ( mif == &_nml_dbus_meta_iface_nm_device_tun
+ && NM_IN_STRSET (pspec->name, NM_DEVICE_TUN_GROUP,
+ NM_DEVICE_TUN_OWNER))) {
+ /* pass */
+ } else {
+ g_error ("property %s.%s (%s.%s) does not have a default value of zero",
+ mif->dbus_iface_name,
+ mpr->dbus_property_name,
+ g_type_name (gtype),
+ pspec->name);
+ }
+ }
+ }
+ }
+
+ if (klass) {
+ for (l = 0; l < mif->n_obj_properties; l++) {
+ guint8 ridx = mif->obj_properties_reverse_idx[l];
+
+ if (ridx != 0xFFu)
+ g_assert_cmpint (mif->dbus_properties[ridx].obj_properties_idx, ==, l);
+ }
+ }
+
+ g_assert (mif == nml_dbus_meta_iface_get (mif->dbus_iface_name));
+ }
+
+ meta_iface = nml_dbus_meta_iface_get (NM_DBUS_INTERFACE);
+ g_assert (meta_iface);
+ g_assert (meta_iface == &_nml_dbus_meta_iface_nm);
+ g_assert_cmpstr (meta_iface->dbus_iface_name, ==, NM_DBUS_INTERFACE);
+
+ meta_property = nml_dbus_meta_property_get (meta_iface, "Version", &prop_idx);
+ g_assert (meta_property);
+ g_assert_cmpstr (meta_property->dbus_property_name, ==, "Version");
+ g_assert (&meta_iface->dbus_properties[prop_idx] == meta_property);
+}
+
+/*****************************************************************************/
+
+static void
+test_dbus_meta_types (void)
+{
+ struct list_data {
+ const char *dbus_iface_name;
+ GType gtype;
+ NMLDBusMetaInteracePrio interface_prio;
+ } list[] = {
+ { NM_DBUS_INTERFACE, NM_TYPE_CLIENT, NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, },
+ { NM_DBUS_INTERFACE_ACCESS_POINT, NM_TYPE_ACCESS_POINT, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_ACTIVE_CONNECTION, NM_TYPE_ACTIVE_CONNECTION, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_LOW, }, /* otherwise, NM_TYPE_VPN_CONNECTION. */
+ { NM_DBUS_INTERFACE_DEVICE_6LOWPAN, NM_TYPE_DEVICE_6LOWPAN, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_ADSL, NM_TYPE_DEVICE_ADSL, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_BOND, NM_TYPE_DEVICE_BOND, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_BRIDGE, NM_TYPE_DEVICE_BRIDGE, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, NM_TYPE_DEVICE_BT, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_DUMMY, NM_TYPE_DEVICE_DUMMY, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_WIRED, NM_TYPE_DEVICE_ETHERNET, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_GENERIC, NM_TYPE_DEVICE_GENERIC, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_INFINIBAND, NM_TYPE_DEVICE_INFINIBAND, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, NM_TYPE_DEVICE_IP_TUNNEL, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_MACSEC, NM_TYPE_DEVICE_MACSEC, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_MACVLAN, NM_TYPE_DEVICE_MACVLAN, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_MODEM, NM_TYPE_DEVICE_MODEM, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, NM_TYPE_DEVICE_OLPC_MESH, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, NM_TYPE_DEVICE_OVS_INTERFACE, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_OVS_PORT, NM_TYPE_DEVICE_OVS_PORT, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, NM_TYPE_DEVICE_OVS_BRIDGE, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_WIFI_P2P, NM_TYPE_DEVICE_WIFI_P2P, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_PPP, NM_TYPE_DEVICE_PPP, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_TEAM, NM_TYPE_DEVICE_TEAM, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_TUN, NM_TYPE_DEVICE_TUN, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_VLAN, NM_TYPE_DEVICE_VLAN, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_WPAN, NM_TYPE_DEVICE_WPAN, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_VXLAN, NM_TYPE_DEVICE_VXLAN, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_WIRELESS, NM_TYPE_DEVICE_WIFI, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DEVICE_WIREGUARD, NM_TYPE_DEVICE_WIREGUARD, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DHCP4_CONFIG, NM_TYPE_DHCP4_CONFIG, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_DHCP6_CONFIG, NM_TYPE_DHCP6_CONFIG, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_IP4_CONFIG, NM_TYPE_IP4_CONFIG, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_IP6_CONFIG, NM_TYPE_IP6_CONFIG, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_WIFI_P2P_PEER, NM_TYPE_WIFI_P2P_PEER, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_SETTINGS_CONNECTION, NM_TYPE_REMOTE_CONNECTION, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_SETTINGS, NM_TYPE_CLIENT, NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, },
+ { NM_DBUS_INTERFACE_DNS_MANAGER, NM_TYPE_CLIENT, NML_DBUS_META_INTERFACE_PRIO_NMCLIENT, },
+ { NM_DBUS_INTERFACE_VPN_CONNECTION, NM_TYPE_VPN_CONNECTION, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ { NM_DBUS_INTERFACE_CHECKPOINT, NM_TYPE_CHECKPOINT, NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_HIGH, },
+ };
+ guint i;
+
+ /* These iface<->gtype associations are copied from "nm-client.c"'s obj_nm_for_gdbus_object().
+ * This is redundant to the meta-data, still check that the meta data matches. */
+ for (i = 0; i < G_N_ELEMENTS (list); i++) {
+ const struct list_data *d = &list[i];
+ const NMLDBusMetaIface *meta_iface;
+
+ meta_iface = nml_dbus_meta_iface_get (d->dbus_iface_name);
+ g_assert (meta_iface);
+ g_assert_cmpint (meta_iface->interface_prio, ==, d->interface_prio);
+ g_assert (meta_iface->get_type_fcn() == d->gtype);
+ }
+}
+/*****************************************************************************/
+
NMTST_DEFINE ();
int main (int argc, char **argv)
@@ -2675,6 +3076,8 @@ int main (int argc, char **argv)
g_test_add_func ("/libnm/general/fixup_vendor_string", test_fixup_vendor_string);
g_test_add_func ("/libnm/general/nm_vpn_service_plugin_read_vpn_details", test_nm_vpn_service_plugin_read_vpn_details);
g_test_add_func ("/libnm/general/test_types", test_types);
+ g_test_add_func ("/libnm/general/test_nml_dbus_meta", test_nml_dbus_meta);
+ g_test_add_func ("/libnm/general/test_dbus_meta_types", test_dbus_meta_types);
return g_test_run ();
}
diff --git a/libnm/tests/test-nm-client.c b/libnm/tests/test-nm-client.c
index c6b26a21ab..4d4cad1262 100644
--- a/libnm/tests/test-nm-client.c
+++ b/libnm/tests/test-nm-client.c
@@ -180,8 +180,8 @@ test_device_added_signal_after_init (void)
g_signal_handlers_disconnect_by_func (client, device_sai_added_cb, &result);
g_signal_handlers_disconnect_by_func (client, devices_sai_notify_cb, &result);
- g_assert ((result & SIGNAL_MASK) == SIGNAL_FIRST);
- g_assert ((result & NOTIFY_MASK) == NOTIFY_SECOND);
+ g_assert ((result & SIGNAL_MASK) == SIGNAL_SECOND);
+ g_assert ((result & NOTIFY_MASK) == NOTIFY_FIRST);
devices = nm_client_get_devices (client);
g_assert (devices);
@@ -635,13 +635,15 @@ assert_ac_and_device (NMClient *client)
device = devices->pdata[0];
if (device != ac_device && devices->len > 1)
device = devices->pdata[1];
- device_ac = nm_device_get_active_connection (device);
- g_assert (device_ac != NULL);
g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, nm_object_get_path (NM_OBJECT (ac_device)));
g_assert (device == ac_device);
- g_assert_cmpstr (nm_object_get_path (NM_OBJECT (ac)), ==, nm_object_get_path (NM_OBJECT (device_ac)));
- g_assert (ac == device_ac);
+
+ device_ac = nm_device_get_active_connection (device);
+ if (device_ac) {
+ g_assert_cmpstr (nm_object_get_path (NM_OBJECT (ac)), ==, nm_object_get_path (NM_OBJECT (device_ac)));
+ g_assert (ac == device_ac);
+ }
}
static void
@@ -995,6 +997,8 @@ test_connection_invalid (void)
gssize idx[4];
gs_unref_variant GVariant *variant = NULL;
+ g_assert (g_main_loop_get_context (gl.loop) == (g_main_context_get_thread_default () ?: g_main_context_default ()));
+
/**************************************************************************
* Add three connections before starting libnm. One valid, two invalid.
*************************************************************************/