/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2018 Red Hat, Inc. */ #ifndef __NM_DBUS_UTILS_H__ #define __NM_DBUS_UTILS_H__ /*****************************************************************************/ 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); bool allow_during_shutdown; } 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, guint * property_idx); 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); /*****************************************************************************/ struct CList; const char **nm_dbus_utils_get_paths_for_clist(const struct CList *lst_head, gssize lst_len, guint member_offset, gboolean expect_all_exported); void nm_dbus_utils_g_value_set_object_path(GValue *value, gpointer object); void nm_dbus_utils_g_value_set_object_path_still_exported(GValue *value, gpointer object); void nm_dbus_utils_g_value_set_object_path_from_hash(GValue * value, GHashTable *hash, gboolean expect_all_exported); /*****************************************************************************/ typedef struct { union { gpointer const obj; gpointer _obj; }; GObject * _notify_target; const GParamSpec *_notify_pspec; gulong _notify_signal_id; union { const bool visible; bool _visible; }; } NMDBusTrackObjPath; void nm_dbus_track_obj_path_init(NMDBusTrackObjPath *track, GObject *target, const GParamSpec *pspec); void nm_dbus_track_obj_path_deinit(NMDBusTrackObjPath *track); void nm_dbus_track_obj_path_notify(const NMDBusTrackObjPath *track); const char *nm_dbus_track_obj_path_get(const NMDBusTrackObjPath *track); void nm_dbus_track_obj_path_set(NMDBusTrackObjPath *track, gpointer obj, gboolean visible); #endif /* __NM_DBUS_UTILS_H__ */