summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-10-30 11:42:58 +0100
committerThomas Haller <thaller@redhat.com>2019-11-11 07:55:33 +0100
commit36d8637741540db91e4544ede7333c7ba0da54c5 (patch)
tree45af734ddbf73b86f106422da1872abf3495a49e
parent031ee2e8df065d440762ed89b375cd34a766e22f (diff)
downloadNetworkManager-th/libnm-no-dbus-codegen-4.tar.gz
libnm: refactor caching of D-Bus objects in NMClientth/libnm-no-dbus-codegen-4
No longer use GDBusObjectMangaerClient and gdbus-codegen generated classes for the NMClient cache. Instead, use GDBusConnection directly and use a custom implementation (NMLDBusObject) for caching the ObjectManager data. CHANGES ------- - This is a complete rework. I think the previous implementation was difficult to understand. There were unfixed bugs and nobody understood the code well enough to fix them. Maybe somebody out there understood the code, but I certainly did not. At least nobody provided patches to fix those issues. I do believe that this implementation is more straightforward and easier to understand. It removes a lot of layers of code. Whether this claim of simplicity is true, each reader must decide for himself/herself. Note that it is still fairly complex. - There was a lingering performance issue with large number of D-Bus objects. The patch tries hard that the implementation scales well. Of course, when we cache N objects that have N-to-M references to other, we still are fundamentally O(N*M) for runtime and memory consumption (with M being the number of references between objects). But each part should behave efficiently and well. - Play well with GMainContext. libnm code (NMClient) is generally not thread safe. However, it should work to use multiple instances in parallel, as long as each access to a NMClient is through the caller's GMainContext. This follows glib's style and effectively allows to use NMClient in a multi threaded scenario. This implies to stick to a main context upon construction and ensure that callbacks are only invoked when iterating that context. Also, NMClient itself shall never iterate the callers context. This also means, libnm must never use g_idle_add() or g_timeout_add(), as those enqueue sources in the g_main_context_default() context. - Get ordering of messages right. All events are consistently enqueued in a GMainContext and processed strictly in order. For example, previously nm-object.c tried to combine signals and emit them on an idle handler. That is wrong, signals must be emitted in the right order and when they happen. Note that when using GInitable's synchronous initialization to initialize the NMClient instance, then we still operate (internally) fully asynchronous. To get this right NMClient has an internal main context. - NMClient takes over most of the functionality. When using D-Bus' ObjectManager interface, one needs to handle basically the entire state of the D-Bus interface. That cannot be separated well into distinct parts, and even if you try, you just end up having closely related code in different source files. Spreading related code does not make it easier to understand, on the contrary. That means, NMClient is inherently complex as it contains most of the logic. I think that is not avoidable, but it's not as bad as it sounds (IMO). - NMClient processes D-Bus messages and state changes in separate steps. First NMClient unpacks the message (e.g. _dbus_handle_properties_changed()) and keep track of the changed data. Then we update the GObject instances (_dbus_handle_objects_changed()) without emitting any signals yet. Finally, we emit all signals and notifications that were collected (_dbus_handle_changes_commit()). Note that for example during the initial GetManagedObjects() reply, NMClient receive a large amount of state at once. But we first apply all the state to our GObject instances before starting to emit any signals. The result is that signals are always emitted in a moment when the cache is consistent. The unavoidable downside is that when you receive a property changed signal, possibly many other properties changed at the same time. - NMDeviceWifi no longer modifies the content of the cache from client side during poke_wireless_devices_with_rf_status(). The content of the cache should be determined by D-Bus alone and follow what NetworkManager service exposes. Local modifications should be avoided. - This aims to bring no API/ABI change, though it does of course bring various subtle changes in behavior. Those should be all for the better, but the goal is not to break any existing clients. This does change internal (albeit externally visible) API, like dropping NM_OBJECT_DBUS_OBJECT_MANAGER property and NMObject no longer implementing GInitableIface and GAsyncInitableIface. - Some uses of gdbus-codegen classes remain in NMVpnPluginOld, NMVpnServicePlugin and NMSecretAgentOld. These are independent of NMClient/NMObject and should be reworked separately. - While we no longer use generated classes from gdbus-codegen, we don't need more glue code than before. Also before there was NMPropertiesInfo and a large amount of code that propagated properties from NMDBus* to NMObject. That got completely reworked, but did not fundamentally change. You still need about the same effort to create the NMLDBusMetaIface and not using generated bindings did not make anything worse. - NMLDBusMetaIface and other meta data is static and immutable. This avoids copying them around. Also, macros like NML_DBUS_META_PROPERTY_INIT_U() have compile time checks to ensure the property types matches. It's pretty hard to misuse them because it won't compile. - The meta data now explicitly encodes the expected D-Bus types and makes sure never to accept wrong data. That would only matter when the server (accidentally or intentionally) exposes unexpected types on D-Bus. I don't think that was previously ensured in all cases. For example, demarshal_generic() only cared about the GObject property type, it didn't know the expected D-Bus type. - Previously GDBusObjectManager would sometimes emit warnings (g_log()). Those probably indicated real bugs. In any case, it prevented us from running CI with G_DEBUG=fatal-warnings, because there would be just too many unrelated crashes. Now we log debug messages that can be enabled with "LIBNM_CLIENT_DEBUG=trace". Some of these messages can also be turned into g_warning()/g_critical() by setting LIBNM_CLIENT_DEBUG=warning,error. Together with G_DEBUG=fatal-warnings, this makes them into assertions. Note that such "assertion failures" might also happen because of a server bug (or change). Thus these are not common assertions that indicate a bug in libnm and are thus not armed unless explicitly requested. In our CI we should now always run with LIBNM_CLIENT_DEBUG=warning,error and G_DEBUG=fatal-warnings and to catch bugs. - Note that this changes the order in which we emit "notify:devices" and "device-added" signals. I think it makes the most sense to emit first "device-removed", then "notify:devices", and finally "device-added" signals. This changes behavior for commit 52ae28f6e5bf ('libnm: queue added/removed signals and suppress uninitialized notifications'), but I don't think that users should actually rely on the order. Still, the new order makes the most sense to me. - In NetworkManager, profiles can be invisible to the user by setting "connection.permissions". Such profiles would be hidden by NMClient's nm_client_get_connections() and their "connection-added"/"connection-removed" signals. Note that NMActiveConnection's nm_active_connection_get_connection() and NMDevice's nm_device_get_available_connections() still exposes such hidden NMRemoteConnection instances. This behavior was preserved. NUMBERS ------- I compared 3 versions of libnm. [1] CCCCCCC, currently latest on nm-1-20 branch [2] CCCCCCC, current master, before this patch [3] this patch All tests were done on Fedora 31, x86_64, gcc 9.2.1-1.fc31. The libraries were build with $ ./contrib/fedora/rpm/build_clean.sh -g -w test -W debug Note that RPM build already stripped the library. A) file size of libnm.so.0.1.0 [1] 2769712 [2] [3] B) `size libnm.so.0.1.0`: text data bss dec hex filename [1] 1534988 73428 13232 1621648 18be90 /usr/lib64/libnm.so.0.1.0 [2] [3] WIP
-rw-r--r--Makefile.am14
-rw-r--r--NEWS3
-rw-r--r--docs/libnm/Makefile.am1
-rw-r--r--docs/libnm/meson.build1
-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
-rw-r--r--po/POTFILES.in3
-rw-r--r--shared/nm-test-utils-impl.c41
60 files changed, 7074 insertions, 6914 deletions
diff --git a/Makefile.am b/Makefile.am
index dde8a7b03c..718355071b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1240,15 +1240,17 @@ libnm_lib_h_priv = \
libnm/nm-dns-manager.h \
libnm/nm-ip4-config.h \
libnm/nm-ip6-config.h \
- libnm/nm-manager.h \
libnm/nm-object-private.h \
libnm/nm-remote-connection-private.h \
- libnm/nm-remote-settings.h
+ $(NULL)
libnm_lib_c_real = \
- libnm/nm-access-point.c \
+ libnm/nm-client.c \
+ libnm/nm-object.c \
+ libnm/nm-device.c \
libnm/nm-active-connection.c \
+ \
+ libnm/nm-access-point.c \
libnm/nm-checkpoint.c \
- libnm/nm-client.c \
libnm/nm-dbus-helpers.c \
libnm/nm-device-6lowpan.c \
libnm/nm-device-adsl.c \
@@ -1277,7 +1279,6 @@ libnm_lib_c_real = \
libnm/nm-device-wimax.c \
libnm/nm-device-wireguard.c \
libnm/nm-device-wpan.c \
- libnm/nm-device.c \
libnm/nm-dhcp-config.c \
libnm/nm-dhcp4-config.c \
libnm/nm-dhcp6-config.c \
@@ -1286,10 +1287,7 @@ libnm_lib_c_real = \
libnm/nm-ip4-config.c \
libnm/nm-ip6-config.c \
libnm/nm-libnm-utils.c \
- libnm/nm-manager.c \
- libnm/nm-object.c \
libnm/nm-remote-connection.c \
- libnm/nm-remote-settings.c \
libnm/nm-secret-agent-old.c \
libnm/nm-vpn-connection.c \
libnm/nm-vpn-editor.c \
diff --git a/NEWS b/NEWS
index 3ae54472f1..7f95d9d7bc 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,9 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* libnm: retire deprecated WiMAX API NMDeviceWimax and NMWimaxNsp.
WiMAX support was removed from NetworkManager in version 1.2 (2016) and no such
type instances would have been created by NMClient for a while now.
+* libnm: heavily internal rework NMClient. This slims down libnm and makes the
+ implementation more efficient. NMClient should work now well with a separate
+ GMainContext.
=============================================
NetworkManager-1.20
diff --git a/docs/libnm/Makefile.am b/docs/libnm/Makefile.am
index 20dc8de571..ce82d7eb94 100644
--- a/docs/libnm/Makefile.am
+++ b/docs/libnm/Makefile.am
@@ -49,7 +49,6 @@ IGNORE_HFILES= \
nm-object-private.h \
nm-property-compare.h \
nm-remote-connection-private.h \
- nm-remote-settings.h \
nm-setting-private.h \
nm-utils-private.h \
nm-core-tests-enum-types.h \
diff --git a/docs/libnm/meson.build b/docs/libnm/meson.build
index 43a13f498a..6cf0e04028 100644
--- a/docs/libnm/meson.build
+++ b/docs/libnm/meson.build
@@ -20,7 +20,6 @@ private_headers = [
'nm-object-private.h',
'nm-property-compare.h',
'nm-remote-connection-private.h',
- 'nm-remote-settings.h',
'nm-setting-private.h',
'nm-utils-private.h',
'nm-core-tests-enum-types.h',
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.
*************************************************************************/
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d3246bccfb..0279f865fa 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -106,6 +106,7 @@ libnm-core/nm-team-utils.c
libnm-core/nm-utils.c
libnm-core/nm-vpn-editor-plugin.c
libnm-core/nm-vpn-plugin-info.c
+libnm/nm-client.c
libnm/nm-device-6lowpan.c
libnm/nm-device-adsl.c
libnm/nm-device-bond.c
@@ -131,10 +132,8 @@ libnm/nm-device-wifi.c
libnm/nm-device-wimax.c
libnm/nm-device-wpan.c
libnm/nm-device.c
-libnm/nm-manager.c
libnm/nm-object.c
libnm/nm-remote-connection.c
-libnm/nm-remote-settings.c
libnm/nm-vpn-plugin-old.c
libnm/nm-vpn-service-plugin.c
data/org.freedesktop.NetworkManager.policy.in.in
diff --git a/shared/nm-test-utils-impl.c b/shared/nm-test-utils-impl.c
index bbe74a9656..6923238efc 100644
--- a/shared/nm-test-utils-impl.c
+++ b/shared/nm-test-utils-impl.c
@@ -528,12 +528,53 @@ _nmtstc_client_new_inside_loop (gboolean sync)
return d.client;
}
+static NMClient *
+_nmtstc_client_new_extra_context (void)
+{
+ GMainContext *inner_context;
+ NMClient *client;
+ GSource *source;
+ guint key_idx;
+
+ inner_context = g_main_context_new ();
+ g_main_context_push_thread_default (inner_context);
+
+ client = nmtstc_client_new (TRUE);
+
+ source = nm_utils_g_main_context_create_integrate_source (inner_context);
+
+ g_main_context_pop_thread_default (inner_context);
+ g_main_context_unref (inner_context);
+
+ g_source_attach (source, g_main_context_get_thread_default ());
+
+ for (key_idx = 0; TRUE; key_idx++) {
+ char s[100];
+
+ /* nmtstc_client_new() may call _nmtstc_client_new_extra_context() repeatedly. We
+ * need to attach the source to a previously unused key. */
+ nm_sprintf_buf (s, "nm-test-extra-context-%u", key_idx);
+ if (!g_object_get_data (G_OBJECT (client), s)) {
+ g_object_set_data_full (G_OBJECT (client),
+ s,
+ source,
+ (GDestroyNotify) nm_g_source_destroy_and_unref);
+ break;
+ }
+ }
+
+ return client;
+}
+
NMClient *
nmtstc_client_new (gboolean allow_iterate_main_context)
{
gboolean inside_loop;
gboolean sync;
+ if (nmtst_get_rand_uint32 () % 5 == 0)
+ return _nmtstc_client_new_extra_context ();
+
if (!allow_iterate_main_context) {
sync = TRUE;
inside_loop = FALSE;