diff options
92 files changed, 4615 insertions, 3247 deletions
diff --git a/Makefile.am b/Makefile.am index 47b4acedfc..ad1e12a597 100644 --- a/Makefile.am +++ b/Makefile.am @@ -366,8 +366,6 @@ CLEANFILES += $(DBUS_INTERFACE_DOCS) $(dispatcher_libnm_dispatcher_core_la_OBJECTS): $(introspection_sources) $(dispatcher_nm_dispatcher_OBJECTS): $(introspection_sources) $(libnm_libnm_la_OBJECTS): $(introspection_sources) -$(src_libNetworkManager_la_OBJECTS): $(introspection_sources) -$(src_libNetworkManagerBase_la_OBJECTS): $(introspection_sources) EXTRA_DIST += \ $(dbusinterfaces_DATA) \ @@ -1423,8 +1421,10 @@ src_libNetworkManagerBase_la_SOURCES = \ src/ndisc/nm-ndisc.h \ src/ndisc/nm-ndisc-private.h \ \ - src/nm-exported-object.c \ - src/nm-exported-object.h \ + src/nm-dbus-utils.c \ + src/nm-dbus-utils.h \ + src/nm-dbus-object.c \ + src/nm-dbus-object.h \ src/nm-ip4-config.c \ src/nm-ip4-config.h \ src/nm-ip6-config.c \ @@ -1452,7 +1452,6 @@ endif src_libNetworkManagerBase_la_LIBADD = \ libnm-core/libnm-core.la \ - introspection/libnmdbus.la \ $(GLIB_LIBS) \ $(SYSTEMD_JOURNAL_LIBS) \ $(LIBUDEV_LIBS) \ @@ -1860,7 +1859,6 @@ src_ppp_libnm_ppp_plugin_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/src/ppp/nm-ppp-plugin.ver" src_ppp_libnm_ppp_plugin_la_LIBADD = \ - introspection/libnmdbus.la \ $(GLIB_LIBS) $(src_ppp_libnm_ppp_plugin_la_OBJECTS): $(libnm_core_lib_h_pub_mkenums) @@ -2515,7 +2513,6 @@ src_devices_adsl_libnm_device_plugin_adsl_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-devices.ver" src_devices_adsl_libnm_device_plugin_adsl_la_LIBADD = \ - introspection/libnmdbus.la \ $(LIBUDEV_LIBS) check-local-devices-adsl: src/devices/adsl/libnm-device-plugin-adsl.la @@ -2591,7 +2588,6 @@ src_devices_wwan_libnm_device_plugin_wwan_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-devices.ver" src_devices_wwan_libnm_device_plugin_wwan_la_LIBADD = \ - introspection/libnmdbus.la \ src/devices/wwan/libnm-wwan.la \ $(GLIB_LIBS) @@ -2649,7 +2645,6 @@ src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-devices.ver" src_devices_bluetooth_libnm_device_plugin_bluetooth_la_LIBADD = \ - introspection/libnmdbus.la \ src/devices/wwan/libnm-wwan.la \ $(GLIB_LIBS) @@ -2690,6 +2685,8 @@ src_devices_wifi_libnm_device_plugin_wifi_la_SOURCES = \ src/devices/wifi/nm-wifi-ap.h \ src/devices/wifi/nm-wifi-utils.c \ src/devices/wifi/nm-wifi-utils.h \ + src/devices/wifi/nm-wifi-common.c \ + src/devices/wifi/nm-wifi-common.h \ src/devices/wifi/nm-device-olpc-mesh.c \ src/devices/wifi/nm-device-olpc-mesh.h @@ -2716,7 +2713,6 @@ src_devices_wifi_libnm_device_plugin_wifi_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-devices.ver" src_devices_wifi_libnm_device_plugin_wifi_la_LIBADD = \ - introspection/libnmdbus.la \ $(GLIB_LIBS) check-local-devices-wifi: src/devices/wifi/libnm-device-plugin-wifi.la @@ -2786,7 +2782,6 @@ src_devices_team_libnm_device_plugin_team_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-devices.ver" src_devices_team_libnm_device_plugin_team_la_LIBADD = \ - introspection/libnmdbus.la \ $(LIBTEAMDCTL_LIBS) \ $(JANSSON_LIBS) \ $(GLIB_LIBS) @@ -2848,7 +2843,6 @@ src_devices_ovs_libnm_device_plugin_ovs_la_LDFLAGS = \ -Wl,--version-script="$(srcdir)/linker-script-devices.ver" src_devices_ovs_libnm_device_plugin_ovs_la_LIBADD = \ - introspection/libnmdbus.la \ $(JANSSON_LIBS) \ $(GLIB_LIBS) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 2259fc7e76..8c3f82ae41 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -31,7 +31,6 @@ #include "nm-core-internal.h" #include "platform/nm-platform.h" -#include "nm-exported-object.h" #include "nm-auth-utils.h" /*****************************************************************************/ @@ -880,62 +879,6 @@ nm_utils_match_connection (NMConnection *const*connections, /*****************************************************************************/ -/** - * nm_utils_g_value_set_object_path: - * @value: a #GValue, initialized to store an object path - * @object: (allow-none): an #NMExportedObject - * - * Sets @value to @object's object path. If @object is %NULL, or not - * exported, @value is set to "/". - */ -void -nm_utils_g_value_set_object_path (GValue *value, gpointer object) -{ - g_return_if_fail (!object || NM_IS_EXPORTED_OBJECT (object)); - - if (object && nm_exported_object_is_exported (object)) - g_value_set_string (value, nm_exported_object_get_path (object)); - else - g_value_set_string (value, "/"); -} - -/** - * nm_utils_g_value_set_object_path_array: - * @value: a #GValue, initialized to store an object path - * @objects: a #GSList of #NMExportedObjects - * @filter_func: (allow-none): function to call on each object in @objects - * @user_data: data to pass to @filter_func - * - * Sets @value to an array of object paths of the objects in @objects. - */ -void -nm_utils_g_value_set_object_path_array (GValue *value, - GSList *objects, - NMUtilsObjectFunc filter_func, - gpointer user_data) -{ - char **paths; - guint i; - GSList *iter; - - paths = g_new (char *, g_slist_length (objects) + 1); - for (i = 0, iter = objects; iter; iter = iter->next) { - NMExportedObject *object = iter->data; - const char *path; - - path = nm_exported_object_get_path (object); - if (!path) - continue; - if (filter_func && !filter_func ((GObject *) object, user_data)) - continue; - paths[i++] = g_strdup (path); - } - paths[i] = NULL; - g_value_take_boxed (value, paths); -} - -/*****************************************************************************/ - int nm_match_spec_device_by_pllink (const NMPlatformLink *pllink, const char *match_device_type, diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 16b0873664..8cd9a19334 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -48,22 +48,6 @@ NMConnection *nm_utils_match_connection (NMConnection *const*connections, NMUtilsMatchFilterFunc match_filter_func, gpointer match_filter_data); -void nm_utils_g_value_set_object_path (GValue *value, gpointer object); - -/** - * NMUtilsObjectFunc: - * @object: the object to filter on - * @user_data: data passed to the function from the caller - * - * Returns: %TRUE if the object should be used, %FALSE if not - */ -typedef gboolean (*NMUtilsObjectFunc) (GObject *object, gpointer user_data); - -void nm_utils_g_value_set_object_path_array (GValue *value, - GSList *objects, - NMUtilsObjectFunc filter_func, - gpointer user_data); - int nm_match_spec_device_by_pllink (const NMPlatformLink *pllink, const char *match_device_type, const GSList *specs, diff --git a/src/devices/adsl/meson.build b/src/devices/adsl/meson.build index f2071db2f6..4b0fade01a 100644 --- a/src/devices/adsl/meson.build +++ b/src/devices/adsl/meson.build @@ -4,7 +4,6 @@ sources = files( ) deps = [ - libnmdbus_dep, libudev_dep, nm_dep ] diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 2512c3187e..8675cbf8bc 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -39,8 +39,6 @@ #include "nm-setting-adsl.h" #include "nm-utils.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Adsl.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF (NMDeviceAdsl); @@ -655,10 +653,24 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_adsl_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_adsl = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_ADSL, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_adsl_class_init (NMDeviceAdslClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); object_class->constructed = constructed; @@ -666,6 +678,8 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_adsl); + parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; @@ -682,8 +696,4 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_ADSL_SKELETON, - NULL); } diff --git a/src/devices/bluetooth/meson.build b/src/devices/bluetooth/meson.build index ec56a8b9a4..eb200679f5 100644 --- a/src/devices/bluetooth/meson.build +++ b/src/devices/bluetooth/meson.build @@ -9,7 +9,6 @@ sources = files( ) deps = [ - libnmdbus_dep, libnm_wwan_dep, nm_dep ] diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 77d258ecdd..0b794cbaa5 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -43,8 +43,6 @@ #include "devices/wwan/nm-modem-manager.h" #include "devices/wwan/nm-modem.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Bluetooth.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceBt); @@ -1152,10 +1150,26 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_bluetooth = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Name", "s", NM_DEVICE_BT_NAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("BtCapabilities", "u", NM_DEVICE_BT_CAPABILITIES), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_bt_class_init (NMDeviceBtClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->constructed = constructed; @@ -1164,6 +1178,8 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) object_class->dispose = dispose; object_class->finalize = finalize; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bluetooth); + device_class->get_generic_capabilities = get_generic_capabilities; device_class->can_auto_connect = can_auto_connect; device_class->deactivate = deactivate; @@ -1207,8 +1223,4 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) G_TYPE_NONE, 2, G_TYPE_UINT /*guint32 in_bytes*/, G_TYPE_UINT /*guint32 out_bytes*/); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_BLUETOOTH_SKELETON, - NULL); } diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 910dd0bfe3..94131bf9f4 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -32,8 +32,6 @@ #include "nm-core-internal.h" #include "nm-ip4-config.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Bond.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceBond); @@ -607,13 +605,31 @@ nm_device_bond_init (NMDeviceBond * self) nm_assert (nm_device_is_master (NM_DEVICE (self))); } +static const NMDBusInterfaceInfoExtended interface_info_device_bond = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_BOND, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Slaves", "ao", NM_DEVICE_SLAVES), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_bond_class_init (NMDeviceBondClass *klass) { + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_BOND_SETTING_NAME, NM_LINK_TYPE_BOND) + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bond); + parent_class->is_master = TRUE; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; @@ -629,10 +645,6 @@ nm_device_bond_class_init (NMDeviceBondClass *klass) parent_class->release_slave = release_slave; parent_class->can_reapply_change = can_reapply_change; parent_class->reapply_connection = reapply_connection; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_BOND_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index 74689aef6a..22d2d6bb24 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -30,8 +30,6 @@ #include "nm-device-factory.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Bridge.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceBridge); @@ -488,13 +486,31 @@ nm_device_bridge_init (NMDeviceBridge * self) nm_assert (nm_device_is_master (NM_DEVICE (self))); } +static const NMDBusInterfaceInfoExtended interface_info_device_bridge = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_BRIDGE, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Slaves", "ao", NM_DEVICE_SLAVES), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_bridge_class_init (NMDeviceBridgeClass *klass) { + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_BRIDGE_SETTING_NAME, NM_LINK_TYPE_BRIDGE) + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bridge); + parent_class->is_master = TRUE; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; @@ -511,10 +527,6 @@ nm_device_bridge_class_init (NMDeviceBridgeClass *klass) parent_class->enslave_slave = enslave_slave; parent_class->release_slave = release_slave; parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_BRIDGE_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-dummy.c b/src/devices/nm-device-dummy.c index 085c44e6a3..07647897ea 100644 --- a/src/devices/nm-device-dummy.c +++ b/src/devices/nm-device-dummy.c @@ -28,8 +28,6 @@ #include "nm-setting-dummy.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Dummy.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceDummy); @@ -156,13 +154,29 @@ nm_device_dummy_init (NMDeviceDummy *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_dummy = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_DUMMY, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_dummy_class_init (NMDeviceDummyClass *klass) { + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_DUMMY) + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_dummy); + device_class->connection_type = NM_SETTING_DUMMY_SETTING_NAME; device_class->complete_connection = complete_connection; device_class->check_connection_compatible = check_connection_compatible; @@ -171,10 +185,6 @@ nm_device_dummy_class_init (NMDeviceDummyClass *klass) device_class->update_connection = update_connection; device_class->act_stage1_prepare = act_stage1_prepare; device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_DUMMY_SKELETON, - NULL); } diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 0e1ebcc6ad..930ab2bac7 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -28,7 +28,6 @@ #include <stdlib.h> #include <unistd.h> #include <errno.h> - #include <libudev.h> #include "nm-device-private.h" @@ -52,8 +51,6 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Wired.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceEthernet); @@ -1714,10 +1711,28 @@ set_property (GObject *object, guint prop_id, } } +static const NMDBusInterfaceInfoExtended interface_info_device_wired = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_WIRED, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PermHwAddress", "s", NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Speed", "u", NM_DEVICE_ETHERNET_SPEED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("S390Subchannels", "as", NM_DEVICE_ETHERNET_S390_SUBCHANNELS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); g_type_class_add_private (object_class, sizeof (NMDeviceEthernetPrivate)); @@ -1729,6 +1744,8 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wired); + parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->check_connection_compatible = check_connection_compatible; parent_class->complete_connection = complete_connection; @@ -1762,10 +1779,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_ETHERNET_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index f6a670b214..27eaf8d6ce 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -26,8 +26,6 @@ #include "platform/nm-platform.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Generic.h" - /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( @@ -203,10 +201,25 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_generic_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_generic = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_GENERIC, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("TypeDescription", "s", NM_DEVICE_GENERIC_TYPE_DESCRIPTION), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_generic_class_init (NMDeviceGenericClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_GENERIC_SETTING_NAME, NM_LINK_TYPE_ANY) @@ -216,6 +229,8 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_generic); + parent_class->realize_start_notify = realize_start_notify; parent_class->get_generic_capabilities = get_generic_capabilities; parent_class->get_type_description = get_type_description; @@ -229,8 +244,4 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_GENERIC_SKELETON, - NULL); } diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 91188d1632..dbba257888 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -32,8 +32,6 @@ #include "nm-device-factory.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Infiniband.h" - #define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition" /*****************************************************************************/ @@ -368,10 +366,25 @@ nm_device_infiniband_init (NMDeviceInfiniband * self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_infiniband = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_INFINIBAND, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_INFINIBAND_SETTING_NAME, NM_LINK_TYPE_INFINIBAND) @@ -379,6 +392,8 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_infiniband); + parent_class->create_and_realize = create_and_realize; parent_class->unrealize = unrealize; parent_class->get_generic_capabilities = get_generic_capabilities; @@ -396,10 +411,6 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_INFINIBAND_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 4b31ad704f..f0ee79ccb2 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -37,8 +37,6 @@ #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "introspection/org.freedesktop.NetworkManager.Device.IPTunnel.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceIPTunnel); @@ -907,10 +905,35 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_ip_tunnel_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_ip_tunnel = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "u", NM_DEVICE_IP_TUNNEL_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Local", "s", NM_DEVICE_IP_TUNNEL_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Remote", "s", NM_DEVICE_IP_TUNNEL_REMOTE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ttl", "y", NM_DEVICE_IP_TUNNEL_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Tos", "y", NM_DEVICE_IP_TUNNEL_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PathMtuDiscovery", "b", NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("InputKey", "s", NM_DEVICE_IP_TUNNEL_INPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("OutputKey", "s", NM_DEVICE_IP_TUNNEL_OUTPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("EncapsulationLimit", "y", NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("FlowLabel", "u", NM_DEVICE_IP_TUNNEL_FLOW_LABEL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Flags", "u", NM_DEVICE_IP_TUNNEL_FLAGS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->constructed = constructed; @@ -918,6 +941,8 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ip_tunnel); + device_class->link_changed = link_changed; device_class->can_reapply_change = can_reapply_change; device_class->complete_connection = complete_connection; @@ -1003,10 +1028,6 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_IPTUNNEL_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-ip-tunnel.h b/src/devices/nm-device-ip-tunnel.h index 6f1fcd756e..1109ace4a7 100644 --- a/src/devices/nm-device-ip-tunnel.h +++ b/src/devices/nm-device-ip-tunnel.h @@ -43,9 +43,6 @@ #define NM_DEVICE_IP_TUNNEL_FLOW_LABEL "flow-label" #define NM_DEVICE_IP_TUNNEL_FLAGS "flags" -/* defined in the parent class, but exposed on D-Bus by the subclass. */ -#define NM_DEVICE_IP_TUNNEL_PARENT NM_DEVICE_PARENT - typedef struct _NMDeviceIPTunnel NMDeviceIPTunnel; typedef struct _NMDeviceIPTunnelClass NMDeviceIPTunnelClass; diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c index 554238a320..9927adb32c 100644 --- a/src/devices/nm-device-macsec.c +++ b/src/devices/nm-device-macsec.c @@ -33,8 +33,6 @@ #include "supplicant/nm-supplicant-interface.h" #include "supplicant/nm-supplicant-config.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Macsec.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceMacsec); @@ -812,10 +810,36 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_macsec_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_macsec = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_MACSEC, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Sci", "t", NM_DEVICE_MACSEC_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("IcvLength", "y", NM_DEVICE_MACSEC_ICV_LENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CipherSuite", "t", NM_DEVICE_MACSEC_CIPHER_SUITE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Window", "u", NM_DEVICE_MACSEC_WINDOW), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("EncodingSa", "y", NM_DEVICE_MACSEC_ENCODING_SA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Validation", "s", NM_DEVICE_MACSEC_VALIDATION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Encrypt", "b", NM_DEVICE_MACSEC_ENCRYPT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Protect", "b", NM_DEVICE_MACSEC_PROTECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("IncludeSci", "b", NM_DEVICE_MACSEC_INCLUDE_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Es", "b", NM_DEVICE_MACSEC_ES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Scb", "b", NM_DEVICE_MACSEC_SCB), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ReplayProtect", "b", NM_DEVICE_MACSEC_REPLAY_PROTECT), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_macsec_class_init (NMDeviceMacsecClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_MACSEC) @@ -823,6 +847,8 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) object_class->get_property = get_property; object_class->dispose = dispose; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_macsec); + parent_class->act_stage2_config = act_stage2_config; parent_class->check_connection_compatible = check_connection_compatible; parent_class->create_and_realize = create_and_realize; @@ -886,10 +912,6 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_MACSEC_SKELETON, - NULL); } /*************************************************************/ diff --git a/src/devices/nm-device-macsec.h b/src/devices/nm-device-macsec.h index 17b33bf593..23e9d2c964 100644 --- a/src/devices/nm-device-macsec.h +++ b/src/devices/nm-device-macsec.h @@ -43,9 +43,6 @@ #define NM_DEVICE_MACSEC_SCB "scb" #define NM_DEVICE_MACSEC_REPLAY_PROTECT "replay-protect" -/* defined in the parent class, but exposed on D-Bus by the subclass. */ -#define NM_DEVICE_MACSEC_PARENT NM_DEVICE_PARENT - typedef struct _NMDeviceMacsec NMDeviceMacsec; typedef struct _NMDeviceMacsecClass NMDeviceMacsecClass; diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index a336012909..cc4b984222 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -36,8 +36,6 @@ #include "nm-ip4-config.h" #include "nm-utils.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Macvlan.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceMacvlan); @@ -475,10 +473,27 @@ nm_device_macvlan_init (NMDeviceMacvlan *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_macvlan = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_MACVLAN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "s", NM_DEVICE_MACVLAN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NoPromisc", "b", NM_DEVICE_MACVLAN_NO_PROMISC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Tab", "b", NM_DEVICE_MACVLAN_TAP), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP) @@ -486,6 +501,8 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_macvlan); + device_class->act_stage1_prepare = act_stage1_prepare; device_class->check_connection_compatible = check_connection_compatible; device_class->complete_connection = complete_connection; @@ -518,10 +535,6 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_MACVLAN_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-macvlan.h b/src/devices/nm-device-macvlan.h index e6d3a33321..c7d4be7c0d 100644 --- a/src/devices/nm-device-macvlan.h +++ b/src/devices/nm-device-macvlan.h @@ -34,9 +34,6 @@ #define NM_DEVICE_MACVLAN_NO_PROMISC "no-promisc" #define NM_DEVICE_MACVLAN_TAP "tap" -/* defined in the parent class, but exposed on D-Bus by the subclass. */ -#define NM_DEVICE_MACVLAN_PARENT NM_DEVICE_PARENT - typedef struct _NMDeviceMacvlan NMDeviceMacvlan; typedef struct _NMDeviceMacvlanClass NMDeviceMacvlanClass; diff --git a/src/devices/nm-device-ppp.c b/src/devices/nm-device-ppp.c index 23ee357018..94df0caed2 100644 --- a/src/devices/nm-device-ppp.c +++ b/src/devices/nm-device-ppp.c @@ -26,8 +26,6 @@ #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Ppp.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDevicePpp); @@ -262,26 +260,35 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_ppp_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_ppp = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_PPP, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_ppp_class_init (NMDevicePppClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_PPPOE_SETTING_NAME, NM_LINK_TYPE_PPP) object_class->dispose = dispose; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ppp); + parent_class->act_stage2_config = act_stage2_config; parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; parent_class->check_connection_compatible = check_connection_compatible; parent_class->create_and_realize = create_and_realize; parent_class->deactivate = deactivate; parent_class->get_generic_capabilities = get_generic_capabilities; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_PPP_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index fa837c4b6e..5dd53054d0 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -34,8 +34,6 @@ #include "nm-setting-tun.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Tun.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceTun); @@ -395,10 +393,30 @@ nm_device_tun_init (NMDeviceTun *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_tun = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_TUN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Owner", "x", NM_DEVICE_TUN_OWNER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Group", "x", NM_DEVICE_TUN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "s", NM_DEVICE_TUN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NoPi", "b", NM_DEVICE_TUN_NO_PI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("VnetHdr", "b", NM_DEVICE_TUN_VNET_HDR), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("MultiQueue", "b", NM_DEVICE_TUN_MULTI_QUEUE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_tun_class_init (NMDeviceTunClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_TUN, NM_LINK_TYPE_TAP) @@ -406,6 +424,8 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_tun); + device_class->connection_type = NM_SETTING_TUN_SETTING_NAME; device_class->link_changed = link_changed; device_class->complete_connection = complete_connection; @@ -449,10 +469,6 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_TUN_SKELETON, - NULL); } diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 0ed9ad844b..186173eb88 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -30,8 +30,6 @@ #include "platform/nm-platform.h" #include "nm-device-factory.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Veth.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceVeth); @@ -127,7 +125,7 @@ get_property (GObject *object, guint prop_id, peer = nm_device_parent_get_device (NM_DEVICE (self)); if (peer && !NM_IS_DEVICE_VETH (peer)) peer = NULL; - nm_utils_g_value_set_object_path (value, peer); + nm_dbus_utils_g_value_set_object_path (value, peer); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -135,16 +133,32 @@ get_property (GObject *object, guint prop_id, } } +static const NMDBusInterfaceInfoExtended interface_info_device_veth = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_VETH, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Peer", "o", NM_DEVICE_VETH_PEER), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_veth_class_init (NMDeviceVethClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VETH) object_class->get_property = get_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_veth); + device_class->can_unmanaged_external_down = can_unmanaged_external_down; device_class->link_changed = link_changed; device_class->parent_changed_notify = parent_changed_notify; @@ -156,10 +170,6 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_VETH_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 21d433eb38..8737f10b6a 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -37,8 +37,6 @@ #include "nm-core-internal.h" #include "platform/nmp-object.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Vlan.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceVlan); @@ -577,16 +575,35 @@ nm_device_vlan_init (NMDeviceVlan * self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_vlan = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_VLAN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("VlanId", "u", NM_DEVICE_VLAN_ID), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_vlan_class_init (NMDeviceVlanClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_VLAN_SETTING_NAME, NM_LINK_TYPE_VLAN) object_class->get_property = get_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vlan); + parent_class->create_and_realize = create_and_realize; parent_class->link_changed = link_changed; parent_class->unrealize_notify = unrealize_notify; @@ -608,10 +625,6 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_VLAN_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-vlan.h b/src/devices/nm-device-vlan.h index 0d788940ee..375e8fa4c9 100644 --- a/src/devices/nm-device-vlan.h +++ b/src/devices/nm-device-vlan.h @@ -36,12 +36,8 @@ typedef enum { NM_VLAN_ERROR_CONNECTION_INCOMPATIBLE, /*< nick=ConnectionIncompatible >*/ } NMVlanError; -/* D-Bus exported properties */ #define NM_DEVICE_VLAN_ID "vlan-id" -/* defined in the parent class, but exposed on D-Bus by the subclass. */ -#define NM_DEVICE_VLAN_PARENT NM_DEVICE_PARENT - typedef struct _NMDeviceVlan NMDeviceVlan; typedef struct _NMDeviceVlanClass NMDeviceVlanClass; diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index e09c7fbbbd..d16754f9ee 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -35,8 +35,6 @@ #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Vxlan.h" - #include "nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceVxlan); @@ -543,16 +541,48 @@ nm_device_vxlan_init (NMDeviceVxlan *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_vxlan = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_VXLAN, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Id", "u", NM_DEVICE_VXLAN_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Group", "s", NM_DEVICE_VXLAN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Local", "s", NM_DEVICE_VXLAN_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Tos", "y", NM_DEVICE_VXLAN_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ttl", "y", NM_DEVICE_VXLAN_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Learning", "b", NM_DEVICE_VXLAN_LEARNING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ageing", "u", NM_DEVICE_VXLAN_AGEING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Limit", "u", NM_DEVICE_VXLAN_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DstPort", "q", NM_DEVICE_VXLAN_DST_PORT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("SrcPortMin", "q", NM_DEVICE_VXLAN_SRC_PORT_MIN), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("SrcPortMax", "q", NM_DEVICE_VXLAN_SRC_PORT_MAX), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Proxy", "b", NM_DEVICE_VXLAN_PROXY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Rsc", "b", NM_DEVICE_VXLAN_RSC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("L2miss", "b", NM_DEVICE_VXLAN_L2MISS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("L3miss", "b", NM_DEVICE_VXLAN_L3MISS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VXLAN) object_class->get_property = get_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vxlan); + device_class->link_changed = link_changed; device_class->unrealize_notify = unrealize_notify; device_class->connection_type = NM_SETTING_VXLAN_SETTING_NAME; @@ -655,10 +685,6 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_VXLAN_SKELETON, - NULL); } /*****************************************************************************/ diff --git a/src/devices/nm-device-vxlan.h b/src/devices/nm-device-vxlan.h index 6f0102dc04..511b71560b 100644 --- a/src/devices/nm-device-vxlan.h +++ b/src/devices/nm-device-vxlan.h @@ -46,9 +46,6 @@ #define NM_DEVICE_VXLAN_L2MISS "l2miss" #define NM_DEVICE_VXLAN_L3MISS "l3miss" -/* defined in the parent class, but exposed on D-Bus by the subclass. */ -#define NM_DEVICE_VXLAN_PARENT NM_DEVICE_PARENT - typedef struct _NMDeviceVxlan NMDeviceVxlan; typedef struct _NMDeviceVxlanClass NMDeviceVxlanClass; diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 23c8c9b500..7175717fdb 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -80,9 +80,6 @@ #include "nm-device-logging.h" _LOG_DECLARE_SELF (NMDevice); -#include "introspection/org.freedesktop.NetworkManager.Device.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Statistics.h" - /*****************************************************************************/ #define DHCP_RESTART_TIMEOUT 120 @@ -506,12 +503,15 @@ typedef struct _NMDevicePrivate { } NMDevicePrivate; -G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_ABSTRACT_TYPE (NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) #define NM_DEVICE_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMDevice, NM_IS_DEVICE) /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_device; +static const GDBusSignalInfo signal_info_state_changed; + static void nm_device_set_proxy_config (NMDevice *self, const char *pac_url); static gboolean update_ext_ip_config (NMDevice *self, int addr_family, gboolean initial, gboolean intersect_configs); @@ -6067,7 +6067,7 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) } if (priv->dhcp4.config) { - nm_exported_object_clear_and_unexport (&priv->dhcp4.config); + nm_dbus_object_clear_and_unexport (&priv->dhcp4.config); _notify (self, PROP_DHCP4_CONFIG); } } @@ -6493,7 +6493,7 @@ dhcp4_start (NMDevice *self) s_ip4 = nm_connection_get_setting_ip4_config (connection); /* Clear old exported DHCP options */ - nm_exported_object_clear_and_unexport (&priv->dhcp4.config); + nm_dbus_object_clear_and_unexport (&priv->dhcp4.config); priv->dhcp4.config = nm_dhcp4_config_new (); hwaddr = nm_platform_link_get_address_as_bytes (nm_device_get_platform (self), @@ -6831,7 +6831,7 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) nm_device_remove_pending_action (self, NM_PENDING_ACTION_DHCP6, FALSE); if (priv->dhcp6.config) { - nm_exported_object_clear_and_unexport (&priv->dhcp6.config); + nm_dbus_object_clear_and_unexport (&priv->dhcp6.config); _notify (self, PROP_DHCP6_CONFIG); } } @@ -7281,7 +7281,7 @@ dhcp6_start (NMDevice *self, gboolean wait_for_ll) NMConnection *connection; NMSettingIPConfig *s_ip6; - nm_exported_object_clear_and_unexport (&priv->dhcp6.config); + nm_dbus_object_clear_and_unexport (&priv->dhcp6.config); priv->dhcp6.config = nm_dhcp6_config_new (); nm_assert (!applied_config_get_current (&priv->dhcp6.ip6_config)); @@ -9256,7 +9256,7 @@ act_request_set (NMDevice *self, NMActRequest *act_request) if (act_request) { priv->act_request_id = g_signal_connect (act_request, - "notify::"NM_EXPORTED_OBJECT_PATH, + "notify::"NM_DBUS_OBJECT_PATH, G_CALLBACK (act_request_set_cb), self); @@ -9887,25 +9887,33 @@ reapply_cb (NMDevice *self, } static void -impl_device_reapply (NMDevice *self, - GDBusMethodInvocation *context, - GVariant *settings, - guint64 version_id, - guint32 flags) +impl_device_reapply (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMDevice *self = NM_DEVICE (obj); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingsConnection *settings_connection; NMConnection *connection = NULL; GError *error = NULL; ReapplyData *reapply_data; + gs_unref_variant GVariant *settings = NULL; + guint64 version_id; + guint32 flags; + + g_variant_get (parameters, "(@a{sa{sv}}tu)", &settings, &version_id, &flags); /* No flags supported as of now. */ if (flags != 0) { error = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "Invalid flags specified"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message); - g_dbus_method_invocation_take_error (context, error); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, invocation, error->message); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -9913,8 +9921,8 @@ impl_device_reapply (NMDevice *self, error = g_error_new_literal (NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ACTIVE, "Device is not activated"); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message); - g_dbus_method_invocation_take_error (context, error); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, invocation, error->message); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -9929,8 +9937,8 @@ impl_device_reapply (NMDevice *self, &error); if (!connection) { g_prefix_error (&error, "The settings specified are invalid: "); - nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, context, error->message); - g_dbus_method_invocation_take_error (context, error); + nm_audit_log_device_op (NM_AUDIT_OP_DEVICE_REAPPLY, self, FALSE, NULL, invocation, error->message); + g_dbus_method_invocation_take_error (invocation, error); return; } nm_connection_clear_secrets (connection); @@ -9943,9 +9951,8 @@ impl_device_reapply (NMDevice *self, } else reapply_data = NULL; - /* Ask the manager to authenticate this request for us */ g_signal_emit (self, signals[AUTH_REQUEST], 0, - context, + invocation, nm_device_get_applied_connection (self), NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE, @@ -10008,36 +10015,40 @@ get_applied_connection_cb (NMDevice *self, } static void -impl_device_get_applied_connection (NMDevice *self, - GDBusMethodInvocation *context, - guint32 flags) +impl_device_get_applied_connection (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMDevice *self = NM_DEVICE (obj); NMConnection *applied_connection; - GError *error = NULL; + guint32 flags; - g_return_if_fail (NM_IS_DEVICE (self)); + g_variant_get (parameters, "(u)", &flags); /* No flags supported as of now. */ if (flags != 0) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "Invalid flags specified"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_FAILED, + "Invalid flags specified"); return; } applied_connection = nm_device_get_applied_connection (self); if (!applied_connection) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "Device is not activated"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "Device is not activated"); return; } - /* Ask the manager to authenticate this request for us */ g_signal_emit (self, signals[AUTH_REQUEST], 0, - context, + invocation, applied_connection, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE, @@ -10186,25 +10197,31 @@ _clear_queued_act_request (NMDevicePrivate *priv) } static void -impl_device_disconnect (NMDevice *self, GDBusMethodInvocation *context) +impl_device_disconnect (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMDevice *self = NM_DEVICE (obj); + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - GError *error = NULL; - if (NM_DEVICE_GET_PRIVATE (self)->act_request == NULL) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_ACTIVE, - "This device is not active"); - g_dbus_method_invocation_take_error (context, error); + if (!priv->act_request) { + g_dbus_method_invocation_return_error_literal (invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_ACTIVE, + "This device is not active"); return; } connection = nm_device_get_applied_connection (self); - g_assert (connection); + nm_assert (connection); - /* Ask the manager to authenticate this request for us */ g_signal_emit (self, signals[AUTH_REQUEST], 0, - context, + invocation, connection, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE, @@ -10236,21 +10253,27 @@ delete_cb (NMDevice *self, } static void -impl_device_delete (NMDevice *self, GDBusMethodInvocation *context) +impl_device_delete (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - GError *error = NULL; + NMDevice *self = NM_DEVICE (obj); - if (!nm_device_is_software (self) || !nm_device_is_real (self)) { - error = g_error_new_literal (NM_DEVICE_ERROR, - NM_DEVICE_ERROR_NOT_SOFTWARE, - "This device is not a software device or is not realized"); - g_dbus_method_invocation_take_error (context, error); + if ( !nm_device_is_software (self) + || !nm_device_is_real (self)) { + g_dbus_method_invocation_return_error_literal (invocation, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_NOT_SOFTWARE, + "This device is not a software device or is not realized"); return; } - /* Ask the manager to authenticate this request for us */ g_signal_emit (self, signals[AUTH_REQUEST], 0, - context, + invocation, NULL, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE, @@ -10544,23 +10567,23 @@ nm_device_set_ip4_config (NMDevice *self, nm_ip4_config_replace (old_config, new_config, &has_changes); if (has_changes) { _LOGD (LOGD_IP4, "ip4-config: update IP4Config instance (%s)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); } } else { has_changes = TRUE; priv->ip4_config = g_object_ref (new_config); - if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config))) - nm_exported_object_export (NM_EXPORTED_OBJECT (new_config)); + if (success && !nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) + nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); _LOGD (LOGD_IP4, "ip4-config: set IP4Config instance (%s)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); } } else if (old_config) { has_changes = TRUE; priv->ip4_config = NULL; _LOGD (LOGD_IP4, "ip4-config: clear IP4Config instance (%s)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); /* Device config is invalid if combined config is invalid */ applied_config_clear (&priv->dev_ip4_config); } @@ -10580,7 +10603,7 @@ nm_device_set_ip4_config (NMDevice *self, g_signal_emit (self, signals[IP4_CONFIG_CHANGED], 0, priv->ip4_config, old_config); if (old_config != priv->ip4_config) - nm_exported_object_clear_and_unexport (&old_config); + nm_dbus_object_clear_and_unexport (&old_config); if ( nm_device_sys_iface_state_is_external (self) && (settings_connection = nm_device_get_settings_connection (self)) @@ -10717,24 +10740,24 @@ nm_device_set_ip6_config (NMDevice *self, nm_ip6_config_replace (old_config, new_config, &has_changes); if (has_changes) { _LOGD (LOGD_IP6, "ip6-config: update IP6Config instance (%s)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); } } else { has_changes = TRUE; priv->ip6_config = g_object_ref (new_config); - if (success && !nm_exported_object_is_exported (NM_EXPORTED_OBJECT (new_config))) - nm_exported_object_export (NM_EXPORTED_OBJECT (new_config)); + if (success && !nm_dbus_object_is_exported (NM_DBUS_OBJECT (new_config))) + nm_dbus_object_export (NM_DBUS_OBJECT (new_config)); _LOGD (LOGD_IP6, "ip6-config: set IP6Config instance (%s)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (new_config))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (new_config))); } } else if (old_config) { has_changes = TRUE; priv->ip6_config = NULL; priv->needs_ip6_subnet = FALSE; _LOGD (LOGD_IP6, "ip6-config: clear IP6Config instance (%s)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (old_config))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (old_config))); } if (has_changes) { @@ -10745,7 +10768,7 @@ nm_device_set_ip6_config (NMDevice *self, g_signal_emit (self, signals[IP6_CONFIG_CHANGED], 0, priv->ip6_config, old_config); if (old_config != priv->ip6_config) - nm_exported_object_clear_and_unexport (&old_config); + nm_dbus_object_clear_and_unexport (&old_config); if ( nm_device_sys_iface_state_is_external (self) && (settings_connection = nm_device_get_settings_connection (self)) @@ -13484,6 +13507,13 @@ _set_state_full (NMDevice *self, _notify (self, PROP_STATE); _notify (self, PROP_STATE_REASON); + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_device, + &signal_info_state_changed, + "(uuu)", + (guint32) state, + (guint32) old_state, + (guint32) reason); g_signal_emit (self, signals[STATE_CHANGED], 0, (guint) state, (guint) old_state, (guint) reason); /* Post-process the event after internal notification */ @@ -14997,16 +15027,16 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->mtu); break; case PROP_IP4_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip4_config : NULL); break; case PROP_DHCP4_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4.config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp4.config : NULL); break; case PROP_IP6_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->ip6_config : NULL); break; case PROP_DHCP6_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6.config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->state) ? priv->dhcp6.config : NULL); break; case PROP_STATE: g_value_set_uint (value, priv->state); @@ -15016,7 +15046,7 @@ get_property (GObject *object, guint prop_id, g_variant_new ("(uu)", priv->state, priv->state_reason)); break; case PROP_ACTIVE_CONNECTION: - nm_utils_g_value_set_object_path (value, priv->act_request_public ? priv->act_request : NULL); + nm_dbus_utils_g_value_set_object_path (value, priv->act_request_public ? priv->act_request : NULL); break; case PROP_DEVICE_TYPE: g_value_set_uint (value, priv->type); @@ -15061,7 +15091,7 @@ get_property (GObject *object, guint prop_id, g_value_set_object (value, nm_device_get_master (self)); break; case PROP_PARENT: - nm_utils_g_value_set_object_path (value, priv->parent_device); + nm_dbus_utils_g_value_set_object_path (value, priv->parent_device); break; case PROP_HW_ADDRESS: g_value_set_string (value, priv->hw_addr); @@ -15106,7 +15136,7 @@ get_property (GObject *object, guint prop_id, if (!NM_DEVICE_GET_PRIVATE (info->slave)->is_enslaved) continue; - path = nm_exported_object_get_path ((NMExportedObject *) info->slave); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (info->slave)); if (path) slave_list[i++] = g_strdup (path); } @@ -15133,15 +15163,115 @@ get_property (GObject *object, guint prop_id, } } +static const GDBusSignalInfo signal_info_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "StateChanged", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("new_state", "u"), + NM_DEFINE_GDBUS_ARG_INFO ("old_state", "u"), + NM_DEFINE_GDBUS_ARG_INFO ("reason", "u"), + ), +); + +static const NMDBusInterfaceInfoExtended interface_info_device = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Reapply", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("version_id", "t"), + NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), + ), + ), + .handle = impl_device_reapply, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetAppliedConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("version_id", "t"), + ), + ), + .handle = impl_device_get_applied_connection, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Disconnect", + ), + .handle = impl_device_disconnect, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Delete", + ), + .handle = impl_device_delete, + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &signal_info_state_changed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Udi", "s", NM_DEVICE_UDI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Interface", "s", NM_DEVICE_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("IpInterface", "s", NM_DEVICE_IP_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Driver", "s", NM_DEVICE_DRIVER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DriverVersion", "s", NM_DEVICE_DRIVER_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("FirmwareVersion", "s", NM_DEVICE_FIRMWARE_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Capabilities", "u", NM_DEVICE_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip4Address", "u", NM_DEVICE_IP4_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("State", "u", NM_DEVICE_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("StateReason", "(uu)", NM_DEVICE_STATE_REASON), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveConnection", "o", NM_DEVICE_ACTIVE_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip4Config", "o", NM_DEVICE_IP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Dhcp4Config", "o", NM_DEVICE_DHCP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip6Config", "o", NM_DEVICE_IP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Dhcp6Config", "o", NM_DEVICE_DHCP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("Managed", "b", NM_DEVICE_MANAGED, NM_AUTH_PERMISSION_NETWORK_CONTROL, NM_AUDIT_OP_DEVICE_MANAGED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("Autoconnect", "b", NM_DEVICE_AUTOCONNECT, NM_AUTH_PERMISSION_NETWORK_CONTROL, NM_AUDIT_OP_DEVICE_AUTOCONNECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("FirmwareMissing", "b", NM_DEVICE_FIRMWARE_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NmPluginMissing", "b", NM_DEVICE_NM_PLUGIN_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DeviceType", "u", NM_DEVICE_DEVICE_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AvailableConnections", "ao", NM_DEVICE_AVAILABLE_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PhysicalPortId", "s", NM_DEVICE_PHYSICAL_PORT_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mtu", "u", NM_DEVICE_MTU), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Metered", "u", NM_DEVICE_METERED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("LldpNeighbors", "aa{sv}", NM_DEVICE_LLDP_NEIGHBORS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Real", "b", NM_DEVICE_REAL), + ), + ), +}; + +const NMDBusInterfaceInfoExtended nm_interface_info_device_statistics = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_STATISTICS, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE ("RefreshRateMs", "u", NM_DEVICE_STATISTICS_REFRESH_RATE_MS, NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS, NM_AUDIT_OP_STATISTICS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("TxBytes", "t", NM_DEVICE_STATISTICS_TX_BYTES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("RxBytes", "t", NM_DEVICE_STATISTICS_RX_BYTES), + ), + ), +}; + static void nm_device_class_init (NMDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); g_type_class_add_private (object_class, sizeof (NMDevicePrivate)); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/Devices"); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/Devices"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device, + &nm_interface_info_device_statistics); object_class->dispose = dispose; object_class->finalize = finalize; @@ -15373,7 +15503,6 @@ nm_device_class_init (NMDeviceClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - /* Statistics */ obj_properties[PROP_REFRESH_RATE_MS] = g_param_spec_uint (NM_DEVICE_STATISTICS_REFRESH_RATE_MS, "", "", 0, UINT32_MAX, 0, @@ -15390,7 +15519,6 @@ nm_device_class_init (NMDeviceClass *klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - /* Connectivity */ obj_properties[PROP_CONNECTIVITY] = g_param_spec_uint (NM_DEVICE_CONNECTIVITY, "", "", NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN, @@ -15472,16 +15600,4 @@ nm_device_class_init (NMDeviceClass *klass) G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_SKELETON, - "Reapply", impl_device_reapply, - "GetAppliedConnection", impl_device_get_applied_connection, - "Disconnect", impl_device_disconnect, - "Delete", impl_device_delete, - NULL); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_STATISTICS_SKELETON, - NULL); } diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 3f3da48578..f990f8331e 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -25,7 +25,7 @@ #include <netinet/in.h> #include "nm-setting-connection.h" -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-dbus-interface.h" #include "nm-connection.h" #include "nm-rfkill-manager.h" @@ -114,8 +114,7 @@ nm_device_state_reason_check (NMDeviceStateReason reason) #define NM_DEVICE_PARENT "parent" /* the "slaves" property is internal in the parent class, but exposed - * by the derived classes NMDeviceBond, NMDeviceBridge and NMDeviceTeam. - * It is thus important that the property name matches. */ + * by the derived classes NMDeviceBond, NMDeviceBridge and NMDeviceTeam. */ #define NM_DEVICE_SLAVES "slaves" /* partially internal */ #define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ @@ -173,9 +172,7 @@ typedef enum { /*< skip >*/ struct _NMDevicePrivate; struct _NMDevice { - NMExportedObject parent; - - /* private */ + NMDBusObject parent; struct _NMDevicePrivate *_priv; }; @@ -191,7 +188,7 @@ typedef enum { /*< skip >*/ } NMDeviceCheckDevAvailableFlags; typedef struct { - NMExportedObjectClass parent; + NMDBusObjectClass parent; const char *default_type_description; diff --git a/src/devices/ovs/meson.build b/src/devices/ovs/meson.build index e75ca80bee..7b1c461746 100644 --- a/src/devices/ovs/meson.build +++ b/src/devices/ovs/meson.build @@ -8,7 +8,6 @@ sources = files( deps = [ jansson_dep, - libnmdbus_dep, nm_dep ] diff --git a/src/devices/ovs/nm-device-ovs-bridge.c b/src/devices/ovs/nm-device-ovs-bridge.c index 53ea2b8287..5244ca8bfb 100644 --- a/src/devices/ovs/nm-device-ovs-bridge.c +++ b/src/devices/ovs/nm-device-ovs-bridge.c @@ -28,10 +28,8 @@ #include "nm-setting-connection.h" #include "nm-setting-ovs-bridge.h" -#include "introspection/org.freedesktop.NetworkManager.Device.OvsBridge.h" - #include "devices/nm-device-logging.h" -_LOG_DECLARE_SELF(NMDeviceOvsBridge); +_LOG_DECLARE_SELF (NMDeviceOvsBridge); /*****************************************************************************/ @@ -133,11 +131,24 @@ nm_device_ovs_bridge_init (NMDeviceOvsBridge *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_ovs_bridge = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *klass) { + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_bridge); + device_class->connection_type = NM_SETTING_OVS_BRIDGE_SETTING_NAME; device_class->is_master = TRUE; device_class->get_type_description = get_type_description; @@ -149,8 +160,4 @@ nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *klass) device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; device_class->enslave_slave = enslave_slave; device_class->release_slave = release_slave; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_OVS_BRIDGE_SKELETON, - NULL); } diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c index ce32c2dd7d..eefe38c80c 100644 --- a/src/devices/ovs/nm-device-ovs-interface.c +++ b/src/devices/ovs/nm-device-ovs-interface.c @@ -28,8 +28,6 @@ #include "nm-setting-ovs-interface.h" #include "nm-setting-ovs-port.h" -#include "introspection/org.freedesktop.NetworkManager.Device.OvsInterface.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceOvsInterface); @@ -185,13 +183,26 @@ nm_device_ovs_interface_init (NMDeviceOvsInterface *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass) { + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_OPENVSWITCH); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_interface); + device_class->connection_type = NM_SETTING_OVS_INTERFACE_SETTING_NAME; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; @@ -202,8 +213,4 @@ nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass) device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; device_class->can_unmanaged_external_down = can_unmanaged_external_down; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_OVS_INTERFACE_SKELETON, - NULL); } diff --git a/src/devices/ovs/nm-device-ovs-port.c b/src/devices/ovs/nm-device-ovs-port.c index cb0915afe6..3f1fe97441 100644 --- a/src/devices/ovs/nm-device-ovs-port.c +++ b/src/devices/ovs/nm-device-ovs-port.c @@ -28,10 +28,8 @@ #include "nm-setting-ovs-port.h" #include "nm-setting-ovs-port.h" -#include "introspection/org.freedesktop.NetworkManager.Device.OvsPort.h" - #include "devices/nm-device-logging.h" -_LOG_DECLARE_SELF(NMDeviceOvsPort); +_LOG_DECLARE_SELF (NMDeviceOvsPort); /*****************************************************************************/ @@ -180,11 +178,24 @@ nm_device_ovs_port_init (NMDeviceOvsPort *self) { } +static const NMDBusInterfaceInfoExtended interface_info_device_ovs_port = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_OVS_PORT, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_ovs_port_class_init (NMDeviceOvsPortClass *klass) { + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_port); + device_class->connection_type = NM_SETTING_OVS_PORT_SETTING_NAME; device_class->is_master = TRUE; device_class->get_type_description = get_type_description; @@ -195,8 +206,4 @@ nm_device_ovs_port_class_init (NMDeviceOvsPortClass *klass) device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; device_class->enslave_slave = enslave_slave; device_class->release_slave = release_slave; - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_OVS_PORT_SKELETON, - NULL); } diff --git a/src/devices/team/meson.build b/src/devices/team/meson.build index 8bcbf5d358..4a533bc5cd 100644 --- a/src/devices/team/meson.build +++ b/src/devices/team/meson.build @@ -5,7 +5,6 @@ sources = files( deps = [ jansson_dep, - libnmdbus_dep, libteamdctl_dep, nm_dep ] diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 3f23a52005..2f1dbde39f 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -37,8 +37,6 @@ #include "nm-ip4-config.h" #include "nm-dbus-compat.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Team.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceTeam); @@ -891,10 +889,27 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_team_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_team = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_TEAM, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Slaves", "ao", NM_DEVICE_SLAVES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Config", "s", NM_DEVICE_TEAM_CONFIG), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_team_class_init (NMDeviceTeamClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_TEAM_SETTING_NAME, NM_LINK_TYPE_TEAM) @@ -903,6 +918,8 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) object_class->dispose = dispose; object_class->get_property = get_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_team); + parent_class->is_master = TRUE; parent_class->create_and_realize = create_and_realize; parent_class->get_generic_capabilities = get_generic_capabilities; @@ -924,8 +941,4 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_TEAM_SKELETON, - NULL); } diff --git a/src/devices/wifi/meson.build b/src/devices/wifi/meson.build index 08bc517789..27eaeea63f 100644 --- a/src/devices/wifi/meson.build +++ b/src/devices/wifi/meson.build @@ -5,6 +5,7 @@ common_sources = files( sources = common_sources + files( 'nm-wifi-factory.c', + 'nm-wifi-common.c', 'nm-device-wifi.c', 'nm-device-olpc-mesh.c' ) @@ -17,7 +18,6 @@ if enable_iwd endif deps = [ - libnmdbus_dep, nm_dep ] diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 218ca80463..f3a3a87921 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -36,12 +36,11 @@ #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-wifi-utils.h" +#include "nm-wifi-common.h" #include "nm-core-internal.h" #include "nm-config.h" #include "nm-iwd-manager.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Wireless.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceIwd); @@ -57,8 +56,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceIwd, ); enum { - ACCESS_POINT_ADDED, - ACCESS_POINT_REMOVED, SCANNING_PROHIBITED, LAST_SIGNAL @@ -122,30 +119,42 @@ _ap_dump (NMDeviceIwd *self, nm_wifi_ap_to_string (ap, buf, sizeof (buf), now_s)); } +static void +_emit_access_point_added_removed (NMDeviceIwd *self, + NMWifiAP *ap, + gboolean is_added /* or else is removed */) +{ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &nm_interface_info_device_wireless, + is_added + ? &nm_signal_info_wireless_access_point_added + : &nm_signal_info_wireless_access_point_removed, + "(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); +} + /* Callers ensure we're not removing current_ap */ static void ap_add_remove (NMDeviceIwd *self, - guint signum, + gboolean is_adding, /* or else is removing */ NMWifiAP *ap, gboolean recheck_available_connections) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - nm_assert (NM_IN_SET (signum, ACCESS_POINT_ADDED, ACCESS_POINT_REMOVED)); - - if (signum == ACCESS_POINT_ADDED) { + if (is_adding) { g_hash_table_insert (priv->aps, - (gpointer) nm_exported_object_export ((NMExportedObject *) ap), + (gpointer) nm_dbus_object_export (NM_DBUS_OBJECT (ap)), g_object_ref (ap)); _ap_dump (self, LOGL_DEBUG, ap, "added", 0); } else _ap_dump (self, LOGL_DEBUG, ap, "removed", 0); - g_signal_emit (self, signals[signum], 0, ap); + _emit_access_point_added_removed (self, ap, is_adding); - if (signum == ACCESS_POINT_REMOVED) { - g_hash_table_remove (priv->aps, nm_exported_object_get_path ((NMExportedObject *) ap)); - nm_exported_object_unexport ((NMExportedObject *) ap); + if (!is_adding) { + g_hash_table_remove (priv->aps, nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); + nm_dbus_object_unexport (NM_DBUS_OBJECT (ap)); g_object_unref (ap); } @@ -177,7 +186,7 @@ set_current_ap (NMDeviceIwd *self, NMWifiAP *new_ap, gboolean recheck_available_ if (old_ap) { if (nm_wifi_ap_get_fake (old_ap)) - ap_add_remove (self, ACCESS_POINT_REMOVED, old_ap, recheck_available_connections); + ap_add_remove (self, FALSE, old_ap, recheck_available_connections); g_object_unref (old_ap); } @@ -217,9 +226,9 @@ update_ap_func (gpointer key, gpointer value, gpointer user_data) _ap_dump (self, LOGL_DEBUG, ap, "removed", 0); - g_signal_emit (self, signals[ACCESS_POINT_REMOVED], 0, ap); + _emit_access_point_added_removed (self, ap, FALSE); - nm_exported_object_unexport ((NMExportedObject *) ap); + nm_dbus_object_unexport (NM_DBUS_OBJECT (ap)); g_object_unref (ap); return TRUE; @@ -351,7 +360,7 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) g_hash_table_iter_init (&ap_iter, priv->new_aps); while (g_hash_table_iter_next (&ap_iter, NULL, (gpointer) &ap)) { - ap_add_remove (self, ACCESS_POINT_ADDED, ap, FALSE); + ap_add_remove (self, TRUE, ap, FALSE); changed = TRUE; } @@ -853,37 +862,17 @@ can_auto_connect (NMDevice *device, ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE); if (ap) { /* All good; connection is usable */ - NM_SET_OUT (specific_object, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap)))); + NM_SET_OUT (specific_object, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)))); return TRUE; } return FALSE; } -static void -impl_device_iwd_get_access_points (NMDeviceIwd *self, - GDBusMethodInvocation *context) -{ - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - gs_free const char **list = NULL; - GVariant *v; - - list = nm_wifi_aps_get_sorted_paths (priv->aps, FALSE); - v = g_variant_new_objv (list, -1); - g_dbus_method_invocation_return_value (context, g_variant_new_tuple (&v, 1)); -} - -static void -impl_device_iwd_get_all_access_points (NMDeviceIwd *self, - GDBusMethodInvocation *context) +GHashTable * +_nm_device_iwd_get_aps (NMDeviceIwd *self) { - NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - gs_free const char **list = NULL; - GVariant *v; - - list = nm_wifi_aps_get_sorted_paths (priv->aps, TRUE); - v = g_variant_new_objv (list, -1); - g_dbus_method_invocation_return_value (context, g_variant_new_tuple (&v, 1)); + return NM_DEVICE_IWD_GET_PRIVATE (self)->aps; } static gboolean @@ -982,10 +971,10 @@ dbus_request_scan_cb (NMDevice *device, g_dbus_method_invocation_return_value (context, NULL); } -static void -impl_device_iwd_request_scan (NMDeviceIwd *self, - GDBusMethodInvocation *context, - GVariant *options) +void +_nm_device_iwd_request_scan (NMDeviceIwd *self, + GVariant *options, + GDBusMethodInvocation *invocation) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); @@ -994,17 +983,16 @@ impl_device_iwd_request_scan (NMDeviceIwd *self, || !priv->dbus_obj || nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED || nm_device_is_activating (device)) { - g_dbus_method_invocation_return_error_literal (context, + g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while unavailable"); return; } - /* Ask the manager to authenticate this request for us */ g_signal_emit_by_name (device, NM_DEVICE_AUTH_REQUEST, - context, + invocation, NULL, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE, @@ -1270,7 +1258,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) */ nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); } set_current_ap (self, ap, FALSE); @@ -1575,7 +1563,7 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, list); break; case PROP_ACTIVE_ACCESS_POINT: - nm_utils_g_value_set_object_path (value, priv->current_ap); + nm_dbus_utils_g_value_set_object_path (value, priv->current_ap); break; case PROP_SCANNING: g_value_set_boolean (value, priv->scanning); @@ -1898,6 +1886,7 @@ static void nm_device_iwd_class_init (NMDeviceIwdClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRELESS_SETTING_NAME, NM_LINK_TYPE_WIFI) @@ -1907,6 +1896,8 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass) object_class->dispose = dispose; object_class->finalize = finalize; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless); + parent_class->can_auto_connect = can_auto_connect; parent_class->is_available = is_available; parent_class->get_autoconnect_allowed = get_autoconnect_allowed; @@ -1970,24 +1961,6 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - signals[ACCESS_POINT_ADDED] = - g_signal_new (NM_DEVICE_IWD_ACCESS_POINT_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - NM_TYPE_WIFI_AP); - - signals[ACCESS_POINT_REMOVED] = - g_signal_new (NM_DEVICE_IWD_ACCESS_POINT_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - NM_TYPE_WIFI_AP); - signals[SCANNING_PROHIBITED] = g_signal_new (NM_DEVICE_IWD_SCANNING_PROHIBITED, G_OBJECT_CLASS_TYPE (object_class), @@ -1995,11 +1968,4 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass) G_STRUCT_OFFSET (NMDeviceIwdClass, scanning_prohibited), NULL, NULL, NULL, G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_WIFI_SKELETON, - "GetAccessPoints", impl_device_iwd_get_access_points, - "GetAllAccessPoints", impl_device_iwd_get_all_access_points, - "RequestScan", impl_device_iwd_request_scan, - NULL); } diff --git a/src/devices/wifi/nm-device-iwd.h b/src/devices/wifi/nm-device-iwd.h index 6619488cf7..6d4ff06bfc 100644 --- a/src/devices/wifi/nm-device-iwd.h +++ b/src/devices/wifi/nm-device-iwd.h @@ -39,11 +39,6 @@ #define NM_DEVICE_IWD_CAPABILITIES NM_DEVICE_WIFI_CAPABILITIES #define NM_DEVICE_IWD_SCANNING NM_DEVICE_WIFI_SCANNING -/* signals */ -#define NM_DEVICE_IWD_ACCESS_POINT_ADDED NM_DEVICE_WIFI_ACCESS_POINT_ADDED -#define NM_DEVICE_IWD_ACCESS_POINT_REMOVED NM_DEVICE_WIFI_ACCESS_POINT_REMOVED - -/* internal signals */ #define NM_DEVICE_IWD_SCANNING_PROHIBITED NM_DEVICE_WIFI_SCANNING_PROHIBITED typedef struct _NMDeviceIwd NMDeviceIwd; @@ -58,4 +53,10 @@ void nm_device_iwd_set_dbus_object (NMDeviceIwd *device, GDBusObject *object); gboolean nm_device_iwd_agent_psk_query (NMDeviceIwd *device, GDBusMethodInvocation *invocation); +GHashTable *_nm_device_iwd_get_aps (NMDeviceIwd *self); + +void _nm_device_iwd_request_scan (NMDeviceIwd *self, + GVariant *options, + GDBusMethodInvocation *invocation); + #endif /* __NETWORKMANAGER_DEVICE_IWD_H__ */ diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 3a4a027afa..a330de038d 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -48,11 +48,6 @@ #include "nm-manager.h" #include "platform/nm-platform.h" -/* This is a bug; but we can't really change API now... */ -#include "nm-vpn-dbus-interface.h" - -#include "introspection/org.freedesktop.NetworkManager.Device.OlpcMesh.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceOlpcMesh); @@ -440,7 +435,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_COMPANION: - nm_utils_g_value_set_object_path (value, priv->companion); + nm_dbus_utils_g_value_set_object_path (value, priv->companion); break; case PROP_ACTIVE_CHANNEL: g_value_set_uint (value, nm_platform_mesh_get_channel (nm_device_get_platform (device), nm_device_get_ifindex (device))); @@ -500,10 +495,26 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_olpc_mesh = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Companion", "o", NM_DEVICE_OLPC_MESH_COMPANION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveChannel", "u", NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_OLPC_MESH_SETTING_NAME, NM_LINK_TYPE_OLPC_MESH) @@ -512,6 +523,8 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) object_class->get_property = get_property; object_class->dispose = dispose; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_olpc_mesh); + parent_class->check_connection_compatible = check_connection_compatible; parent_class->get_autoconnect_allowed = get_autoconnect_allowed; parent_class->complete_connection = complete_connection; @@ -534,9 +547,5 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_OLPC_MESH_SKELETON, - NULL); } diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index a7283b63ac..7aae9ea6ca 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -28,6 +28,7 @@ #include <unistd.h> #include <errno.h> +#include "nm-wifi-ap.h" #include "nm-common-macros.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" @@ -49,11 +50,10 @@ #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-wifi-utils.h" +#include "nm-wifi-common.h" #include "nm-core-internal.h" #include "nm-config.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Wireless.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceWifi); @@ -76,8 +76,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWifi, ); enum { - ACCESS_POINT_ADDED, - ACCESS_POINT_REMOVED, SCANNING_PROHIBITED, LAST_SIGNAL @@ -188,7 +186,7 @@ static void request_wireless_scan (NMDeviceWifi *self, const GPtrArray *ssids); static void ap_add_remove (NMDeviceWifi *self, - guint signum, + gboolean is_adding, NMWifiAP *ap, gboolean recheck_available_connections); @@ -416,7 +414,7 @@ set_current_ap (NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available /* Remove any AP from the internal list if it was created by NM or isn't known to the supplicant */ if (mode == NM_802_11_MODE_ADHOC || mode == NM_802_11_MODE_AP || nm_wifi_ap_get_fake (old_ap)) - ap_add_remove (self, ACCESS_POINT_REMOVED, old_ap, recheck_available_connections); + ap_add_remove (self, FALSE, old_ap, recheck_available_connections); g_object_unref (old_ap); } @@ -483,28 +481,31 @@ periodic_update_cb (gpointer user_data) static void ap_add_remove (NMDeviceWifi *self, - guint signum, + gboolean is_adding, /* or else removing */ NMWifiAP *ap, gboolean recheck_available_connections) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - nm_assert (NM_IN_SET (signum, ACCESS_POINT_ADDED, ACCESS_POINT_REMOVED)); - - if (signum == ACCESS_POINT_ADDED) { + if (is_adding) { g_hash_table_insert (priv->aps, - (gpointer) nm_exported_object_export ((NMExportedObject *) ap), + (gpointer) nm_dbus_object_export (NM_DBUS_OBJECT (ap)), g_object_ref (ap)); _ap_dump (self, LOGL_DEBUG, ap, "added", 0); } else _ap_dump (self, LOGL_DEBUG, ap, "removed", 0); - g_signal_emit (self, signals[signum], 0, ap); + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &nm_interface_info_device_wireless, + is_adding + ? &nm_signal_info_wireless_access_point_added + : &nm_signal_info_wireless_access_point_removed, + "(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); - if (signum == ACCESS_POINT_REMOVED) { - g_hash_table_remove (priv->aps, nm_exported_object_get_path ((NMExportedObject *) ap)); - nm_exported_object_unexport ((NMExportedObject *) ap); - g_object_unref (ap); + if (!is_adding) { + g_hash_table_remove (priv->aps, nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); + nm_dbus_object_clear_and_unexport (&ap); } _notify (self, PROP_ACCESS_POINTS); @@ -529,7 +530,7 @@ remove_all_aps (NMDeviceWifi *self) again: g_hash_table_iter_init (&iter, priv->aps); if (g_hash_table_iter_next (&iter, NULL, (gpointer) &ap)) { - ap_add_remove (self, ACCESS_POINT_REMOVED, ap, FALSE); + ap_add_remove (self, FALSE, ap, FALSE); goto again; } @@ -990,37 +991,17 @@ can_auto_connect (NMDevice *device, ap = nm_wifi_aps_find_first_compatible (priv->aps, connection, FALSE); if (ap) { /* All good; connection is usable */ - NM_SET_OUT (specific_object, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap)))); + NM_SET_OUT (specific_object, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)))); return TRUE; } return FALSE; } -static void -impl_device_wifi_get_access_points (NMDeviceWifi *self, - GDBusMethodInvocation *context) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gs_free const char **list = NULL; - GVariant *v; - - list = nm_wifi_aps_get_sorted_paths (priv->aps, FALSE); - v = g_variant_new_objv (list, -1); - g_dbus_method_invocation_return_value (context, g_variant_new_tuple (&v, 1)); -} - -static void -impl_device_wifi_get_all_access_points (NMDeviceWifi *self, - GDBusMethodInvocation *context) +GHashTable * +_nm_device_wifi_get_aps (NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - gs_free const char **list = NULL; - GVariant *v; - - list = nm_wifi_aps_get_sorted_paths (priv->aps, TRUE); - v = g_variant_new_objv (list, -1); - g_dbus_method_invocation_return_value (context, g_variant_new_tuple (&v, 1)); + return NM_DEVICE_WIFI_GET_PRIVATE (self)->aps; } static void @@ -1168,10 +1149,10 @@ dbus_request_scan_cb (NMDevice *device, g_dbus_method_invocation_return_value (context, NULL); } -static void -impl_device_wifi_request_scan (NMDeviceWifi *self, - GDBusMethodInvocation *context, - GVariant *options) +void +_nm_device_wifi_request_scan (NMDeviceWifi *self, + GVariant *options, + GDBusMethodInvocation *invocation) { NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); @@ -1181,7 +1162,7 @@ impl_device_wifi_request_scan (NMDeviceWifi *self, || !priv->sup_iface || nm_device_get_state (device) < NM_DEVICE_STATE_DISCONNECTED || nm_device_is_activating (device)) { - g_dbus_method_invocation_return_error_literal (context, + g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while unavailable or activating"); @@ -1189,7 +1170,7 @@ impl_device_wifi_request_scan (NMDeviceWifi *self, } if (nm_supplicant_interface_get_scanning (priv->sup_iface)) { - g_dbus_method_invocation_return_error_literal (context, + g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed while already scanning"); @@ -1198,17 +1179,16 @@ impl_device_wifi_request_scan (NMDeviceWifi *self, last_scan = nm_supplicant_interface_get_last_scan_time (priv->sup_iface); if (last_scan && (nm_utils_get_monotonic_timestamp_s () - last_scan) < 10) { - g_dbus_method_invocation_return_error_literal (context, + g_dbus_method_invocation_return_error_literal (invocation, NM_DEVICE_ERROR, NM_DEVICE_ERROR_NOT_ALLOWED, "Scanning not allowed immediately following previous scan"); return; } - /* Ask the manager to authenticate this request for us */ g_signal_emit_by_name (device, NM_DEVICE_AUTH_REQUEST, - context, + invocation, NULL, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE, @@ -1605,7 +1585,7 @@ supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface, } } - ap_add_remove (self, ACCESS_POINT_ADDED, ap, TRUE); + ap_add_remove (self, TRUE, ap, TRUE); } /* Update the current AP if the supplicant notified a current BSS change @@ -1642,7 +1622,7 @@ supplicant_iface_bss_removed_cb (NMSupplicantInterface *iface, if (nm_wifi_ap_set_fake (ap, TRUE)) _ap_dump (self, LOGL_DEBUG, ap, "updated", 0); } else { - ap_add_remove (self, ACCESS_POINT_REMOVED, ap, TRUE); + ap_add_remove (self, FALSE, ap, TRUE); schedule_ap_list_dump (self); } } @@ -2543,7 +2523,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) if (ap) { nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); goto done; } @@ -2560,11 +2540,11 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) nm_wifi_ap_set_address (ap, nm_device_get_hw_address (device)); g_object_freeze_notify (G_OBJECT (self)); - ap_add_remove (self, ACCESS_POINT_ADDED, ap, TRUE); + ap_add_remove (self, TRUE, ap, TRUE); g_object_thaw_notify (G_OBJECT (self)); set_current_ap (self, ap, FALSE); nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); return NM_ACT_STAGE_RETURN_SUCCESS; done: @@ -2976,7 +2956,7 @@ activation_success_handler (NMDevice *device) } nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (priv->current_ap))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (priv->current_ap))); } periodic_update (self); @@ -3174,7 +3154,7 @@ get_property (GObject *object, guint prop_id, g_value_take_boxed (value, list); break; case PROP_ACTIVE_ACCESS_POINT: - nm_utils_g_value_set_object_path (value, priv->current_ap); + nm_dbus_utils_g_value_set_object_path (value, priv->current_ap); break; case PROP_SCANNING: g_value_set_boolean (value, priv->is_scanning); @@ -3280,6 +3260,7 @@ static void nm_device_wifi_class_init (NMDeviceWifiClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRELESS_SETTING_NAME, NM_LINK_TYPE_WIFI) @@ -3290,6 +3271,8 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) object_class->dispose = dispose; object_class->finalize = finalize; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless); + parent_class->can_auto_connect = can_auto_connect; parent_class->get_autoconnect_allowed = get_autoconnect_allowed; parent_class->is_available = is_available; @@ -3356,24 +3339,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - signals[ACCESS_POINT_ADDED] = - g_signal_new (NM_DEVICE_WIFI_ACCESS_POINT_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - NM_TYPE_WIFI_AP); - - signals[ACCESS_POINT_REMOVED] = - g_signal_new (NM_DEVICE_WIFI_ACCESS_POINT_REMOVED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, NULL, - G_TYPE_NONE, 1, - NM_TYPE_WIFI_AP); - signals[SCANNING_PROHIBITED] = g_signal_new (NM_DEVICE_WIFI_SCANNING_PROHIBITED, G_OBJECT_CLASS_TYPE (object_class), @@ -3381,13 +3346,4 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) G_STRUCT_OFFSET (NMDeviceWifiClass, scanning_prohibited), NULL, NULL, NULL, G_TYPE_BOOLEAN, 1, G_TYPE_BOOLEAN); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DEVICE_WIFI_SKELETON, - "GetAccessPoints", impl_device_wifi_get_access_points, - "GetAllAccessPoints", impl_device_wifi_get_all_access_points, - "RequestScan", impl_device_wifi_request_scan, - NULL); } - - diff --git a/src/devices/wifi/nm-device-wifi.h b/src/devices/wifi/nm-device-wifi.h index 09707d4f4b..632bbac1f4 100644 --- a/src/devices/wifi/nm-device-wifi.h +++ b/src/devices/wifi/nm-device-wifi.h @@ -23,7 +23,6 @@ #define __NETWORKMANAGER_DEVICE_WIFI_H__ #include "devices/nm-device.h" -#include "nm-wifi-ap.h" #define NM_TYPE_DEVICE_WIFI (nm_device_wifi_get_type ()) #define NM_DEVICE_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIFI, NMDeviceWifi)) @@ -39,11 +38,6 @@ #define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities" #define NM_DEVICE_WIFI_SCANNING "scanning" -/* signals */ -#define NM_DEVICE_WIFI_ACCESS_POINT_ADDED "access-point-added" -#define NM_DEVICE_WIFI_ACCESS_POINT_REMOVED "access-point-removed" - -/* internal signals */ #define NM_DEVICE_WIFI_SCANNING_PROHIBITED "scanning-prohibited" typedef struct _NMDeviceWifi NMDeviceWifi; @@ -53,4 +47,10 @@ GType nm_device_wifi_get_type (void); NMDevice * nm_device_wifi_new (const char *iface, NMDeviceWifiCapabilities capabilities); +GHashTable *_nm_device_wifi_get_aps (NMDeviceWifi *self); + +void _nm_device_wifi_request_scan (NMDeviceWifi *self, + GVariant *options, + GDBusMethodInvocation *invocation); + #endif /* __NETWORKMANAGER_DEVICE_WIFI_H__ */ diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index c3c64e767a..31af1be803 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -21,20 +21,19 @@ #include "nm-default.h" +#include "nm-wifi-ap.h" + #include <string.h> #include <stdlib.h> -#include "nm-wifi-ap.h" +#include "nm-setting-wireless.h" + #include "nm-wifi-utils.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-core-internal.h" #include "platform/nm-platform.h" -#include "nm-setting-wireless.h" - -#include "introspection/org.freedesktop.NetworkManager.AccessPoint.h" - #define PROTO_WPA "wpa" #define PROTO_RSN "rsn" @@ -75,15 +74,15 @@ typedef struct { } NMWifiAPPrivate; struct _NMWifiAP { - NMExportedObject parent; + NMDBusObject parent; NMWifiAPPrivate _priv; }; struct _NMWifiAPClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMWifiAP, nm_wifi_ap, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMWifiAP, nm_wifi_ap, NM_TYPE_DBUS_OBJECT) #define NM_WIFI_AP_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMWifiAP, NM_IS_WIFI_AP) @@ -105,7 +104,7 @@ nm_wifi_ap_get_id (NMWifiAP *ap) g_return_val_if_fail (NM_IS_WIFI_AP (ap), 0); - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)); g_return_val_if_fail (path, 0); nm_assert (g_str_has_prefix (path, NM_DBUS_PATH_ACCESS_POINT"/")); @@ -116,13 +115,26 @@ nm_wifi_ap_get_id (NMWifiAP *ap) return i; } -const GByteArray * nm_wifi_ap_get_ssid (const NMWifiAP *ap) +const GByteArray * +nm_wifi_ap_get_ssid (const NMWifiAP *ap) { g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL); return NM_WIFI_AP_GET_PRIVATE (ap)->ssid; } +static GVariant * +nm_wifi_ap_get_ssid_as_variant (const NMWifiAP *self) +{ + const NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self); + + if (priv->ssid) { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + priv->ssid->data, priv->ssid->len, 1); + } else + return g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0); +} + gboolean nm_wifi_ap_set_ssid (NMWifiAP *ap, const guint8 *ssid, gsize len) { @@ -330,7 +342,7 @@ guint32 nm_wifi_ap_get_max_bitrate (NMWifiAP *ap) { g_return_val_if_fail (NM_IS_WIFI_AP (ap), 0); - g_return_val_if_fail (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (ap)), 0); + g_return_val_if_fail (nm_dbus_object_is_exported (NM_DBUS_OBJECT (ap)), 0); return NM_WIFI_AP_GET_PRIVATE (ap)->max_bitrate; } @@ -978,7 +990,7 @@ nm_wifi_ap_to_string (const NMWifiAP *self, if (priv->supplicant_path) supplicant_id = strrchr (priv->supplicant_path, '/') ?: supplicant_id; - export_path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (self)); + export_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); if (export_path) export_path = strrchr (export_path, '/') ?: export_path; else @@ -1120,8 +1132,8 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE ((NMWifiAP *) object); - GVariant *ssid; + NMWifiAP *self = NM_WIFI_AP (object); + NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self); switch (prop_id) { case PROP_FLAGS: @@ -1134,12 +1146,7 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->rsn_flags); break; case PROP_SSID: - if (priv->ssid) { - ssid = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - priv->ssid->data, priv->ssid->len, 1); - } else - ssid = g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0); - g_value_take_variant (value, ssid); + g_value_take_variant (value, nm_wifi_ap_get_ssid_as_variant (self)); break; case PROP_FREQUENCY: g_value_set_uint (value, priv->freq); @@ -1343,6 +1350,28 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_wifi_ap_parent_class)->finalize (object); } +static const NMDBusInterfaceInfoExtended interface_info_access_point = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_ACCESS_POINT, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Flags", "u", NM_WIFI_AP_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WpaFlags", "u", NM_WIFI_AP_WPA_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RsnFlags", "u", NM_WIFI_AP_RSN_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ssid", "ay", NM_WIFI_AP_SSID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Frequency", "u", NM_WIFI_AP_FREQUENCY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_WIFI_AP_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "u", NM_WIFI_AP_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("MaxBitrate", "u", NM_WIFI_AP_MAX_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Strength", "y", NM_WIFI_AP_STRENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("LastSeen", "i", NM_WIFI_AP_LAST_SEEN), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_wifi_ap_class_init (NMWifiAPClass *ap_class) { @@ -1360,9 +1389,10 @@ nm_wifi_ap_class_init (NMWifiAPClass *ap_class) | NM_802_11_AP_SEC_KEY_MGMT_802_1X ) GObjectClass *object_class = G_OBJECT_CLASS (ap_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (ap_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (ap_class); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_ACCESS_POINT); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_ACCESS_POINT); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_access_point); object_class->get_property = get_property; object_class->finalize = finalize; @@ -1425,10 +1455,6 @@ nm_wifi_ap_class_init (NMWifiAPClass *ap_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ap_class), - NMDBUS_TYPE_ACCESS_POINT_SKELETON, - NULL); } /*****************************************************************************/ @@ -1487,7 +1513,7 @@ nm_wifi_aps_get_sorted_paths (GHashTable *aps, gboolean include_without_ssid) const char *path; /* update @list inplace to hold instead the export-path. */ - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (ap)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ap)); nm_assert (path); list[j++] = (gpointer) path; } diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index 1748223121..314f2265f1 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -22,7 +22,7 @@ #ifndef __NM_WIFI_AP_H__ #define __NM_WIFI_AP_H__ -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-dbus-interface.h" #include "nm-connection.h" diff --git a/src/devices/wifi/nm-wifi-common.c b/src/devices/wifi/nm-wifi-common.c new file mode 100644 index 0000000000..005aac9d60 --- /dev/null +++ b/src/devices/wifi/nm-wifi-common.c @@ -0,0 +1,188 @@ +/*-*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2018 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-wifi-common.h" + +#include "devices/nm-device.h" +#include "nm-wifi-ap.h" +#include "nm-device-wifi.h" + +#if WITH_IWD +#include "nm-device-iwd.h" +#endif + +/*****************************************************************************/ + +static GHashTable * +_dispatch_get_aps (NMDevice *device) +{ +#if WITH_IWD + if (NM_IS_DEVICE_IWD (device)) + return _nm_device_iwd_get_aps (NM_DEVICE_IWD (device)); +#endif + return _nm_device_wifi_get_aps (NM_DEVICE_WIFI (device)); +} + +static void +_dispatch_request_scan (NMDevice *device, + GVariant *options, + GDBusMethodInvocation *invocation) +{ +#if WITH_IWD + if (NM_IS_DEVICE_IWD (device)) { + _nm_device_iwd_request_scan (NM_DEVICE_IWD (device), + options, + invocation); + } +#endif + _nm_device_wifi_request_scan (NM_DEVICE_WIFI (device), + options, + invocation); +} + +static void +impl_device_wifi_get_access_points (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + gs_free const char **list = NULL; + GVariant *v; + GHashTable *aps; + + /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ + + aps = _dispatch_get_aps (NM_DEVICE (obj)); + list = nm_wifi_aps_get_sorted_paths (aps, FALSE); + v = g_variant_new_objv (list, -1); + g_dbus_method_invocation_return_value (invocation, + g_variant_new_tuple (&v, 1)); +} + +static void +impl_device_wifi_get_all_access_points (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + gs_free const char **list = NULL; + GVariant *v; + GHashTable *aps; + + /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ + + aps = _dispatch_get_aps (NM_DEVICE (obj)); + list = nm_wifi_aps_get_sorted_paths (aps, TRUE); + v = g_variant_new_objv (list, -1); + g_dbus_method_invocation_return_value (invocation, + g_variant_new_tuple (&v, 1)); +} + +static void +impl_device_wifi_request_scan (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + gs_unref_variant GVariant *options = NULL; + + /* NOTE: this handler is called both for NMDevicwWifi and NMDeviceIwd. */ + + g_variant_get (parameters, "(@a{sv})", &options); + + _dispatch_request_scan (NM_DEVICE (obj), + options, + invocation); +} + +const GDBusSignalInfo nm_signal_info_wireless_access_point_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "AccessPointAdded", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("access_point", "o"), + ), +); + +const GDBusSignalInfo nm_signal_info_wireless_access_point_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "AccessPointRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("access_point", "o"), + ), +); + +const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_WIRELESS, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetAccessPoints", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("access_points", "ao"), + ), + ), + .handle = impl_device_wifi_get_access_points, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetAllAccessPoints", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("access_points", "ao"), + ), + ), + .handle = impl_device_wifi_get_all_access_points, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "RequestScan", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("options", "a{sv}"), + ), + ), + .handle = impl_device_wifi_request_scan, + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &nm_signal_info_wireless_access_point_added, + &nm_signal_info_wireless_access_point_removed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PermHwAddress", "s", NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "u", NM_DEVICE_WIFI_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("BitRate", "u", NM_DEVICE_WIFI_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AccessPoints", "ao", NM_DEVICE_WIFI_ACCESS_POINTS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveAccessPoint", "o", NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WirelessCapabilities", "u", NM_DEVICE_WIFI_CAPABILITIES), + ), + ), + .legacy_property_changed = TRUE, +}; diff --git a/src/devices/wifi/nm-wifi-common.h b/src/devices/wifi/nm-wifi-common.h new file mode 100644 index 0000000000..4df4a5903b --- /dev/null +++ b/src/devices/wifi/nm-wifi-common.h @@ -0,0 +1,32 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2018 Red Hat, Inc. + */ + +#ifndef __NM_WIFI_COMMON_H__ +#define __NM_WIFI_COMMON_H__ + +#include "nm-dbus-utils.h" + +/*****************************************************************************/ + +extern const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless; +extern const GDBusSignalInfo nm_signal_info_wireless_access_point_added; +extern const GDBusSignalInfo nm_signal_info_wireless_access_point_removed; + +#endif /* __NM_WIFI_COMMON_H__ */ diff --git a/src/devices/wwan/meson.build b/src/devices/wwan/meson.build index 53a47b8617..032b35853f 100644 --- a/src/devices/wwan/meson.build +++ b/src/devices/wwan/meson.build @@ -46,8 +46,6 @@ sources = files( 'nm-wwan-factory.c' ) -deps += libnmdbus_dep - libnm_device_plugin_wwan = shared_module( 'nm-device-plugin-wwan', sources: sources, diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 7aa2fd9315..0820b82db0 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -32,8 +32,6 @@ #include "NetworkManagerUtils.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Modem.h" - #include "devices/nm-device-logging.h" _LOG_DECLARE_SELF(NMDeviceModem); @@ -741,16 +739,33 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_device_modem_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_device_modem = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DEVICE_MODEM, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ModemCapabilities", "u", NM_DEVICE_MODEM_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CurrentCapabilities", "u", NM_DEVICE_MODEM_CURRENT_CAPABILITIES), + ), + ), + .legacy_property_changed = TRUE, +}; + static void -nm_device_modem_class_init (NMDeviceModemClass *mclass) +nm_device_modem_class_init (NMDeviceModemClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (mclass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (mclass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_modem); + device_class->get_generic_capabilities = get_generic_capabilities; device_class->get_type_description = get_type_description; device_class->check_connection_compatible = check_connection_compatible; @@ -793,8 +808,4 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (mclass), - NMDBUS_TYPE_DEVICE_MODEM_SKELETON, - NULL); } diff --git a/src/dhcp/nm-dhcp-listener.c b/src/dhcp/nm-dhcp-listener.c index 11651110b9..d7d38e5463 100644 --- a/src/dhcp/nm-dhcp-listener.c +++ b/src/dhcp/nm-dhcp-listener.c @@ -60,7 +60,7 @@ const NMDhcpClientFactory *const _nm_dhcp_manager_factories[4] = { /*****************************************************************************/ typedef struct { - NMBusManager * dbus_mgr; + NMDBusManager * dbus_mgr; gulong new_conn_id; gulong dis_conn_id; GHashTable * connections; @@ -192,15 +192,17 @@ _method_call (GDBusConnection *connection, { NMDhcpListener *self = NM_DHCP_LISTENER (user_data); - if (!nm_streq0 (interface_name, NM_DHCP_HELPER_SERVER_INTERFACE_NAME)) - g_return_if_reached (); - if (!nm_streq0 (method_name, NM_DHCP_HELPER_SERVER_METHOD_NOTIFY)) - g_return_if_reached (); - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(a{sv})"))) - g_return_if_reached (); + if ( !nm_streq (interface_name, NM_DHCP_HELPER_SERVER_INTERFACE_NAME) + || !nm_streq (method_name, NM_DHCP_HELPER_SERVER_METHOD_NOTIFY)) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); + return; + } _method_call_handle (self, parameters); - g_dbus_method_invocation_return_value (invocation, NULL); } @@ -235,7 +237,7 @@ _dbus_connection_register_object (NMDhcpListener *self, } static void -new_connection_cb (NMBusManager *mgr, +new_connection_cb (NMDBusManager *mgr, GDBusConnection *connection, GDBusObjectManager *manager, NMDhcpListener *self) @@ -258,7 +260,7 @@ new_connection_cb (NMBusManager *mgr, } static void -dis_connection_cb (NMBusManager *mgr, +dis_connection_cb (NMDBusManager *mgr, GDBusConnection *connection, NMDhcpListener *self) { @@ -282,16 +284,16 @@ nm_dhcp_listener_init (NMDhcpListener *self) /* Maps GDBusConnection :: signal-id */ priv->connections = g_hash_table_new (nm_direct_hash, NULL); - priv->dbus_mgr = nm_bus_manager_get (); + priv->dbus_mgr = nm_dbus_manager_get (); /* Register the socket our DHCP clients will return lease info on */ - nm_bus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); + nm_dbus_manager_private_server_register (priv->dbus_mgr, PRIV_SOCK_PATH, PRIV_SOCK_TAG); priv->new_conn_id = g_signal_connect (priv->dbus_mgr, - NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "::" PRIV_SOCK_TAG, G_CALLBACK (new_connection_cb), self); priv->dis_conn_id = g_signal_connect (priv->dbus_mgr, - NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "::" PRIV_SOCK_TAG, G_CALLBACK (dis_connection_cb), self); } diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index e366dba383..d075307867 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -408,7 +408,7 @@ start_dnsmasq (NMDnsDnsmasq *self) const char *argv[15]; GPid pid = 0; guint idx = 0; - NMBusManager *dbus_mgr; + NMDBusManager *dbus_mgr; GDBusConnection *connection; if (priv->running) { @@ -460,10 +460,10 @@ start_dnsmasq (NMDnsDnsmasq *self) return; } - dbus_mgr = nm_bus_manager_get (); + dbus_mgr = nm_dbus_manager_get (); g_return_if_fail (dbus_mgr); - connection = nm_bus_manager_get_connection (dbus_mgr); + connection = nm_dbus_manager_get_connection (dbus_mgr); g_return_if_fail (connection); priv->dnsmasq_cancellable = g_cancellable_new (); diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 2119160212..037e4835fb 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -46,6 +46,7 @@ #include "nm-ip6-config.h" #include "NetworkManagerUtils.h" #include "nm-config.h" +#include "nm-dbus-object.h" #include "devices/nm-device.h" #include "nm-manager.h" @@ -54,8 +55,6 @@ #include "nm-dns-systemd-resolved.h" #include "nm-dns-unbound.h" -#include "introspection/org.freedesktop.NetworkManager.DnsManager.h" - #define HASH_LEN 20 #ifndef RESOLVCONF_PATH @@ -135,15 +134,15 @@ typedef struct { } NMDnsManagerPrivate; struct _NMDnsManager { - NMExportedObject parent; + NMDBusObject parent; NMDnsManagerPrivate _priv; }; struct _NMDnsManagerClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMDnsManager, nm_dns_manager, NM_TYPE_DBUS_OBJECT) #define NM_DNS_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDnsManager, NM_IS_DNS_MANAGER) @@ -2107,18 +2106,30 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_dns_manager_parent_class)->finalize (object); } +static const NMDBusInterfaceInfoExtended interface_info_dns_manager = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DNS_MANAGER, + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Mode", "s", NM_DNS_MANAGER_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RcManager", "s", NM_DNS_MANAGER_RC_MANAGER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Configuration", "aa{sv}", NM_DNS_MANAGER_CONFIGURATION), + ), + ), +}; + static void nm_dns_manager_class_init (NMDnsManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; - exported_object_class->export_path = NM_DBUS_PATH "/DnsManager"; - exported_object_class->export_on_construction = TRUE; + dbus_object_class->export_path = NM_DBUS_PATH "/DnsManager"; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_dns_manager); + dbus_object_class->export_on_construction = TRUE; obj_properties[PROP_MODE] = g_param_spec_string (NM_DNS_MANAGER_MODE, "", "", @@ -2148,8 +2159,4 @@ nm_dns_manager_class_init (NMDnsManagerClass *klass) 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass), - NMDBUS_TYPE_DNS_MANAGER_SKELETON, - NULL); } diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index fe2ef59467..2e790d0b14 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -396,15 +396,15 @@ static void nm_dns_systemd_resolved_init (NMDnsSystemdResolved *self) { NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE (self); - NMBusManager *dbus_mgr; + NMDBusManager *dbus_mgr; GDBusConnection *connection; c_list_init (&priv->request_queue_lst_head); - dbus_mgr = nm_bus_manager_get (); + dbus_mgr = nm_dbus_manager_get (); g_return_if_fail (dbus_mgr); - connection = nm_bus_manager_get_connection (dbus_mgr); + connection = nm_dbus_manager_get_connection (dbus_mgr); g_return_if_fail (connection); priv->init_cancellable = g_cancellable_new (); diff --git a/src/main.c b/src/main.c index e829fea0fc..3c6c6d3aac 100644 --- a/src/main.c +++ b/src/main.c @@ -48,7 +48,7 @@ #include "settings/nm-settings.h" #include "nm-auth-manager.h" #include "nm-core-internal.h" -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-connectivity.h" #include "dns/nm-dns-manager.h" #include "systemd/nm-sd.h" @@ -225,6 +225,7 @@ int main (int argc, char *argv[]) { gboolean success = FALSE; + NMManager *manager; NMConfig *config; GError *error = NULL; gboolean wrote_pidfile = FALSE; @@ -236,7 +237,7 @@ main (int argc, char *argv[]) * https://bugzilla.gnome.org/show_bug.cgi?id=674885 */ g_type_ensure (G_TYPE_SOCKET); g_type_ensure (G_TYPE_DBUS_CONNECTION); - g_type_ensure (NM_TYPE_BUS_MANAGER); + g_type_ensure (NM_TYPE_DBUS_MANAGER); _nm_utils_is_manager_process = TRUE; @@ -394,27 +395,22 @@ main (int argc, char *argv[]) NM_CONFIG_KEYFILE_KEY_MAIN_AUTH_POLKIT, NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT_BOOL)); - nm_manager_setup (); + manager = nm_manager_setup (); - if (!nm_bus_manager_get_connection (nm_bus_manager_get ())) { - nm_log_warn (LOGD_CORE, "Failed to connect to D-Bus; only private bus is available"); - } else { - /* Start our DBus service */ - if (!nm_bus_manager_start_service (nm_bus_manager_get ())) { - nm_log_err (LOGD_CORE, "failed to start the dbus service."); - goto done; - } - } + if (!nm_dbus_manager_start (nm_dbus_manager_get (), + nm_manager_dbus_set_property_handle, + manager)) + goto done; #if WITH_CONCHECK - NM_UTILS_KEEP_ALIVE (nm_manager_get (), nm_connectivity_get (), "NMManager-depends-on-NMConnectivity"); + NM_UTILS_KEEP_ALIVE (manager, nm_connectivity_get (), "NMManager-depends-on-NMConnectivity"); #endif nm_dispatcher_init (); - g_signal_connect (nm_manager_get (), NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config); + g_signal_connect (manager, NM_MANAGER_CONFIGURE_QUIT, G_CALLBACK (manager_configure_quit), config); - if (!nm_manager_start (nm_manager_get (), &error)) { + if (!nm_manager_start (manager, &error)) { nm_log_err (LOGD_CORE, "failed to initialize: %s", error->message); goto done; } @@ -448,11 +444,14 @@ done: * state here. We don't bother updating the state as devices * change during regular operation. If NM is killed with SIGKILL, * it misses to update the state. */ - nm_manager_write_device_state (nm_manager_get ()); + nm_manager_write_device_state (manager); - nm_exported_object_class_set_quitting (); + /* FIXME: we don't properly shut down on exit. That is a bug. + * NMDBusObject have an assertion that they get unexported before disposing. + * We need to disable this assertion during our leaky shutdown. */ + nm_dbus_object_set_quitting (); - nm_manager_stop (nm_manager_get ()); + nm_manager_stop (manager); nm_config_state_set (config, TRUE, TRUE); diff --git a/src/meson.build b/src/meson.build index e814f58403..39a41ca751 100644 --- a/src/meson.build +++ b/src/meson.build @@ -65,14 +65,14 @@ sources = files( 'main-utils.c', 'NetworkManagerUtils.c', 'nm-core-utils.c', - 'nm-exported-object.c', + 'nm-dbus-object.c', + 'nm-dbus-utils.c', 'nm-ip4-config.c', 'nm-ip6-config.c', 'nm-logging.c' ) deps = [ - libnmdbus_dep, libsystemd_dep, libudev_dep, nm_core_dep diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 7f5d1bed27..49e34169d8 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -32,8 +32,6 @@ #include "NetworkManagerUtils.h" #include "nm-core-internal.h" -#include "introspection/org.freedesktop.NetworkManager.Connection.Active.h" - typedef struct _NMActiveConnectionPrivate { NMSettingsConnection *settings_connection; NMConnection *applied_connection; @@ -103,12 +101,15 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_DBUS_OBJECT) #define NM_ACTIVE_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMActiveConnection, NM_IS_ACTIVE_CONNECTION) /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_active_connection; +static const GDBusSignalInfo signal_info_state_changed; + static void check_master_ready (NMActiveConnection *self); static void _device_cleanup (NMActiveConnection *self); static void _settings_connection_notify_flags (NMSettingsConnection *settings_connection, @@ -191,8 +192,8 @@ _settings_connection_removed (NMSettingsConnection *connection, * re-link; in that case we'd just clean the references to the old connection here). * Let's remove ourselves from the bus so that we're not exposed with a dangling * reference to the setting connection once it's gone. */ - if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self))) - nm_exported_object_unexport (NM_EXPORTED_OBJECT (self)); + if (nm_dbus_object_is_exported (NM_DBUS_OBJECT (self))) + nm_dbus_object_unexport (NM_DBUS_OBJECT (self)); } static void @@ -223,6 +224,18 @@ nm_active_connection_get_state (NMActiveConnection *self) return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->state; } +static void +emit_state_changed (NMActiveConnection *self, guint state, guint reason) +{ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_active_connection, + &signal_info_state_changed, + "(uu)", + (guint32) state, + (guint32) reason); + g_signal_emit (self, signals[STATE_CHANGED], 0, state, reason); +} + void nm_active_connection_set_state (NMActiveConnection *self, NMActiveConnectionState new_state, @@ -253,7 +266,7 @@ nm_active_connection_set_state (NMActiveConnection *self, old_state = priv->state; priv->state = new_state; priv->state_set = TRUE; - g_signal_emit (self, signals[STATE_CHANGED], 0, (guint) new_state, (guint) reason); + emit_state_changed (self, new_state, reason); _notify (self, PROP_STATE); check_master_ready (self); @@ -451,7 +464,7 @@ nm_active_connection_set_settings_connection (NMActiveConnection *self, * never changes (once it's set). That has effects for NMVpnConnection and * NMActivationRequest. * For example, we'd have to cancel all pending seret requests. */ - g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self))); + g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (self))); _set_settings_connection (self, connection); @@ -810,7 +823,7 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m /* Master is write-once, and must be set before exporting the object */ g_return_if_fail (priv->master == NULL); - g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self))); + g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (self))); if (priv->device) { /* Note, the master ActiveConnection may not yet have a device */ g_return_if_fail (priv->device != nm_active_connection_get_device (master)); @@ -1171,7 +1184,7 @@ get_property (GObject *object, guint prop_id, case PROP_DEVICES: devices = g_ptr_array_sized_new (2); if (priv->device && priv->state < NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) - g_ptr_array_add (devices, g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (priv->device)))); + g_ptr_array_add (devices, g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (priv->device)))); g_ptr_array_add (devices, NULL); g_value_take_boxed (value, (char **) g_ptr_array_free (devices, FALSE)); break; @@ -1213,7 +1226,7 @@ get_property (GObject *object, guint prop_id, case PROP_MASTER: if (priv->master) master_device = nm_active_connection_get_device (priv->master); - nm_utils_g_value_set_object_path (value, master_device); + nm_dbus_utils_g_value_set_object_path (value, master_device); break; case PROP_INT_SUBJECT: g_value_set_object (value, priv->subject); @@ -1389,22 +1402,59 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object); } +static const GDBusSignalInfo signal_info_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "StateChanged", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("state", "u"), + NM_DEFINE_GDBUS_ARG_INFO ("reason", "u"), + ), +); + +static const NMDBusInterfaceInfoExtended interface_info_active_connection = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &signal_info_state_changed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Connection", "o", NM_ACTIVE_CONNECTION_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("SpecificObject", "o", NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Id", "s", NM_ACTIVE_CONNECTION_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Uuid", "s", NM_ACTIVE_CONNECTION_UUID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Type", "s", NM_ACTIVE_CONNECTION_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Devices", "ao", NM_ACTIVE_CONNECTION_DEVICES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("State", "u", NM_ACTIVE_CONNECTION_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("StateFlags", "u", NM_ACTIVE_CONNECTION_STATE_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Default", "b", NM_ACTIVE_CONNECTION_DEFAULT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip4Config", "o", NM_ACTIVE_CONNECTION_IP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Dhcp4Config", "o", NM_ACTIVE_CONNECTION_DHCP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Default6", "b", NM_ACTIVE_CONNECTION_DEFAULT6), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Ip6Config", "o", NM_ACTIVE_CONNECTION_IP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Dhcp6Config", "o", NM_ACTIVE_CONNECTION_DHCP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Vpn", "b", NM_ACTIVE_CONNECTION_VPN), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Master", "o", NM_ACTIVE_CONNECTION_MASTER), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_active_connection_class_init (NMActiveConnectionClass *ac_class) { GObjectClass *object_class = G_OBJECT_CLASS (ac_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (ac_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (ac_class); g_type_class_add_private (ac_class, sizeof (NMActiveConnectionPrivate)); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/ActiveConnection"); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/ActiveConnection"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_active_connection); object_class->get_property = get_property; object_class->set_property = set_property; object_class->constructed = constructed; object_class->dispose = dispose; - /* D-Bus exported properties */ obj_properties[PROP_CONNECTION] = g_param_spec_string (NM_ACTIVE_CONNECTION_CONNECTION, "", "", NULL, @@ -1580,9 +1630,4 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (ac_class), - NMDBUS_TYPE_ACTIVE_CONNECTION_SKELETON, - NULL); } - diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 3015b5c584..4d893e2c76 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -21,10 +21,9 @@ #ifndef __NETWORKMANAGER_ACTIVE_CONNECTION_H__ #define __NETWORKMANAGER_ACTIVE_CONNECTION_H__ -#include "nm-exported-object.h" -#include "nm-connection.h" - #include "nm-utils/c-list.h" +#include "nm-connection.h" +#include "nm-dbus-object.h" #define NM_TYPE_ACTIVE_CONNECTION (nm_active_connection_get_type ()) #define NM_ACTIVE_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnection)) @@ -71,7 +70,7 @@ struct _NMActiveConnectionPrivate; struct _NMActiveConnection { - NMExportedObject parent; + NMDBusObject parent; struct _NMActiveConnectionPrivate *_priv; /* active connection can be tracked in a list by NMManager. This is @@ -80,7 +79,7 @@ struct _NMActiveConnection { }; typedef struct { - NMExportedObjectClass parent; + NMDBusObjectClass parent; /* re-emits device state changes as a convenience for subclasses for * device states >= DISCONNECTED. diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c index ffb102d2ed..9b0251365c 100644 --- a/src/nm-auth-subject.c +++ b/src/nm-auth-subject.c @@ -186,18 +186,18 @@ _new_unix_process (GDBusMethodInvocation *context, g_return_val_if_fail (context || (connection && message), NULL); if (context) { - success = nm_bus_manager_get_caller_info (nm_bus_manager_get (), - context, - &dbus_sender, - &uid, - &pid); + success = nm_dbus_manager_get_caller_info (nm_dbus_manager_get (), + context, + &dbus_sender, + &uid, + &pid); } else if (message) { - success = nm_bus_manager_get_caller_info_from_message (nm_bus_manager_get (), - connection, - message, - &dbus_sender, - &uid, - &pid); + success = nm_dbus_manager_get_caller_info_from_message (nm_dbus_manager_get (), + connection, + message, + &dbus_sender, + &uid, + &pid); } else g_assert_not_reached (); diff --git a/src/nm-checkpoint-manager.c b/src/nm-checkpoint-manager.c index fd1d41b4b5..44c1f49f48 100644 --- a/src/nm-checkpoint-manager.c +++ b/src/nm-checkpoint-manager.c @@ -26,7 +26,6 @@ #include "nm-connection.h" #include "nm-core-utils.h" #include "devices/nm-device.h" -#include "nm-exported-object.h" #include "nm-manager.h" #include "nm-utils.h" #include "nm-utils/c-list.h" @@ -78,7 +77,7 @@ item_destroy (gpointer data) CheckpointItem *item = data; c_list_unlink_stale (&item->list); - nm_exported_object_unexport (NM_EXPORTED_OBJECT (item->checkpoint)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (item->checkpoint)); g_object_unref (G_OBJECT (item->checkpoint)); g_slice_free (CheckpointItem, item); } @@ -100,7 +99,7 @@ rollback_timeout_cb (NMCheckpointManager *self) result = nm_checkpoint_rollback (item->checkpoint); if (result) g_variant_unref (result); - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (item->checkpoint)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (item->checkpoint)); if (!g_hash_table_remove (self->checkpoints, path)) nm_assert_not_reached(); removed = TRUE; @@ -185,7 +184,7 @@ nm_checkpoint_manager_create (NMCheckpointManager *self, device = NM_DEVICE (iter->data); if (!nm_device_is_real (device)) continue; - device_path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device)); + device_path = nm_dbus_object_get_path (NM_DBUS_OBJECT (device)); if (device_path) g_ptr_array_add (paths, (gpointer) device_path); } @@ -217,7 +216,7 @@ nm_checkpoint_manager_create (NMCheckpointManager *self, g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INVALID_ARGUMENTS, "device '%s' is already included in checkpoint %s", nm_device_get_iface (device), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (checkpoint))); return NULL; } } @@ -230,8 +229,7 @@ nm_checkpoint_manager_create (NMCheckpointManager *self, if (NM_FLAGS_HAS (flags, NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL)) g_hash_table_remove_all (self->checkpoints); - nm_exported_object_export (NM_EXPORTED_OBJECT (checkpoint)); - checkpoint_path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint)); + checkpoint_path = nm_dbus_object_export (NM_DBUS_OBJECT (checkpoint)); item = g_slice_new0 (CheckpointItem); item->checkpoint = checkpoint; @@ -326,7 +324,7 @@ nm_checkpoint_manager_get_checkpoint_paths (NMCheckpointManager *self) strv = g_new (char *, num + 1); c_list_for_each_entry (item, &self->list, list) - strv[i++] = g_strdup (nm_exported_object_get_path (NM_EXPORTED_OBJECT (item->checkpoint))); + strv[i++] = g_strdup (nm_dbus_object_get_path (NM_DBUS_OBJECT (item->checkpoint))); nm_assert (i == num); strv[i] = NULL; diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c index 476e27e71a..0ae3aac215 100644 --- a/src/nm-checkpoint.c +++ b/src/nm-checkpoint.c @@ -34,7 +34,6 @@ #include "settings/nm-settings-connection.h" #include "nm-simple-connection.h" #include "nm-utils.h" -#include "introspection/org.freedesktop.NetworkManager.Checkpoint.h" /*****************************************************************************/ @@ -68,15 +67,15 @@ typedef struct { } NMCheckpointPrivate; struct _NMCheckpoint { - NMExportedObject parent; + NMDBusObject parent; NMCheckpointPrivate _priv; }; struct _NMCheckpointClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMCheckpoint, nm_checkpoint, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMCheckpoint, nm_checkpoint, NM_TYPE_DBUS_OBJECT) #define NM_CHECKPOINT_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMCheckpoint, NM_IS_CHECKPOINT) @@ -183,7 +182,7 @@ nm_checkpoint_rollback (NMCheckpoint *self) GError *local_error = NULL; GVariantBuilder builder; - _LOGI ("rollback of %s", nm_exported_object_get_path ((NMExportedObject *) self)); + _LOGI ("rollback of %s", nm_dbus_object_get_path (NM_DBUS_OBJECT (self))); g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{su}")); /* Start rolling-back each device */ @@ -382,7 +381,7 @@ device_checkpoint_create (NMDevice *device, const char *path; NMActRequest *act_request; - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (device)); dev_checkpoint = g_slice_new0 (DeviceCheckpoint); dev_checkpoint->device = g_object_ref (device); @@ -392,7 +391,7 @@ device_checkpoint_create (NMDevice *device, if (nm_device_get_unmanaged_mask (device, NM_UNMANAGED_USER_EXPLICIT)) { dev_checkpoint->unmanaged_explicit = - !!nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT); + !!nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT); } else dev_checkpoint->unmanaged_explicit = NM_UNMAN_FLAG_OP_FORGET; @@ -445,7 +444,7 @@ get_property (GObject *object, guint prop_id, g_hash_table_iter_init (&iter, priv->devices); while (g_hash_table_iter_next (&iter, (gpointer *) &device, NULL)) devices = g_slist_append (devices, device); - nm_utils_g_value_set_object_path_array (value, devices, NULL, NULL); + nm_dbus_utils_g_value_set_object_path_array (value, devices, NULL, NULL); break; case PROP_CREATED: g_value_set_int64 (value, priv->created); @@ -538,14 +537,29 @@ dispose (GObject *object) G_OBJECT_CLASS (nm_checkpoint_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_checkpoint = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_CHECKPOINT, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Devices", "ao", NM_CHECKPOINT_DEVICES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Created", "x", NM_CHECKPOINT_CREATED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RollbackTimeout", "u", NM_CHECKPOINT_ROLLBACK_TIMEOUT), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class) { GObjectClass *object_class = G_OBJECT_CLASS (checkpoint_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (checkpoint_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (checkpoint_class); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/Checkpoint"); - exported_object_class->export_on_construction = FALSE; + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/Checkpoint"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_checkpoint); object_class->dispose = dispose; object_class->get_property = get_property; @@ -569,8 +583,4 @@ nm_checkpoint_class_init (NMCheckpointClass *checkpoint_class) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (checkpoint_class), - NMDBUS_TYPE_CHECKPOINT_SKELETON, - NULL); } diff --git a/src/nm-checkpoint.h b/src/nm-checkpoint.h index fccf8af3f6..5d0f73295a 100644 --- a/src/nm-checkpoint.h +++ b/src/nm-checkpoint.h @@ -21,7 +21,7 @@ #ifndef __NETWORKMANAGER_CHECKPOINT_H__ #define __NETWORKMANAGER_CHECKPOINT_H__ -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-dbus-interface.h" #define NM_TYPE_CHECKPOINT (nm_checkpoint_get_type ()) diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index 965bcec78f..82a9b75f0c 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -33,7 +33,7 @@ #include "nm-dbus-interface.h" #include "nm-core-internal.h" #include "nm-dbus-compat.h" -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "NetworkManagerUtils.h" /* The base path for our GDBusObjectManagerServers. They do not contain @@ -45,80 +45,98 @@ /*****************************************************************************/ +typedef struct { + CList registration_lst; + NMDBusObject *obj; + NMDBusObjectClass *klass; + guint info_idx; + guint registration_id; +} RegistrationData; + +/* we require that @path is the first member of NMDBusManagerData + * because _objects_by_path_hash() requires that. */ +G_STATIC_ASSERT (G_STRUCT_OFFSET (struct _NMDBusObjectInternal, path) == 0); + enum { - DBUS_CONNECTION_CHANGED = 0, PRIVATE_CONNECTION_NEW, PRIVATE_CONNECTION_DISCONNECTED, - NUMBER_OF_SIGNALS, + + LAST_SIGNAL }; -static guint signals[NUMBER_OF_SIGNALS]; +static guint signals[LAST_SIGNAL]; typedef struct { - GDBusConnection *connection; - GDBusObjectManagerServer *obj_manager; - gboolean started; + GHashTable *objects_by_path; + CList objects_lst_head; CList private_servers_lst_head; - GDBusProxy *proxy; + NMDBusManagerSetPropertyHandler set_property_handler; + gpointer set_property_handler_data; - gulong bus_closed_id; - guint reconnect_id; -} NMBusManagerPrivate; + GDBusConnection *connection; + GDBusProxy *proxy; + guint objmgr_registration_id; +} NMDBusManagerPrivate; -struct _NMBusManager { +struct _NMDBusManager { GObject parent; - NMBusManagerPrivate _priv; + NMDBusManagerPrivate _priv; }; -struct _NMBusManagerClass { +struct _NMDBusManagerClass { GObjectClass parent; }; -G_DEFINE_TYPE(NMBusManager, nm_bus_manager, G_TYPE_OBJECT) +G_DEFINE_TYPE(NMDBusManager, nm_dbus_manager, G_TYPE_OBJECT) -#define NM_BUS_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMBusManager, NM_IS_BUS_MANAGER) +#define NM_DBUS_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDBusManager, NM_IS_DBUS_MANAGER) /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_CORE #define _NMLOG(level, ...) __NMLOG_DEFAULT (level, _NMLOG_DOMAIN, "bus-manager", __VA_ARGS__) +NM_DEFINE_SINGLETON_GETTER (NMDBusManager, nm_dbus_manager_get, NM_TYPE_DBUS_MANAGER); + /*****************************************************************************/ -static gboolean nm_bus_manager_init_bus (NMBusManager *self); -static void nm_bus_manager_cleanup (NMBusManager *self); -static void start_reconnection_timeout (NMBusManager *self); +static const GDBusInterfaceInfo interface_info_objmgr; +static const GDBusSignalInfo signal_info_objmgr_interfaces_added; +static const GDBusSignalInfo signal_info_objmgr_interfaces_removed; -/*****************************************************************************/ +static void _objmgr_emit_interfaces_added (NMDBusManager *self, + NMDBusObject *obj); -NM_DEFINE_SINGLETON_REGISTER (NMBusManager); +/*****************************************************************************/ -NMBusManager * -nm_bus_manager_get (void) +static guint +_objects_by_path_hash (gconstpointer user_data) { - if (G_UNLIKELY (!singleton_instance)) { - nm_bus_manager_setup (g_object_new (NM_TYPE_BUS_MANAGER, NULL)); - if (!nm_bus_manager_init_bus (singleton_instance)) - start_reconnection_timeout (singleton_instance); - } - return singleton_instance; + const char *const*p_data = user_data; + + nm_assert (p_data); + nm_assert (*p_data); + nm_assert ((*p_data)[0] == '/'); + + return nm_hash_str (*p_data); } -void -nm_bus_manager_setup (NMBusManager *instance) +static gboolean +_objects_by_path_equal (gconstpointer user_data_a, gconstpointer user_data_b) { - static char already_setup = FALSE; + const char *const*p_data_a = user_data_a; + const char *const*p_data_b = user_data_b; - g_assert (NM_IS_BUS_MANAGER (instance)); - g_assert (!already_setup); - g_assert (!singleton_instance); + nm_assert (p_data_a); + nm_assert (*p_data_a); + nm_assert ((*p_data_a)[0] == '/'); + nm_assert (p_data_b); + nm_assert (*p_data_b); + nm_assert ((*p_data_b)[0] == '/'); - already_setup = TRUE; - singleton_instance = instance; - nm_singleton_instance_register (); - _LOGD ("setup %s singleton (%p)", "NMBusManager", singleton_instance); + return nm_streq (*p_data_a, *p_data_b); } /*****************************************************************************/ @@ -141,7 +159,7 @@ typedef struct { */ CList object_mgr_lst_head; - NMBusManager *manager; + NMDBusManager *manager; } PrivateServer; typedef struct { @@ -311,11 +329,11 @@ private_server_free (gpointer ptr) } void -nm_bus_manager_private_server_register (NMBusManager *self, - const char *path, - const char *tag) +nm_dbus_manager_private_server_register (NMDBusManager *self, + const char *path, + const char *tag) { - NMBusManagerPrivate *priv; + NMDBusManagerPrivate *priv; PrivateServer *s; gs_unref_object GDBusAuthObserver *auth_observer = NULL; GDBusServer *server; @@ -323,11 +341,11 @@ nm_bus_manager_private_server_register (NMBusManager *self, gs_free char *address = NULL; gs_free char *guid = NULL; - g_return_if_fail (NM_IS_BUS_MANAGER (self)); + g_return_if_fail (NM_IS_DBUS_MANAGER (self)); g_return_if_fail (path); g_return_if_fail (tag); - priv = NM_BUS_MANAGER_GET_PRIVATE (self); + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); /* Only one instance per tag; but don't warn */ c_list_for_each_entry (s, &priv->private_servers_lst_head, private_servers_lst) { @@ -410,7 +428,7 @@ private_server_get_connection_by_owner (PrivateServer *s, const char *owner) /*****************************************************************************/ static gboolean -_bus_get_unix_pid (NMBusManager *self, +_bus_get_unix_pid (NMDBusManager *self, const char *sender, gulong *out_pid, GError **error) @@ -418,7 +436,7 @@ _bus_get_unix_pid (NMBusManager *self, guint32 unix_pid = G_MAXUINT32; gs_unref_variant GVariant *ret = NULL; - ret = _nm_dbus_proxy_call_sync (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, + ret = _nm_dbus_proxy_call_sync (NM_DBUS_MANAGER_GET_PRIVATE (self)->proxy, "GetConnectionUnixProcessID", g_variant_new ("(s)", sender), G_VARIANT_TYPE ("(u)"), @@ -434,7 +452,7 @@ _bus_get_unix_pid (NMBusManager *self, } static gboolean -_bus_get_unix_user (NMBusManager *self, +_bus_get_unix_user (NMDBusManager *self, const char *sender, gulong *out_user, GError **error) @@ -442,7 +460,7 @@ _bus_get_unix_user (NMBusManager *self, guint32 unix_uid = G_MAXUINT32; gs_unref_variant GVariant *ret = NULL; - ret = _nm_dbus_proxy_call_sync (NM_BUS_MANAGER_GET_PRIVATE (self)->proxy, + ret = _nm_dbus_proxy_call_sync (NM_DBUS_MANAGER_GET_PRIVATE (self)->proxy, "GetConnectionUnixUser", g_variant_new ("(s)", sender), G_VARIANT_TYPE ("(u)"), @@ -464,7 +482,7 @@ _bus_get_unix_user (NMBusManager *self, * return the sender and the UID of the sender. */ static gboolean -_get_caller_info (NMBusManager *self, +_get_caller_info (NMDBusManager *self, GDBusMethodInvocation *context, GDBusConnection *connection, GDBusMessage *message, @@ -472,7 +490,7 @@ _get_caller_info (NMBusManager *self, gulong *out_uid, gulong *out_pid) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); const char *sender; if (context) { @@ -541,28 +559,28 @@ _get_caller_info (NMBusManager *self, } gboolean -nm_bus_manager_get_caller_info (NMBusManager *self, - GDBusMethodInvocation *context, - char **out_sender, - gulong *out_uid, - gulong *out_pid) +nm_dbus_manager_get_caller_info (NMDBusManager *self, + GDBusMethodInvocation *context, + char **out_sender, + gulong *out_uid, + gulong *out_pid) { return _get_caller_info (self, context, NULL, NULL, out_sender, out_uid, out_pid); } gboolean -nm_bus_manager_get_caller_info_from_message (NMBusManager *self, - GDBusConnection *connection, - GDBusMessage *message, - char **out_sender, - gulong *out_uid, - gulong *out_pid) +nm_dbus_manager_get_caller_info_from_message (NMDBusManager *self, + GDBusConnection *connection, + GDBusMessage *message, + char **out_sender, + gulong *out_uid, + gulong *out_pid) { return _get_caller_info (self, NULL, connection, message, out_sender, out_uid, out_pid); } /** - * nm_bus_manager_ensure_uid: + * nm_dbus_manager_ensure_uid: * * @self: bus manager instance * @context: D-Bus method invocation @@ -578,19 +596,19 @@ nm_bus_manager_get_caller_info_from_message (NMBusManager *self, * Returns: %TRUE if the check succeeded, %FALSE otherwise */ gboolean -nm_bus_manager_ensure_uid (NMBusManager *self, - GDBusMethodInvocation *context, - gulong uid, - GQuark error_domain, - int error_code) +nm_dbus_manager_ensure_uid (NMDBusManager *self, + GDBusMethodInvocation *context, + gulong uid, + GQuark error_domain, + int error_code) { gulong caller_uid; GError *error = NULL; - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), FALSE); + g_return_val_if_fail (NM_IS_DBUS_MANAGER (self), FALSE); g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (context), FALSE); - if (!nm_bus_manager_get_caller_info (self, context, NULL, &caller_uid, NULL)) { + if (!nm_dbus_manager_get_caller_info (self, context, NULL, &caller_uid, NULL)) { error = g_error_new_literal (error_domain, error_code, "Unable to determine request UID."); @@ -610,11 +628,11 @@ nm_bus_manager_ensure_uid (NMBusManager *self, } gboolean -nm_bus_manager_get_unix_user (NMBusManager *self, - const char *sender, - gulong *out_uid) +nm_dbus_manager_get_unix_user (NMDBusManager *self, + const char *sender, + gulong *out_uid) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); PrivateServer *s; GError *error = NULL; @@ -645,386 +663,931 @@ nm_bus_manager_get_unix_user (NMBusManager *self, /*****************************************************************************/ -/* Only cleanup a specific dbus connection, not all our private data */ -static void -nm_bus_manager_cleanup (NMBusManager *self) +const char * +nm_dbus_manager_connection_get_private_name (NMDBusManager *self, + GDBusConnection *connection) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + NMDBusManagerPrivate *priv; + PrivateServer *s; + const char *owner; - g_clear_object (&priv->proxy); + g_return_val_if_fail (NM_IS_DBUS_MANAGER (self), FALSE); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); - if (priv->connection) { - g_signal_handler_disconnect (priv->connection, priv->bus_closed_id); - priv->bus_closed_id = 0; - g_clear_object (&priv->connection); + if (g_dbus_connection_get_unique_name (connection)) { + /* Shortcut. The connection is not a private connection. */ + return NULL; } - g_dbus_object_manager_server_set_connection (priv->obj_manager, NULL); - priv->started = FALSE; + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + c_list_for_each_entry (s, &priv->private_servers_lst_head, private_servers_lst) { + if ((owner = private_server_get_connection_owner (s, connection))) + return owner; + } + g_return_val_if_reached (NULL); } -static gboolean -nm_bus_manager_reconnect (gpointer user_data) +/** + * nm_dbus_manager_new_proxy: + * @self: the #NMDBusManager + * @connection: the GDBusConnection for which this connection should be created + * @proxy_type: the type of #GDBusProxy to create + * @name: any name on the message bus + * @path: name of the object instance to call methods on + * @iface: name of the interface to call methods on + * + * Creates a new proxy (of type @proxy_type) for a name on a given bus. Since + * the process which called the D-Bus method could be coming from a private + * connection or the system bus connection, different proxies must be created + * for each case. This function abstracts that. + * + * Returns: a #GDBusProxy capable of calling D-Bus methods of the calling process + */ +GDBusProxy * +nm_dbus_manager_new_proxy (NMDBusManager *self, + GDBusConnection *connection, + GType proxy_type, + const char *name, + const char *path, + const char *iface) { - NMBusManager *self = NM_BUS_MANAGER (user_data); - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + const char *owner; + GDBusProxy *proxy; + GError *error = NULL; - g_assert (self != NULL); + g_return_val_if_fail (g_type_is_a (proxy_type, G_TYPE_DBUS_PROXY), NULL); + g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); - if (nm_bus_manager_init_bus (self)) { - if (nm_bus_manager_start_service (self)) { - _LOGI ("reconnected to the system bus"); - g_signal_emit (self, signals[DBUS_CONNECTION_CHANGED], - 0, priv->connection); - priv->reconnect_id = 0; - return FALSE; - } + /* Might be a private connection, for which @name is fake */ + owner = nm_dbus_manager_connection_get_private_name (self, connection); + if (owner) { + g_return_val_if_fail (!g_strcmp0 (owner, name), NULL); + name = NULL; } - /* Try again */ - nm_bus_manager_cleanup (self); - return TRUE; + proxy = g_initable_new (proxy_type, NULL, &error, + "g-connection", connection, + "g-flags", (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS), + "g-name", name, + "g-object-path", path, + "g-interface-name", iface, + NULL); + if (!proxy) { + _LOGW ("could not create proxy for %s on connection %s: %s", + iface, name, error->message); + g_error_free (error); + } + return proxy; } -static void -start_reconnection_timeout (NMBusManager *self) +/*****************************************************************************/ + +GDBusConnection * +nm_dbus_manager_get_connection (NMDBusManager *self) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + g_return_val_if_fail (NM_IS_DBUS_MANAGER (self), NULL); - if (priv->reconnect_id) - g_source_remove (priv->reconnect_id); + return NM_DBUS_MANAGER_GET_PRIVATE (self)->connection; +} + +/*****************************************************************************/ + +static const NMDBusInterfaceInfoExtended * +_reg_data_get_interface_info (RegistrationData *reg_data) +{ + nm_assert (reg_data); - /* Schedule timeout for reconnection attempts */ - priv->reconnect_id = g_timeout_add_seconds (3, nm_bus_manager_reconnect, self); + return reg_data->klass->interface_infos[reg_data->info_idx]; } +/*****************************************************************************/ + static void -closed_cb (GDBusConnection *connection, - gboolean remote_peer_vanished, - GError *error, - gpointer user_data) +dbus_vtable_method_call (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) { - NMBusManager *self = NM_BUS_MANAGER (user_data); - - /* Clean up existing connection */ - _LOGW ("disconnected by the system bus"); + RegistrationData *reg_data = user_data; + NMDBusObject *obj = reg_data->obj; + const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data); + const NMDBusMethodInfoExtended *method_info = NULL; + gboolean on_same_interface; + + on_same_interface = nm_streq (interface_info->parent.name, interface_name); + + /* handle property setter first... */ + if ( !on_same_interface + && nm_streq (interface_name, DBUS_INTERFACE_PROPERTIES) + && nm_streq (method_name, "Set")) { + NMDBusManager *self = nm_dbus_object_get_manager (obj); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + const NMDBusPropertyInfoExtended *property_info = NULL; + const char *property_interface; + const char *property_name; + gs_unref_variant GVariant *value = NULL; + + g_variant_get (parameters, "(&s&sv)", &property_interface, &property_name, &value); + + nm_assert (nm_streq (property_interface, interface_info->parent.name)); + + property_info = (const NMDBusPropertyInfoExtended *) nm_dbus_utils_interface_info_lookup_property (&interface_info->parent, + property_name); + if ( !property_info + || !NM_FLAGS_HAS (property_info->parent.flags, G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE)) + g_return_if_reached (); + + if (!priv->set_property_handler) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_AUTH_FAILED, + "Cannot authenticate setting property %s", + property_name); + return; + } - nm_bus_manager_cleanup (self); + priv->set_property_handler (obj, + interface_info, + property_info, + connection, + sender, + invocation, + value, + priv->set_property_handler_data); + return; + } - g_signal_emit (G_OBJECT (self), signals[DBUS_CONNECTION_CHANGED], 0, NULL); + if (on_same_interface) { + method_info = (const NMDBusMethodInfoExtended *) nm_dbus_utils_interface_info_lookup_method (&interface_info->parent, + method_name); + } + if (!method_info) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); + return; + } - start_reconnection_timeout (self); + method_info->handle (reg_data->obj, + interface_info, + method_info, + connection, + sender, + invocation, + parameters); } -static gboolean -nm_bus_manager_init_bus (NMBusManager *self) +static GVariant * +dbus_vtable_get_property (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *property_name, + GError **error, + gpointer user_data) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - GError *error = NULL; + RegistrationData *reg_data = user_data; + const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data); + const NMDBusPropertyInfoExtended *property_info; + + property_info = (const NMDBusPropertyInfoExtended *) nm_dbus_utils_interface_info_lookup_property (&interface_info->parent, + property_name); + if (!property_info) + g_return_val_if_reached (NULL); + + return nm_dbus_utils_get_property (G_OBJECT (reg_data->obj), + property_info->parent.signature, + property_info->property_name); +} - if (priv->connection) { - _LOGW ("DBus Manager already has a valid connection"); - return FALSE; - } +static const GDBusInterfaceVTable dbus_vtable = { + .method_call = dbus_vtable_method_call, + .get_property = dbus_vtable_get_property, - priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); - if (!priv->connection) { - /* Log with 'info' severity; there won't be a bus daemon in minimal - * environments (eg, initrd) where we only want to use the private - * socket. - */ - _LOGI ("could not connect to the system bus (%s); only the " - "private D-Bus socket will be available", - error->message); - g_error_free (error); - return FALSE; + /* set_property is handled via method_call as well. We need to authenticate + * which requires an asynchronous handler. */ + .set_property = NULL, +}; + +static void +_obj_register (NMDBusManager *self, + NMDBusObject *obj) +{ + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + guint i, k; + guint n_klasses; + GType gtype; + NMDBusObjectClass *klasses[10]; + const NMDBusInterfaceInfoExtended *const*prev_interface_infos = NULL; + + nm_assert (c_list_is_empty (&obj->internal.registration_lst_head)); + nm_assert (priv->connection); + + n_klasses = 0; + gtype = G_OBJECT_TYPE (obj); + while (gtype != NM_TYPE_DBUS_OBJECT) { + nm_assert (n_klasses < G_N_ELEMENTS (klasses)); + klasses[n_klasses++] = g_type_class_ref (gtype); + gtype = g_type_parent (gtype); } - g_dbus_connection_set_exit_on_close (priv->connection, FALSE); - priv->bus_closed_id = g_signal_connect (priv->connection, "closed", - G_CALLBACK (closed_cb), self); - - priv->proxy = g_dbus_proxy_new_sync (priv->connection, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, - NULL, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - NULL, &error); - if (!priv->proxy) { - g_clear_object (&priv->connection); - _LOGW ("could not create org.freedesktop.DBus proxy (%s); only the " - "private D-Bus socket will be available", - error->message); - g_error_free (error); - return FALSE; + for (k = n_klasses; k > 0; ) { + NMDBusObjectClass *klass = NM_DBUS_OBJECT_CLASS (klasses[--k]); + + if (!klass->interface_infos) + continue; + + if (prev_interface_infos == klass->interface_infos) { + /* derived classes inherrit the interface-infos from the parent class. + * For convenience, we allow the subclass to leave interface-infos untouched, + * but it means we must ignore the parent's interface, because we already + * handled it. + * + * Note that the loop goes from the parent classes to child classes */ + continue; + } + prev_interface_infos = klass->interface_infos; + + for (i = 0; klass->interface_infos[i]; i++) { + const NMDBusInterfaceInfoExtended *interface_info = klass->interface_infos[i]; + RegistrationData *reg_data; + gs_free_error GError *error = NULL; + guint registration_id; + + reg_data = g_slice_new (RegistrationData); + + registration_id = g_dbus_connection_register_object (priv->connection, + obj->internal.path, + NM_UNCONST_PTR (GDBusInterfaceInfo, &interface_info->parent), + &dbus_vtable, + reg_data, + NULL, + &error); + if (!registration_id) { + _LOGE ("failure to register object %s: %s", obj->internal.path, error->message); + g_slice_free (RegistrationData, reg_data); + continue; + } + + reg_data->obj = obj; + reg_data->klass = g_type_class_ref (G_TYPE_FROM_CLASS (klass)); + reg_data->info_idx = i; + reg_data->registration_id = registration_id; + c_list_link_tail (&obj->internal.registration_lst_head, ®_data->registration_lst); + } } - g_dbus_object_manager_server_set_connection (priv->obj_manager, priv->connection); - return TRUE; + for (k = 0; k < n_klasses; k++) + g_type_class_unref (klasses[k]); + + nm_assert (!c_list_is_empty (&obj->internal.registration_lst_head)); + + /* Currently the interfaces of an object do not changed and strictly depend on the object glib type. + * We don't need more flixibility, and it simplifies the code. Hence, now emit interface-added + * signal for the new object. + * + * Warning: note that if @obj's notify signal is currently blocked via g_object_freeze_notify(), + * we might emit properties with an inconsistent (internal) state. There is no easy solution, + * because we have to emit the signal now, and we don't know what the correct desired state + * of the properties is. + * Another problem is, upon unfreezing the signals, we immediately send PropertiesChanged + * notifications out. Which is a bit odd, as we just export the object. + * + * In general, it's ok to export an object with frozen signals. But you better make sure + * that all properties are in a self-consistent state when exporting the object. */ + _objmgr_emit_interfaces_added (self, obj); } -/* Register our service on the bus; shouldn't be called until - * all necessary message handlers have been registered, because - * when we register on the bus, clients may start to call. - */ -gboolean -nm_bus_manager_start_service (NMBusManager *self) +static void +_obj_unregister (NMDBusManager *self, + NMDBusObject *obj) { - NMBusManagerPrivate *priv; - gs_unref_variant GVariant *ret = NULL; - int result; - GError *err = NULL; - - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), FALSE); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + RegistrationData *reg_data; + GVariantBuilder builder; - priv = NM_BUS_MANAGER_GET_PRIVATE (self); + nm_assert (NM_IS_DBUS_OBJECT (obj)); - if (priv->started) { - _LOGE ("service has already started"); - return FALSE; + if (!priv->connection) { + /* nothing to do for the moment. */ + nm_assert (c_list_is_empty (&obj->internal.registration_lst_head)); + return; } - /* Pointless to request a name when we aren't connected to the bus */ - if (!priv->proxy) - return FALSE; - - ret = _nm_dbus_proxy_call_sync (priv->proxy, - "RequestName", - g_variant_new ("(su)", - NM_DBUS_SERVICE, - DBUS_NAME_FLAG_DO_NOT_QUEUE), - G_VARIANT_TYPE ("(u)"), - G_DBUS_CALL_FLAGS_NONE, -1, - NULL, &err); - if (!ret) { - _LOGE ("could not acquire the NetworkManager service: '%s'", err->message); - g_error_free (err); - return FALSE; - } + nm_assert (!c_list_is_empty (&obj->internal.registration_lst_head)); + nm_assert (priv->objmgr_registration_id); - g_variant_get (ret, "(u)", &result); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - _LOGE ("could not acquire the NetworkManager service as it is already taken"); - return FALSE; + while ((reg_data = c_list_last_entry (&obj->internal.registration_lst_head, RegistrationData, registration_lst))) { + g_variant_builder_add (&builder, + "s", + _reg_data_get_interface_info (reg_data)->parent.name); + c_list_unlink_stale (®_data->registration_lst); + if (!g_dbus_connection_unregister_object (priv->connection, reg_data->registration_id)) + nm_assert_not_reached (); + g_type_class_unref (reg_data->klass); + g_slice_free (RegistrationData, reg_data); } - priv->started = TRUE; - return priv->started; + g_dbus_connection_emit_signal (priv->connection, + NULL, + OBJECT_MANAGER_SERVER_BASE_PATH, + interface_info_objmgr.name, + signal_info_objmgr_interfaces_removed.name, + g_variant_new ("(oas)", + obj->internal.path, + &builder), + NULL); } -GDBusConnection * -nm_bus_manager_get_connection (NMBusManager *self) +NMDBusObject * +nm_dbus_manager_lookup_object (NMDBusManager *self, const char *path) { - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), NULL); + NMDBusManagerPrivate *priv; + gpointer ptr; + NMDBusObject *obj; + + g_return_val_if_fail (NM_IS_DBUS_MANAGER (self), NULL); + g_return_val_if_fail (path, NULL); + + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + + ptr = g_hash_table_lookup (priv->objects_by_path, &path); + if (!ptr) + return NULL; - return NM_BUS_MANAGER_GET_PRIVATE (self)->connection; + obj = (NMDBusObject *) (((char *) ptr) - G_STRUCT_OFFSET (NMDBusObject, internal)); + nm_assert (NM_IS_DBUS_OBJECT (obj)); + return obj; } void -nm_bus_manager_register_object (NMBusManager *self, - GDBusObjectSkeleton *object) +_nm_dbus_manager_obj_export (NMDBusObject *obj) { - NMBusManagerPrivate *priv; + NMDBusManager *self; + NMDBusManagerPrivate *priv; - g_return_if_fail (NM_IS_BUS_MANAGER (self)); - g_return_if_fail (NM_IS_EXPORTED_OBJECT (object)); + g_return_if_fail (NM_IS_DBUS_OBJECT (obj)); + g_return_if_fail (obj->internal.path); + g_return_if_fail (NM_IS_DBUS_MANAGER (obj->internal.bus_manager)); + g_return_if_fail (c_list_is_empty (&obj->internal.objects_lst)); + nm_assert (c_list_is_empty (&obj->internal.registration_lst_head)); - priv = NM_BUS_MANAGER_GET_PRIVATE (self); + self = obj->internal.bus_manager; + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); -#if NM_MORE_ASSERTS >= 1 - if (g_dbus_object_manager_server_is_exported (priv->obj_manager, object)) - g_return_if_reached (); -#endif + if (!g_hash_table_add (priv->objects_by_path, &obj->internal)) + nm_assert_not_reached (); + c_list_link_tail (&priv->objects_lst_head, &obj->internal.objects_lst); - g_dbus_object_manager_server_export (priv->obj_manager, object); + if (priv->connection) + _obj_register (self, obj); } -GDBusObjectSkeleton * -nm_bus_manager_get_registered_object (NMBusManager *self, - const char *path) +void +_nm_dbus_manager_obj_unexport (NMDBusObject *obj) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + NMDBusManager *self; + NMDBusManagerPrivate *priv; + + g_return_if_fail (NM_IS_DBUS_OBJECT (obj)); + g_return_if_fail (obj->internal.path); + g_return_if_fail (NM_IS_DBUS_MANAGER (obj->internal.bus_manager)); + g_return_if_fail (!c_list_is_empty (&obj->internal.objects_lst)); + + self = obj->internal.bus_manager; + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + + nm_assert (&obj->internal == g_hash_table_lookup (priv->objects_by_path, &obj->internal)); + nm_assert (c_list_contains (&priv->objects_lst_head, &obj->internal.objects_lst)); + + _obj_unregister (self, obj); - return G_DBUS_OBJECT_SKELETON (g_dbus_object_manager_get_object ((GDBusObjectManager *) priv->obj_manager, path)); + if (!g_hash_table_remove (priv->objects_by_path, &obj->internal)) + nm_assert_not_reached (); + c_list_unlink (&obj->internal.objects_lst); } void -nm_bus_manager_unregister_object (NMBusManager *self, - GDBusObjectSkeleton *object) +_nm_dbus_manager_obj_notify (NMDBusObject *obj, + guint n_pspecs, + const GParamSpec *const*pspecs) { - NMBusManagerPrivate *priv; - gs_free char *path = NULL; + NMDBusManager *self; + NMDBusManagerPrivate *priv; + RegistrationData *reg_data; + guint i, p; + gboolean any_legacy_signals = FALSE; + gboolean any_legacy_properties = FALSE; + GVariantBuilder legacy_builder; + GVariant *device_statistics_args = NULL; + + nm_assert (NM_IS_DBUS_OBJECT (obj)); + nm_assert (obj->internal.path); + nm_assert (NM_IS_DBUS_MANAGER (obj->internal.bus_manager)); + nm_assert (!c_list_is_empty (&obj->internal.objects_lst)); + + c_list_for_each_entry (reg_data, &obj->internal.registration_lst_head, registration_lst) { + if (_reg_data_get_interface_info (reg_data)->legacy_property_changed) { + any_legacy_signals = TRUE; + break; + } + } + + self = obj->internal.bus_manager; + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); - g_return_if_fail (NM_IS_BUS_MANAGER (self)); - g_return_if_fail (NM_IS_EXPORTED_OBJECT (object)); + /* do a naive search for the matching NMDBusPropertyInfoExtended infos. Since the number of + * (interaces x properties) is static and possibly small, this naive search is effectively + * O(1). We might wanna introduce some index to lookup the properties in question faster. + * + * The nice part of this implementation is however, that the order in which properties + * are added to the GVariant is strictly defined to be the order in which the D-Bus property-info + * is declared. Getting a defined ordering with some smart lookup would be hard. */ + c_list_for_each_entry (reg_data, &obj->internal.registration_lst_head, registration_lst) { + const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data); + gboolean has_properties = FALSE; + GVariantBuilder builder; + GVariantBuilder invalidated_builder; + GVariant *args; + + if (!interface_info->parent.properties) + continue; + + for (i = 0; interface_info->parent.properties[i]; i++) { + const NMDBusPropertyInfoExtended *property_info = (const NMDBusPropertyInfoExtended *) interface_info->parent.properties[i]; + + for (p = 0; p < n_pspecs; p++) { + const GParamSpec *pspec = pspecs[p]; + gs_unref_variant GVariant *value = NULL; + + if (!nm_streq (property_info->property_name, pspec->name)) + continue; + + value = nm_dbus_utils_get_property (G_OBJECT (obj), + property_info->parent.signature, + property_info->property_name); + + if ( property_info->include_in_legacy_property_changed + && any_legacy_signals) { + /* also track the value in the legacy_builder to emit legacy signals below. */ + if (!any_legacy_properties) { + any_legacy_properties = TRUE; + g_variant_builder_init (&legacy_builder, G_VARIANT_TYPE ("a{sv}")); + } + g_variant_builder_add (&legacy_builder, "{sv}", property_info->parent.name, value); + } - priv = NM_BUS_MANAGER_GET_PRIVATE (self); + if (!has_properties) { + has_properties = TRUE; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); + } + g_variant_builder_add (&builder, "{sv}", property_info->parent.name, value); + } + } + + if (!has_properties) + continue; + + args = g_variant_builder_end (&builder); + + if (G_UNLIKELY (interface_info == &nm_interface_info_device_statistics)) { + /* we treat the Device.Statistics signal special, because we need to + * emit a signal also for it (below). */ + nm_assert (!device_statistics_args); + device_statistics_args = g_variant_ref_sink (args); + } -#if NM_MORE_ASSERTS >= 1 - if (!g_dbus_object_manager_server_is_exported (priv->obj_manager, object)) - g_return_if_reached (); -#endif + g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as")); + g_dbus_connection_emit_signal (priv->connection, + NULL, + obj->internal.path, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(s@a{sv}as)", + interface_info->parent.name, + args, + &invalidated_builder), + NULL); + } - g_object_get (G_OBJECT (object), "g-object-path", &path, NULL); - g_return_if_fail (path != NULL); + if (G_UNLIKELY (device_statistics_args)) { + /* this is a special interface: it has a legacy PropertiesChanged signal, + * however, contrary to other interfaces with ~regular~ legacy signals, + * we only notify about properties that actually belong to this interface. */ + g_dbus_connection_emit_signal (priv->connection, + NULL, + obj->internal.path, + nm_interface_info_device_statistics.parent.name, + "PropertiesChanged", + g_variant_new ("(@a{sv})", + device_statistics_args), + NULL); + g_variant_unref (device_statistics_args); + } - g_dbus_object_manager_server_unexport (priv->obj_manager, path); + if (any_legacy_properties) { + gs_unref_variant GVariant *args = NULL; + + /* The legacy PropertyChanged signal on the NetworkManager D-Bus interface is + * deprecated for the standard signal on org.freedesktop.DBus.Properties. However, + * for backward compatibility, we still need to emit it. + * + * Due to a bug in dbus-glib in NetworkManager <= 1.0, the signal would + * not only notify about properties that were actually on the corresponding + * D-Bus interface. Instead, it would notify about all relevant properties + * on all interfaces that had such a signal. + * + * For example, "HwAddress" gets emitted both on "fdo.NM.Device.Ethernet" + * and "fdo.NM.Device.Veth" for veth interfaces, although only the former + * actually has such a property. + * Also note that "fdo.NM.Device" interface has no legacy signal. All notifications + * about its properties are instead emitted on the interfaces of the subtypes. + * + * See bgo#770629 and commit bef26a2e69f51259095fa080221db73de09fd38d. + */ + args = g_variant_ref_sink (g_variant_new ("(a{sv})", + &legacy_builder)); + c_list_for_each_entry (reg_data, &obj->internal.registration_lst_head, registration_lst) { + const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data); + + if (interface_info->legacy_property_changed) { + g_dbus_connection_emit_signal (priv->connection, + NULL, + obj->internal.path, + interface_info->parent.name, + "PropertiesChanged", + args, + NULL); + } + } + } } -const char * -nm_bus_manager_connection_get_private_name (NMBusManager *self, - GDBusConnection *connection) +void +_nm_dbus_manager_obj_emit_signal (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + GVariant *args) { - NMBusManagerPrivate *priv; - PrivateServer *s; - const char *owner; + NMDBusManager *self; + NMDBusManagerPrivate *priv; - g_return_val_if_fail (NM_IS_BUS_MANAGER (self), FALSE); - g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), FALSE); + g_return_if_fail (NM_IS_DBUS_OBJECT (obj)); + g_return_if_fail (obj->internal.path); + g_return_if_fail (NM_IS_DBUS_MANAGER (obj->internal.bus_manager)); + g_return_if_fail (!c_list_is_empty (&obj->internal.objects_lst)); - if (g_dbus_connection_get_unique_name (connection)) { - /* Shortcut. The connection is not a private connection. */ - return NULL; + self = obj->internal.bus_manager; + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + + if (!priv->connection) { + nm_g_variant_unref_floating (args); + return; } - priv = NM_BUS_MANAGER_GET_PRIVATE (self); - c_list_for_each_entry (s, &priv->private_servers_lst_head, private_servers_lst) { - if ((owner = private_server_get_connection_owner (s, connection))) - return owner; + g_dbus_connection_emit_signal (priv->connection, + NULL, + obj->internal.path, + interface_info->parent.name, + signal_info->name, + args, + NULL); +} + +/*****************************************************************************/ + +static GVariantBuilder * +_obj_collect_properties_per_interface (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + GVariantBuilder *builder) +{ + guint i; + + g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sv}")); + if (interface_info->parent.properties) { + for (i = 0; interface_info->parent.properties[i]; i++) { + const NMDBusPropertyInfoExtended *property_info = (const NMDBusPropertyInfoExtended *) interface_info->parent.properties[i]; + gs_unref_variant GVariant *variant = NULL; + + variant = nm_dbus_utils_get_property (G_OBJECT (obj), + property_info->parent.signature, + property_info->property_name); + g_variant_builder_add (builder, + "{sv}", + property_info->parent.name, + variant); + } } - g_return_val_if_reached (NULL); + return builder; } -/** - * nm_bus_manager_new_proxy: - * @self: the #NMBusManager - * @connection: the GDBusConnection for which this connection should be created - * @proxy_type: the type of #GDBusProxy to create - * @name: any name on the message bus - * @path: name of the object instance to call methods on - * @iface: name of the interface to call methods on - * - * Creates a new proxy (of type @proxy_type) for a name on a given bus. Since - * the process which called the D-Bus method could be coming from a private - * connection or the system bus connection, different proxies must be created - * for each case. This function abstracts that. - * - * Returns: a #GDBusProxy capable of calling D-Bus methods of the calling process - */ -GDBusProxy * -nm_bus_manager_new_proxy (NMBusManager *self, - GDBusConnection *connection, - GType proxy_type, - const char *name, - const char *path, - const char *iface) +static GVariantBuilder * +_obj_collect_properties_all (NMDBusObject *obj, + GVariantBuilder *builder) { - const char *owner; - GDBusProxy *proxy; - GError *error = NULL; + RegistrationData *reg_data; - g_return_val_if_fail (g_type_is_a (proxy_type, G_TYPE_DBUS_PROXY), NULL); - g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); + g_variant_builder_init (builder, G_VARIANT_TYPE ("a{sa{sv}}")); - /* Might be a private connection, for which @name is fake */ - owner = nm_bus_manager_connection_get_private_name (self, connection); - if (owner) { - g_return_val_if_fail (!g_strcmp0 (owner, name), NULL); - name = NULL; + c_list_for_each_entry (reg_data, &obj->internal.registration_lst_head, registration_lst) { + const NMDBusInterfaceInfoExtended *interface_info = _reg_data_get_interface_info (reg_data); + GVariantBuilder properties_builder; + + g_variant_builder_add (builder, + "{sa{sv}}", + interface_info->parent.name, + _obj_collect_properties_per_interface (obj, + interface_info, + &properties_builder)); } - proxy = g_initable_new (proxy_type, NULL, &error, - "g-connection", connection, - "g-flags", (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS), - "g-name", name, - "g-object-path", path, - "g-interface-name", iface, - NULL); + return builder; +} + +static void +_objmgr_emit_interfaces_added (NMDBusManager *self, + NMDBusObject *obj) +{ + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + GVariantBuilder builder; + + nm_assert (NM_IS_DBUS_OBJECT (obj)); + nm_assert (priv->connection); + nm_assert (priv->objmgr_registration_id); + + g_dbus_connection_emit_signal (priv->connection, + NULL, + OBJECT_MANAGER_SERVER_BASE_PATH, + interface_info_objmgr.name, + signal_info_objmgr_interfaces_added.name, + g_variant_new ("(oa{sa{sv}})", + obj->internal.path, + _obj_collect_properties_all (obj, &builder)), + NULL); +} + +static void +dbus_vtable_objmgr_method_call (GDBusConnection *connection, + const char *sender, + const char *object_path, + const char *interface_name, + const char *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) +{ + NMDBusManager *self = user_data; + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + GVariantBuilder array_builder; + NMDBusObject *obj; + + nm_assert (nm_streq0 (object_path, OBJECT_MANAGER_SERVER_BASE_PATH)); + + if ( !nm_streq (method_name, "GetManagedObjects") + || !nm_streq (interface_name, interface_info_objmgr.name)) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s - only GetManagedObjects() is supported", + method_name); + return; + } + + g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}")); + c_list_for_each_entry (obj, &priv->objects_lst_head, internal.objects_lst) { + GVariantBuilder interfaces_builder; + + /* note that we are called on an idle handler. Hence, all properties are + * supposed to be in a consistent state. That is true, if you always + * g_object_thaw_notify() before returning to the mainloop. Keeping + * signals frozen between while returning from the current call stack + * is anyway a very fragile thing, easy to get wrong. Don't do that. */ + g_variant_builder_add (&array_builder, + "{oa{sa{sv}}}", + obj->internal.path, + _obj_collect_properties_all (obj, + &interfaces_builder)); + } + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(a{oa{sa{sv}}})", + &array_builder)); +} + +static const GDBusInterfaceVTable dbus_vtable_objmgr = { + .method_call = dbus_vtable_objmgr_method_call +}; + +static const GDBusSignalInfo signal_info_objmgr_interfaces_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "InterfacesAdded", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("object_path", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("interfaces_and_properties", "a{sa{sv}}"), + ), +); + +static const GDBusSignalInfo signal_info_objmgr_interfaces_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "InterfacesRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("object_path", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("interfaces", "as"), + ), +); + +static const GDBusInterfaceInfo interface_info_objmgr = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + "org.freedesktop.DBus.ObjectManager", + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_GDBUS_METHOD_INFO ( + "GetManagedObjects", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("object_paths_interfaces_and_properties", "a{oa{sa{sv}}}"), + ), + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &signal_info_objmgr_interfaces_added, + &signal_info_objmgr_interfaces_removed, + ), +); + +/*****************************************************************************/ + +gboolean +nm_dbus_manager_start (NMDBusManager *self, + NMDBusManagerSetPropertyHandler set_property_handler, + gpointer set_property_handler_data) +{ + NMDBusManagerPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_unref_object GDBusConnection *connection = NULL; + gs_unref_object GDBusProxy *proxy = NULL; + guint32 result; + guint registration_id; + NMDBusObject *obj; + + g_return_val_if_fail (NM_IS_DBUS_MANAGER (self), FALSE); + + priv = NM_DBUS_MANAGER_GET_PRIVATE (self); + + priv->set_property_handler = set_property_handler; + priv->set_property_handler_data = set_property_handler_data; + + g_return_val_if_fail (!priv->connection, FALSE); + + /* we will create the D-Bus connection and registering the name synchronously. + * The reason why that is necessary is because: + * (1) if we are unable to create a D-Bus connection, it means D-Bus is not + * available and we run in D-Bus less mode. We do not support creating + * a D-Bus connection later on. This disconnected mode is useful for initrd + * (well, currently not yet, but will be). + * (2) if we are able to create the connection and register the name, + * all is good and we run with D-Bus. Note that D-Bus disconnects + * from D-Bus are ignored. Essentially, we do not support restarting + * D-Bus. + * (3) if we are able to create the connection but registration fails, + * it means that something is borked. Quite possibly another NetworkManager + * instance is running. We need to exit right away. + * To appease (1) and (3), we cannot initalize synchronously, because we need + * to know right away whether another NetworkManager instance is running (3). + **/ + + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, + NULL, + &error); + if (!connection) { + _LOGI ("cannot connect to D-Bus and proceed without (%s)", error->message); + return TRUE; + } + + g_dbus_connection_set_exit_on_close (connection, FALSE); + + proxy = g_dbus_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + NULL, + &error); if (!proxy) { - _LOGW ("could not create proxy for %s on connection %s: %s", - iface, name, error->message); - g_error_free (error); + _LOGE ("fatal failure to initialize D-Bus: %s", error->message); + return FALSE; } - return proxy; + + ret = _nm_dbus_proxy_call_sync (proxy, + "RequestName", + g_variant_new ("(su)", + NM_DBUS_SERVICE, + DBUS_NAME_FLAG_DO_NOT_QUEUE), + G_VARIANT_TYPE ("(u)"), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + &error); + if (!ret) { + _LOGE ("fatal failure to aquire D-Bus service \"%s"": %s", + NM_DBUS_SERVICE, error->message); + return FALSE; + } + + g_variant_get (ret, "(u)", &result); + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + _LOGE ("fatal failure to acquire D-Bus service \"%s\" (%u). Service already taken", + NM_DBUS_SERVICE, (guint) result); + return FALSE; + } + + registration_id = g_dbus_connection_register_object (connection, + OBJECT_MANAGER_SERVER_BASE_PATH, + NM_UNCONST_PTR (GDBusInterfaceInfo, &interface_info_objmgr), + &dbus_vtable_objmgr, + self, + NULL, + &error); + if (!registration_id) { + _LOGE ("failure to register object manager: %s", error->message); + return FALSE; + } + + priv->objmgr_registration_id = registration_id; + priv->connection = g_steal_pointer (&connection); + priv->proxy = g_steal_pointer (&proxy); + + _LOGI ("aquired D-Bus service \"%s\"", NM_DBUS_SERVICE); + + c_list_for_each_entry (obj, &priv->objects_lst_head, internal.objects_lst) + _obj_register (self, obj); + + return TRUE; } /*****************************************************************************/ static void -nm_bus_manager_init (NMBusManager *self) +nm_dbus_manager_init (NMDBusManager *self) { - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); c_list_init (&priv->private_servers_lst_head); - priv->obj_manager = g_dbus_object_manager_server_new (OBJECT_MANAGER_SERVER_BASE_PATH); + c_list_init (&priv->objects_lst_head); + priv->objects_by_path = g_hash_table_new ((GHashFunc) _objects_by_path_hash, (GEqualFunc) _objects_by_path_equal); } static void dispose (GObject *object) { - NMBusManager *self = NM_BUS_MANAGER (object); - NMBusManagerPrivate *priv = NM_BUS_MANAGER_GET_PRIVATE (self); - GList *exported, *iter; + NMDBusManager *self = NM_DBUS_MANAGER (object); + NMDBusManagerPrivate *priv = NM_DBUS_MANAGER_GET_PRIVATE (self); PrivateServer *s, *s_safe; + /* All exported NMDBusObject instances keep the manager alive, so we don't + * expect any remaining objects. */ + nm_assert (!priv->objects_by_path || g_hash_table_size (priv->objects_by_path) == 0); + nm_assert (c_list_is_empty (&priv->objects_lst_head)); + + g_clear_pointer (&priv->objects_by_path, g_hash_table_destroy); + c_list_for_each_entry_safe (s, s_safe, &priv->private_servers_lst_head, private_servers_lst) private_server_free (s); - nm_bus_manager_cleanup (self); - - if (priv->obj_manager) { - /* The ObjectManager owns the last reference to many exported - * objects, and when that reference is dropped the objects unregister - * themselves via nm_bus_manager_unregister_object(). By that time - * priv->obj_manager is already NULL and that prints warnings. Unregister - * them before clearing the ObjectManager instead. - */ - exported = g_dbus_object_manager_get_objects ((GDBusObjectManager *) priv->obj_manager); - for (iter = exported; iter; iter = iter->next) { - nm_bus_manager_unregister_object (self, iter->data); - g_object_unref (iter->data); - } - g_list_free (exported); - g_clear_object (&priv->obj_manager); + if (priv->objmgr_registration_id) { + g_dbus_connection_unregister_object (priv->connection, + nm_steal_int (&priv->objmgr_registration_id)); } - nm_clear_g_source (&priv->reconnect_id); + g_clear_object (&priv->proxy); + g_clear_object (&priv->connection); - G_OBJECT_CLASS (nm_bus_manager_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_dbus_manager_parent_class)->dispose (object); } static void -nm_bus_manager_class_init (NMBusManagerClass *klass) +nm_dbus_manager_class_init (NMDBusManagerClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->dispose = dispose; - signals[DBUS_CONNECTION_CHANGED] = - g_signal_new (NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[PRIVATE_CONNECTION_NEW] = - g_signal_new (NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW, + g_signal_new (NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_DBUS_CONNECTION, G_TYPE_DBUS_OBJECT_MANAGER_SERVER); signals[PRIVATE_CONNECTION_DISCONNECTED] = - g_signal_new (NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, + g_signal_new (NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_POINTER); } - - - diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h index 153f7cdce2..617f8a674c 100644 --- a/src/nm-dbus-manager.h +++ b/src/nm-dbus-manager.h @@ -19,75 +19,89 @@ * Copyright (C) 2006 - 2008 Novell, Inc. */ -#ifndef __NM_BUS_MANAGER_H__ -#define __NM_BUS_MANAGER_H__ - -#define NM_TYPE_BUS_MANAGER (nm_bus_manager_get_type ()) -#define NM_BUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_BUS_MANAGER, NMBusManager)) -#define NM_BUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_BUS_MANAGER, NMBusManagerClass)) -#define NM_IS_BUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NM_TYPE_BUS_MANAGER)) -#define NM_IS_BUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_BUS_MANAGER)) -#define NM_BUS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_BUS_MANAGER, NMBusManagerClass)) - -#define NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED "dbus-connection-changed" -#define NM_BUS_MANAGER_PRIVATE_CONNECTION_NEW "private-connection-new" -#define NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "private-connection-disconnected" - -typedef struct _NMBusManagerClass NMBusManagerClass; - -GType nm_bus_manager_get_type (void); - -NMBusManager * nm_bus_manager_get (void); -void nm_bus_manager_setup (NMBusManager *instance); - -gboolean nm_bus_manager_start_service (NMBusManager *self); - -GDBusConnection * nm_bus_manager_get_connection (NMBusManager *self); - -gboolean nm_bus_manager_get_caller_info (NMBusManager *self, - GDBusMethodInvocation *context, - char **out_sender, - gulong *out_uid, - gulong *out_pid); - -gboolean nm_bus_manager_ensure_uid (NMBusManager *self, - GDBusMethodInvocation *context, - gulong uid, - GQuark error_domain, - int error_code); - -const char *nm_bus_manager_connection_get_private_name (NMBusManager *self, - GDBusConnection *connection); - -gboolean nm_bus_manager_get_unix_user (NMBusManager *self, - const char *sender, - gulong *out_uid); - -gboolean nm_bus_manager_get_caller_info_from_message (NMBusManager *self, - GDBusConnection *connection, - GDBusMessage *message, - char **out_sender, - gulong *out_uid, - gulong *out_pid); - -void nm_bus_manager_register_object (NMBusManager *self, - GDBusObjectSkeleton *object); - -void nm_bus_manager_unregister_object (NMBusManager *self, - GDBusObjectSkeleton *object); - -GDBusObjectSkeleton *nm_bus_manager_get_registered_object (NMBusManager *self, - const char *path); - -void nm_bus_manager_private_server_register (NMBusManager *self, - const char *path, - const char *tag); - -GDBusProxy *nm_bus_manager_new_proxy (NMBusManager *self, - GDBusConnection *connection, - GType proxy_type, - const char *name, - const char *path, - const char *iface); - -#endif /* __NM_BUS_MANAGER_H__ */ +#ifndef __NM_DBUS_MANAGER_H__ +#define __NM_DBUS_MANAGER_H__ + +#include "nm-dbus-utils.h" + +#define NM_TYPE_DBUS_MANAGER (nm_dbus_manager_get_type ()) +#define NM_DBUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_DBUS_MANAGER, NMDBusManager)) +#define NM_DBUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_DBUS_MANAGER, NMDBusManagerClass)) +#define NM_IS_DBUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NM_TYPE_DBUS_MANAGER)) +#define NM_IS_DBUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_DBUS_MANAGER)) +#define NM_DBUS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_DBUS_MANAGER, NMDBusManagerClass)) + +#define NM_DBUS_MANAGER_PRIVATE_CONNECTION_NEW "private-connection-new" +#define NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED "private-connection-disconnected" + +typedef struct _NMDBusManagerClass NMDBusManagerClass; + +GType nm_dbus_manager_get_type (void); + +NMDBusManager *nm_dbus_manager_get (void); + +typedef void (*NMDBusManagerSetPropertyHandler) (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusPropertyInfoExtended *property_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *value, + gpointer user_data); + +gboolean nm_dbus_manager_start (NMDBusManager *self, + NMDBusManagerSetPropertyHandler handler, + gpointer handler_data); + +GDBusConnection *nm_dbus_manager_get_connection (NMDBusManager *self); + +NMDBusObject *nm_dbus_manager_lookup_object (NMDBusManager *self, const char *path); + +void _nm_dbus_manager_obj_export (NMDBusObject *obj); +void _nm_dbus_manager_obj_unexport (NMDBusObject *obj); +void _nm_dbus_manager_obj_notify (NMDBusObject *obj, + guint n_pspecs, + const GParamSpec *const*pspecs); +void _nm_dbus_manager_obj_emit_signal (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + GVariant *args); + +gboolean nm_dbus_manager_get_caller_info (NMDBusManager *self, + GDBusMethodInvocation *context, + char **out_sender, + gulong *out_uid, + gulong *out_pid); + +gboolean nm_dbus_manager_ensure_uid (NMDBusManager *self, + GDBusMethodInvocation *context, + gulong uid, + GQuark error_domain, + int error_code); + +const char *nm_dbus_manager_connection_get_private_name (NMDBusManager *self, + GDBusConnection *connection); + +gboolean nm_dbus_manager_get_unix_user (NMDBusManager *self, + const char *sender, + gulong *out_uid); + +gboolean nm_dbus_manager_get_caller_info_from_message (NMDBusManager *self, + GDBusConnection *connection, + GDBusMessage *message, + char **out_sender, + gulong *out_uid, + gulong *out_pid); + +void nm_dbus_manager_private_server_register (NMDBusManager *self, + const char *path, + const char *tag); + +GDBusProxy *nm_dbus_manager_new_proxy (NMDBusManager *self, + GDBusConnection *connection, + GType proxy_type, + const char *name, + const char *path, + const char *iface); + +#endif /* __NM_DBUS_MANAGER_H__ */ diff --git a/src/nm-dbus-object.c b/src/nm-dbus-object.c new file mode 100644 index 0000000000..b8670041fb --- /dev/null +++ b/src/nm-dbus-object.c @@ -0,0 +1,319 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-dbus-object.h" + +#include "nm-dbus-manager.h" + +/*****************************************************************************/ + +static gboolean quitting = FALSE; + +void +nm_dbus_object_set_quitting (void) +{ + nm_assert (!quitting); + quitting = TRUE; +} + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE (NMDBusObject, + PROP_PATH, +); + +G_DEFINE_ABSTRACT_TYPE (NMDBusObject, nm_dbus_object, G_TYPE_OBJECT); + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_CORE +#define _NMLOG(level, ...) __NMLOG_DEFAULT_WITH_ADDR (level, _NMLOG_DOMAIN, "dbus-object", __VA_ARGS__) + +#define _NMLOG2_DOMAIN LOGD_DBUS_PROPS +#define _NMLOG2(level, ...) __NMLOG_DEFAULT_WITH_ADDR (level, _NMLOG2_DOMAIN, "properties-changed", __VA_ARGS__) + +/*****************************************************************************/ + +static char * +_create_export_path (NMDBusObjectClass *klass) +{ + const char *class_export_path, *p; + static GHashTable *prefix_counters; + guint64 *counter; + + class_export_path = klass->export_path; + + nm_assert (class_export_path); + + p = strchr (class_export_path, '%'); + if (p) { + if (G_UNLIKELY (!prefix_counters)) + prefix_counters = g_hash_table_new (nm_str_hash, g_str_equal); + + nm_assert (p[1] == 'l'); + nm_assert (p[2] == 'l'); + nm_assert (p[3] == 'u'); + nm_assert (p[4] == '\0'); + + counter = g_hash_table_lookup (prefix_counters, class_export_path); + if (!counter) { + counter = g_slice_new0 (guint64); + g_hash_table_insert (prefix_counters, (char *) class_export_path, counter); + } + + NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral") + return g_strdup_printf (class_export_path, (unsigned long long) (++(*counter))); + NM_PRAGMA_WARNING_REENABLE + } + + return g_strdup (class_export_path); +} + +/** + * nm_dbus_object_export: + * @self: an #NMDBusObject + * + * Exports @self on all active and future D-Bus connections. + * + * The path to export @self on is taken from its #NMObjectClass's %export_path + * member. If the %export_path contains "%u", then it will be replaced with a + * monotonically increasing integer ID (with each distinct %export_path having + * its own counter). Otherwise, %export_path will be used literally (implying + * that @self must be a singleton). + * + * Returns: the path @self was exported under + */ +const char * +nm_dbus_object_export (NMDBusObject *self) +{ + static guint64 id_counter = 0; + + g_return_val_if_fail (NM_IS_DBUS_OBJECT (self), NULL); + + g_return_val_if_fail (!self->internal.path, self->internal.path); + + self->internal.path = _create_export_path (NM_DBUS_OBJECT_GET_CLASS (self)); + + self->internal.export_version_id = ++id_counter; + + _LOGT ("export: \"%s\"", self->internal.path); + + _nm_dbus_manager_obj_export (self); + + _notify (self, PROP_PATH); + return self->internal.path; +} + +/** + * nm_dbus_object_unexport: + * @self: an #NMDBusObject + * + * Unexports @self on all active D-Bus connections (and prevents it from being + * auto-exported on future connections). + */ +void +nm_dbus_object_unexport (NMDBusObject *self) +{ + g_return_if_fail (NM_IS_DBUS_OBJECT (self)); + + g_return_if_fail (self->internal.path); + + _LOGT ("unexport: \"%s\"", self->internal.path); + + _nm_dbus_manager_obj_unexport (self); + + g_clear_pointer (&self->internal.path, g_free); + self->internal.export_version_id = 0; + + _notify (self, PROP_PATH); +} + +/*****************************************************************************/ + +void +_nm_dbus_object_clear_and_unexport (NMDBusObject **location) +{ + NMDBusObject *self; + + g_return_if_fail (location); + if (!*location) + return; + + self = g_steal_pointer (location); + + g_return_if_fail (NM_IS_DBUS_OBJECT (self)); + + if (self->internal.path) + nm_dbus_object_unexport (self); + + g_object_unref (self); +} + +/*****************************************************************************/ + +void +nm_dbus_object_emit_signal_variant (NMDBusObject *self, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + GVariant *args) +{ + if (!self->internal.path) { + nm_g_variant_unref_floating (args); + return; + } + _nm_dbus_manager_obj_emit_signal (self, interface_info, signal_info, args); +} + +void +nm_dbus_object_emit_signal (NMDBusObject *self, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + const char *format, + ...) +{ + va_list ap; + + nm_assert (NM_IS_DBUS_OBJECT (self)); + nm_assert (format); + + if (!self->internal.path) + return; + + va_start (ap, format); + _nm_dbus_manager_obj_emit_signal (self, + interface_info, + signal_info, + g_variant_new_va (format, NULL, &ap)); + va_end (ap); +} + +/*****************************************************************************/ + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMDBusObject *self = NM_DBUS_OBJECT (object); + + switch (prop_id) { + case PROP_PATH: + g_value_set_string (value, self->internal.path); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispatch_properties_changed (GObject *object, + guint n_pspecs, + GParamSpec **pspecs) +{ + NMDBusObject *self = NM_DBUS_OBJECT (object); + + if (self->internal.path) + _nm_dbus_manager_obj_notify (self, n_pspecs, (const GParamSpec *const*) pspecs); + + G_OBJECT_CLASS (nm_dbus_object_parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs); +} + +/*****************************************************************************/ + +static void +nm_dbus_object_init (NMDBusObject *self) +{ + c_list_init (&self->internal.objects_lst); + c_list_init (&self->internal.registration_lst_head); + self->internal.bus_manager = nm_g_object_ref (nm_dbus_manager_get ()); +} + +static void +constructed (GObject *object) +{ + NMDBusObjectClass *klass; + + G_OBJECT_CLASS (nm_dbus_object_parent_class)->constructed (object); + + klass = NM_DBUS_OBJECT_GET_CLASS (object); + + if (klass->export_on_construction) + nm_dbus_object_export ((NMDBusObject *) object); + + /* NMDBusObject types should be very careful when overwriting notify(). + * It is possible to do, but this is a reminder that it's probably not + * a good idea. + * + * It's not a good idea, because NMDBusObject uses dispatch_properties_changed() + * to emit signals about a bunch of property changes. So, we want to make + * use of g_object_freeze_notify() / g_object_thaw_notify() to combine multiple + * property changes in one signal on D-Bus. Note that notify() is not invoked + * while the signal is frozen, that means, whatever you do inside notify() + * will not make it into the same batch of PropertiesChanged signal. That is + * confusing, and probably not what you want. + * + * Simple solution: don't overwrite notify(). */ + nm_assert (!G_OBJECT_CLASS (klass)->notify); +} + +static void +dispose (GObject *object) +{ + NMDBusObject *self = NM_DBUS_OBJECT (object); + + /* Objects should have already been unexported by their owner, unless + * we are quitting, where many objects stick around until exit. + */ + if (!quitting) { + if (self->internal.path) { + g_warn_if_reached (); + nm_dbus_object_unexport (self); + } + } else if (nm_clear_g_free (&self->internal.path)) { + /* FIXME: do a proper, coordinate shutdown, so that no objects stay + * alive nor exported. */ + _notify (self, PROP_PATH); + } + + G_OBJECT_CLASS (nm_dbus_object_parent_class)->dispose (object); + + g_clear_object (&self->internal.bus_manager); +} + +static void +nm_dbus_object_class_init (NMDBusObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = constructed; + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->dispatch_properties_changed = dispatch_properties_changed; + + obj_properties[PROP_PATH] = + g_param_spec_string (NM_DBUS_OBJECT_PATH, "", "", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/nm-dbus-object.h b/src/nm-dbus-object.h new file mode 100644 index 0000000000..bf2f2d0c64 --- /dev/null +++ b/src/nm-dbus-object.h @@ -0,0 +1,157 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_OBJECT_H__ +#define __NM_DBUS_OBJECT_H__ + +/*****************************************************************************/ + +#include "nm-utils/c-list.h" +#include "nm-dbus-utils.h" + +/*****************************************************************************/ + +void nm_dbus_object_set_quitting (void); + +/*****************************************************************************/ + +/* "org.freedesktop.NetworkManager.Device.Statistics" is a special interface, + * because although it has a legacy PropertiesChanged signal, it only notifies + * about properties that actually exist on that interface. That is, because it + * was added with 1.4.0 release, and thus didn't have the broken behavior like + * other legacy interfaces. Those notify about *all* properties, even if they + * are not part of that D-Bus interface. See also "include_in_legacy_property_changed" + * and "legacy_property_changed". */ +extern const NMDBusInterfaceInfoExtended nm_interface_info_device_statistics; + +/*****************************************************************************/ + +#define NM_TYPE_DBUS_OBJECT (nm_dbus_object_get_type ()) +#define NM_DBUS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DBUS_OBJECT, NMDBusObject)) +#define NM_DBUS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DBUS_OBJECT, NMDBusObjectClass)) +#define NM_IS_DBUS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DBUS_OBJECT)) +#define NM_IS_DBUS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DBUS_OBJECT)) +#define NM_DBUS_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DBUS_OBJECT, NMDBusObjectClass)) + +#define NM_DBUS_OBJECT_PATH "path" + +/* NMDBusObject and NMDBusManager cooperate strongly. Hence, there is an + * internal data structure attached to the NMDBusObject accessible to both of them. */ +struct _NMDBusObjectInternal { + char *path; + NMDBusManager *bus_manager; + CList objects_lst; + CList registration_lst_head; + + /* we perform asynchronous operation on exported objects. For example, we receive + * a Set property call, and asynchronously validate the operation. We must make + * sure that when the authentication is complete, that we are still looking at + * the same (exported) object. In the meantime, the object could have been + * unexported, or even re-exported afterwards. If that happens, we want + * to fail the request. For that, we keep track of a version id. */ + guint64 export_version_id; +}; + +struct _NMDBusObject { + GObject parent; + struct _NMDBusObjectInternal internal; +}; + +#define NM_DEFINE_DBUS_INTERFACE_INFO(...) \ + ((NMDBusInterfaceInfo *) (&((const NMDBusInterfaceInfo) { \ + __VA_ARGS__ \ + }))) + +typedef struct { + GObjectClass parent; + + const char *export_path; + + const NMDBusInterfaceInfoExtended *const*interface_infos; + + bool export_on_construction; +} NMDBusObjectClass; + +GType nm_dbus_object_get_type (void); + +static inline NMDBusManager * +nm_dbus_object_get_manager (NMDBusObject *obj) +{ + nm_assert (NM_IS_DBUS_OBJECT (obj)); + + return obj->internal.bus_manager; +} + +static inline guint64 +nm_dbus_object_get_export_version_id (NMDBusObject *obj) +{ + nm_assert (NM_IS_DBUS_OBJECT (obj)); + + return obj->internal.export_version_id; +} + +/** + * nm_dbus_object_get_path: + * @self: an #NMDBusObject + * + * Gets @self's D-Bus path. + * + * Returns: @self's D-Bus path, or %NULL if @self is not exported. + */ +static inline const char * +nm_dbus_object_get_path (NMDBusObject *self) +{ + g_return_val_if_fail (NM_IS_DBUS_OBJECT (self), NULL); + + return self->internal.path; +} + +/** + * nm_dbus_object_is_exported: + * @self: an #NMDBusObject + * + * Checks if @self is exported + * + * Returns: %TRUE if @self is exported + */ +static inline gboolean +nm_dbus_object_is_exported (NMDBusObject *self) +{ + return !!nm_dbus_object_get_path (self); +} + +const char *nm_dbus_object_export (NMDBusObject *self); +void nm_dbus_object_unexport (NMDBusObject *self); + +void _nm_dbus_object_clear_and_unexport (NMDBusObject **location); +#define nm_dbus_object_clear_and_unexport(location) _nm_dbus_object_clear_and_unexport ((NMDBusObject **) (location)) + +void nm_dbus_object_emit_signal_variant (NMDBusObject *self, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + GVariant *args); + +void nm_dbus_object_emit_signal (NMDBusObject *self, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + const char *format, + ...); + +#endif /* __NM_DBUS_OBJECT_H__ */ diff --git a/src/nm-dbus-utils.c b/src/nm-dbus-utils.c new file mode 100644 index 0000000000..514dc798c6 --- /dev/null +++ b/src/nm-dbus-utils.c @@ -0,0 +1,149 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#include "nm-default.h" + +#include "nm-dbus-utils.h" + +#include "nm-dbus-object.h" + +/*****************************************************************************/ + +const GDBusSignalInfo nm_signal_info_property_changed_legacy = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "PropertiesChanged", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("properties", "a{sv}"), + ), +); + +GDBusPropertyInfo * +nm_dbus_utils_interface_info_lookup_property (const GDBusInterfaceInfo *interface_info, + const char *property_name) +{ + guint i; + + nm_assert (interface_info); + nm_assert (property_name); + + /* there is also g_dbus_interface_info_lookup_property(), however that makes use + * of a global cache. */ + if (interface_info->properties) { + for (i = 0; interface_info->properties[i]; i++) { + GDBusPropertyInfo *info = interface_info->properties[i]; + + if (nm_streq (info->name, property_name)) + return info; + } + } + + return NULL; +} + +GDBusMethodInfo * +nm_dbus_utils_interface_info_lookup_method (const GDBusInterfaceInfo *interface_info, + const char *method_name) +{ + guint i; + + nm_assert (interface_info); + nm_assert (method_name); + + /* there is also g_dbus_interface_info_lookup_property(), however that makes use + * of a global cache. */ + if (interface_info->methods) { + for (i = 0; interface_info->methods[i]; i++) { + GDBusMethodInfo *info = interface_info->methods[i]; + + if (nm_streq (info->name, method_name)) + return info; + } + } + + return NULL; +} + +GVariant * +nm_dbus_utils_get_property (GObject *obj, + const char *signature, + const char *property_name) +{ + GParamSpec *pspec; + nm_auto_unset_gvalue GValue value = G_VALUE_INIT; + + nm_assert (G_IS_OBJECT (obj)); + nm_assert (g_variant_type_string_is_valid (signature)); + nm_assert (property_name && property_name[0]); + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), property_name); + if (!pspec) + g_return_val_if_reached (NULL); + + g_value_init (&value, pspec->value_type); + g_object_get_property (obj, property_name, &value); + /* returns never-floating variant */ + return g_dbus_gvalue_to_gvariant (&value, G_VARIANT_TYPE (signature)); +} + +/*****************************************************************************/ + +void +nm_dbus_utils_g_value_set_object_path (GValue *value, gpointer object) +{ + const char *path; + + g_return_if_fail (!object || NM_IS_DBUS_OBJECT (object)); + + if ( object + && (path = nm_dbus_object_get_path (object))) + g_value_set_string (value, path); + else + g_value_set_string (value, "/"); +} + +void +nm_dbus_utils_g_value_set_object_path_array (GValue *value, + GSList *objects, + gboolean (*filter_func) (GObject *object, gpointer user_data), + gpointer user_data) +{ + char **paths; + guint i; + GSList *iter; + + paths = g_new (char *, g_slist_length (objects) + 1); + for (i = 0, iter = objects; iter; iter = iter->next) { + NMDBusObject *object = iter->data; + const char *path; + + path = nm_dbus_object_get_path (object); + if (!path) + continue; + if ( filter_func + && !filter_func ((GObject *) object, user_data)) + continue; + paths[i++] = g_strdup (path); + } + paths[i] = NULL; + g_value_take_boxed (value, paths); +} + +/*****************************************************************************/ + + diff --git a/src/nm-dbus-utils.h b/src/nm-dbus-utils.h new file mode 100644 index 0000000000..9c322a6d75 --- /dev/null +++ b/src/nm-dbus-utils.h @@ -0,0 +1,177 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright 2018 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_UTILS_H__ +#define __NM_DBUS_UTILS_H__ + +/*****************************************************************************/ + +#define NM_EXPORT_PATH_NUMBERED(basepath) ""basepath"/%llu" + +/*****************************************************************************/ + +struct _NMDBusInterfaceInfoExtended; +struct _NMDBusMethodInfoExtended; + +struct _NMDBusPropertyInfoExtendedBase { + GDBusPropertyInfo _parent; + const char *property_name; + + /* Whether the properties needs to be notified on the legacy + * PropertyChanged signal. This is only to preserve API, new + * properties should not use this. */ + bool include_in_legacy_property_changed; +}; + +struct _NMDBusPropertyInfoExtendedReadWritable { + struct _NMDBusPropertyInfoExtendedBase _base; + + /* this is the polkit permission type for authenticating setting + * the property. */ + const char *permission; + + /* this is the audit operation type for writing the property. */ + const char *audit_op; +}; + +typedef struct { + union { + + GDBusPropertyInfo _parent; + struct _NMDBusPropertyInfoExtendedBase _base; + struct _NMDBusPropertyInfoExtendedReadWritable writable; + + /* duplicate the base structure in the union, so that the common fields + * are accessible directly in the parent struct. */ + struct { + GDBusPropertyInfo parent; + const char *property_name; + + /* Whether the properties needs to be notified on the legacy + * PropertyChanged signal. This is only to preserve API, new + * properties should not use this. */ + bool include_in_legacy_property_changed; + }; + }; +} NMDBusPropertyInfoExtended; + +G_STATIC_ASSERT (G_STRUCT_OFFSET (NMDBusPropertyInfoExtended, property_name) == G_STRUCT_OFFSET (struct _NMDBusPropertyInfoExtendedBase, property_name)); +G_STATIC_ASSERT (G_STRUCT_OFFSET (NMDBusPropertyInfoExtended, include_in_legacy_property_changed) == G_STRUCT_OFFSET (struct _NMDBusPropertyInfoExtendedBase, include_in_legacy_property_changed)); + +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_FULL(m_name, m_signature, m_property_name, m_include_in_legacy_property_changed) \ + ((GDBusPropertyInfo *) &((const struct _NMDBusPropertyInfoExtendedBase) { \ + ._parent = { \ + .ref_count = -1, \ + .name = m_name, \ + .signature = m_signature, \ + .flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE, \ + }, \ + .property_name = m_property_name, \ + .include_in_legacy_property_changed = m_include_in_legacy_property_changed, \ + })) + +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE(m_name, m_signature, m_property_name) \ + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_FULL (m_name, m_signature, m_property_name, FALSE) + +/* define a legacy property. Do not use for new code. */ +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L(m_name, m_signature, m_property_name) \ + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_FULL (m_name, m_signature, m_property_name, TRUE) + +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_FULL(m_name, m_signature, m_property_name, m_permission, m_audit_op, m_include_in_legacy_property_changed) \ + ((GDBusPropertyInfo *) &((const struct _NMDBusPropertyInfoExtendedReadWritable) { \ + ._base = { \ + ._parent = { \ + .ref_count = -1, \ + .name = m_name, \ + .signature = m_signature, \ + .flags = G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE, \ + }, \ + .property_name = m_property_name, \ + .include_in_legacy_property_changed = m_include_in_legacy_property_changed, \ + }, \ + .permission = m_permission, \ + .audit_op = m_audit_op, \ + })) + +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE(m_name, m_signature, m_property_name, m_permission, m_audit_op) \ + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_FULL (m_name, m_signature, m_property_name, m_permission, m_audit_op, FALSE) + +/* define a legacy property. Do not use for new code. */ +#define NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L(m_name, m_signature, m_property_name, m_permission, m_audit_op) \ + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_FULL (m_name, m_signature, m_property_name, m_permission, m_audit_op, TRUE) + +typedef struct _NMDBusMethodInfoExtended { + GDBusMethodInfo parent; + void (*handle) (NMDBusObject *obj, + const struct _NMDBusInterfaceInfoExtended *interface_info, + const struct _NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters); +} NMDBusMethodInfoExtended; + +#define NM_DEFINE_DBUS_METHOD_INFO_EXTENDED(parent_, ...) \ + ((GDBusMethodInfo *) (&((const NMDBusMethodInfoExtended) { \ + .parent = parent_, \ + __VA_ARGS__ \ + }))) + +typedef struct _NMDBusInterfaceInfoExtended { + GDBusInterfaceInfo parent; + + /* Whether the interface has a legacy property changed signal (@nm_signal_info_property_changed_legacy). + * New interfaces should not use this. */ + bool legacy_property_changed:1; +} NMDBusInterfaceInfoExtended; + +extern const GDBusSignalInfo nm_signal_info_property_changed_legacy; + +#define NM_DBUS_INTERFACE_INFOS(...) \ + ({ \ + static const NMDBusInterfaceInfoExtended *const _interface_infos[] = { \ + __VA_ARGS__, \ + NULL, \ + }; \ + _interface_infos; \ + }); + +/*****************************************************************************/ + +GDBusPropertyInfo *nm_dbus_utils_interface_info_lookup_property (const GDBusInterfaceInfo *interface_info, + const char *property_name); + +GDBusMethodInfo *nm_dbus_utils_interface_info_lookup_method (const GDBusInterfaceInfo *interface_info, + const char *method_name); + +GVariant *nm_dbus_utils_get_property (GObject *obj, + const char *signature, + const char *property_name); + +/*****************************************************************************/ + +void nm_dbus_utils_g_value_set_object_path (GValue *value, gpointer object); + +void nm_dbus_utils_g_value_set_object_path_array (GValue *value, + GSList *objects, + gboolean (*filter_func) (GObject *object, gpointer user_data), + gpointer user_data); + +#endif /* __NM_DBUS_UTILS_H__ */ diff --git a/src/nm-dhcp4-config.c b/src/nm-dhcp4-config.c index 10f58bc62b..9bf5919e02 100644 --- a/src/nm-dhcp4-config.c +++ b/src/nm-dhcp4-config.c @@ -26,9 +26,7 @@ #include "nm-dbus-interface.h" #include "nm-utils.h" -#include "nm-exported-object.h" - -#include "introspection/org.freedesktop.NetworkManager.DHCP4Config.h" +#include "nm-dbus-object.h" /*****************************************************************************/ @@ -41,15 +39,15 @@ typedef struct { } NMDhcp4ConfigPrivate; struct _NMDhcp4Config { - NMExportedObject parent; + NMDBusObject parent; NMDhcp4ConfigPrivate _priv; }; struct _NMDhcp4ConfigClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMDhcp4Config, nm_dhcp4_config, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMDhcp4Config, nm_dhcp4_config, NM_TYPE_DBUS_OBJECT) #define NM_DHCP4_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDhcp4Config, NM_IS_DHCP4_CONFIG) @@ -147,17 +145,31 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_dhcp4_config_parent_class)->finalize (object); } +static const NMDBusInterfaceInfoExtended interface_info_dhcp4_config = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DHCP4_CONFIG, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Options", "a{sv}", NM_DHCP4_CONFIG_OPTIONS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_dhcp4_config_class_init (NMDhcp4ConfigClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (config_class); object_class->get_property = get_property; object_class->finalize = finalize; - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/DHCP4Config"); - exported_object_class->export_on_construction = TRUE; + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/DHCP4Config"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_dhcp4_config); + dbus_object_class->export_on_construction = TRUE; obj_properties[PROP_OPTIONS] = g_param_spec_variant (NM_DHCP4_CONFIG_OPTIONS, "", "", @@ -167,8 +179,4 @@ nm_dhcp4_config_class_init (NMDhcp4ConfigClass *config_class) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (config_class), - NMDBUS_TYPE_DHCP4_CONFIG_SKELETON, - NULL); } diff --git a/src/nm-dhcp6-config.c b/src/nm-dhcp6-config.c index d51d77ef37..1b9f9a5009 100644 --- a/src/nm-dhcp6-config.c +++ b/src/nm-dhcp6-config.c @@ -26,9 +26,7 @@ #include "nm-dbus-interface.h" #include "nm-utils.h" -#include "nm-exported-object.h" - -#include "introspection/org.freedesktop.NetworkManager.DHCP6Config.h" +#include "nm-dbus-object.h" /*****************************************************************************/ @@ -41,15 +39,15 @@ typedef struct { } NMDhcp6ConfigPrivate; struct _NMDhcp6Config { - NMExportedObject parent; + NMDBusObject parent; NMDhcp6ConfigPrivate _priv; }; struct _NMDhcp6ConfigClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMDhcp6Config, nm_dhcp6_config, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMDhcp6Config, nm_dhcp6_config, NM_TYPE_DBUS_OBJECT) #define NM_DHCP6_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDhcp6Config, NM_IS_DHCP6_CONFIG) @@ -145,17 +143,31 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_dhcp6_config_parent_class)->finalize (object); } +static const NMDBusInterfaceInfoExtended interface_info_dhcp6_config = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_DHCP6_CONFIG, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Options", "a{sv}", NM_DHCP6_CONFIG_OPTIONS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_dhcp6_config_class_init (NMDhcp6ConfigClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (config_class); object_class->get_property = get_property; object_class->finalize = finalize; - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/DHCP6Config"); - exported_object_class->export_on_construction = TRUE; + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/DHCP6Config"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_dhcp6_config); + dbus_object_class->export_on_construction = TRUE; obj_properties[PROP_OPTIONS] = g_param_spec_variant (NM_DHCP6_CONFIG_OPTIONS, "", "", @@ -165,8 +177,4 @@ nm_dhcp6_config_class_init (NMDhcp6ConfigClass *config_class) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (config_class), - NMDBUS_TYPE_DHCP6_CONFIG_SKELETON, - NULL); } diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c index c465adf258..29bf5c9748 100644 --- a/src/nm-dispatcher.c +++ b/src/nm-dispatcher.c @@ -284,9 +284,10 @@ fill_device_props (NMDevice *device, g_variant_new_uint32 (nm_device_get_device_type (device))); g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_STATE, g_variant_new_uint32 (nm_device_get_state (device))); - if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (device))) + if (nm_dbus_object_is_exported (NM_DBUS_OBJECT (device))) { g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_PATH, - g_variant_new_object_path (nm_exported_object_get_path (NM_EXPORTED_OBJECT (device)))); + g_variant_new_object_path (nm_dbus_object_get_path (NM_DBUS_OBJECT (device)))); + } proxy_config = nm_device_get_proxy_config (device); if (proxy_config) diff --git a/src/nm-exported-object.c b/src/nm-exported-object.c deleted file mode 100644 index 4db83d351b..0000000000 --- a/src/nm-exported-object.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2014-2016 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-exported-object.h" - -#include <stdarg.h> -#include <string.h> - -#include "nm-dbus-manager.h" - -#include "devices/nm-device.h" -#include "nm-active-connection.h" -#include "introspection/org.freedesktop.NetworkManager.Device.Statistics.h" - -#if NM_MORE_ASSERTS >= 2 -#define _ASSERT_NO_EARLY_EXPORT -#endif - -/*****************************************************************************/ - -static gboolean quitting = FALSE; - -/*****************************************************************************/ - -NM_GOBJECT_PROPERTIES_DEFINE (NMExportedObject, - PROP_PATH, -); - -typedef struct { - GDBusInterfaceSkeleton *interface; - guint property_changed_signal_id; - GHashTable *pending_notifies; -} InterfaceData; - -typedef struct _NMExportedObjectPrivate { - NMBusManager *bus_mgr; - char *path; - - InterfaceData *interfaces; - guint num_interfaces; - - guint notify_idle_id; - -#ifdef _ASSERT_NO_EARLY_EXPORT - bool _constructed:1; -#endif -} NMExportedObjectPrivate; - -G_DEFINE_ABSTRACT_TYPE (NMExportedObject, nm_exported_object, G_TYPE_DBUS_OBJECT_SKELETON); - -#define NM_EXPORTED_OBJECT_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMExportedObject, NM_IS_EXPORTED_OBJECT) - -/*****************************************************************************/ - -typedef struct { - GHashTable *properties; - GSList *skeleton_types; - GArray *methods; -} NMExportedObjectClassInfo; - -static NM_CACHED_QUARK_FCN ("NMExportedObjectClassInfo", nm_exported_object_class_info_quark) - -/*****************************************************************************/ - -#define _NMLOG_DOMAIN LOGD_CORE -#define _NMLOG(level, ...) __NMLOG_DEFAULT_WITH_ADDR (level, _NMLOG_DOMAIN, "exported-object", __VA_ARGS__) - -#define _NMLOG2_DOMAIN LOGD_DBUS_PROPS -#define _NMLOG2(level, ...) __NMLOG_DEFAULT_WITH_ADDR (level, _NMLOG2_DOMAIN, "properties-changed", __VA_ARGS__) - -/*****************************************************************************/ - -/* "AddConnectionUnsaved" -> "handle-add-connection-unsaved" */ -char * -nm_exported_object_skeletonify_method_name (const char *dbus_method_name) -{ - GString *out; - const char *p; - - out = g_string_new ("handle"); - for (p = dbus_method_name; *p; p++) { - if (g_ascii_isupper (*p) || p == dbus_method_name) { - g_string_append_c (out, '-'); - g_string_append_c (out, g_ascii_tolower (*p)); - } else - g_string_append_c (out, *p); - } - - return g_string_free (out, FALSE); -} - -/* "can-modify" -> "CanModify" */ -static char * -dbusify_name (const char *gobject_name) -{ - GString *out; - const char *p; - gboolean capitalize = TRUE; - - out = g_string_new (""); - for (p = gobject_name; *p; p++) { - if (capitalize) { - g_string_append_c (out, g_ascii_toupper (*p)); - capitalize = FALSE; - } else if (*p == '-') - capitalize = TRUE; - else - g_string_append_c (out, *p); - } - - return g_string_free (out, FALSE); -} - -/* "can_modify" -> "can-modify". Returns %NULL if @gobject_name contains no underscores */ -static char * -hyphenify_name (const char *gobject_name) -{ - char *hyphen_name, *p; - - if (!strchr (gobject_name, '_')) - return NULL; - - hyphen_name = g_strdup (gobject_name); - for (p = hyphen_name; *p; p++) { - if (*p == '_') - *p = '-'; - } - return hyphen_name; -} - -/* Called when an #NMExportedObject emits a signal that corresponds to a D-Bus - * signal, and re-emits that signal on the correct skeleton object as well. - */ -static gboolean -nm_exported_object_signal_hook (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - NMExportedObject *self = g_value_get_object (¶m_values[0]); - NMExportedObjectPrivate *priv; - GSignalQuery *signal_info = data; - GDBusInterfaceSkeleton *interface = NULL; - GValue *dbus_param_values; - guint i; - - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - if (!priv->path) - return TRUE; - - for (i = 0; i < priv->num_interfaces; i++) { - InterfaceData *ifdata = &priv->interfaces[i]; - - if (g_type_is_a (G_OBJECT_TYPE (ifdata->interface), signal_info->itype)) { - interface = ifdata->interface; - break; - } - } - g_return_val_if_fail (interface != NULL, TRUE); - - dbus_param_values = g_newa (GValue, n_param_values); - memset (dbus_param_values, 0, sizeof (GValue) * n_param_values); - g_value_init (&dbus_param_values[0], G_OBJECT_TYPE (interface)); - g_value_set_object (&dbus_param_values[0], interface); - for (i = 1; i < n_param_values; i++) { - if (g_type_is_a (param_values[i].g_type, NM_TYPE_EXPORTED_OBJECT)) { - NMExportedObject *arg = g_value_get_object (¶m_values[i]); - - g_value_init (&dbus_param_values[i], G_TYPE_STRING); - if (arg && nm_exported_object_is_exported (arg)) - g_value_set_string (&dbus_param_values[i], nm_exported_object_get_path (arg)); - else - g_value_set_string (&dbus_param_values[i], "/"); - } else { - g_value_init (&dbus_param_values[i], param_values[i].g_type); - g_value_copy (¶m_values[i], &dbus_param_values[i]); - } - } - - g_signal_emitv (dbus_param_values, signal_info->signal_id, 0, NULL); - - for (i = 0; i < n_param_values; i++) - g_value_unset (&dbus_param_values[i]); - - return TRUE; -} - -/** - * nm_exported_object_class_add_interface: - * @object_class: an #NMExportedObjectClass - * @dbus_skeleton_type: the type of the #GDBusInterfaceSkeleton to add - * @...: method name / handler pairs, %NULL-terminated - * - * Adds @dbus_skeleton_type to the list of D-Bus interfaces implemented by - * @object_class. Instances of @object_class will automatically have a skeleton - * of that type created, which will be exported when you call - * nm_exported_object_export(). - * - * The skeleton's properties will be initialized from the #NMExportedObject's, - * and bidirectional bindings will be set up between them. When exported - * properties change, both the org.freedesktop.DBus.Properties.PropertiesChanged - * signal and the traditional NetworkManager PropertiesChanged signal will be - * emitted. - * - * When a signal is emitted on an #NMExportedObject that has the same name as a - * signal on @dbus_skeleton_type, it will automatically be emitted on the - * skeleton as well; #NMExportedObject arguments in the signal will be converted - * to D-Bus object paths in the skeleton signal. - * - * The arguments after @dbus_skeleton_type are pairs of D-Bus method names (in - * CamelCase), and the corresponding handlers for them (which must have the same - * prototype as the corresponding "handle-..." signal on @dbus_skeleton_type, - * except with no return value, and with the first argument being an object of - * @object_class's type, not of @dbus_skeleton_type). - * - * It is a programmer error if: - * - @object_class does not define a property of the same name and type as - * each of @dbus_skeleton_type's properties. - * - @object_class does not define a signal with the same name and arguments - * as each of @dbus_skeleton_type's signals. - * - the list of method names includes any names that do not correspond to - * "handle-" signals on @dbus_skeleton_type. - * - the list of method names does not include every method defined by - * @dbus_skeleton_type. - */ -void -nm_exported_object_class_add_interface (NMExportedObjectClass *object_class, - GType dbus_skeleton_type, - ...) -{ - NMExportedObjectClassInfo *classinfo; - NMExportedObjectDBusMethodImpl method; - va_list ap; - const char *method_name; - GCallback impl; - gs_free GType *interfaces = NULL; - guint n_interfaces; - guint n_signals, n_method_signals; - guint object_signal_id; - GSignalQuery query; - int i, s; - GObjectClass *dbus_object_class; - gs_free GParamSpec **dbus_properties = NULL; - GParamSpec *object_property; - guint n_dbus_properties; - - g_return_if_fail (NM_IS_EXPORTED_OBJECT_CLASS (object_class)); - g_return_if_fail (g_type_is_a (dbus_skeleton_type, G_TYPE_DBUS_INTERFACE_SKELETON)); - - classinfo = g_type_get_qdata (G_TYPE_FROM_CLASS (object_class), - nm_exported_object_class_info_quark ()); - if (!classinfo) { - classinfo = g_slice_new (NMExportedObjectClassInfo); - classinfo->skeleton_types = NULL; - classinfo->methods = g_array_new (FALSE, FALSE, sizeof (NMExportedObjectDBusMethodImpl)); - classinfo->properties = g_hash_table_new (nm_str_hash, g_str_equal); - g_type_set_qdata (G_TYPE_FROM_CLASS (object_class), - nm_exported_object_class_info_quark (), classinfo); - } - - classinfo->skeleton_types = g_slist_prepend (classinfo->skeleton_types, - GSIZE_TO_POINTER (dbus_skeleton_type)); - - /* Ensure @dbus_skeleton_type's class_init has run, so its signals/properties - * will be defined. - */ - dbus_object_class = g_type_class_ref (dbus_skeleton_type); - - /* Add method implementations from the varargs */ - va_start (ap, dbus_skeleton_type); - while ((method_name = va_arg (ap, const char *)) && (impl = va_arg (ap, GCallback))) { - method.dbus_skeleton_type = dbus_skeleton_type; - method.method_name = nm_exported_object_skeletonify_method_name (method_name); - g_assert (g_signal_lookup (method.method_name, dbus_skeleton_type) != 0); - method.impl = impl; - - g_array_append_val (classinfo->methods, method); - } - va_end (ap); - - /* Properties */ - dbus_properties = g_object_class_list_properties (dbus_object_class, &n_dbus_properties); - for (i = 0; i < n_dbus_properties; i++) { - char *hyphen_name; - - if (g_str_has_prefix (dbus_properties[i]->name, "g-")) - continue; - - object_property = g_object_class_find_property (G_OBJECT_CLASS (object_class), - dbus_properties[i]->name); - g_assert (object_property != NULL); - g_assert (object_property->value_type == dbus_properties[i]->value_type); - - g_assert (!g_hash_table_contains (classinfo->properties, dbus_properties[i]->name)); - g_hash_table_insert (classinfo->properties, - g_strdup (dbus_properties[i]->name), - dbusify_name (dbus_properties[i]->name)); - hyphen_name = hyphenify_name (dbus_properties[i]->name); - if (hyphen_name) { - g_assert (!g_hash_table_contains (classinfo->properties, hyphen_name)); - g_hash_table_insert (classinfo->properties, - hyphen_name, - dbusify_name (dbus_properties[i]->name)); - } - } - - /* Signals. Unlike g_object_class_list_properties(), g_signal_list_ids() is - * "shallow", so we need to query each implemented gdbus-generated interface - * separately. - */ - interfaces = g_type_interfaces (dbus_skeleton_type, &n_interfaces); - n_method_signals = 0; - for (i = 0; i < n_interfaces; i++) { - gs_free guint *dbus_signals = NULL; - - dbus_signals = g_signal_list_ids (interfaces[i], &n_signals); - for (s = 0; s < n_signals; s++) { - g_signal_query (dbus_signals[s], &query); - - /* PropertiesChanged is handled specially */ - if (!strcmp (query.signal_name, "properties-changed")) - continue; - - if (g_str_has_prefix (query.signal_name, "handle-")) { - n_method_signals++; - continue; - } - - object_signal_id = g_signal_lookup (query.signal_name, G_TYPE_FROM_CLASS (object_class)); - g_assert (object_signal_id != 0); - - g_signal_add_emission_hook (object_signal_id, 0, - nm_exported_object_signal_hook, - g_memdup (&query, sizeof (query)), - g_free); - } - } - - g_type_class_unref (dbus_object_class); -} - -/*****************************************************************************/ - -/* "meta-marshaller" that receives the skeleton "handle-foo" signal, replaces - * the skeleton object with an #NMExportedObject in the parameters, drops the - * user_data parameter, and adds a "TRUE" return value (indicating to gdbus that - * the signal was handled). - */ -static void -nm_exported_object_meta_marshal (GClosure *closure, GValue *return_value, - guint n_param_values, const GValue *param_values, - gpointer invocation_hint, gpointer marshal_data) -{ - GValue *local_param_values; - - local_param_values = g_new0 (GValue, n_param_values); - g_value_init (&local_param_values[0], G_TYPE_POINTER); - g_value_set_pointer (&local_param_values[0], closure->data); - memcpy (local_param_values + 1, param_values + 1, (n_param_values - 1) * sizeof (GValue)); - - g_cclosure_marshal_generic (closure, NULL, - n_param_values, local_param_values, - invocation_hint, - ((GCClosure *)closure)->callback); - g_value_set_boolean (return_value, TRUE); - - g_value_unset (&local_param_values[0]); - g_free (local_param_values); -} - -static NM_CACHED_QUARK_FCN ("skeleton-data", _skeleton_data_quark) - -typedef struct { - GBinding **prop_bindings; - gulong *method_signals; -} SkeletonData; - -GDBusInterfaceSkeleton * -nm_exported_object_skeleton_create (GType dbus_skeleton_type, - GObjectClass *object_class, - const NMExportedObjectDBusMethodImpl *methods, - guint methods_len, - GObject *target) -{ - GDBusInterfaceSkeleton *interface; - gs_free GParamSpec **properties = NULL; - SkeletonData *skeleton_data; - guint n_properties; - guint i, j; - - interface = G_DBUS_INTERFACE_SKELETON (g_object_new (dbus_skeleton_type, NULL)); - - skeleton_data = g_slice_new (SkeletonData); - - /* Bind properties */ - properties = g_object_class_list_properties (G_OBJECT_GET_CLASS (interface), &n_properties); - skeleton_data->prop_bindings = g_new (GBinding *, n_properties + 1); - for (i = 0, j = 0; i < n_properties; i++) { - GParamSpec *nm_property; - GBindingFlags flags; - GBinding *prop_binding; - - nm_property = g_object_class_find_property (object_class, properties[i]->name); - if (!nm_property) - continue; - - flags = G_BINDING_SYNC_CREATE; - if ( (nm_property->flags & G_PARAM_WRITABLE) - && !(nm_property->flags & G_PARAM_CONSTRUCT_ONLY)) - flags |= G_BINDING_BIDIRECTIONAL; - prop_binding = g_object_bind_property (target, properties[i]->name, - interface, properties[i]->name, - flags); - if (prop_binding) - skeleton_data->prop_bindings[j++] = prop_binding; - } - skeleton_data->prop_bindings[j++] = NULL; - - /* Bind methods */ - skeleton_data->method_signals = g_new (gulong, methods_len + 1); - for (i = 0, j = 0; i < methods_len; i++) { - const NMExportedObjectDBusMethodImpl *method = &methods[i]; - GClosure *closure; - gulong method_signal; - - /* ignore methods that are for a different skeleton-type. */ - if ( method->dbus_skeleton_type - && method->dbus_skeleton_type != dbus_skeleton_type) - continue; - - closure = g_cclosure_new_swap (method->impl, target, NULL); - g_closure_set_meta_marshal (closure, NULL, nm_exported_object_meta_marshal); - method_signal = g_signal_connect_closure (interface, method->method_name, closure, FALSE); - - if (method_signal != 0) - skeleton_data->method_signals[j++] = method_signal; - } - skeleton_data->method_signals[j++] = 0; - - g_object_set_qdata ((GObject *) interface, _skeleton_data_quark (), skeleton_data); - - return interface; -} - -static void -nm_exported_object_create_skeletons (NMExportedObject *self, - GType object_type) -{ - NMExportedObjectPrivate *priv; - GObjectClass *object_class; - NMExportedObjectClassInfo *classinfo; - GSList *iter; - const NMExportedObjectDBusMethodImpl *methods; - guint i, methods_len; - guint num_interfaces; - InterfaceData *interfaces; - - classinfo = g_type_get_qdata (object_type, nm_exported_object_class_info_quark ()); - if (!classinfo) - return; - - object_class = g_type_class_peek (object_type); - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - methods = classinfo->methods->len ? &g_array_index (classinfo->methods, NMExportedObjectDBusMethodImpl, 0) : NULL; - methods_len = classinfo->methods->len; - - num_interfaces = g_slist_length (classinfo->skeleton_types); - g_return_if_fail (num_interfaces > 0); - - interfaces = g_slice_alloc (sizeof (InterfaceData) * (num_interfaces + priv->num_interfaces)); - - for (i = num_interfaces, iter = classinfo->skeleton_types; iter; iter = iter->next) { - InterfaceData *ifdata = &interfaces[--i]; - - ifdata->interface = nm_exported_object_skeleton_create (GPOINTER_TO_SIZE (iter->data), - object_class, - methods, - methods_len, - (GObject *) self); - g_dbus_object_skeleton_add_interface ((GDBusObjectSkeleton *) self, ifdata->interface); - - ifdata->property_changed_signal_id = g_signal_lookup ("properties-changed", G_OBJECT_TYPE (ifdata->interface)); - - ifdata->pending_notifies = g_hash_table_new_full (nm_direct_hash, - NULL, - NULL, - (GDestroyNotify) g_variant_unref); - } - nm_assert (i == 0); - - /* The list of interfaces priv->interfaces is to be sorted from parent-class to derived-class. - * On the other hand, if one class defines multiple interfaces, the interfaces are sorted in - * the order of calls to nm_exported_object_class_add_interface(). */ - if (priv->num_interfaces > 0) { - memcpy (&interfaces[num_interfaces], priv->interfaces, sizeof (InterfaceData) * priv->num_interfaces); - g_slice_free1 (sizeof (InterfaceData) * priv->num_interfaces, priv->interfaces); - } - - priv->num_interfaces = num_interfaces + priv->num_interfaces; - priv->interfaces = interfaces; -} - -void -nm_exported_object_skeleton_release (GDBusInterfaceSkeleton *interface) -{ - SkeletonData *skeleton_data; - guint j; - - g_return_if_fail (G_IS_DBUS_INTERFACE_SKELETON (interface)); - - skeleton_data = g_object_steal_qdata ((GObject *) interface, _skeleton_data_quark ()); - - for (j = 0; skeleton_data->prop_bindings[j]; j++) - g_object_unref (skeleton_data->prop_bindings[j]); - for (j = 0; skeleton_data->method_signals[j]; j++) - g_signal_handler_disconnect (interface, skeleton_data->method_signals[j]); - - g_free (skeleton_data->prop_bindings); - g_free (skeleton_data->method_signals); - g_slice_free (SkeletonData, skeleton_data); - - g_object_unref (interface); -} - -static void -nm_exported_object_destroy_skeletons (NMExportedObject *self) -{ - NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - guint n; - - g_return_if_fail (priv->num_interfaces > 0); - nm_assert (priv->interfaces); - - n = priv->num_interfaces; - - while (priv->num_interfaces > 0) { - InterfaceData *ifdata = &priv->interfaces[--priv->num_interfaces]; - - g_dbus_object_skeleton_remove_interface ((GDBusObjectSkeleton *) self, ifdata->interface); - nm_exported_object_skeleton_release (ifdata->interface); - g_hash_table_destroy (ifdata->pending_notifies); - } - - g_slice_free1 (sizeof (InterfaceData) * n, priv->interfaces); - priv->interfaces = NULL; -} - -static char * -_create_export_path (NMExportedObjectClass *klass) -{ - const char *class_export_path, *p; - static GHashTable *prefix_counters; - guint64 *counter; - - class_export_path = klass->export_path; - - nm_assert (class_export_path); - - p = strchr (class_export_path, '%'); - if (p) { - if (G_UNLIKELY (!prefix_counters)) - prefix_counters = g_hash_table_new (nm_str_hash, g_str_equal); - - nm_assert (p[1] == 'l'); - nm_assert (p[2] == 'l'); - nm_assert (p[3] == 'u'); - nm_assert (p[4] == '\0'); - - counter = g_hash_table_lookup (prefix_counters, class_export_path); - if (!counter) { - counter = g_slice_new0 (guint64); - g_hash_table_insert (prefix_counters, (char *) class_export_path, counter); - } - - NM_PRAGMA_WARNING_DISABLE("-Wformat-nonliteral") - return g_strdup_printf (class_export_path, (unsigned long long) (++(*counter))); - NM_PRAGMA_WARNING_REENABLE - } - - return g_strdup (class_export_path); -} - -/** - * nm_exported_object_get_path: - * @self: an #NMExportedObject - * - * Gets @self's D-Bus path. - * - * Returns: @self's D-Bus path, or %NULL if @self is not exported. - */ -const char * -nm_exported_object_get_path (NMExportedObject *self) -{ - g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); - - return NM_EXPORTED_OBJECT_GET_PRIVATE (self)->path; -} - -/** - * nm_exported_object_is_exported: - * @self: an #NMExportedObject - * - * Checks if @self is exported - * - * Returns: %TRUE if @self is exported - */ -gboolean -nm_exported_object_is_exported (NMExportedObject *self) -{ - g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), FALSE); - - return NM_EXPORTED_OBJECT_GET_PRIVATE (self)->path != NULL; -} - -/** - * nm_exported_object_export: - * @self: an #NMExportedObject - * - * Exports @self on all active and future D-Bus connections. - * - * The path to export @self on is taken from its #NMObjectClass's %export_path - * member. If the %export_path contains "%u", then it will be replaced with a - * monotonically increasing integer ID (with each distinct %export_path having - * its own counter). Otherwise, %export_path will be used literally (implying - * that @self must be a singleton). - * - * Returns: the path @self was exported under - */ -const char * -nm_exported_object_export (NMExportedObject *self) -{ - NMExportedObjectPrivate *priv; - GType type; - - g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - g_return_val_if_fail (!priv->path, priv->path); - g_return_val_if_fail (!priv->bus_mgr, priv->path); - -#ifdef _ASSERT_NO_EARLY_EXPORT - nm_assert (priv->_constructed); -#endif - - priv->bus_mgr = nm_bus_manager_get (); - if (!priv->bus_mgr) - g_return_val_if_reached (NULL); - g_object_add_weak_pointer ((GObject *) priv->bus_mgr, (gpointer *) &priv->bus_mgr); - - type = G_OBJECT_TYPE (self); - while (type != NM_TYPE_EXPORTED_OBJECT) { - nm_exported_object_create_skeletons (self, type); - type = g_type_parent (type); - } - - priv->path = _create_export_path (NM_EXPORTED_OBJECT_GET_CLASS (self)); - - _LOGT ("export: \"%s\"", priv->path); - g_dbus_object_skeleton_set_object_path (G_DBUS_OBJECT_SKELETON (self), priv->path); - - /* Important: priv->path and priv->interfaces must not change while - * the object is registered. */ - - nm_bus_manager_register_object (priv->bus_mgr, (GDBusObjectSkeleton *) self); - - _notify (self, PROP_PATH); - - return priv->path; -} - -/** - * nm_exported_object_unexport: - * @self: an #NMExportedObject - * - * Unexports @self on all active D-Bus connections (and prevents it from being - * auto-exported on future connections). - */ -void -nm_exported_object_unexport (NMExportedObject *self) -{ - NMExportedObjectPrivate *priv; - - g_return_if_fail (NM_IS_EXPORTED_OBJECT (self)); - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - g_return_if_fail (priv->path); - - /* Important: priv->path and priv->interfaces must not change while - * the object is registered. */ - - _LOGT ("unexport: \"%s\"", priv->path); - - if (priv->bus_mgr) { - nm_bus_manager_unregister_object (priv->bus_mgr, (GDBusObjectSkeleton *) self); - g_object_remove_weak_pointer ((GObject *) priv->bus_mgr, (gpointer *) &priv->bus_mgr); - priv->bus_mgr = NULL; - } - - nm_exported_object_destroy_skeletons (self); - - g_dbus_object_skeleton_set_object_path ((GDBusObjectSkeleton *) self, NULL); - - g_clear_pointer (&priv->path, g_free); - - nm_clear_g_source (&priv->notify_idle_id); - - _notify (self, PROP_PATH); -} - -/*****************************************************************************/ - -void -_nm_exported_object_clear_and_unexport (NMExportedObject **location) -{ - NMExportedObject *self; - NMExportedObjectPrivate *priv; - - if (!location || !*location) - return; - - self = *location; - *location = NULL; - - g_return_if_fail (NM_IS_EXPORTED_OBJECT (self)); - - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - if (priv->path) - nm_exported_object_unexport (self); - - g_object_unref (self); -} - -/*****************************************************************************/ - -GDBusInterfaceSkeleton * -nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type) -{ - NMExportedObjectPrivate *priv; - guint i; - - g_return_val_if_fail (NM_IS_EXPORTED_OBJECT (self), NULL); - - priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - g_return_val_if_fail (priv->path, NULL); - g_return_val_if_fail (priv->num_interfaces > 0, NULL); - - nm_assert (priv->interfaces); - - for (i = 0; i < priv->num_interfaces; i++) { - InterfaceData *ifdata = &priv->interfaces[i]; - - if (G_TYPE_CHECK_INSTANCE_TYPE (ifdata->interface, interface_type)) - return ifdata->interface; - } - return NULL; -} - -/*****************************************************************************/ - -void -nm_exported_object_class_set_quitting (void) -{ - quitting = TRUE; -} - -/*****************************************************************************/ - -typedef struct { - const char *property_name; - GVariant *variant; -} PendingNotifiesItem; - -static int -_sort_pending_notifies (gconstpointer a, gconstpointer b, gpointer user_data) -{ - return strcmp (((const PendingNotifiesItem *) a)->property_name, - ((const PendingNotifiesItem *) b)->property_name); -} - -static gboolean -idle_emit_properties_changed (gpointer self) -{ - NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (NM_EXPORTED_OBJECT (self)); - guint k; - - priv->notify_idle_id = 0; - - for (k = 0; k < priv->num_interfaces; k++) { - InterfaceData *ifdata = &priv->interfaces[k]; - gs_unref_variant GVariant *variant = NULL; - PendingNotifiesItem *values; - GVariantBuilder notifies; - GHashTableIter hash_iter; - guint i, n; - - n = g_hash_table_size (ifdata->pending_notifies); - if (n == 0) - continue; - - nm_assert (ifdata->property_changed_signal_id); - - /* We use here alloca in a loop, something that is usually avoided. - * But the number of interfaces "priv->num_interfaces" is small (determined by - * the depth of the type inheritance) and the number of possible pending_notifies - * "n" is small (determined by the number of GObject properties). */ - values = g_alloca (sizeof (values[0]) * n); - - i = 0; - g_hash_table_iter_init (&hash_iter, ifdata->pending_notifies); - while (g_hash_table_iter_next (&hash_iter, (gpointer) &values[i].property_name, (gpointer) &values[i].variant)) - i++; - nm_assert (i == n); - - g_qsort_with_data (values, n, sizeof (values[0]), _sort_pending_notifies, NULL); - - g_variant_builder_init (¬ifies, G_VARIANT_TYPE_VARDICT); - for (i = 0; i < n; i++) - g_variant_builder_add (¬ifies, "{sv}", values[i].property_name, values[i].variant); - variant = g_variant_ref_sink (g_variant_builder_end (¬ifies)); - - - if (_LOG2D_ENABLED ()) { - gs_free char *notification = g_variant_print (variant, TRUE); - - _LOG2D ("type %s, iface %s: %s", - G_OBJECT_TYPE_NAME (self), G_OBJECT_TYPE_NAME (ifdata->interface), - notification); - } - - g_signal_emit (ifdata->interface, ifdata->property_changed_signal_id, 0, variant); - - g_hash_table_remove_all (ifdata->pending_notifies); - } - - return G_SOURCE_REMOVE; -} - -static void -nm_exported_object_notify (GObject *object, GParamSpec *pspec) -{ - NMExportedObject *self = (NMExportedObject *) object; - NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - NMExportedObjectClassInfo *classinfo; - GType type; - const char *dbus_property_name = NULL; - GValue value = G_VALUE_INIT; - GVariant *value_variant; - InterfaceData *ifdata = NULL; - const GVariantType *vtype; - guint i, j; - - /* Hook to emit deprecated "PropertiesChanged" signal on NetworkManager interfaces. - * This is to preserve deprecated D-Bus API, nowadays we use instead - * the "PropertiesChanged" signal of "org.freedesktop.DBus.Properties". */ - - if (priv->num_interfaces == 0) - return; - - for (type = G_OBJECT_TYPE (self); type; type = g_type_parent (type)) { - classinfo = g_type_get_qdata (type, nm_exported_object_class_info_quark ()); - if (!classinfo) - continue; - - dbus_property_name = g_hash_table_lookup (classinfo->properties, pspec->name); - if (dbus_property_name) - break; - } - if (!dbus_property_name) { - _LOG2T ("ignoring notification for prop %s on type %s", - pspec->name, G_OBJECT_TYPE_NAME (self)); - return; - } - - for (i = 0; i < priv->num_interfaces; i++) { - GDBusInterfaceInfo *iinfo; - - ifdata = &priv->interfaces[i]; - iinfo = g_dbus_interface_skeleton_get_info (ifdata->interface); - for (j = 0; iinfo->properties[j]; j++) { - if (nm_streq (iinfo->properties[j]->name, dbus_property_name)) { - vtype = G_VARIANT_TYPE (iinfo->properties[j]->signature); - goto vtype_found; - } - } - } - g_return_if_reached (); - -vtype_found: - g_value_init (&value, pspec->value_type); - g_object_get_property ((GObject *) self, pspec->name, &value); - value_variant = g_dbus_gvalue_to_gvariant (&value, vtype); - g_value_unset (&value); - - if ( ( NM_IS_DEVICE (self) - && !NMDBUS_IS_DEVICE_STATISTICS_SKELETON (ifdata->interface)) - || NM_IS_ACTIVE_CONNECTION (self)) { - /* This PropertiesChanged signal is nodaways deprecated in favor - * of "org.freedesktop.DBus.Properties"'s PropertiesChanged signal. - * This function solely exists to raise the NM version of PropertiesChanged. - * - * With types exported on D-Bus that are implemented as derived - * types in glib (NMDevice and NMActiveConnection), multiple types - * in the inheritance tree define a "PropertiesChanged" signal. - * - * In 1.0.0 and earlier, the signal was emitted once for every interface - * that had a "PropertiesChanged" signal. For example: - * - NMDeviceEthernet.HwAddress was emitted on "fdo.NM.Device.Ethernet" - * and "fdo.NM.Device.Veth" (if the device was of type NMDeviceVeth). - * - NMVpnConnection.VpnState was emitted on "fdo.NM.Connecion.Active" - * and "fdo.NM.VPN.Connection". - * - * NMDevice is special in that it didn't have a "PropertiesChanged" signal. - * Thus, a change to "NMDevice.StateReason" would be emitted on "fdo.NM.Device.Ethernet" - * and also on "fdo.NM.Device.Veth" (in case of a device of type NMDeviceVeth). - * - * The releases of 1.2.0 and 1.4.0 failed to realize above and broke this behavior. - * This special handling here is to bring back the 1.0.0 behavior. - * - * The Device.Statistics signal is special, because it was only added with 1.4.0 - * and didn't have above behavior. So let's save the overhead of emitting multiple - * deprecated signals for wrong interfaces. */ - for (i = 0, j = 0; i < priv->num_interfaces; i++) { - ifdata = &priv->interfaces[i]; - if ( ifdata->property_changed_signal_id - && !NMDBUS_IS_DEVICE_STATISTICS_SKELETON (ifdata->interface)) { - j++; - g_hash_table_insert (ifdata->pending_notifies, - (gpointer) dbus_property_name, - g_variant_ref (value_variant)); - } - } - nm_assert (j > 0); - g_variant_unref (value_variant); - } else if (ifdata->property_changed_signal_id) { - /* @dbus_property_name is inside classinfo and never freed, thus we don't clone it. - * Also, we do a pointer, not string comparison. */ - g_hash_table_insert (ifdata->pending_notifies, - (gpointer) dbus_property_name, - value_variant); - } else - g_variant_unref (value_variant); - - if (!priv->notify_idle_id) - priv->notify_idle_id = g_idle_add (idle_emit_properties_changed, self); -} - -/*****************************************************************************/ - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMExportedObject *self = NM_EXPORTED_OBJECT (object); - NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - switch (prop_id) { - case PROP_PATH: - g_value_set_string (value, priv->path); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_exported_object_init (NMExportedObject *self) -{ - NMExportedObjectPrivate *priv; - - priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_EXPORTED_OBJECT, NMExportedObjectPrivate); - self->_priv = priv; -} - -static void -constructed (GObject *object) -{ - NMExportedObjectClass *klass; - - G_OBJECT_CLASS (nm_exported_object_parent_class)->constructed (object); - -#ifdef _ASSERT_NO_EARLY_EXPORT - NM_EXPORTED_OBJECT_GET_PRIVATE (NM_EXPORTED_OBJECT (object))->_constructed = TRUE; -#endif - - klass = NM_EXPORTED_OBJECT_GET_CLASS (object); - - if (klass->export_on_construction) - nm_exported_object_export ((NMExportedObject *) object); -} - -static void -dispose (GObject *object) -{ - NMExportedObject *self = NM_EXPORTED_OBJECT (object); - NMExportedObjectPrivate *priv = NM_EXPORTED_OBJECT_GET_PRIVATE (self); - - /* Objects should have already been unexported by their owner, unless - * we are quitting, where many objects stick around until exit. - */ - if (!quitting) { - if (priv->path) { - g_warn_if_reached (); - nm_exported_object_unexport (self); - } - } else if (nm_clear_g_free (&priv->path)) - _notify (self, PROP_PATH); - - nm_clear_g_source (&priv->notify_idle_id); - - G_OBJECT_CLASS (nm_exported_object_parent_class)->dispose (object); -} - -static void -nm_exported_object_class_init (NMExportedObjectClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (NMExportedObjectPrivate)); - - object_class->constructed = constructed; - object_class->notify = nm_exported_object_notify; - object_class->dispose = dispose; - object_class->get_property = get_property; - - obj_properties[PROP_PATH] = - g_param_spec_string (NM_EXPORTED_OBJECT_PATH, "", "", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); -} diff --git a/src/nm-exported-object.h b/src/nm-exported-object.h deleted file mode 100644 index 47559a20f0..0000000000 --- a/src/nm-exported-object.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2014 Red Hat, Inc. - */ - -#ifndef NM_EXPORTED_OBJECT_H -#define NM_EXPORTED_OBJECT_H - -/*****************************************************************************/ - -#define NM_EXPORT_PATH_NUMBERED(basepath) ""basepath"/%llu" - -char *nm_exported_object_skeletonify_method_name (const char *dbus_method_name); - -typedef struct { - GType dbus_skeleton_type; - char *method_name; - GCallback impl; -} NMExportedObjectDBusMethodImpl; - -GDBusInterfaceSkeleton *nm_exported_object_skeleton_create (GType dbus_skeleton_type, - GObjectClass *object_class, - const NMExportedObjectDBusMethodImpl *methods, - guint methods_len, - GObject *target); -void nm_exported_object_skeleton_release (GDBusInterfaceSkeleton *interface); - -/*****************************************************************************/ - -#define NM_TYPE_EXPORTED_OBJECT (nm_exported_object_get_type ()) -#define NM_EXPORTED_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_EXPORTED_OBJECT, NMExportedObject)) -#define NM_EXPORTED_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_EXPORTED_OBJECT, NMExportedObjectClass)) -#define NM_IS_EXPORTED_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_EXPORTED_OBJECT)) -#define NM_IS_EXPORTED_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_EXPORTED_OBJECT)) -#define NM_EXPORTED_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_EXPORTED_OBJECT, NMExportedObjectClass)) - -#define NM_EXPORTED_OBJECT_PATH "path" - -struct _NMExportedObjectPrivate; - -struct _NMExportedObject { - GDBusObjectSkeleton parent; - struct _NMExportedObjectPrivate *_priv; -}; - -typedef struct { - GDBusObjectSkeletonClass parent; - - const char *export_path; - char export_on_construction; -} NMExportedObjectClass; - -GType nm_exported_object_get_type (void); - -void nm_exported_object_class_set_quitting (void); - -void nm_exported_object_class_add_interface (NMExportedObjectClass *object_class, - GType dbus_skeleton_type, - ...) G_GNUC_NULL_TERMINATED; - -const char *nm_exported_object_export (NMExportedObject *self); -const char *nm_exported_object_get_path (NMExportedObject *self); -gboolean nm_exported_object_is_exported (NMExportedObject *self); -void nm_exported_object_unexport (NMExportedObject *self); -GDBusInterfaceSkeleton *nm_exported_object_get_interface_by_type (NMExportedObject *self, GType interface_type); - -void _nm_exported_object_clear_and_unexport (NMExportedObject **location); -#define nm_exported_object_clear_and_unexport(location) _nm_exported_object_clear_and_unexport ((NMExportedObject **) (location)) - -#endif /* NM_EXPORTED_OBJECT_H */ diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 7f543eb077..c85a054ae9 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -629,21 +629,34 @@ nm_config_get_configure_and_quit (NMConfig *config) return TRUE; } -NMBusManager * -nm_bus_manager_get (void) +NMDBusManager * +nm_dbus_manager_get (void) +{ + return NULL; +} + +void +_nm_dbus_manager_obj_export (NMDBusObject *obj) +{ +} + +void +_nm_dbus_manager_obj_unexport (NMDBusObject *obj) { - return GUINT_TO_POINTER (1); } void -nm_bus_manager_register_object (NMBusManager *bus_manager, - GDBusObjectSkeleton *object) +_nm_dbus_manager_obj_notify (NMDBusObject *obj, + guint n_pspecs, + const GParamSpec *const*pspecs) { } void -nm_bus_manager_unregister_object (NMBusManager *bus_manager, - GDBusObjectSkeleton *object) +_nm_dbus_manager_obj_emit_signal (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const GDBusSignalInfo *signal_info, + GVariant *args) { } diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 9893b14084..3fc176ca38 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -36,8 +36,7 @@ #include "platform/nm-platform-utils.h" #include "NetworkManagerUtils.h" #include "nm-core-internal.h" - -#include "introspection/org.freedesktop.NetworkManager.IP4Config.h" +#include "nm-dbus-object.h" /*****************************************************************************/ @@ -318,15 +317,15 @@ typedef struct { } NMIP4ConfigPrivate; struct _NMIP4Config { - NMExportedObject parent; + NMDBusObject parent; NMIP4ConfigPrivate _priv; }; struct _NMIP4ConfigClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_DBUS_OBJECT) #define NM_IP4_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP4Config, NM_IS_IP4_CONFIG) @@ -1954,7 +1953,7 @@ nm_ip4_config_dump (const NMIP4Config *self, const char *detail) return; } - str = nm_exported_object_get_path (NM_EXPORTED_OBJECT (self)); + str = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); if (str) g_message (" path: %s", str); @@ -3212,13 +3211,37 @@ finalize (GObject *object) nm_dedup_multi_index_unref (priv->multi_idx); } +static const NMDBusInterfaceInfoExtended interface_info_ip4_config = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_IP4_CONFIG, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Addresses", "aau", NM_IP4_CONFIG_ADDRESSES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AddressData", "aa{sv}", NM_IP4_CONFIG_ADDRESS_DATA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Gateway", "s", NM_IP4_CONFIG_GATEWAY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Routes", "aau", NM_IP4_CONFIG_ROUTES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RouteData", "aa{sv}", NM_IP4_CONFIG_ROUTE_DATA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Nameservers", "au", NM_IP4_CONFIG_NAMESERVERS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Domains", "as", NM_IP4_CONFIG_DOMAINS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Searches", "as", NM_IP4_CONFIG_SEARCHES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsOptions", "as", NM_IP4_CONFIG_DNS_OPTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsPriority", "i", NM_IP4_CONFIG_DNS_PRIORITY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WinsServers", "au", NM_IP4_CONFIG_WINS_SERVERS), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_ip4_config_class_init (NMIP4ConfigClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (config_class); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/IP4Config"); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/IP4Config"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_ip4_config); object_class->get_property = get_property; object_class->set_property = set_property; @@ -3298,8 +3321,4 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (config_class), - NMDBUS_TYPE_IP4_CONFIG_SKELETON, - NULL); } diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index d4c67d8943..ec525526d2 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -23,7 +23,6 @@ #include "nm-setting-connection.h" -#include "nm-exported-object.h" #include "nm-setting-ip4-config.h" #include "nm-utils/nm-dedup-multi.h" diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 8d2d9471a4..184c318c4f 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -38,8 +38,7 @@ #include "NetworkManagerUtils.h" #include "nm-ip4-config.h" #include "ndisc/nm-ndisc.h" - -#include "introspection/org.freedesktop.NetworkManager.IP6Config.h" +#include "nm-dbus-object.h" /*****************************************************************************/ @@ -82,15 +81,15 @@ typedef struct { } NMIP6ConfigPrivate; struct _NMIP6Config { - NMExportedObject parent; + NMDBusObject parent; NMIP6ConfigPrivate _priv; }; struct _NMIP6ConfigClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_DBUS_OBJECT) #define NM_IP6_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMIP6Config, NM_IS_IP6_CONFIG) @@ -1486,7 +1485,7 @@ nm_ip6_config_dump (const NMIP6Config *self, const char *detail) g_message ("--------- NMIP6Config %p (%s)", self, detail); - str = nm_exported_object_get_path (NM_EXPORTED_OBJECT (self)); + str = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); if (str) g_message (" path: %s", str); @@ -2773,13 +2772,36 @@ finalize (GObject *object) nm_dedup_multi_index_unref (priv->multi_idx); } +static const NMDBusInterfaceInfoExtended interface_info_ip6_config = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_IP6_CONFIG, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Addresses", "a(ayuay)", NM_IP6_CONFIG_ADDRESSES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AddressData", "aa{sv}", NM_IP6_CONFIG_ADDRESS_DATA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Gateway", "s", NM_IP6_CONFIG_GATEWAY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Routes", "a(ayuayu)", NM_IP6_CONFIG_ROUTES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RouteData", "aa{sv}", NM_IP6_CONFIG_ROUTE_DATA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Nameservers", "aay", NM_IP6_CONFIG_NAMESERVERS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Domains", "as", NM_IP6_CONFIG_DOMAINS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Searches", "as", NM_IP6_CONFIG_SEARCHES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsOptions", "as", NM_IP6_CONFIG_DNS_OPTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsPriority", "i", NM_IP6_CONFIG_DNS_PRIORITY), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_ip6_config_class_init (NMIP6ConfigClass *config_class) { GObjectClass *object_class = G_OBJECT_CLASS (config_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (config_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (config_class); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/IP6Config"); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/IP6Config"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_ip6_config); object_class->get_property = get_property; object_class->set_property = set_property; @@ -2853,8 +2875,4 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (config_class), - NMDBUS_TYPE_IP6_CONFIG_SKELETON, - NULL); } diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 34d98b034a..882047d1c1 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -23,7 +23,6 @@ #include <netinet/in.h> -#include "nm-exported-object.h" #include "nm-setting-ip6-config.h" #include "nm-utils/nm-dedup-multi.h" diff --git a/src/nm-manager.c b/src/nm-manager.c index 06a64e257c..8aec327703 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -56,12 +56,10 @@ #include "nm-dbus-compat.h" #include "nm-checkpoint.h" #include "nm-checkpoint-manager.h" +#include "nm-dbus-object.h" #include "nm-dispatcher.h" #include "NetworkManagerUtils.h" -#include "introspection/org.freedesktop.NetworkManager.h" -#include "introspection/org.freedesktop.NetworkManager.Device.h" - /*****************************************************************************/ typedef struct { @@ -80,8 +78,6 @@ enum { INTERNAL_DEVICE_ADDED, DEVICE_REMOVED, INTERNAL_DEVICE_REMOVED, - STATE_CHANGED, - CHECK_PERMISSIONS, ACTIVE_CONNECTION_ADDED, ACTIVE_CONNECTION_REMOVED, CONFIGURE_QUIT, @@ -141,7 +137,6 @@ typedef struct { NMHostnameManager *hostname_manager; - NMBusManager *dbus_mgr; struct { GDBusConnection *connection; guint id; @@ -185,15 +180,15 @@ typedef struct { } NMManagerPrivate; struct _NMManager { - NMExportedObject parent; + NMDBusObject parent; NMManagerPrivate _priv; }; typedef struct { - NMExportedObjectClass parent; + NMDBusObjectClass parent; } NMManagerClass; -G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMManager, nm_manager, NM_TYPE_DBUS_OBJECT) #define NM_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMManager, NM_IS_MANAGER) @@ -270,8 +265,18 @@ NM_DEFINE_SINGLETON_INSTANCE (NMManager); /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_manager; +static const GDBusSignalInfo signal_info_check_permissions; +static const GDBusSignalInfo signal_info_state_changed; +static const GDBusSignalInfo signal_info_device_added; +static const GDBusSignalInfo signal_info_device_removed; + static gboolean add_device (NMManager *self, NMDevice *device, GError **error); +static void _emit_device_added_removed (NMManager *self, + NMDevice *device, + gboolean is_added); + static NMActiveConnection *_new_active_connection (NMManager *self, NMConnection *connection, NMConnection *applied, @@ -604,7 +609,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) nm_assert (NM_IS_ACTIVE_CONNECTION (active)); nm_assert (c_list_contains (&priv->active_connections_lst_head, &active->active_connections_lst)); - notify = nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active)); + notify = nm_dbus_object_is_exported (NM_DBUS_OBJECT (active)); c_list_unlink (&active->active_connections_lst); g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active); @@ -614,7 +619,7 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) connection = nm_g_object_ref (nm_active_connection_get_settings_connection (active)); - nm_exported_object_clear_and_unexport (&active); + nm_dbus_object_clear_and_unexport (&active); if (connection) _delete_volatile_connection_do (self, connection); @@ -710,8 +715,8 @@ active_connection_add (NMManager *self, G_CALLBACK (active_connection_default_changed), self); - if (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (active))) - nm_exported_object_export (NM_EXPORTED_OBJECT (active)); + if (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (active))) + nm_dbus_object_export (NM_DBUS_OBJECT (active)); g_signal_emit (self, signals[ACTIVE_CONNECTION_ADDED], 0, active); @@ -801,7 +806,7 @@ active_connection_get_by_path (NMManager *manager, const char *path) nm_assert (path); c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) { - if (nm_streq0 (path, nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac)))) + if (nm_streq0 (path, nm_dbus_object_get_path (NM_DBUS_OBJECT (ac)))) return ac; } return NULL; @@ -888,24 +893,27 @@ out: } static void -impl_manager_reload (NMManager *self, - GDBusMethodInvocation *context, - guint32 flags) -{ - NMManagerPrivate *priv; +impl_manager_reload (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; - GError *error = NULL; - - g_return_if_fail (NM_IS_MANAGER (self)); + guint32 flags; - priv = NM_MANAGER_GET_PRIVATE (self); + g_variant_get (parameters, "(u)", &flags); - chain = nm_auth_chain_new_context (context, _reload_auth_cb, self); + chain = nm_auth_chain_new_context (invocation, _reload_auth_cb, self); if (!chain) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to authenticate request"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request"); return; } @@ -924,7 +932,7 @@ nm_manager_get_device_by_path (NMManager *manager, const char *path) g_return_val_if_fail (path != NULL, NULL); for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - if (!strcmp (nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)), path)) + if (!strcmp (nm_dbus_object_get_path (NM_DBUS_OBJECT (iter->data)), path)) return NM_DEVICE (iter->data); } return NULL; @@ -1076,7 +1084,11 @@ set_state (NMManager *self, NMState state) _LOGI (LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string (state)); _notify (self, PROP_STATE); - g_signal_emit (self, signals[STATE_CHANGED], 0, priv->state); + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_manager, + &signal_info_state_changed, + "(u)", + (guint32) priv->state); } static NMState @@ -1338,8 +1350,7 @@ remove_device (NMManager *self, * Control that by passing @unconfigure_ip_config. */ nm_device_removed (device, unconfigure_ip_config); - g_signal_emit (self, signals[DEVICE_REMOVED], 0, device); - _notify (self, PROP_DEVICES); + _emit_device_added_removed (self, device, FALSE); } else { /* unrealize() does not release a slave device from master and * clear IP configurations, do it here */ @@ -1349,7 +1360,7 @@ remove_device (NMManager *self, g_signal_emit (self, signals[INTERNAL_DEVICE_REMOVED], 0, device); _notify (self, PROP_ALL_DEVICES); - nm_exported_object_clear_and_unexport (&device); + nm_dbus_object_clear_and_unexport (&device); check_if_startup_complete (self); } @@ -2407,17 +2418,31 @@ device_iface_changed (NMDevice *device, retry_connections_for_parent_device (self, device); } +static void +_emit_device_added_removed (NMManager *self, + NMDevice *device, + gboolean is_added) +{ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_manager, + is_added + ? &signal_info_device_added + : &signal_info_device_removed, + "(o)", + nm_dbus_object_get_path (NM_DBUS_OBJECT (device))); + g_signal_emit (self, + signals[is_added ? DEVICE_ADDED : DEVICE_REMOVED], + 0, + device); + _notify (self, PROP_DEVICES); +} static void device_realized (NMDevice *device, GParamSpec *pspec, NMManager *self) { - gboolean real = nm_device_is_real (device); - - /* Emit D-Bus signals */ - g_signal_emit (self, signals[real ? DEVICE_ADDED : DEVICE_REMOVED], 0, device); - _notify (self, PROP_DEVICES); + _emit_device_added_removed (self, device, nm_device_is_real (device)); } #if WITH_CONCHECK @@ -2588,7 +2613,7 @@ add_device (NMManager *self, NMDevice *device, GError **error) NM_UNMANAGED_SLEEPING, manager_sleeping (self)); - dbus_path = nm_exported_object_export (NM_EXPORTED_OBJECT (device)); + dbus_path = nm_dbus_object_export (NM_DBUS_OBJECT (device)); _LOG2I (LOGD_DEVICE, device, "new %s device (%s)", type_desc, dbus_path); nm_settings_device_added (priv->settings, device); @@ -2967,7 +2992,7 @@ _get_devices (NMManager *self, for (i = 0, iter = priv->devices; iter; iter = iter->next) { const char *path; - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (iter->data)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (iter->data)); if ( path && (all_devices || nm_device_is_real (iter->data))) paths[i++] = path; @@ -2979,40 +3004,63 @@ _get_devices (NMManager *self, } static void -impl_manager_get_devices (NMManager *self, - GDBusMethodInvocation *context) +impl_manager_get_devices (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - _get_devices (self, context, FALSE); + NMManager *self = NM_MANAGER (obj); + + _get_devices (self, invocation, FALSE); } static void -impl_manager_get_all_devices (NMManager *self, - GDBusMethodInvocation *context) +impl_manager_get_all_devices (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - _get_devices (self, context, TRUE); + NMManager *self = NM_MANAGER (obj); + + _get_devices (self, invocation, TRUE); } static void -impl_manager_get_device_by_ip_iface (NMManager *self, - GDBusMethodInvocation *context, - const char *iface) -{ +impl_manager_get_device_by_ip_iface (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); NMDevice *device; const char *path = NULL; + const char *iface; + + g_variant_get (parameters, "(&s)", &iface); device = find_device_by_ip_iface (self, iface); if (device) - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (device)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (device)); - if (path == NULL) { - g_dbus_method_invocation_return_error (context, + if (!path) { + g_dbus_method_invocation_return_error (invocation, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, "No device found for the requested iface."); - } else { - g_dbus_method_invocation_return_value (context, - g_variant_new ("(o)", path)); + return; } + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(o)", path)); } static gboolean @@ -3524,11 +3572,11 @@ _internal_activate_vpn (NMManager *self, NMActiveConnection *active, GError **er { nm_assert (NM_IS_VPN_CONNECTION (active)); - nm_exported_object_export (NM_EXPORTED_OBJECT (active)); + nm_dbus_object_export (NM_DBUS_OBJECT (active)); if (!nm_vpn_manager_activate_connection (NM_MANAGER_GET_PRIVATE (self)->vpn_manager, NM_VPN_CONNECTION (active), error)) { - nm_exported_object_unexport (NM_EXPORTED_OBJECT (active)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (active)); return FALSE; } @@ -3771,7 +3819,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * _LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s", nm_settings_connection_get_id (connection), master_ac, - nm_exported_object_get_path (NM_EXPORTED_OBJECT (master_ac)) ?: ""); + nm_dbus_object_get_path (NM_DBUS_OBJECT (master_ac)) ?: ""); } /* Check slaves for master connection and possibly activate them */ @@ -3881,7 +3929,7 @@ _new_vpn_active_connection (NMManager *self, return (NMActiveConnection *) nm_vpn_connection_new (settings_connection, device, - nm_exported_object_get_path (NM_EXPORTED_OBJECT (parent)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (parent)), subject); } @@ -4219,7 +4267,7 @@ _activation_auth_done (NMActiveConnection *active, FALSE); g_dbus_method_invocation_return_value (context, g_variant_new ("(o)", - nm_exported_object_get_path (NM_EXPORTED_OBJECT (active)))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (active)))); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, TRUE, NULL, subject, NULL); return; @@ -4240,12 +4288,15 @@ _activation_auth_done (NMActiveConnection *active, } static void -impl_manager_activate_connection (NMManager *self, - GDBusMethodInvocation *context, - const char *connection_path, - const char *device_path, - const char *specific_object_path) -{ +impl_manager_activate_connection (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); gs_unref_object NMActiveConnection *active = NULL; gs_unref_object NMAuthSubject *subject = NULL; @@ -4253,6 +4304,11 @@ impl_manager_activate_connection (NMManager *self, NMDevice *device = NULL; gboolean is_vpn = FALSE; GError *error = NULL; + const char *connection_path; + const char *device_path; + const char *specific_object_path; + + g_variant_get (parameters, "(&o&o&o)", &connection_path, &device_path, &specific_object_path); /* Normalize object paths */ if (g_strcmp0 (connection_path, "/") == 0) @@ -4295,7 +4351,7 @@ impl_manager_activate_connection (NMManager *self, } subject = validate_activation_request (self, - context, + invocation, NM_CONNECTION (connection), device_path, &device, @@ -4322,7 +4378,7 @@ impl_manager_activate_connection (NMManager *self, NULL, _activation_auth_done, self, - context); + invocation); return; error: @@ -4330,7 +4386,7 @@ error: nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL, subject, error->message); } - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } /*****************************************************************************/ @@ -4371,7 +4427,7 @@ activation_add_done (NMSettings *settings, context, g_variant_new ("(oo)", nm_connection_get_path (NM_CONNECTION (new_connection)), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (active)))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (active)))); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD_ACTIVATE, nm_active_connection_get_settings_connection (active), TRUE, @@ -4448,12 +4504,15 @@ _add_and_activate_auth_done (NMActiveConnection *active, } static void -impl_manager_add_and_activate_connection (NMManager *self, - GDBusMethodInvocation *context, - GVariant *settings, - const char *device_path, - const char *specific_object_path) -{ +impl_manager_add_and_activate_connection (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMConnection *connection = NULL; GSList *all_connections = NULL; @@ -4462,6 +4521,11 @@ impl_manager_add_and_activate_connection (NMManager *self, GError *error = NULL; NMDevice *device = NULL; gboolean vpn = FALSE; + gs_unref_variant GVariant *settings = NULL; + const char *device_path; + const char *specific_object_path; + + g_variant_get (parameters, "(@a{sa{sv}}&o&o)", &settings, &device_path, &specific_object_path); /* Normalize object paths */ if (g_strcmp0 (specific_object_path, "/") == 0) @@ -4481,7 +4545,7 @@ impl_manager_add_and_activate_connection (NMManager *self, _nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL); subject = validate_activation_request (self, - context, + invocation, connection, device_path, &device, @@ -4549,7 +4613,7 @@ impl_manager_add_and_activate_connection (NMManager *self, connection, g_object_unref); - nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, context); + nm_active_connection_authorize (active, connection, _add_and_activate_auth_done, self, invocation); g_object_unref (subject); return; @@ -4561,7 +4625,7 @@ error: g_clear_object (&active); g_assert (error); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } /*****************************************************************************/ @@ -4661,10 +4725,15 @@ deactivate_net_auth_done_cb (NMAuthChain *chain, } static void -impl_manager_deactivate_connection (NMManager *self, - GDBusMethodInvocation *context, - const char *active_path) -{ +impl_manager_deactivate_connection (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *ac; NMSettingsConnection *connection = NULL; @@ -4672,6 +4741,9 @@ impl_manager_deactivate_connection (NMManager *self, NMAuthSubject *subject = NULL; NMAuthChain *chain; char *error_desc = NULL; + const char *active_path; + + g_variant_get (parameters, "(&o)", &active_path); /* Find the connection by its object path */ ac = active_connection_get_by_path (self, active_path); @@ -4686,7 +4758,7 @@ impl_manager_deactivate_connection (NMManager *self, } /* Validate the caller */ - subject = nm_auth_subject_new_unix_process_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (invocation); if (!subject) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -4706,7 +4778,7 @@ impl_manager_deactivate_connection (NMManager *self, } /* Validate the user request */ - chain = nm_auth_chain_new_subject (subject, context, deactivate_net_auth_done_cb, self); + chain = nm_auth_chain_new_subject (subject, invocation, deactivate_net_auth_done_cb, self); if (!chain) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -4724,7 +4796,7 @@ done: nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL, subject, error->message); } - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } g_clear_object (&subject); } @@ -5001,22 +5073,27 @@ sleep_auth_done_cb (NMAuthChain *chain, #endif static void -impl_manager_sleep (NMManager *self, - GDBusMethodInvocation *context, - gboolean do_sleep) -{ - NMManagerPrivate *priv; +impl_manager_sleep (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GError *error = NULL; gs_unref_object NMAuthSubject *subject = NULL; #if 0 NMAuthChain *chain; const char *error_desc = NULL; #endif + gboolean do_sleep; - g_return_if_fail (NM_IS_MANAGER (self)); + g_variant_get (parameters, "(b)", &do_sleep); - priv = NM_MANAGER_GET_PRIVATE (self); - subject = nm_auth_subject_new_unix_process_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (invocation); if (priv->sleeping == do_sleep) { error = g_error_new (NM_MANAGER_ERROR, @@ -5024,7 +5101,7 @@ impl_manager_sleep (NMManager *self, "Already %s", do_sleep ? "asleep" : "awake"); nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", FALSE, subject, error->message); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -5038,11 +5115,11 @@ impl_manager_sleep (NMManager *self, */ _internal_sleep (self, do_sleep); nm_audit_log_control_op (NM_AUDIT_OP_SLEEP_CONTROL, do_sleep ? "on" : "off", TRUE, subject, NULL); - g_dbus_method_invocation_return_value (context, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); return; #if 0 - chain = nm_auth_chain_new (context, sleep_auth_done_cb, self, &error_desc); + chain = nm_auth_chain_new (invocation, sleep_auth_done_cb, self, &error_desc); if (chain) { priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "sleep", GUINT_TO_POINTER (do_sleep), NULL); @@ -5051,7 +5128,7 @@ impl_manager_sleep (NMManager *self, error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, error_desc); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } #endif } @@ -5133,17 +5210,21 @@ enable_net_done_cb (NMAuthChain *chain, } static void -impl_manager_enable (NMManager *self, - GDBusMethodInvocation *context, - gboolean enable) -{ - NMManagerPrivate *priv; +impl_manager_enable (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; GError *error = NULL; + gboolean enable; - g_return_if_fail (NM_IS_MANAGER (self)); - - priv = NM_MANAGER_GET_PRIVATE (self); + g_variant_get (parameters, "(b)", &enable); if (priv->net_enabled == enable) { error = g_error_new (NM_MANAGER_ERROR, @@ -5152,7 +5233,7 @@ impl_manager_enable (NMManager *self, goto done; } - chain = nm_auth_chain_new_context (context, enable_net_done_cb, self); + chain = nm_auth_chain_new_context (invocation, enable_net_done_cb, self); if (!chain) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -5166,7 +5247,7 @@ impl_manager_enable (NMManager *self, done: if (error) - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } /* Permissions */ @@ -5237,19 +5318,24 @@ get_permissions_done_cb (NMAuthChain *chain, } static void -impl_manager_get_permissions (NMManager *self, - GDBusMethodInvocation *context) -{ +impl_manager_get_permissions (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; - GError *error = NULL; - chain = nm_auth_chain_new_context (context, get_permissions_done_cb, self); + chain = nm_auth_chain_new_context (invocation, get_permissions_done_cb, self); if (!chain) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to authenticate request."); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); return; } @@ -5273,49 +5359,69 @@ impl_manager_get_permissions (NMManager *self, } static void -impl_manager_get_state (NMManager *self, - GDBusMethodInvocation *context) +impl_manager_state (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMManager *self = NM_MANAGER (obj); + nm_manager_update_state (self); - g_dbus_method_invocation_return_value (context, + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", NM_MANAGER_GET_PRIVATE (self)->state)); } static void -impl_manager_set_logging (NMManager *self, - GDBusMethodInvocation *context, - const char *level, - const char *domains) -{ +impl_manager_set_logging (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); GError *error = NULL; + const char *level; + const char *domains; /* The permission is already enforced by the D-Bus daemon, but we ensure * that the caller is still alive so that clients are forced to wait and * we'll be able to switch to polkit without breaking behavior. */ - if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_manager_get (), + invocation, + G_MAXULONG, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED)) return; + g_variant_get (parameters, "(&s&s)", &level, &domains); + if (nm_logging_setup (level, domains, NULL, &error)) { _LOGI (LOGD_CORE, "logging: level '%s' domains '%s'", nm_logging_level_to_string (), nm_logging_domains_to_string ()); } if (error) - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); else - g_dbus_method_invocation_return_value (context, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); } static void -impl_manager_get_logging (NMManager *manager, - GDBusMethodInvocation *context) -{ - g_dbus_method_invocation_return_value (context, +impl_manager_get_logging (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(ss)", nm_logging_level_to_string (), nm_logging_domains_to_string ())); @@ -5398,20 +5504,24 @@ check_connectivity_auth_done_cb (NMAuthChain *chain, } static void -impl_manager_check_connectivity (NMManager *self, - GDBusMethodInvocation *context) -{ +impl_manager_check_connectivity (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; - GError *error = NULL; - /* Validate the request */ - chain = nm_auth_chain_new_context (context, check_connectivity_auth_done_cb, self); + chain = nm_auth_chain_new_context (invocation, check_connectivity_auth_done_cb, self); if (!chain) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to authenticate request."); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal(invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); return; } @@ -5725,318 +5835,134 @@ policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer u } } -#define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied" +/*****************************************************************************/ typedef struct { NMManager *self; - GDBusConnection *connection; - GDBusMessage *message; - NMAuthSubject *subject; - const char *permission; - const char *audit_op; - char *audit_prop_value; - GType interface_type; - const char *glib_propname; -} PropertyFilterData; + NMDBusObject *obj; + const NMDBusInterfaceInfoExtended *interface_info; + const NMDBusPropertyInfoExtended *property_info; + GVariant *value; + guint64 export_version_id; +} DBusSetPropertyHandle; -static void -free_property_filter_data (PropertyFilterData *pfd) -{ - g_object_unref (pfd->self); - g_object_unref (pfd->connection); - g_object_unref (pfd->message); - g_clear_object (&pfd->subject); - g_free (pfd->audit_prop_value); - g_slice_free (PropertyFilterData, pfd); -} +#define NM_PERM_DENIED_ERROR "org.freedesktop.NetworkManager.PermissionDenied" static void -prop_set_auth_done_cb (NMAuthChain *chain, - GError *error, - GDBusMethodInvocation *context, /* NULL */ - gpointer user_data) +_dbus_set_property_auth_cb (NMAuthChain *chain, + GError *error, + GDBusMethodInvocation *invocation, + gpointer user_data) { - PropertyFilterData *pfd = user_data; - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self); + DBusSetPropertyHandle *handle_data = user_data; + gs_unref_object NMDBusObject *obj = handle_data->obj; + const NMDBusInterfaceInfoExtended *interface_info = handle_data->interface_info; + const NMDBusPropertyInfoExtended *property_info = handle_data->property_info; + gs_unref_variant GVariant *value = handle_data->value; + guint64 export_version_id = handle_data->export_version_id; + gs_unref_object NMManager *self = handle_data->self; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthCallResult result; - GDBusMessage *reply = NULL; - const char *error_message; + const char *error_name = NULL; + const char *error_message = NULL; gs_unref_object NMExportedObject *object = NULL; - const NMGlobalDnsConfig *global_dns; - gs_unref_variant GVariant *value = NULL; - GVariant *args; + GValue gvalue; + + g_slice_free (DBusSetPropertyHandle, handle_data); priv->auth_chains = g_slist_remove (priv->auth_chains, chain); - result = nm_auth_chain_get_result (chain, pfd->permission); - if (error || (result != NM_AUTH_CALL_RESULT_YES)) { - reply = g_dbus_message_new_method_error_literal (pfd->message, - NM_PERM_DENIED_ERROR, - (error_message = "Not authorized to perform this operation")); - if (error) - error_message = error->message; - goto done; - } + result = nm_auth_chain_get_result (chain, property_info->writable.permission); - object = NM_EXPORTED_OBJECT (nm_bus_manager_get_registered_object (priv->dbus_mgr, - g_dbus_message_get_path (pfd->message))); - if (!object) { - reply = g_dbus_message_new_method_error_literal (pfd->message, - "org.freedesktop.DBus.Error.UnknownObject", - (error_message = "Object doesn't exist.")); - goto done; + if ( error + || result != NM_AUTH_CALL_RESULT_YES) { + error_name = NM_PERM_DENIED_ERROR; + error_message = error ? error->message : "Not authorized to perform this operation"; + goto out; } - /* do some extra type checking... */ - if (!nm_exported_object_get_interface_by_type (object, pfd->interface_type)) { - reply = g_dbus_message_new_method_error_literal (pfd->message, - "org.freedesktop.DBus.Error.InvalidArgs", - (error_message = "Object is of unexpected type.")); - goto done; + if (export_version_id != nm_dbus_object_get_export_version_id (obj)) { + error_name = "org.freedesktop.DBus.Error.UnknownObject"; + error_message = "Object was deleted while authenticating"; + goto out; } - args = g_dbus_message_get_body (pfd->message); - g_variant_get (args, "(&s&sv)", NULL, NULL, &value); - g_assert (pfd->glib_propname); + /* Handle some properties specially *sigh* */ + if ( interface_info == &interface_info_manager + && nm_streq (property_info->property_name, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) { + const NMGlobalDnsConfig *global_dns; - if (!strcmp (pfd->glib_propname, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) { - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE ("a{sv}"))); global_dns = nm_config_data_get_global_dns_config (nm_config_get_data (priv->config)); - - if (global_dns && !nm_global_dns_config_is_internal (global_dns)) { - reply = g_dbus_message_new_method_error_literal (pfd->message, - NM_PERM_DENIED_ERROR, - (error_message = "Global DNS configuration already set via configuration file")); - goto done; + if ( global_dns + && !nm_global_dns_config_is_internal (global_dns)) { + error_name = NM_PERM_DENIED_ERROR; + error_message = "Global DNS configuration already set via configuration file"; + goto out; } - /* ... but set the property on the @object itself. It would be correct to set the property - * on the skeleton interface, but as it is now, the result is the same. */ - g_object_set (object, pfd->glib_propname, value, NULL); - } else if (!strcmp (pfd->glib_propname, NM_DEVICE_STATISTICS_REFRESH_RATE_MS)) { - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_UINT32)); - /* the same here */ - g_object_set (object, pfd->glib_propname, (guint) g_variant_get_uint32 (value), NULL); - } else { - g_assert (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)); - /* the same here */ - g_object_set (object, pfd->glib_propname, g_variant_get_boolean (value), NULL); } - reply = g_dbus_message_new_method_reply (pfd->message); - g_dbus_message_set_body (reply, g_variant_new_tuple (NULL, 0)); - error_message = NULL; -done: - nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, !error_message, pfd->subject, error_message); + g_dbus_gvariant_to_gvalue (value, &gvalue); + g_object_set_property (G_OBJECT (obj), property_info->property_name, &gvalue); + g_value_unset (&gvalue); - g_dbus_connection_send_message (pfd->connection, reply, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, - NULL, NULL); - g_object_unref (reply); +out: + nm_audit_log_control_op (property_info->writable.audit_op, + property_info->property_name, + !error_message, + nm_auth_chain_get_subject (chain), + error_message); + if (error_message) + g_dbus_method_invocation_return_dbus_error (invocation, error_name, error_message); + else + g_dbus_method_invocation_return_value (invocation, NULL); nm_auth_chain_unref (chain); - - free_property_filter_data (pfd); } -static gboolean -do_set_property_check (gpointer user_data) +void +nm_manager_dbus_set_property_handle (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusPropertyInfoExtended *property_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *value, + gpointer user_data) { - PropertyFilterData *pfd = user_data; - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pfd->self); - GDBusMessage *reply = NULL; + NMManager *self = user_data; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; const char *error_message = NULL; + gs_unref_object NMAuthSubject *subject = NULL; + DBusSetPropertyHandle *handle_data; - pfd->subject = nm_auth_subject_new_unix_process_from_message (pfd->connection, pfd->message); - if (!pfd->subject) { - reply = g_dbus_message_new_method_error_literal (pfd->message, - NM_PERM_DENIED_ERROR, - (error_message = "Could not determine request UID.")); - goto out; + subject = nm_auth_subject_new_unix_process_from_context (invocation); + if (!subject) { + error_message = "Could not determine request UID"; + goto err; } - /* Validate the user request */ - chain = nm_auth_chain_new_subject (pfd->subject, NULL, prop_set_auth_done_cb, pfd); - if (!chain) { - reply = g_dbus_message_new_method_error_literal (pfd->message, - NM_PERM_DENIED_ERROR, - (error_message = "Could not authenticate request.")); - goto out; - } + handle_data = g_slice_new0 (DBusSetPropertyHandle); + handle_data->self = g_object_ref (self); + handle_data->obj = g_object_ref (obj); + handle_data->interface_info = interface_info; + handle_data->property_info = property_info; + handle_data->value = g_variant_ref (value); + handle_data->export_version_id = nm_dbus_object_get_export_version_id (obj); + chain = nm_auth_chain_new_subject (subject, invocation, _dbus_set_property_auth_cb, handle_data); priv->auth_chains = g_slist_append (priv->auth_chains, chain); - nm_auth_chain_add_call (chain, pfd->permission, TRUE); - -out: - if (reply) { - nm_audit_log_control_op (pfd->audit_op, pfd->audit_prop_value, FALSE, pfd->subject, error_message); - g_dbus_connection_send_message (pfd->connection, reply, - G_DBUS_SEND_MESSAGE_FLAGS_NONE, - NULL, NULL); - g_object_unref (reply); - free_property_filter_data (pfd); - } - - return FALSE; -} - -static GDBusMessage * -prop_filter (GDBusConnection *connection, - GDBusMessage *message, - gboolean incoming, - gpointer user_data) -{ - gs_unref_object NMManager *self = NULL; - GVariant *args; - const char *propiface = NULL; - const char *propname = NULL; - const char *glib_propname = NULL, *permission = NULL; - const char *audit_op = NULL; - GType interface_type = G_TYPE_INVALID; - PropertyFilterData *pfd; - const GVariantType *expected_type = G_VARIANT_TYPE_BOOLEAN; - gs_unref_variant GVariant *value = NULL; - - self = g_weak_ref_get (user_data); - if (!self) - return message; - - /* The sole purpose of this function is to validate property accesses on the - * NMManager object since gdbus doesn't give us this functionality. - */ - - /* Only filter org.freedesktop.DBus.Properties.Set calls */ - if ( !incoming - || g_dbus_message_get_message_type (message) != G_DBUS_MESSAGE_TYPE_METHOD_CALL - || g_strcmp0 (g_dbus_message_get_interface (message), DBUS_INTERFACE_PROPERTIES) != 0 - || g_strcmp0 (g_dbus_message_get_member (message), "Set") != 0) - return message; - - args = g_dbus_message_get_body (message); - if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("(ssv)"))) - return message; - g_variant_get (args, "(&s&sv)", &propiface, &propname, &value); - - /* Only filter calls to filtered properties, on existing objects */ - if (!strcmp (propiface, NM_DBUS_INTERFACE)) { - if (!strcmp (propname, "WirelessEnabled")) { - glib_propname = NM_MANAGER_WIRELESS_ENABLED; - permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI; - audit_op = NM_AUDIT_OP_RADIO_CONTROL; - } else if (!strcmp (propname, "WwanEnabled")) { - glib_propname = NM_MANAGER_WWAN_ENABLED; - permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN; - audit_op = NM_AUDIT_OP_RADIO_CONTROL; - } else if (!strcmp (propname, "WimaxEnabled")) { - glib_propname = NM_MANAGER_WIMAX_ENABLED; - permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX; - audit_op = NM_AUDIT_OP_RADIO_CONTROL; - } else if (!strcmp (propname, "GlobalDnsConfiguration")) { - glib_propname = NM_MANAGER_GLOBAL_DNS_CONFIGURATION; - permission = NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS; - audit_op = NM_AUDIT_OP_NET_CONTROL; - expected_type = G_VARIANT_TYPE ("a{sv}"); - } else if (!strcmp (propname, "ConnectivityCheckEnabled")) { - glib_propname = NM_MANAGER_CONNECTIVITY_CHECK_ENABLED; - permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK; - audit_op = NM_AUDIT_OP_NET_CONTROL; - } else - return message; - interface_type = NMDBUS_TYPE_MANAGER_SKELETON; - } else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE)) { - if (!strcmp (propname, "Autoconnect")) { - glib_propname = NM_DEVICE_AUTOCONNECT; - permission = NM_AUTH_PERMISSION_NETWORK_CONTROL; - audit_op = NM_AUDIT_OP_DEVICE_AUTOCONNECT; - } else if (!strcmp (propname, "Managed")) { - glib_propname = NM_DEVICE_MANAGED; - permission = NM_AUTH_PERMISSION_NETWORK_CONTROL; - audit_op = NM_AUDIT_OP_DEVICE_MANAGED; - } else - return message; - interface_type = NMDBUS_TYPE_DEVICE_SKELETON; - } else if (!strcmp (propiface, NM_DBUS_INTERFACE_DEVICE_STATISTICS)) { - if (!strcmp (propname, "RefreshRateMs")) { - glib_propname = NM_DEVICE_STATISTICS_REFRESH_RATE_MS; - permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_STATISTICS; - audit_op = NM_AUDIT_OP_STATISTICS; - expected_type = G_VARIANT_TYPE ("u"); - } else - return message; - interface_type = NMDBUS_TYPE_DEVICE_SKELETON; - } else - return message; - - if (!g_variant_is_of_type (value, expected_type)) - return message; - - /* This filter function is called from a gdbus worker thread which we can't - * make other D-Bus calls from. In particular, we cannot call - * org.freedesktop.DBus.GetConnectionUnixUser to find the remote UID. - */ - pfd = g_slice_new0 (PropertyFilterData); - pfd->self = self; - self = NULL; - pfd->connection = g_object_ref (connection); - pfd->message = message; - pfd->permission = permission; - pfd->interface_type = interface_type; - pfd->glib_propname = glib_propname; - pfd->audit_op = audit_op; - if (g_variant_is_of_type (value, G_VARIANT_TYPE_BOOLEAN)) { - pfd->audit_prop_value = g_strdup_printf ("%s:%d", pfd->glib_propname, - g_variant_get_boolean (value)); - } else - pfd->audit_prop_value = g_strdup (pfd->glib_propname); - - g_idle_add (do_set_property_check, pfd); - - return NULL; -} - -/*****************************************************************************/ - -static int -_set_prop_filter_free2 (gpointer user_data) -{ - g_slice_free (GWeakRef, user_data); - return G_SOURCE_REMOVE; -} - -static void -_set_prop_filter_free (gpointer user_data) -{ - g_weak_ref_clear (user_data); - - /* Delay the final deletion of the user_data. There is a race when - * calling g_dbus_connection_remove_filter() that the callback and user_data - * might have been copied and being executed after the destroy function - * runs (bgo #704568). - * This doesn't really fix the race, but it should work well enough. */ - g_timeout_add_seconds (2, _set_prop_filter_free2, user_data); -} - -static void -_set_prop_filter (NMManager *self, GDBusConnection *connection) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - - nm_assert ((!priv->prop_filter.connection) == (!priv->prop_filter.id)); - - if (priv->prop_filter.connection == connection) - return; - - if (priv->prop_filter.connection) { - g_dbus_connection_remove_filter (priv->prop_filter.connection, priv->prop_filter.id); - priv->prop_filter.id = 0; - g_clear_object (&priv->prop_filter.connection); - } - if (connection) { - GWeakRef *wptr; + nm_auth_chain_add_call (chain, property_info->writable.permission, TRUE); + return; - wptr = g_slice_new (GWeakRef); - g_weak_ref_init (wptr, self); - priv->prop_filter.id = g_dbus_connection_add_filter (connection, prop_filter, wptr, _set_prop_filter_free); - priv->prop_filter.connection = g_object_ref (connection); - } +err: + nm_audit_log_control_op (property_info->writable.audit_op, + property_info->property_name, + FALSE, + invocation, + error_message); + g_dbus_method_invocation_return_error_literal (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_AUTH_FAILED, + error_message); } /*****************************************************************************/ @@ -6096,7 +6022,7 @@ checkpoint_auth_done_cb (NMAuthChain *chain, (NMCheckpointCreateFlags) flags, &error); if (checkpoint) { - arg = nm_exported_object_get_path (NM_EXPORTED_OBJECT (checkpoint)); + arg = nm_dbus_object_get_path (NM_DBUS_OBJECT (checkpoint)); variant = g_variant_new ("(o)", arg); } } else if (nm_streq0 (op, NM_AUDIT_OP_CHECKPOINT_DESTROY)) { @@ -6122,58 +6048,67 @@ checkpoint_auth_done_cb (NMAuthChain *chain, } static void -impl_manager_checkpoint_create (NMManager *self, - GDBusMethodInvocation *context, - const char *const *devices, - guint32 rollback_timeout, - guint32 flags) -{ - NMManagerPrivate *priv; +impl_manager_checkpoint_create (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; - GError *error = NULL; + char **devices; + guint32 rollback_timeout; + guint32 flags; G_STATIC_ASSERT_EXPR (sizeof (flags) <= sizeof (NMCheckpointCreateFlags)); - g_return_if_fail (NM_IS_MANAGER (self)); - priv = NM_MANAGER_GET_PRIVATE (self); - chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + chain = nm_auth_chain_new_context (invocation, checkpoint_auth_done_cb, self); if (!chain) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to authenticate request."); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); return; } + g_variant_get (parameters, "(^aouu)", &devices, &rollback_timeout, &flags); + priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL); - nm_auth_chain_set_data (chain, "devices", g_strdupv ((char **) devices), (GDestroyNotify) g_strfreev); + nm_auth_chain_set_data (chain, "devices", devices, (GDestroyNotify) g_strfreev); nm_auth_chain_set_data (chain, "flags", GUINT_TO_POINTER (flags), NULL); nm_auth_chain_set_data (chain, "timeout", GUINT_TO_POINTER (rollback_timeout), NULL); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); } static void -impl_manager_checkpoint_destroy (NMManager *self, - GDBusMethodInvocation *context, - const char *checkpoint_path) -{ - NMManagerPrivate *priv; - GError *error = NULL; +impl_manager_checkpoint_destroy (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; + const char *checkpoint_path; - g_return_if_fail (NM_IS_MANAGER (self)); - priv = NM_MANAGER_GET_PRIVATE (self); - - chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + chain = nm_auth_chain_new_context (invocation, checkpoint_auth_done_cb, self); if (!chain) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to authenticate request."); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); return; } + g_variant_get (parameters, "(&o)", &checkpoint_path); + priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_DESTROY, NULL); nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free); @@ -6181,26 +6116,30 @@ impl_manager_checkpoint_destroy (NMManager *self, } static void -impl_manager_checkpoint_rollback (NMManager *self, - GDBusMethodInvocation *context, - const char *checkpoint_path) -{ - NMManagerPrivate *priv; - GError *error = NULL; +impl_manager_checkpoint_rollback (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMManager *self = NM_MANAGER (obj); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMAuthChain *chain; + const char *checkpoint_path; - g_return_if_fail (NM_IS_MANAGER (self)); - priv = NM_MANAGER_GET_PRIVATE (self); - - chain = nm_auth_chain_new_context (context, checkpoint_auth_done_cb, self); + chain = nm_auth_chain_new_context (invocation, checkpoint_auth_done_cb, self); if (!chain) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to authenticate request."); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_return_error_literal (invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_PERMISSION_DENIED, + "Unable to authenticate request."); return; } + g_variant_get (parameters, "(&o)", &checkpoint_path); + priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_ROLLBACK, NULL); nm_auth_chain_set_data (chain, "checkpoint_path", g_strdup (checkpoint_path), g_free); @@ -6213,7 +6152,10 @@ static void auth_mgr_changed (NMAuthManager *auth_manager, gpointer user_data) { /* Let clients know they should re-check their authorization */ - g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0); + nm_dbus_object_emit_signal (user_data, + &interface_info_manager, + &signal_info_check_permissions, + "()"); } #define KERN_RFKILL_OP_CHANGE_ALL 3 @@ -6338,14 +6280,6 @@ periodic_update_active_connection_timestamps (gpointer user_data) return G_SOURCE_CONTINUE; } -static void -dbus_connection_changed_cb (NMBusManager *dbus_mgr, - GDBusConnection *connection, - gpointer user_data) -{ - _set_prop_filter (NM_MANAGER (user_data), connection); -} - /*****************************************************************************/ void @@ -6412,8 +6346,7 @@ nm_manager_setup (void) nm_singleton_instance_register (); _LOGD (LOGD_CORE, "setup %s singleton (%p)", "NMManager", singleton_instance); - nm_exported_object_export ((NMExportedObject *) self); - + nm_dbus_object_export (NM_DBUS_OBJECT (self)); return self; } @@ -6426,11 +6359,9 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_manager_parent_class)->constructed (object); - _set_prop_filter (self, nm_bus_manager_get_connection (priv->dbus_mgr)); - priv->settings = nm_settings_new (); - nm_exported_object_export (NM_EXPORTED_OBJECT (priv->settings)); + nm_dbus_object_export (NM_DBUS_OBJECT (priv->settings)); g_signal_connect (priv->settings, "notify::" NM_SETTINGS_STARTUP_COMPLETE, G_CALLBACK (settings_startup_complete_changed), self); @@ -6529,12 +6460,6 @@ nm_manager_init (NMManager *self) priv->state = NM_STATE_DISCONNECTED; priv->startup = TRUE; - priv->dbus_mgr = g_object_ref (nm_bus_manager_get ()); - g_signal_connect (priv->dbus_mgr, - NM_BUS_MANAGER_DBUS_CONNECTION_CHANGED, - G_CALLBACK (dbus_connection_changed_cb), - self); - /* sleep/wake handling */ priv->sleep_monitor = nm_sleep_monitor_new (); g_signal_connect (priv->sleep_monitor, NM_SLEEP_MONITOR_SLEEPING, @@ -6633,7 +6558,7 @@ get_property (GObject *object, guint prop_id, case PROP_ACTIVE_CONNECTIONS: ptrarr = g_ptr_array_new (); c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) { - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (ac)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (ac)); if (path) g_ptr_array_add (ptrarr, g_strdup (path)); } @@ -6656,7 +6581,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, vbool); break; case PROP_PRIMARY_CONNECTION: - nm_utils_g_value_set_object_path (value, priv->primary_connection); + nm_dbus_utils_g_value_set_object_path (value, priv->primary_connection); break; case PROP_PRIMARY_CONNECTION_TYPE: type = NULL; @@ -6670,13 +6595,13 @@ get_property (GObject *object, guint prop_id, g_value_set_string (value, type ? type : ""); break; case PROP_ACTIVATING_CONNECTION: - nm_utils_g_value_set_object_path (value, priv->activating_connection); + nm_dbus_utils_g_value_set_object_path (value, priv->activating_connection); break; case PROP_SLEEPING: g_value_set_boolean (value, priv->sleeping); break; case PROP_DEVICES: - nm_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL); + nm_dbus_utils_g_value_set_object_path_array (value, priv->devices, device_is_real, NULL); break; case PROP_METERED: g_value_set_uint (value, priv->metered); @@ -6687,7 +6612,7 @@ get_property (GObject *object, guint prop_id, nm_global_dns_config_to_dbus (dns_config, value); break; case PROP_ALL_DEVICES: - nm_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL); + nm_dbus_utils_g_value_set_object_path_array (value, priv->devices, NULL, NULL); break; case PROP_CHECKPOINTS: strv = NULL; @@ -6825,13 +6750,6 @@ dispose (GObject *object) g_clear_object (&priv->vpn_manager); - /* Unregister property filter */ - if (priv->dbus_mgr) { - g_signal_handlers_disconnect_by_func (priv->dbus_mgr, dbus_connection_changed_cb, self); - g_clear_object (&priv->dbus_mgr); - } - _set_prop_filter (self, NULL); - sleep_devices_clear (self); g_clear_pointer (&priv->sleep_devices, g_hash_table_unref); @@ -6880,22 +6798,264 @@ finalize (GObject *object) g_object_unref (priv->platform); } +static const GDBusSignalInfo signal_info_check_permissions = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "CheckPermissions", +); + +static const GDBusSignalInfo signal_info_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "StateChanged", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("state", "u"), + ), +); + +static const GDBusSignalInfo signal_info_device_added = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "DeviceAdded", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("device_path", "o"), + ), +); + +static const GDBusSignalInfo signal_info_device_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "DeviceRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("device_path", "o"), + ), +); + +static const NMDBusInterfaceInfoExtended interface_info_manager = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Reload", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), + ), + ), + .handle = impl_manager_reload, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetDevices", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("devices", "ao"), + ), + ), + .handle = impl_manager_get_devices, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetAllDevices", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("devices", "ao"), + ), + ), + .handle = impl_manager_get_all_devices, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetDeviceByIpIface", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("iface", "s"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("device", "o"), + ), + ), + .handle = impl_manager_get_device_by_ip_iface, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "ActivateConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("device", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("specific_object", "o"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("active_connection", "o"), + ), + ), + .handle = impl_manager_activate_connection, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "AddAndActivateConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("device", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("specific_object", "o"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), + NM_DEFINE_GDBUS_ARG_INFO ("active_connection", "o"), + ), + ), + .handle = impl_manager_add_and_activate_connection, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "DeactivateConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("active_connection", "o"), + ), + ), + .handle = impl_manager_deactivate_connection, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Sleep", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("sleep", "b"), + ), + ), + .handle = impl_manager_sleep, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Enable", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("enable", "b"), + ), + ), + .handle = impl_manager_enable, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetPermissions", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("permissions", "a{ss}"), + ), + ), + .handle = impl_manager_get_permissions, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SetLogging", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("level", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("domains", "s"), + ), + ), + .handle = impl_manager_set_logging, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetLogging", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("level", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("domains", "s"), + ), + ), + .handle = impl_manager_get_logging, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "CheckConnectivity", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connectivity", "u"), + ), + ), + .handle = impl_manager_check_connectivity, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "state", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("state", "u"), + ), + ), + .handle = impl_manager_state, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "CheckpointCreate", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("devices", "ao"), + NM_DEFINE_GDBUS_ARG_INFO ("rollback_timeout", "u"), + NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("checkpoint", "o"), + ), + ), + .handle = impl_manager_checkpoint_create, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "CheckpointDestroy", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("checkpoint", "o"), + ), + ), + .handle = impl_manager_checkpoint_destroy, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "CheckpointRollback", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("checkpoint", "o"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("result", "a{su}"), + ), + ), + .handle = impl_manager_checkpoint_rollback, + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &signal_info_check_permissions, + &signal_info_state_changed, + &signal_info_device_added, + &signal_info_device_removed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Devices", "ao", NM_MANAGER_DEVICES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AllDevices", "ao", NM_MANAGER_ALL_DEVICES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Checkpoints", "ao", NM_MANAGER_CHECKPOINTS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("NetworkingEnabled", "b", NM_MANAGER_NETWORKING_ENABLED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("WirelessEnabled", "b", NM_MANAGER_WIRELESS_ENABLED, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, NM_AUDIT_OP_RADIO_CONTROL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WirelessHardwareEnabled", "b", NM_MANAGER_WIRELESS_HARDWARE_ENABLED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("WwanEnabled", "b", NM_MANAGER_WWAN_ENABLED, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, NM_AUDIT_OP_RADIO_CONTROL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WwanHardwareEnabled", "b", NM_MANAGER_WWAN_HARDWARE_ENABLED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("WimaxEnabled", "b", NM_MANAGER_WIMAX_ENABLED, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, NM_AUDIT_OP_RADIO_CONTROL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WimaxHardwareEnabled", "b", NM_MANAGER_WIMAX_HARDWARE_ENABLED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActiveConnections", "ao", NM_MANAGER_ACTIVE_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PrimaryConnection", "o", NM_MANAGER_PRIMARY_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("PrimartConnectionType", "s", NM_MANAGER_PRIMARY_CONNECTION_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Metered", "u", NM_MANAGER_METERED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ActivatingConnection", "o", NM_MANAGER_ACTIVATING_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Startup", "b", NM_MANAGER_STARTUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Version", "s", NM_MANAGER_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Capabilities", "u", NM_MANAGER_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("State", "u", NM_MANAGER_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Connectivity", "u", NM_MANAGER_CONNECTIVITY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("ConnectivityCheckAvailable", "b", NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("ConnectivityCheckEnabled", "b", NM_MANAGER_CONNECTIVITY_CHECK_ENABLED, NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, NM_AUDIT_OP_NET_CONTROL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L ("GlobalDnsConfiguration", "a{sv}", NM_MANAGER_GLOBAL_DNS_CONFIGURATION, NM_AUTH_PERMISSION_SETTINGS_MODIFY_GLOBAL_DNS, NM_AUDIT_OP_NET_CONTROL), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_manager_class_init (NMManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (manager_class); - exported_object_class->export_path = NM_DBUS_PATH; + dbus_object_class->export_path = NM_DBUS_PATH; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_manager); - /* virtual methods */ object_class->constructed = constructed; object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; - /* properties */ obj_properties[PROP_VERSION] = g_param_spec_string (NM_MANAGER_VERSION, "", "", NULL, @@ -6903,11 +7063,11 @@ nm_manager_class_init (NMManagerClass *manager_class) G_PARAM_STATIC_STRINGS); obj_properties[PROP_CAPABILITIES] = - g_param_spec_variant (NM_MANAGER_CAPABILITIES, "", "", - G_VARIANT_TYPE ("au"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); + g_param_spec_variant (NM_MANAGER_CAPABILITIES, "", "", + G_VARIANT_TYPE ("au"), + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); obj_properties[PROP_STATE] = g_param_spec_uint (NM_MANAGER_STATE, "", "", @@ -7068,7 +7228,7 @@ nm_manager_class_init (NMManagerClass *manager_class) /* signals */ - /* D-Bus exported; emitted only for realized devices */ + /* emitted only for realized devices */ signals[DEVICE_ADDED] = g_signal_new (NM_MANAGER_DEVICE_ADDED, G_OBJECT_CLASS_TYPE (object_class), @@ -7084,7 +7244,7 @@ nm_manager_class_init (NMManagerClass *manager_class) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); - /* D-Bus exported; emitted only for realized devices when a device + /* emitted only for realized devices when a device * becomes unrealized or removed */ signals[DEVICE_REMOVED] = g_signal_new (NM_MANAGER_DEVICE_REMOVED, @@ -7101,20 +7261,6 @@ nm_manager_class_init (NMManagerClass *manager_class) NULL, NULL, NULL, G_TYPE_NONE, 1, G_TYPE_OBJECT); - signals[STATE_CHANGED] = - g_signal_new (NM_MANAGER_STATE_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 1, G_TYPE_UINT); - - signals[CHECK_PERMISSIONS] = - g_signal_new (NM_MANAGER_CHECK_PERMISSIONS, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); - signals[ACTIVE_CONNECTION_ADDED] = g_signal_new (NM_MANAGER_ACTIVE_CONNECTION_ADDED, G_OBJECT_CLASS_TYPE (object_class), @@ -7135,25 +7281,4 @@ nm_manager_class_init (NMManagerClass *manager_class) G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (manager_class), - NMDBUS_TYPE_MANAGER_SKELETON, - "Reload", impl_manager_reload, - "GetDevices", impl_manager_get_devices, - "GetAllDevices", impl_manager_get_all_devices, - "GetDeviceByIpIface", impl_manager_get_device_by_ip_iface, - "ActivateConnection", impl_manager_activate_connection, - "AddAndActivateConnection", impl_manager_add_and_activate_connection, - "DeactivateConnection", impl_manager_deactivate_connection, - "Sleep", impl_manager_sleep, - "Enable", impl_manager_enable, - "GetPermissions", impl_manager_get_permissions, - "SetLogging", impl_manager_set_logging, - "GetLogging", impl_manager_get_logging, - "CheckConnectivity", impl_manager_check_connectivity, - "state", impl_manager_get_state, - "CheckpointCreate", impl_manager_checkpoint_create, - "CheckpointDestroy", impl_manager_checkpoint_destroy, - "CheckpointRollback", impl_manager_checkpoint_rollback, - NULL); } diff --git a/src/nm-manager.h b/src/nm-manager.h index 1019022df4..57936dfb8b 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -22,9 +22,9 @@ #ifndef __NETWORKMANAGER_MANAGER_H__ #define __NETWORKMANAGER_MANAGER_H__ -#include "nm-exported-object.h" #include "settings/nm-settings-connection.h" #include "nm-utils/c-list.h" +#include "nm-dbus-manager.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) #define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) @@ -60,14 +60,11 @@ /* Not exported */ #define NM_MANAGER_SLEEPING "sleeping" -/* signals */ -#define NM_MANAGER_CHECK_PERMISSIONS "check-permissions" +/* Signals */ #define NM_MANAGER_DEVICE_ADDED "device-added" #define NM_MANAGER_DEVICE_REMOVED "device-removed" -#define NM_MANAGER_STATE_CHANGED "state-changed" #define NM_MANAGER_USER_PERMISSIONS_CHANGED "user-permissions-changed" -/* Internal signals */ #define NM_MANAGER_ACTIVE_CONNECTION_ADDED "active-connection-added" #define NM_MANAGER_ACTIVE_CONNECTION_REMOVED "active-connection-removed" #define NM_MANAGER_CONFIGURE_QUIT "configure-quit" @@ -153,4 +150,13 @@ gboolean nm_manager_remove_device (NMManager *self, const char *ifname, NMDeviceType device_type); +void nm_manager_dbus_set_property_handle (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusPropertyInfoExtended *property_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *value, + gpointer user_data); + #endif /* __NETWORKMANAGER_MANAGER_H__ */ diff --git a/src/nm-policy.c b/src/nm-policy.c index 23033c2457..7cbf4864b0 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1358,7 +1358,7 @@ process_secondaries (NMPolicy *self, if (connected) { _LOGD (LOGD_DEVICE, "secondary connection '%s' succeeded; active path '%s'", nm_active_connection_get_settings_connection_id (active), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (active))); /* Secondary connection activated */ secondary_data->secondaries = g_slist_remove (secondary_data->secondaries, secondary_active); @@ -1374,7 +1374,7 @@ process_secondaries (NMPolicy *self, } else { _LOGD (LOGD_DEVICE, "secondary connection '%s' failed; active path '%s'", nm_active_connection_get_settings_connection_id (active), - nm_exported_object_get_path (NM_EXPORTED_OBJECT (active))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (active))); /* Secondary connection failed -> do not watch other connections */ priv->pending_secondaries = g_slist_remove (priv->pending_secondaries, secondary_data); @@ -1670,7 +1670,7 @@ activate_secondary_connections (NMPolicy *self, ac = nm_manager_activate_connection (priv->manager, settings_con, NULL, - nm_exported_object_get_path (NM_EXPORTED_OBJECT (req)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (req)), device, nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (req)), NM_ACTIVATION_TYPE_MANAGED, diff --git a/src/nm-types.h b/src/nm-types.h index 239202cf41..4434c8cce5 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -28,13 +28,14 @@ #define _NM_SD_MAX_CLIENT_ID_LEN (sizeof (guint32) + 128) /* core */ +typedef struct _NMDBusObject NMDBusObject; typedef struct _NMExportedObject NMExportedObject; typedef struct _NMActiveConnection NMActiveConnection; typedef struct _NMAuditManager NMAuditManager; typedef struct _NMVpnConnection NMVpnConnection; typedef struct _NMActRequest NMActRequest; typedef struct _NMAuthSubject NMAuthSubject; -typedef struct _NMBusManager NMBusManager; +typedef struct _NMDBusManager NMDBusManager; typedef struct _NMConfig NMConfig; typedef struct _NMConfigData NMConfigData; typedef struct _NMArpingManager NMArpingManager; diff --git a/src/ppp/meson.build b/src/ppp/meson.build index 9c2045efff..20edb9d055 100644 --- a/src/ppp/meson.build +++ b/src/ppp/meson.build @@ -22,7 +22,6 @@ nm_pppd_plugin = shared_module( name = 'nm-ppp-plugin' deps = [ - libnmdbus_dep, nm_dep ] diff --git a/src/ppp/nm-ppp-manager.c b/src/ppp/nm-ppp-manager.c index 36697f082f..2bf230a86b 100644 --- a/src/ppp/nm-ppp-manager.c +++ b/src/ppp/nm-ppp-manager.c @@ -50,13 +50,12 @@ #include "nm-act-request.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" +#include "nm-dbus-object.h" #include "nm-pppd-plugin.h" #include "nm-ppp-plugin-api.h" #include "nm-ppp-status.h" -#include "introspection/org.freedesktop.NetworkManager.PPP.h" - #define NM_PPPD_PLUGIN PPPD_PLUGIN_DIR "/nm-pppd-plugin.so" static NM_CACHED_QUARK_FCN ("ppp-manager-secret-tries", ppp_manager_secret_tries_quark) @@ -116,17 +115,17 @@ typedef struct { } NMPPPManagerPrivate; struct _NMPPPManager { - NMExportedObject parent; + NMDBusObject parent; NMPPPManagerPrivate _priv; }; typedef struct { - NMExportedObjectClass parent; + NMDBusObjectClass parent; } NMPPPManagerClass; -G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, NM_TYPE_DBUS_OBJECT) -#define NM_PPP_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMPPPManager, NM_IS_PPP_MANAGER) +#define NM_PPP_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMPPPManager, NM_IS_PPP_MANAGER, NMDBusObject) /*****************************************************************************/ @@ -332,20 +331,27 @@ ppp_secrets_cb (NMActRequest *req, * against libnm just to parse this. So instead, let's just send what * it needs. */ - g_dbus_method_invocation_return_value ( - priv->pending_secrets_context, - g_variant_new ("(ss)", username ? username : "", password ? password : "")); + g_dbus_method_invocation_return_value (priv->pending_secrets_context, + g_variant_new ("(ss)", + username ?: "", + password ?: "")); - out: +out: priv->pending_secrets_context = NULL; priv->secrets_id = NULL; priv->secrets_setting_name = NULL; } static void -impl_ppp_manager_need_secrets (NMPPPManager *manager, - GDBusMethodInvocation *context) +impl_ppp_manager_need_secrets (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMPPPManager *manager = NM_PPP_MANAGER (obj); NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); NMConnection *applied_connection; const char *username = NULL; @@ -364,7 +370,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, /* Use existing secrets from the connection */ if (extract_details_from_connection (applied_connection, NULL, &username, &password, &error)) { /* Send existing secrets to the PPP plugin */ - priv->pending_secrets_context = context; + priv->pending_secrets_context = invocation; ppp_secrets_cb (priv->act_req, priv->secrets_id, NULL, NULL, manager); } else { _LOGW ("%s", error->message); @@ -389,30 +395,45 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, ppp_secrets_cb, manager); g_object_set_qdata (G_OBJECT (applied_connection), ppp_manager_secret_tries_quark (), GUINT_TO_POINTER (++tries)); - priv->pending_secrets_context = context; + priv->pending_secrets_context = invocation; if (hints) g_ptr_array_free (hints, TRUE); } static void -impl_ppp_manager_set_state (NMPPPManager *manager, - GDBusMethodInvocation *context, - guint32 state) +impl_ppp_manager_set_state (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - g_signal_emit (manager, signals[STATE_CHANGED], 0, (guint) state); + NMPPPManager *manager = NM_PPP_MANAGER (obj); + guint32 state; - g_dbus_method_invocation_return_value (context, NULL); + g_variant_get (parameters, "(u)", &state); + g_signal_emit (manager, signals[STATE_CHANGED], 0, (guint) state); + g_dbus_method_invocation_return_value (invocation, NULL); } static void -impl_ppp_manager_set_ifindex (NMPPPManager *manager, - GDBusMethodInvocation *context, - gint32 ifindex) +impl_ppp_manager_set_ifindex (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMPPPManager *manager = NM_PPP_MANAGER (obj); NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); const NMPlatformLink *plink = NULL; nm_auto_nmpobj const NMPObject *obj_keep_alive = NULL; + gint32 ifindex; + + g_variant_get (parameters, "(i)", &ifindex); _LOGD ("set-ifindex %d", (int) ifindex); @@ -439,7 +460,7 @@ impl_ppp_manager_set_ifindex (NMPPPManager *manager, obj_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink)); g_signal_emit (manager, signals[IFINDEX_SET], 0, ifindex, plink->name); - g_dbus_method_invocation_return_value (context, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); } static gboolean @@ -469,18 +490,26 @@ set_ip_config_common (NMPPPManager *self, } static void -impl_ppp_manager_set_ip4_config (NMPPPManager *manager, - GDBusMethodInvocation *context, - GVariant *config_dict) +impl_ppp_manager_set_ip4_config (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMPPPManager *manager = NM_PPP_MANAGER (obj); NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); gs_unref_object NMIP4Config *config = NULL; NMPlatformIP4Address address; guint32 u32, mtu; GVariantIter *iter; + gs_unref_variant GVariant *config_dict = NULL; _LOGI ("(IPv4 Config Get) reply received."); + g_variant_get (parameters, "(@a{sv})", &config_dict); + nm_clear_g_source (&priv->ppp_timeout_handler); if (!set_ip_config_common (manager, config_dict, &mtu)) @@ -538,7 +567,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, g_signal_emit (manager, signals[IP4_CONFIG], 0, config); out: - g_dbus_method_invocation_return_value (context, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); } /* Converts the named Interface Identifier item to an IPv6 LL address and @@ -571,19 +600,27 @@ iid_value_to_ll6_addr (GVariant *dict, } static void -impl_ppp_manager_set_ip6_config (NMPPPManager *manager, - GDBusMethodInvocation *context, - GVariant *config_dict) +impl_ppp_manager_set_ip6_config (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMPPPManager *manager = NM_PPP_MANAGER (obj); NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); gs_unref_object NMIP6Config *config = NULL; NMPlatformIP6Address addr; struct in6_addr a; NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; gboolean has_peer = FALSE; + gs_unref_variant GVariant *config_dict = NULL; _LOGI ("(IPv6 Config Get) reply received."); + g_variant_get (parameters, "(@a{sv})", &config_dict); + nm_clear_g_source (&priv->ppp_timeout_handler); if (!set_ip_config_common (manager, config_dict, NULL)) @@ -619,7 +656,7 @@ impl_ppp_manager_set_ip6_config (NMPPPManager *manager, _LOGE ("invalid IPv6 address received!"); out: - g_dbus_method_invocation_return_value (context, NULL); + g_dbus_method_invocation_return_value (invocation, NULL); } /*****************************************************************************/ @@ -926,7 +963,7 @@ create_pppd_cmd_line (NMPPPManager *self, nm_cmd_line_add_int (cmd, 0); nm_cmd_line_add_string (cmd, "ipparam"); - nm_cmd_line_add_string (cmd, nm_exported_object_get_path (NM_EXPORTED_OBJECT (self))); + nm_cmd_line_add_string (cmd, nm_dbus_object_get_path (NM_DBUS_OBJECT (self))); nm_cmd_line_add_string (cmd, "plugin"); nm_cmd_line_add_string (cmd, NM_PPPD_PLUGIN); @@ -1005,7 +1042,7 @@ _ppp_manager_start (NMPPPManager *manager, return FALSE; #endif - nm_exported_object_export (NM_EXPORTED_OBJECT (manager)); + nm_dbus_object_export (NM_DBUS_OBJECT (manager)); priv->pid = 0; @@ -1079,7 +1116,7 @@ out: nm_cmd_line_destroy (ppp_cmd); if (priv->pid <= 0) - nm_exported_object_unexport (NM_EXPORTED_OBJECT (manager)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (manager)); return priv->pid > 0; } @@ -1183,7 +1220,7 @@ _ppp_manager_stop_async (NMPPPManager *manager, NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); StopContext *ctx; - nm_exported_object_unexport (NM_EXPORTED_OBJECT (manager)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (manager)); ctx = g_slice_new0 (StopContext); ctx->manager = g_object_ref (manager); @@ -1220,10 +1257,10 @@ _ppp_manager_stop_async (NMPPPManager *manager, static void _ppp_manager_stop_sync (NMPPPManager *manager) { - NMExportedObject *exported = NM_EXPORTED_OBJECT (manager); + NMDBusObject *dbus = NM_DBUS_OBJECT (manager); - if (nm_exported_object_is_exported (exported)) - nm_exported_object_unexport (exported); + if (nm_dbus_object_is_exported (dbus)) + nm_dbus_object_unexport (dbus); _ppp_cleanup (manager); _ppp_kill (manager); @@ -1293,11 +1330,11 @@ static void dispose (GObject *object) { NMPPPManager *self = (NMPPPManager *) object; - NMExportedObject *exported = NM_EXPORTED_OBJECT (self); + NMDBusObject *dbus = NM_DBUS_OBJECT (self); NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); - if (nm_exported_object_is_exported (exported)) - nm_exported_object_unexport (exported); + if (nm_dbus_object_is_exported (dbus)) + nm_dbus_object_unexport (dbus); _ppp_cleanup (self); _ppp_kill (self); @@ -1317,18 +1354,73 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_ppp_manager_parent_class)->finalize (object); } +static const NMDBusInterfaceInfoExtended interface_info_ppp = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_PPP, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "NeedSecrets", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("username", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("password", "s"), + ), + ), + .handle = impl_ppp_manager_need_secrets, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SetIp4Config", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("config", "a{sv}"), + ), + ), + .handle = impl_ppp_manager_set_ip4_config, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SetIp6Config", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("config", "a{sv}"), + ), + ), + .handle = impl_ppp_manager_set_ip6_config, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SetState", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("state", "u"), + ), + ), + .handle = impl_ppp_manager_set_state, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SetIfindex", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("ifindex", "i"), + ), + ), + .handle = impl_ppp_manager_set_ifindex, + ), + ), + ), +}; + static void nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (manager_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (manager_class); object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; object_class->set_property = set_property; - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/PPP"); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH"/PPP"); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_ppp); obj_properties[PROP_PARENT_IFACE] = g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, "", "", @@ -1385,15 +1477,6 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) G_TYPE_NONE, 2, G_TYPE_UINT /*guint32 in_bytes*/, G_TYPE_UINT /*guint32 out_bytes*/); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (manager_class), - NMDBUS_TYPE_PPP_MANAGER_SKELETON, - "NeedSecrets", impl_ppp_manager_need_secrets, - "SetIp4Config", impl_ppp_manager_set_ip4_config, - "SetIp6Config", impl_ppp_manager_set_ip6_config, - "SetState", impl_ppp_manager_set_state, - "SetIfindex", impl_ppp_manager_set_ifindex, - NULL); } NMPPPOps ppp_ops = { diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index c92389ffcb..06eaf51e41 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -38,8 +38,6 @@ #include "nm-core-internal.h" #include "nm-utils/c-list.h" -#include "introspection/org.freedesktop.NetworkManager.AgentManager.h" - /*****************************************************************************/ enum { @@ -67,15 +65,15 @@ typedef struct { } NMAgentManagerPrivate; struct _NMAgentManager { - NMExportedObject parent; + NMDBusObject parent; NMAgentManagerPrivate _priv; }; struct _NMAgentManagerClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_OBJECT) +G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_DBUS_OBJECT) #define NM_AGENT_MANAGER_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMAgentManager, NM_IS_AGENT_MANAGER) @@ -392,10 +390,10 @@ agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data) } static void -impl_agent_manager_register_with_capabilities (NMAgentManager *self, - GDBusMethodInvocation *context, - const char *identifier, - guint32 capabilities) +agent_manager_register_with_capabilities (NMAgentManager *self, + GDBusMethodInvocation *context, + const char *identifier, + guint32 capabilities) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); NMAuthSubject *subject; @@ -460,45 +458,56 @@ done: } static void -impl_agent_manager_register (NMAgentManager *self, - GDBusMethodInvocation *context, - const char *identifier) +impl_agent_manager_register (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - impl_agent_manager_register_with_capabilities (self, context, identifier, 0); + const char *identifier; + + g_variant_get (parameters, "(&s)", &identifier); + agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, 0); } static void -impl_agent_manager_unregister (NMAgentManager *self, - GDBusMethodInvocation *context) +impl_agent_manager_register_with_capabilities (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - GError *error = NULL; - char *sender = NULL; + const char *identifier; + guint32 capabilities; - if (!nm_bus_manager_get_caller_info (nm_bus_manager_get (), - context, - &sender, - NULL, - NULL)) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, - "Unable to determine request sender."); - goto done; - } + g_variant_get (parameters, "(&su)", &identifier, &capabilities); + agent_manager_register_with_capabilities (NM_AGENT_MANAGER (obj), invocation, identifier, capabilities); +} + +static void +impl_agent_manager_unregister (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMAgentManager *self = NM_AGENT_MANAGER (obj); - /* Found the agent, unregister and remove it */ if (!remove_agent (self, sender)) { - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, - "Caller is not registered as an Agent"); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + "Caller is not registered as an Agent"); + return; } - g_dbus_method_invocation_return_value (context, NULL); - -done: - if (error) - g_dbus_method_invocation_take_error (context, error); - g_free (sender); + g_dbus_method_invocation_return_value (invocation, NULL); } /*****************************************************************************/ @@ -1586,7 +1595,7 @@ constructed (GObject *object) priv->auth_mgr = g_object_ref (nm_auth_manager_get ()); priv->session_monitor = g_object_ref (nm_session_monitor_get ()); - nm_exported_object_export (NM_EXPORTED_OBJECT (object)); + nm_dbus_object_export (NM_DBUS_OBJECT (object)); g_signal_connect (priv->auth_mgr, NM_AUTH_MANAGER_SIGNAL_CHANGED, @@ -1622,20 +1631,64 @@ cancel_more: g_clear_object (&priv->auth_mgr); } - nm_exported_object_unexport (NM_EXPORTED_OBJECT (object)); + nm_dbus_object_unexport (NM_DBUS_OBJECT (object)); g_clear_object (&priv->session_monitor); G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); } +static const NMDBusInterfaceInfoExtended interface_info_agent_manager = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_AGENT_MANAGER, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Register", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("identifier", "s"), + ), + ), + .handle = impl_agent_manager_register, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "RegisterWithCapabilities", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("identifier", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("capabilities", "u"), + ), + ), + .handle = impl_agent_manager_register_with_capabilities, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "RegisterWithCapabilities", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("identifier", "s"), + NM_DEFINE_GDBUS_ARG_INFO ("capabilities", "u"), + ), + ), + .handle = impl_agent_manager_register_with_capabilities, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Unregister", + ), + .handle = impl_agent_manager_unregister, + ), + ), + ), +}; + static void nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) { GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (agent_manager_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (agent_manager_class); - exported_object_class->export_path = NM_DBUS_PATH_AGENT_MANAGER; + dbus_object_class->export_path = NM_DBUS_PATH_AGENT_MANAGER; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_agent_manager); object_class->constructed = constructed; object_class->dispose = dispose; @@ -1649,11 +1702,4 @@ nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (agent_manager_class), - NMDBUS_TYPE_AGENT_MANAGER_SKELETON, - "Register", impl_agent_manager_register, - "RegisterWithCapabilities", impl_agent_manager_register_with_capabilities, - "Unregister", impl_agent_manager_unregister, - NULL); } diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index f6845818dd..8c27f26bbe 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -23,7 +23,7 @@ #include "nm-connection.h" -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-secret-agent.h" #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 33ce4ba2bf..1f6f15a905 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -51,7 +51,7 @@ typedef struct { NMSecretAgentCapabilities capabilities; GSList *permissions; GDBusProxy *proxy; - NMBusManager *bus_mgr; + NMDBusManager *bus_mgr; GDBusConnection *connection; CList requests; gulong on_disconnected_id; @@ -631,7 +631,7 @@ _on_disconnected_cleanup (NMSecretAgentPrivate *priv) } static void -_on_disconnected_private_connection (NMBusManager *mgr, +_on_disconnected_private_connection (NMDBusManager *mgr, GDBusConnection *connection, NMSecretAgent *self) { @@ -715,9 +715,9 @@ nm_secret_agent_new (GDBusMethodInvocation *context, priv = NM_SECRET_AGENT_GET_PRIVATE (self); - priv->bus_mgr = g_object_ref (nm_bus_manager_get ()); + priv->bus_mgr = g_object_ref (nm_dbus_manager_get ()); priv->connection = g_object_ref (connection); - priv->connection_is_private = !!nm_bus_manager_connection_get_private_name (priv->bus_mgr, connection); + priv->connection_is_private = !!nm_dbus_manager_connection_get_private_name (priv->bus_mgr, connection); _LOGt ("constructed: %s, owner=%s%s%s (%s), private-connection=%d, unique-name=%s%s%s, capabilities=%s", (description = _create_description (dbus_owner, identifier, uid)), @@ -734,18 +734,18 @@ nm_secret_agent_new (GDBusMethodInvocation *context, priv->capabilities = capabilities; priv->subject = g_object_ref (subject); - priv->proxy = nm_bus_manager_new_proxy (priv->bus_mgr, - priv->connection, - G_TYPE_DBUS_PROXY, - priv->dbus_owner, - NM_DBUS_PATH_SECRET_AGENT, - NM_DBUS_INTERFACE_SECRET_AGENT); + priv->proxy = nm_dbus_manager_new_proxy (priv->bus_mgr, + priv->connection, + G_TYPE_DBUS_PROXY, + priv->dbus_owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT); /* we cannot subscribe to notify::g-name-owner because that doesn't work * for unique names and it doesn't work for private connections. */ if (priv->connection_is_private) { priv->on_disconnected_id = g_signal_connect (priv->bus_mgr, - NM_BUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, + NM_DBUS_MANAGER_PRIVATE_CONNECTION_DISCONNECTED, G_CALLBACK (_on_disconnected_private_connection), self); } else { diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index c499dbfe38..657ac14213 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -39,8 +39,6 @@ #include "nm-core-internal.h" #include "nm-audit-manager.h" -#include "introspection/org.freedesktop.NetworkManager.Settings.Connection.h" - #define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps" #define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids" @@ -60,7 +58,6 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingsConnection, ); enum { - UPDATED, REMOVED, UPDATED_INTERNAL, LAST_SIGNAL @@ -115,7 +112,7 @@ typedef struct _NMSettingsConnectionPrivate { } NMSettingsConnectionPrivate; -G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_EXPORTED_OBJECT, +G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT, G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_settings_connection_connection_interface_init) ) @@ -146,12 +143,9 @@ G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_E /*****************************************************************************/ -static void -_emit_updated (NMSettingsConnection *self, gboolean by_user) -{ - g_signal_emit (self, signals[UPDATED], 0); - g_signal_emit (self, signals[UPDATED_INTERNAL], 0, by_user); -} +static const GDBusSignalInfo signal_info_updated; +static const GDBusSignalInfo signal_info_removed; +static const NMDBusInterfaceInfoExtended interface_info_settings_connection; /*****************************************************************************/ @@ -526,6 +520,16 @@ set_persist_mode (NMSettingsConnection *self, NMSettingsConnectionPersistMode pe } static void +_emit_updated (NMSettingsConnection *self, gboolean by_user) +{ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings_connection, + &signal_info_updated, + "()"); + g_signal_emit (self, signals[UPDATED_INTERNAL], 0, by_user); +} + +static void connection_changed_cb (NMSettingsConnection *self, gpointer unused) { set_persist_mode (self, NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED); @@ -1573,18 +1577,25 @@ get_settings_auth_cb (NMSettingsConnection *self, } static void -impl_settings_connection_get_settings (NMSettingsConnection *self, - GDBusMethodInvocation *context) -{ - NMAuthSubject *subject; +impl_settings_connection_get_settings (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; - subject = _new_auth_subject (context, &error); - if (subject) { - auth_start (self, context, subject, NULL, get_settings_auth_cb, NULL); - g_object_unref (subject); - } else - g_dbus_method_invocation_take_error (context, error); + subject = _new_auth_subject (invocation, &error); + if (!subject) { + g_dbus_method_invocation_take_error (invocation, error); + return; + } + + auth_start (self, invocation, subject, NULL, get_settings_auth_cb, NULL); } typedef struct { @@ -1897,54 +1908,87 @@ error: } static void -impl_settings_connection_update (NMSettingsConnection *self, - GDBusMethodInvocation *context, - GVariant *new_settings) +impl_settings_connection_update (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - settings_connection_update (self, FALSE, context, new_settings, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get (parameters, "(@a{sa{sv}})", &settings); + settings_connection_update (self, FALSE, invocation, settings, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); } static void -impl_settings_connection_update_unsaved (NMSettingsConnection *self, - GDBusMethodInvocation *context, - GVariant *new_settings) +impl_settings_connection_update_unsaved (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - settings_connection_update (self, FALSE, context, new_settings, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get (parameters, "(@a{sa{sv}})", &settings); + settings_connection_update (self, FALSE, invocation, settings, NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY); } static void -impl_settings_connection_save (NMSettingsConnection *self, - GDBusMethodInvocation *context) +impl_settings_connection_save (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - settings_connection_update (self, FALSE, context, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + + settings_connection_update (self, FALSE, invocation, NULL, NM_SETTINGS_UPDATE2_FLAG_TO_DISK); } static void -impl_settings_connection_update2 (NMSettingsConnection *self, - GDBusMethodInvocation *context, - GVariant *settings, - guint32 flags_u, - GVariant *args) -{ +impl_settings_connection_update2 (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_variant GVariant *settings = NULL; + gs_unref_variant GVariant *args = NULL; + guint32 flags_u; GError *error = NULL; GVariantIter iter; const char *args_name; - const NMSettingsUpdate2Flags flags = (NMSettingsUpdate2Flags) flags_u; + NMSettingsUpdate2Flags flags; const NMSettingsUpdate2Flags ALL_PERSIST_MODES = NM_SETTINGS_UPDATE2_FLAG_TO_DISK | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_DETACHED | NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY; + g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args); + if (NM_FLAGS_ANY (flags_u, ~((guint32) (ALL_PERSIST_MODES | NM_SETTINGS_UPDATE2_FLAG_VOLATILE | NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)))) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Unknown flags"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } + flags = (NMSettingsUpdate2Flags) flags_u; + if ( ( NM_FLAGS_ANY (flags, ALL_PERSIST_MODES) && !nm_utils_is_power_of_two (flags & ALL_PERSIST_MODES)) || ( NM_FLAGS_HAS (flags, NM_SETTINGS_UPDATE2_FLAG_VOLATILE) @@ -1953,7 +1997,7 @@ impl_settings_connection_update2 (NMSettingsConnection *self, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Conflicting flags"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -1961,7 +2005,7 @@ impl_settings_connection_update2 (NMSettingsConnection *self, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "args is of invalid type"); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } @@ -1970,13 +2014,13 @@ impl_settings_connection_update2 (NMSettingsConnection *self, error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_ARGUMENTS, "Unsupported argument '%s'", args_name); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); return; } settings_connection_update (self, TRUE, - context, + invocation, settings, flags); } @@ -2029,26 +2073,30 @@ get_modify_permission_basic (NMSettingsConnection *self) } static void -impl_settings_connection_delete (NMSettingsConnection *self, - GDBusMethodInvocation *context) -{ - NMAuthSubject *subject = NULL; +impl_settings_connection_delete (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; if (!check_writable (NM_CONNECTION (self), &error)) - goto out_err; + goto err; - subject = _new_auth_subject (context, &error); - if (subject) { - auth_start (self, context, subject, get_modify_permission_basic (self), delete_auth_cb, NULL); - g_object_unref (subject); - } else - goto out_err; + subject = _new_auth_subject (invocation, &error); + if (!subject) + goto err; + auth_start (self, invocation, subject, get_modify_permission_basic (self), delete_auth_cb, NULL); return; -out_err: +err: nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, self, FALSE, NULL, subject, error->message); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); } /*****************************************************************************/ @@ -2107,24 +2155,33 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self, } static void -impl_settings_connection_get_secrets (NMSettingsConnection *self, - GDBusMethodInvocation *context, - const gchar *setting_name) -{ - NMAuthSubject *subject; +impl_settings_connection_get_secrets (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; + const char *setting_name; - subject = _new_auth_subject (context, &error); - if (subject) { - auth_start (self, - context, - subject, - get_modify_permission_basic (self), - dbus_get_secrets_auth_cb, - g_strdup (setting_name)); - g_object_unref (subject); - } else - g_dbus_method_invocation_take_error (context, error); + subject = _new_auth_subject (invocation, &error); + if (!subject) { + g_dbus_method_invocation_take_error (invocation, error); + return; + } + + g_variant_get (parameters, "(&s)", &setting_name); + + auth_start (self, + invocation, + subject, + get_modify_permission_basic (self), + dbus_get_secrets_auth_cb, + g_strdup (setting_name)); } static void @@ -2173,26 +2230,31 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, } static void -impl_settings_connection_clear_secrets (NMSettingsConnection *self, - GDBusMethodInvocation *context) -{ - NMAuthSubject *subject; +impl_settings_connection_clear_secrets (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (obj); + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; - subject = _new_auth_subject (context, &error); - if (subject) { - auth_start (self, - context, - subject, - get_modify_permission_basic (self), - dbus_clear_secrets_auth_cb, - NULL); - g_object_unref (subject); - } else { + subject = _new_auth_subject (invocation, &error); + if (!subject) { nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, self, FALSE, NULL, NULL, error->message); - g_dbus_method_invocation_take_error (context, error); + g_dbus_method_invocation_take_error (invocation, error); + return; } + auth_start (self, + invocation, + subject, + get_modify_permission_basic (self), + dbus_clear_secrets_auth_cb, + NULL); } /*****************************************************************************/ @@ -2216,7 +2278,12 @@ nm_settings_connection_signal_remove (NMSettingsConnection *self) if (priv->removed) return; priv->removed = TRUE; - g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_REMOVED); + + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings_connection, + &signal_info_removed, + "()"); + g_signal_emit (self, signals[REMOVED], 0); } gboolean @@ -3010,22 +3077,119 @@ set_property (GObject *object, guint prop_id, } } +static const GDBusSignalInfo signal_info_updated = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "Updated", +); + +static const GDBusSignalInfo signal_info_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "Removed", +); + +static const NMDBusInterfaceInfoExtended interface_info_settings_connection = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_SETTINGS_CONNECTION, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Update", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("properties", "a{sa{sv}}"), + ), + ), + .handle = impl_settings_connection_update, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "UpdateUnsaved", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("properties", "a{sa{sv}}"), + ), + ), + .handle = impl_settings_connection_update_unsaved, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Delete", + ), + .handle = impl_settings_connection_delete, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetSettings", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("settings", "a{sa{sv}}"), + ), + ), + .handle = impl_settings_connection_get_settings, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetSecrets", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("setting_name", "s"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("secrets", "a{sa{sv}}"), + ), + ), + .handle = impl_settings_connection_get_secrets, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "ClearSecrets", + ), + .handle = impl_settings_connection_clear_secrets, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Save", + ), + .handle = impl_settings_connection_save, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "Update2", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("settings", "a{sa{sv}}"), + NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"), + NM_DEFINE_GDBUS_ARG_INFO ("args", "a{sv}"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("result", "a{sv}"), + ), + ), + .handle = impl_settings_connection_update2, + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &signal_info_updated, + &signal_info_removed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Unsaved", "b", NM_SETTINGS_CONNECTION_UNSAVED), + ), + ), + .legacy_property_changed = TRUE, +}; + static void -nm_settings_connection_class_init (NMSettingsConnectionClass *class) +nm_settings_connection_class_init (NMSettingsConnectionClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - g_type_class_add_private (class, sizeof (NMSettingsConnectionPrivate)); + g_type_class_add_private (klass, sizeof (NMSettingsConnectionPrivate)); - exported_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_SETTINGS); + dbus_object_class->export_path = NM_EXPORT_PATH_NUMBERED (NM_DBUS_PATH_SETTINGS); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_settings_connection); object_class->constructed = constructed; object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; - class->supports_secrets = supports_secrets; + klass->supports_secrets = supports_secrets; obj_properties[PROP_UNSAVED] = g_param_spec_boolean (NM_SETTINGS_CONNECTION_UNSAVED, "", "", @@ -3056,20 +3220,10 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); - - signals[UPDATED] = - g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - /* internal signal, with an argument (gboolean by_user). */ signals[UPDATED_INTERNAL] = g_signal_new (NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, - G_TYPE_FROM_CLASS (class), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, @@ -3077,24 +3231,12 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) signals[REMOVED] = g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, - G_TYPE_FROM_CLASS (class), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), - NMDBUS_TYPE_SETTINGS_CONNECTION_SKELETON, - "Update", impl_settings_connection_update, - "UpdateUnsaved", impl_settings_connection_update_unsaved, - "Delete", impl_settings_connection_delete, - "GetSettings", impl_settings_connection_get_settings, - "GetSecrets", impl_settings_connection_get_secrets, - "ClearSecrets", impl_settings_connection_clear_secrets, - "Save", impl_settings_connection_save, - "Update2", impl_settings_connection_update2, - NULL); } static void diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 29ec05dd10..f5b3179312 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -24,7 +24,7 @@ #include <net/ethernet.h> -#include "nm-exported-object.h" +#include "nm-dbus-object.h" #include "nm-connection.h" #define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) @@ -34,13 +34,9 @@ #define NM_IS_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_CONNECTION)) #define NM_SETTINGS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) -/* Signals */ -#define NM_SETTINGS_CONNECTION_UPDATED "updated" #define NM_SETTINGS_CONNECTION_REMOVED "removed" #define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" #define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" - -/* Internal signals */ #define NM_SETTINGS_CONNECTION_UPDATED_INTERNAL "updated-internal" /* Properties */ @@ -106,12 +102,12 @@ typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; struct _NMSettingsConnectionPrivate; struct _NMSettingsConnection { - NMExportedObject parent; + NMDBusObject parent; struct _NMSettingsConnectionPrivate *_priv; }; struct _NMSettingsConnectionClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; gboolean (*commit_changes) (NMSettingsConnection *self, NMConnection *new_connection, diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 7adf76ef30..8d804175f9 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -62,6 +62,7 @@ #include "nm-utils.h" #include "nm-core-internal.h" +#include "nm-dbus-object.h" #include "devices/nm-device-ethernet.h" #include "nm-settings-connection.h" #include "nm-settings-plugin.h" @@ -77,8 +78,6 @@ #include "nm-dispatcher.h" #include "nm-hostname-manager.h" -#include "introspection/org.freedesktop.NetworkManager.Settings.h" - /*****************************************************************************/ #define EXPORT(sym) void * __export_##sym = &sym; @@ -107,7 +106,6 @@ enum { CONNECTION_UPDATED, CONNECTION_REMOVED, CONNECTION_FLAGS_CHANGED, - NEW_CONNECTION, /* exported, not used internally */ LAST_SIGNAL }; @@ -135,15 +133,15 @@ typedef struct { } NMSettingsPrivate; struct _NMSettings { - NMExportedObject parent; + NMDBusObject parent; NMSettingsPrivate _priv; }; struct _NMSettingsClass { - NMExportedObjectClass parent; + NMDBusObjectClass parent; }; -G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); +G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_DBUS_OBJECT); #define NM_SETTINGS_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSettings, NM_IS_SETTINGS) @@ -154,6 +152,10 @@ G_DEFINE_TYPE (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT); /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_settings; +static const GDBusSignalInfo signal_info_new_connection; +static const GDBusSignalInfo signal_info_connection_removed; + static void claim_connection (NMSettings *self, NMSettingsConnection *connection); @@ -267,11 +269,17 @@ nm_settings_for_each_connection (NMSettings *self, } static void -impl_settings_list_connections (NMSettings *self, - GDBusMethodInvocation *context) +impl_settings_list_connections (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GPtrArray *connections; + gs_unref_ptrarray GPtrArray *connections = NULL; GHashTableIter iter; gpointer key; @@ -281,9 +289,8 @@ impl_settings_list_connections (NMSettings *self, g_ptr_array_add (connections, key); g_ptr_array_add (connections, NULL); - g_dbus_method_invocation_return_value (context, + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(^ao)", connections->pdata)); - g_ptr_array_unref (connections); } NMSettingsConnection * @@ -308,14 +315,22 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid) } static void -impl_settings_get_connection_by_uuid (NMSettings *self, - GDBusMethodInvocation *context, - const char *uuid) +impl_settings_get_connection_by_uuid (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *dbus_connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsConnection *connection = NULL; - NMAuthSubject *subject = NULL; + gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; char *error_desc = NULL; + const char *uuid; + + g_variant_get (parameters, "(&s)", &uuid); connection = nm_settings_get_connection_by_uuid (self, uuid); if (!connection) { @@ -325,7 +340,7 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - subject = nm_auth_subject_new_unix_process_from_context (context); + subject = nm_auth_subject_new_unix_process_from_context (invocation); if (!subject) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -343,16 +358,13 @@ impl_settings_get_connection_by_uuid (NMSettings *self, goto error; } - g_clear_object (&subject); - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection)))); + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(o)", + nm_connection_get_path (NM_CONNECTION (connection)))); return; error: - g_assert (error); - g_dbus_method_invocation_take_error (context, error); - g_clear_object (&subject); + g_dbus_method_invocation_take_error (invocation, error); } /** @@ -500,7 +512,7 @@ nm_settings_get_unmanaged_specs (NMSettings *self) } static NMSettingsPlugin * -get_plugin (NMSettings *self, guint32 capability) +get_plugin (NMSettings *self, NMSettingsPluginCapabilities capability) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -816,6 +828,19 @@ connection_flags_changed (NMSettingsConnection *connection, } static void +_emit_connection_removed (NMSettings *self, + NMSettingsConnection *connection) +{ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings, + &signal_info_connection_removed, + "(o)", + nm_connection_get_path (NM_CONNECTION (connection))); + + g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); +} + +static void connection_removed (NMSettingsConnection *connection, gpointer user_data) { NMSettings *self = NM_SETTINGS (user_data); @@ -842,13 +867,12 @@ connection_removed (NMSettingsConnection *connection, gpointer user_data) g_hash_table_remove (priv->connections, (gpointer) cpath); g_clear_pointer (&priv->connections_cached_list, g_free); - /* Notify D-Bus */ - g_signal_emit (self, signals[CONNECTION_REMOVED], 0, connection); + _emit_connection_removed (self, connection); /* Re-emit for listeners like NMPolicy */ _notify (self, PROP_CONNECTIONS); - if (nm_exported_object_is_exported (NM_EXPORTED_OBJECT (connection))) - nm_exported_object_unexport (NM_EXPORTED_OBJECT (connection)); + if (nm_dbus_object_is_exported (NM_DBUS_OBJECT (connection))) + nm_dbus_object_unexport (NM_DBUS_OBJECT (connection)); check_startup_complete (self); @@ -968,7 +992,7 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) /* Export the connection over D-Bus */ g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); - path = nm_exported_object_export (NM_EXPORTED_OBJECT (connection)); + path = nm_dbus_object_export (NM_DBUS_OBJECT (connection)); nm_connection_set_path (NM_CONNECTION (connection), path); g_hash_table_insert (priv->connections, @@ -982,12 +1006,14 @@ claim_connection (NMSettings *self, NMSettingsConnection *connection) * have been initially loaded. */ if (priv->connections_loaded) { - /* Internal added signal */ + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_settings, + &signal_info_new_connection, + "(o)", + nm_connection_get_path (NM_CONNECTION (connection))); + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); _notify (self, PROP_CONNECTIONS); - - /* Exported D-Bus signal */ - g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } nm_settings_connection_added (connection); @@ -1312,12 +1338,12 @@ done: } static void -impl_settings_add_connection_add_cb (NMSettings *self, - NMSettingsConnection *connection, - GError *error, - GDBusMethodInvocation *context, - NMAuthSubject *subject, - gpointer user_data) +settings_add_connection_add_cb (NMSettings *self, + NMSettingsConnection *connection, + GError *error, + GDBusMethodInvocation *context, + NMAuthSubject *subject, + gpointer user_data) { if (error) { g_dbus_method_invocation_return_gerror (context, error); @@ -1332,10 +1358,10 @@ impl_settings_add_connection_add_cb (NMSettings *self, } static void -impl_settings_add_connection_helper (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings, - gboolean save_to_disk) +settings_add_connection_helper (NMSettings *self, + GDBusMethodInvocation *context, + GVariant *settings, + gboolean save_to_disk) { gs_unref_object NMConnection *connection = NULL; GError *error = NULL; @@ -1355,77 +1381,111 @@ impl_settings_add_connection_helper (NMSettings *self, connection, save_to_disk, context, - impl_settings_add_connection_add_cb, + settings_add_connection_add_cb, NULL); } static void -impl_settings_add_connection (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings) +impl_settings_add_connection (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - impl_settings_add_connection_helper (self, context, settings, TRUE); + NMSettings *self = NM_SETTINGS (obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get (parameters, "(@a{sa{sv}})", &settings); + settings_add_connection_helper (self, invocation, settings, TRUE); } static void -impl_settings_add_connection_unsaved (NMSettings *self, - GDBusMethodInvocation *context, - GVariant *settings) +impl_settings_add_connection_unsaved (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { - impl_settings_add_connection_helper (self, context, settings, FALSE); + NMSettings *self = NM_SETTINGS (obj); + gs_unref_variant GVariant *settings = NULL; + + g_variant_get (parameters, "(@a{sa{sv}})", &settings); + settings_add_connection_helper (self, invocation, settings, FALSE); } static void -impl_settings_load_connections (NMSettings *self, - GDBusMethodInvocation *context, - char **filenames) +impl_settings_load_connections (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GPtrArray *failures; + gs_unref_ptrarray GPtrArray *failures = NULL; GSList *iter; - int i; + guint i; + gs_free const char **filenames = NULL; + + g_variant_get (parameters, "(^a&s)", &filenames); /* The permission is already enforced by the D-Bus daemon, but we ensure * that the caller is still alive so that clients are forced to wait and * we'll be able to switch to polkit without breaking behavior. */ - if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; - failures = g_ptr_array_new (); + if (filenames) { + for (i = 0; filenames[i]; i++) { + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - for (i = 0; filenames[i]; i++) { - for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { - NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); - - if (nm_settings_plugin_load_connection (plugin, filenames[i])) - break; - } + if (nm_settings_plugin_load_connection (plugin, filenames[i])) + break; + } - if (!iter) { - if (!g_path_is_absolute (filenames[i])) - _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); - g_ptr_array_add (failures, (char *) filenames[i]); + if (!iter) { + if (!g_path_is_absolute (filenames[i])) + _LOGW ("connection filename '%s' is not an absolute path", filenames[i]); + if (!failures) + failures = g_ptr_array_new (); + g_ptr_array_add (failures, (char *) filenames[i]); + } } } - g_ptr_array_add (failures, NULL); - g_dbus_method_invocation_return_value ( - context, - g_variant_new ("(b^as)", - failures->len == 1, - failures->pdata)); - g_ptr_array_unref (failures); + if (failures) + g_ptr_array_add (failures, NULL); + + g_dbus_method_invocation_return_value (invocation, + g_variant_new ("(b^as)", + (gboolean) (!!failures), + failures + ? (const char **) failures->pdata + : NM_PTRARRAY_EMPTY (const char *))); } static void -impl_settings_reload_connections (NMSettings *self, - GDBusMethodInvocation *context) +impl_settings_reload_connections (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; @@ -1433,11 +1493,11 @@ impl_settings_reload_connections (NMSettings *self, * that the caller is still alive so that clients are forced to wait and * we'll be able to switch to polkit without breaking behavior. */ - if (!nm_bus_manager_ensure_uid (nm_bus_manager_get (), - context, - G_MAXULONG, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED)) + if (!nm_dbus_manager_ensure_uid (nm_dbus_object_get_manager (obj), + invocation, + G_MAXULONG, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED)) return; for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { @@ -1446,7 +1506,7 @@ impl_settings_reload_connections (NMSettings *self, nm_settings_plugin_reload_connections (plugin); } - g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE)); + g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", TRUE)); } /*****************************************************************************/ @@ -1498,37 +1558,42 @@ pk_hostname_cb (NMAuthChain *chain, } static void -impl_settings_save_hostname (NMSettings *self, - GDBusMethodInvocation *context, - const char *hostname) +impl_settings_save_hostname (NMDBusObject *obj, + const NMDBusInterfaceInfoExtended *interface_info, + const NMDBusMethodInfoExtended *method_info, + GDBusConnection *connection, + const char *sender, + GDBusMethodInvocation *invocation, + GVariant *parameters) { + NMSettings *self = NM_SETTINGS (obj); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMAuthChain *chain; - GError *error = NULL; + const char *hostname; + + g_variant_get (parameters, "(&s)", &hostname); /* Minimal validation of the hostname */ if (!nm_hostname_manager_validate_hostname (hostname)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_HOSTNAME, - "The hostname was too long or contained invalid characters."); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_HOSTNAME, + "The hostname was too long or contained invalid characters."); + return; } - chain = nm_auth_chain_new_context (context, pk_hostname_cb, self); + chain = nm_auth_chain_new_context (invocation, pk_hostname_cb, self); if (!chain) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to authenticate the request."); - goto done; + g_dbus_method_invocation_return_error_literal (invocation, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to authenticate the request."); + return; } priv->auths = g_slist_append (priv->auths, chain); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free); - -done: - if (error) - g_dbus_method_invocation_take_error (context, error); } /*****************************************************************************/ @@ -1900,13 +1965,123 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); } +static const GDBusSignalInfo signal_info_new_connection = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "NewConnection", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + ), +); + +static const GDBusSignalInfo signal_info_connection_removed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "ConnectionRemoved", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + ), +); + +static const NMDBusInterfaceInfoExtended interface_info_settings = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_SETTINGS, + .methods = NM_DEFINE_GDBUS_METHOD_INFOS ( + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "ListConnections", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connections", "ao"), + ), + ), + .handle = impl_settings_list_connections, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "GetConnectionByUuid", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("uuid", "s"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "o"), + ), + ), + .handle = impl_settings_get_connection_by_uuid, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "AddConnection", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), + ), + ), + .handle = impl_settings_add_connection, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "AddConnectionUnsaved", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("connection", "a{sa{sv}}"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("path", "o"), + ), + ), + .handle = impl_settings_add_connection_unsaved, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "LoadConnections", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("filenames", "as"), + ), + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("status", "b"), + NM_DEFINE_GDBUS_ARG_INFO ("failures", "as"), + ), + ), + .handle = impl_settings_load_connections, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "ReloadConnections", + .out_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("status", "b"), + ), + ), + .handle = impl_settings_reload_connections, + ), + NM_DEFINE_DBUS_METHOD_INFO_EXTENDED ( + NM_DEFINE_GDBUS_METHOD_INFO_INIT ( + "SaveHostname", + .in_args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("hostname", "s"), + ), + ), + .handle = impl_settings_save_hostname, + ), + ), + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &signal_info_new_connection, + &signal_info_connection_removed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Connections", "ao", NM_SETTINGS_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Hostname", "s", NM_SETTINGS_HOSTNAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("CanModify", "b", NM_SETTINGS_CAN_MODIFY), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_settings_class_init (NMSettingsClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - NMExportedObjectClass *exported_object_class = NM_EXPORTED_OBJECT_CLASS (class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (class); - exported_object_class->export_path = NM_DBUS_PATH_SETTINGS; + dbus_object_class->export_path = NM_DBUS_PATH_SETTINGS; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_settings); object_class->get_property = get_property; object_class->dispose = dispose; @@ -1975,23 +2150,4 @@ nm_settings_class_init (NMSettingsClass *class) 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - signals[NEW_CONNECTION] = - g_signal_new ("new-connection", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), - NMDBUS_TYPE_SETTINGS_SKELETON, - "ListConnections", impl_settings_list_connections, - "GetConnectionByUuid", impl_settings_get_connection_by_uuid, - "AddConnection", impl_settings_add_connection, - "AddConnectionUnsaved", impl_settings_add_connection_unsaved, - "LoadConnections", impl_settings_load_connections, - "ReloadConnections", impl_settings_reload_connections, - "SaveHostname", impl_settings_save_hostname, - NULL); } - diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 0ecffb708a..2a5a5053c5 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -28,8 +28,6 @@ #include "nm-connection.h" -#include "nm-exported-object.h" - #define NM_TYPE_SETTINGS (nm_settings_get_type ()) #define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings)) #define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass)) diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build index 555a772e8f..fdf308be09 100644 --- a/src/settings/plugins/ifcfg-rh/meson.build +++ b/src/settings/plugins/ifcfg-rh/meson.build @@ -51,7 +51,7 @@ libnm_settings_plugin_ifcfg_rh = shared_module( sources: sources, dependencies: deps, c_args: cflags, - link_with: [libnmdbus_ifcfg_rh, libnms_ifcfg_rh_core], + link_with: [libnms_ifcfg_rh_core], link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, install: true, diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index 37c3e8d0f8..e66ecfdccc 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -37,7 +37,6 @@ #include "settings/nm-settings-plugin.h" #include "nm-config.h" #include "NetworkManagerUtils.h" -#include "nm-exported-object.h" #include "nms-ifcfg-rh-connection.h" #include "nms-ifcfg-rh-common.h" @@ -807,18 +806,18 @@ _method_call (GDBusConnection *connection, SettingsPluginIfcfg *self = SETTINGS_PLUGIN_IFCFG (user_data); const char *ifcfg; - if (nm_streq0 (interface_name, IFCFGRH1_IFACE1_NAME)) { - if (nm_streq0 (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) { - if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)"))) - g_return_if_reached (); - - g_variant_get (parameters, "(&s)", &ifcfg); - impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg); - return; - } + if ( !nm_streq (interface_name, IFCFGRH1_IFACE1_NAME) + || !nm_streq (method_name, IFCFGRH1_IFACE1_METHOD_GET_IFCFG_DETAILS)) { + g_dbus_method_invocation_return_error (invocation, + G_DBUS_ERROR, + G_DBUS_ERROR_UNKNOWN_METHOD, + "Unknown method %s", + method_name); + return; } - g_return_if_reached (); + g_variant_get (parameters, "(&s)", &ifcfg); + impl_ifcfgrh_get_ifcfg_details (self, invocation, ifcfg); } static GDBusInterfaceInfo *const interface_info = NM_DEFINE_GDBUS_INTERFACE_INFO ( diff --git a/src/tests/config/test-config.c b/src/tests/config/test-config.c index c8ad69a523..8398841d39 100644 --- a/src/tests/config/test-config.c +++ b/src/tests/config/test-config.c @@ -1037,13 +1037,6 @@ main (int argc, char **argv) { nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); - /* Initialize the DBus manager singleton explicitly, because it is accessed by - * the class initializer of NMDevice (used by the NMTestDevice stub). - * This way, we skip calling nm_bus_manager_init_bus() which would - * either fail and/or cause unexpected actions in the test. - * */ - nm_bus_manager_setup (g_object_new (NM_TYPE_BUS_MANAGER, NULL)); - nm_fake_platform_setup (); g_test_add_func ("/config/simple", test_config_simple); diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c index 964167fc8f..7e9b6c9cb0 100644 --- a/src/vpn/nm-vpn-connection.c +++ b/src/vpn/nm-vpn-connection.c @@ -51,8 +51,6 @@ #include "nm-vpn-manager.h" #include "dns/nm-dns-manager.h" -#include "introspection/org.freedesktop.NetworkManager.VPN.Connection.h" - typedef enum { /* Only system secrets */ SECRETS_REQ_SYSTEM = 0, @@ -82,7 +80,6 @@ typedef enum { } VpnState; enum { - VPN_STATE_CHANGED, INTERNAL_STATE_CHANGED, INTERNAL_RETRY_AFTER_FAILURE, @@ -159,19 +156,6 @@ struct _NMVpnConnection { struct _NMVpnConnectionClass { NMActiveConnectionClass parent; - - /* Signals */ - void (*vpn_state_changed) (NMVpnConnection *self, - NMVpnConnectionState new_state, - NMActiveConnectionStateReason reason); - - /* not exported over D-Bus */ - void (*internal_state_changed) (NMVpnConnection *self, - NMVpnConnectionState new_state, - NMVpnConnectionState old_state, - NMActiveConnectionStateReason reason); - - void (*internal_failed_retry) (NMVpnConnection *self); }; G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) @@ -180,6 +164,9 @@ G_DEFINE_TYPE (NMVpnConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) /*****************************************************************************/ +static const NMDBusInterfaceInfoExtended interface_info_vpn_connection; +static const GDBusSignalInfo signal_info_vpn_state_changed; + static NMSettingsConnection *_get_settings_connection (NMVpnConnection *self, gboolean allow_missing); @@ -511,7 +498,12 @@ _set_vpn_state (NMVpnConnection *self, old_external_state = _state_to_nm_vpn_state (old_vpn_state); new_external_state = _state_to_nm_vpn_state (priv->vpn_state); if (new_external_state != old_external_state) { - g_signal_emit (self, signals[VPN_STATE_CHANGED], 0, new_external_state, reason); + nm_dbus_object_emit_signal (NM_DBUS_OBJECT (self), + &interface_info_vpn_connection, + &signal_info_vpn_state_changed, + "(uu)", + (guint32) new_external_state, + (guint32) reason); g_signal_emit (self, signals[INTERNAL_STATE_CHANGED], 0, new_external_state, old_external_state, @@ -1176,8 +1168,8 @@ _cleanup_failed_config (NMVpnConnection *self) { NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - nm_exported_object_clear_and_unexport (&priv->ip4_config); - nm_exported_object_clear_and_unexport (&priv->ip6_config); + nm_dbus_object_clear_and_unexport (&priv->ip4_config); + nm_dbus_object_clear_and_unexport (&priv->ip6_config); _LOGW ("VPN connection: did not receive valid IP config information"); _set_vpn_state (self, STATE_FAILED, NM_ACTIVE_CONNECTION_STATE_REASON_IP_CONFIG_INVALID, FALSE); @@ -1394,12 +1386,12 @@ nm_vpn_connection_config_get (NMVpnConnection *self, GVariant *dict) priv->has_ip4 = FALSE; if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_HAS_IP4, "b", &b)) priv->has_ip4 = b; - nm_exported_object_clear_and_unexport (&priv->ip4_config); + nm_dbus_object_clear_and_unexport (&priv->ip4_config); priv->has_ip6 = FALSE; if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_HAS_IP6, "b", &b)) priv->has_ip6 = b; - nm_exported_object_clear_and_unexport (&priv->ip6_config); + nm_dbus_object_clear_and_unexport (&priv->ip6_config); nm_vpn_connection_config_maybe_complete (self, TRUE); } @@ -1653,7 +1645,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) g_object_unref (config); } else { priv->ip4_config = config; - nm_exported_object_export (NM_EXPORTED_OBJECT (config)); + nm_dbus_object_export (NM_DBUS_OBJECT (config)); g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP4_CONFIG); } @@ -1842,7 +1834,7 @@ next: g_object_unref (config); } else { priv->ip6_config = config; - nm_exported_object_export (NM_EXPORTED_OBJECT (config)); + nm_dbus_object_export (NM_DBUS_OBJECT (config)); g_object_notify ((GObject *) self, NM_ACTIVE_CONNECTION_IP6_CONFIG); } @@ -2329,7 +2321,7 @@ nm_vpn_connection_activate (NMVpnConnection *self, if (nm_vpn_plugin_info_supports_multiple (plugin_info)) { const char *path; - path = nm_exported_object_get_path (NM_EXPORTED_OBJECT (self)); + path = nm_dbus_object_get_path (NM_DBUS_OBJECT (self)); if (path) path = strrchr (path, '/'); g_return_if_fail (path); @@ -2779,8 +2771,8 @@ dispose (GObject *object) nm_clear_g_cancellable (&priv->cancellable); g_clear_object (&priv->proxy_config); - nm_exported_object_clear_and_unexport (&priv->ip4_config); - nm_exported_object_clear_and_unexport (&priv->ip6_config); + nm_dbus_object_clear_and_unexport (&priv->ip4_config); + nm_dbus_object_clear_and_unexport (&priv->ip6_config); g_clear_object (&priv->proxy); g_clear_object (&priv->plugin_info); @@ -2830,14 +2822,14 @@ get_property (GObject *object, guint prop_id, g_value_set_string (value, priv->banner ? priv->banner : ""); break; case PROP_IP4_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->vpn_state) ? priv->ip4_config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->vpn_state) ? priv->ip4_config : NULL); break; case PROP_IP6_CONFIG: - nm_utils_g_value_set_object_path (value, ip_config_valid (priv->vpn_state) ? priv->ip6_config : NULL); + nm_dbus_utils_g_value_set_object_path (value, ip_config_valid (priv->vpn_state) ? priv->ip6_config : NULL); break; case PROP_MASTER: parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (object)); - nm_utils_g_value_set_object_path (value, parent_dev); + nm_dbus_utils_g_value_set_object_path (value, parent_dev); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2845,16 +2837,42 @@ get_property (GObject *object, guint prop_id, } } +static const GDBusSignalInfo signal_info_vpn_state_changed = NM_DEFINE_GDBUS_SIGNAL_INFO_INIT ( + "VpnStateChanged", + .args = NM_DEFINE_GDBUS_ARG_INFOS ( + NM_DEFINE_GDBUS_ARG_INFO ("state", "u"), + NM_DEFINE_GDBUS_ARG_INFO ("reason", "u"), + ), +); + +static const NMDBusInterfaceInfoExtended interface_info_vpn_connection = { + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( + NM_DBUS_INTERFACE_VPN_CONNECTION, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS ( + &nm_signal_info_property_changed_legacy, + &signal_info_vpn_state_changed, + ), + .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("VpnState", "u", NM_VPN_CONNECTION_VPN_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Banner", "s", NM_VPN_CONNECTION_BANNER), + ), + ), + .legacy_property_changed = TRUE, +}; + static void nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (connection_class); NMActiveConnectionClass *active_class = NM_ACTIVE_CONNECTION_CLASS (connection_class); + NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (connection_class); + + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_vpn_connection); - /* virtual methods */ object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; + active_class->device_state_changed = device_state_changed; active_class->device_changed = device_changed; @@ -2881,13 +2899,6 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) g_object_class_override_property (object_class, PROP_IP6_CONFIG, NM_ACTIVE_CONNECTION_IP6_CONFIG); - signals[VPN_STATE_CHANGED] = - g_signal_new ("vpn-state-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); - signals[INTERNAL_STATE_CHANGED] = g_signal_new (NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED, G_OBJECT_CLASS_TYPE (object_class), @@ -2901,8 +2912,4 @@ nm_vpn_connection_class_init (NMVpnConnectionClass *connection_class) G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0); - - nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (connection_class), - NMDBUS_TYPE_VPN_CONNECTION_SKELETON, - NULL); } diff --git a/src/vpn/nm-vpn-connection.h b/src/vpn/nm-vpn-connection.h index 038d0efded..10d40e192b 100644 --- a/src/vpn/nm-vpn-connection.h +++ b/src/vpn/nm-vpn-connection.h @@ -42,7 +42,6 @@ #define NM_VPN_CONNECTION_BANNER "banner" /* Signals */ -/* not exported: includes old reason code */ #define NM_VPN_CONNECTION_INTERNAL_STATE_CHANGED "internal-state-changed" #define NM_VPN_CONNECTION_INTERNAL_RETRY_AFTER_FAILURE "internal-retry-after-failure" |