diff options
Diffstat (limited to 'src/libnm-client-impl/nm-device.c')
| -rw-r--r-- | src/libnm-client-impl/nm-device.c | 120 |
1 files changed, 108 insertions, 12 deletions
diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c index 4d097935..a680a05f 100644 --- a/src/libnm-client-impl/nm-device.c +++ b/src/libnm-client-impl/nm-device.c @@ -61,7 +61,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice, PROP_IP4_CONNECTIVITY, PROP_IP6_CONNECTIVITY, PROP_INTERFACE_FLAGS, - PROP_HW_ADDRESS, ); + PROP_HW_ADDRESS, + PROP_PORTS, ); enum { STATE_CHANGED, @@ -80,9 +81,15 @@ enum { _PROPERTY_O_IDX_NUM, }; +enum { + PROPERTY_AO_IDX_AVAILABLE_CONNECTIONS, + PROPERTY_AO_IDX_PORTS, + _PROPERTY_AO_IDX_NUM, +}; + typedef struct _NMDevicePrivate { NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NUM]; - NMLDBusPropertyAO available_connections; + NMLDBusPropertyAO property_ao[_PROPERTY_AO_IDX_NUM]; GPtrArray * lldp_neighbors; char * driver; char * driver_version; @@ -109,6 +116,7 @@ typedef struct _NMDevicePrivate { bool real; bool hw_address_is_new : 1; + bool ports_is_new : 1; guint32 old_state; @@ -457,6 +465,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) case PROP_HW_ADDRESS: g_value_set_string(value, nm_device_get_hw_address(device)); break; + case PROP_PORTS: + g_value_take_boxed(value, _nm_utils_copy_object_array(nm_device_get_ports(device))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -509,7 +520,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT NML_DBUS_META_PROPERTY_INIT_AO_PROP("AvailableConnections", PROP_AVAILABLE_CONNECTIONS, NMDevicePrivate, - available_connections, + property_ao[PROPERTY_AO_IDX_AVAILABLE_CONNECTIONS], nm_remote_connection_get_type, .is_always_ready = TRUE), NML_DBUS_META_PROPERTY_INIT_U("Capabilities", @@ -588,6 +599,15 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT PROP_PHYSICAL_PORT_ID, NMDevicePrivate, physical_port_id), + NML_DBUS_META_PROPERTY_INIT_FCN( + "Ports", + PROP_PORTS, + "ao", + _nm_device_notify_update_prop_ports, + .prop_struct_offset = + G_STRUCT_OFFSET(NMDevicePrivate, property_ao[PROPERTY_AO_IDX_PORTS]), + .extra.property_vtable_ao = + &((const NMLDBusPropertVTableAO){.get_o_type_fcn = (nm_device_get_type)})), NML_DBUS_META_PROPERTY_INIT_B("Real", PROP_REAL, NMDevicePrivate, real), NML_DBUS_META_PROPERTY_INIT_IGNORE("State", "u"), NML_DBUS_META_PROPERTY_INIT_FCN("StateReason", @@ -595,6 +615,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device = NML_DBUS_META_IFACE_INIT "(uu)", _notify_update_prop_state_reason), NML_DBUS_META_PROPERTY_INIT_S("Udi", PROP_UDI, NMDevicePrivate, udi), ), + .base_struct_offset = G_STRUCT_OFFSET(NMDevice, _priv), ); static void @@ -614,9 +635,7 @@ nm_device_class_init(NMDeviceClass *klass) _NM_OBJECT_CLASS_INIT_PRIV_PTR_INDIRECT(nm_object_class, NMDevice); _NM_OBJECT_CLASS_INIT_PROPERTY_O_FIELDS_N(nm_object_class, NMDevicePrivate, property_o); - _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_1(nm_object_class, - NMDevicePrivate, - available_connections); + _NM_OBJECT_CLASS_INIT_PROPERTY_AO_FIELDS_N(nm_object_class, NMDevicePrivate, property_ao); klass->connection_compatible = connection_compatible; @@ -1034,6 +1053,20 @@ nm_device_class_init(NMDeviceClass *klass) NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMDevice:ports: + * + * The port devices of the controller device. For devices that cannot be + * controllers this is likely to be always empty. + * + * Since: 1.34 + **/ + obj_properties[PROP_PORTS] = g_param_spec_boxed(NM_DEVICE_PORTS, + "", + "", + G_TYPE_PTR_ARRAY, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device); /** @@ -1241,6 +1274,27 @@ nm_device_get_type_description(NMDevice *device) return _nml_coerce_property_str_not_empty(priv->type_description); } +/** + * nm_device_get_ports: + * @device: a #NMDevice + * + * Gets the devices currently set as port of @device. + * + * Returns: (element-type NMDevice): the #GPtrArray containing #NMDevices that + * are slaves of @device. This is the internal copy used by the device and + * must not be modified. + * + * Since: 1.34 + **/ +const GPtrArray * +nm_device_get_ports(NMDevice *device) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), NULL); + + return nml_dbus_property_ao_get_objs_as_ptrarray( + &NM_DEVICE_GET_PRIVATE(device)->property_ao[PROPERTY_AO_IDX_PORTS]); +} + NMLDBusNotifyUpdatePropFlags _nm_device_notify_update_prop_hw_address(NMClient * client, NMLDBusObject * dbobj, @@ -1267,8 +1321,8 @@ _nm_device_notify_update_prop_hw_address(NMClient * client, priv->hw_address_is_new = is_new; - nm_utils_strdup_reset(&priv->hw_address, - _nml_coerce_property_str_not_empty(g_variant_get_string(value, NULL))); + nm_strdup_reset(&priv->hw_address, + _nml_coerce_property_str_not_empty(g_variant_get_string(value, NULL))); /* always emit a changed signal here, even if "priv->hw_address" might be unchanged. * We want to emit the signal because we received a PropertiesChanged signal on D-Bus, @@ -1305,6 +1359,48 @@ nm_device_get_hw_address(NMDevice *device) return priv->hw_address; } +NMLDBusNotifyUpdatePropFlags +_nm_device_notify_update_prop_ports(NMClient * client, + NMLDBusObject * dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant * value) +{ + const NMLDBusMetaProperty *meta_property = + &_nml_dbus_meta_iface_nm_device.dbus_properties[_NML_DEVICE_META_PROPERTY_INDEX_PORTS]; + NMLDBusNotifyUpdatePropFlags notify_update_prop_flags; + NMDevice * self = NM_DEVICE(dbobj->nmobj); + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceClass * klass; + gboolean is_new = (meta_iface == &_nml_dbus_meta_iface_nm_device); + + nm_assert(nm_streq(meta_property->dbus_property_name, "Ports")); + + if (!is_new && priv->ports_is_new) { + /* once the instance is marked to honor the new property, the + * changed signal for the old variant gets ignored. */ + goto out; + } + priv->ports_is_new = is_new; + + notify_update_prop_flags = + nml_dbus_property_ao_notify(client, + &priv->property_ao[PROPERTY_AO_IDX_PORTS], + dbobj, + &_nml_dbus_meta_iface_nm_device, + _NML_DEVICE_META_PROPERTY_INDEX_PORTS, + value); + if (notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE) + goto out; + nm_assert(notify_update_prop_flags == NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY); + + klass = NM_DEVICE_GET_CLASS(self); + if (klass->slaves_param_spec) + _nm_client_queue_notify_object(client, self, klass->slaves_param_spec); +out: + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NONE; +} + /** * nm_device_get_capabilities: * @device: a #NMDevice @@ -1652,7 +1748,7 @@ nm_device_get_available_connections(NMDevice *device) g_return_val_if_fail(NM_IS_DEVICE(device), NULL); return nml_dbus_property_ao_get_objs_as_ptrarray( - &NM_DEVICE_GET_PRIVATE(device)->available_connections); + &NM_DEVICE_GET_PRIVATE(device)->property_ao[PROPERTY_AO_IDX_AVAILABLE_CONNECTIONS]); } static const char * @@ -2770,7 +2866,7 @@ connection_compatible(NMDevice *device, NMConnection *connection, GError **error g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, - _("The interface names of the device and the connection didn't match.")); + _("The interface names of the device and the connection didn't match")); return FALSE; } @@ -2999,9 +3095,9 @@ nm_lldp_neighbor_get_attr_names(NMLldpNeighbor *neighbor) g_return_val_if_fail(NM_IS_LLDP_NEIGHBOR(neighbor), NULL); - keys = nm_utils_strdict_get_keys(neighbor->attrs, TRUE, NULL); + keys = nm_strdict_get_keys(neighbor->attrs, TRUE, NULL); - return nm_utils_strv_make_deep_copied_nonnull(keys); + return nm_strv_make_deep_copied_nonnull(keys); } /** |