summary refs log tree commit diff
path: root/tools
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2021-10-01 23:05:04 +0200
committerMichael Biebl <biebl@debian.org>2021-10-01 23:05:04 +0200
commite74c568b07b50b97873fb4ee1d776dedefbd54d6 (patch)
tree3469f17ea9af91f7ff169b890633bda68b0cf76e /tools
parentbfe522304da217296e2a61040f58e35ec5d6f3f2 (diff)
New upstream version 1.32.12 upstream/1.32.12
Diffstat (limited to 'tools')
-rwxr-xr-xtools/check-docs.sh10
-rwxr-xr-xtools/check-tree.sh6
-rwxr-xr-xtools/create-exports-NetworkManager.sh31
-rwxr-xr-xtools/generate-docs-nm-property-infos.pl159
-rwxr-xr-xtools/generate-docs-nm-property-infos.py140
-rwxr-xr-xtools/generate-docs-nm-settings-docs-merge.py3
-rwxr-xr-xtools/run-nm-test.sh16
-rwxr-xr-xtools/test-networkmanager-service.py113
8 files changed, 191 insertions, 287 deletions
diff --git a/tools/check-docs.sh b/tools/check-docs.sh
index f4f05b91..c2e6761d 100755
--- a/tools/check-docs.sh
+++ b/tools/check-docs.sh
@@ -23,15 +23,15 @@ same_lines() {
 
 libnm_headers() {
     (
-        ls -1 "$1/libnm"/*.h "$1/libnm-core"/*.h | \
+        ls -1 "$1/src/libnm-client-public"/*.h "$1/src/libnm-core-public"/*.h | \
         if [ -n "$2" ]; then
-            grep -v -F "$1/libnm-core/nm-core-enum-types.h" | \
-            grep -v -F "$1/libnm/nm-enum-types.h"
+            grep -v -F "$1/src/libnm-core-public/nm-core-enum-types.h" | \
+            grep -v -F "$1/src/libnm-client-public/nm-enum-types.h"
         else
             cat
         fi
         if [ -n "$2" ]; then
-            ls -1 "$2/libnm"/*.h "$2/libnm-core"/*.h
+            ls -1 "$2/src/libnm-client-public"/*.h "$2/src/libnm-core-public"/*.h
         fi
     ) | sort | uniq
 }
@@ -63,7 +63,7 @@ F1_EXTRA="
 nm-core-enum-types
 nm-enum-types
 "
-F2="$(grep -l "$(sed -n 's/^[\t ]*\(.*_get_type\);/\1/p' "$SOURCEDIR/libnm/libnm.ver" | word_regex)" \
+F2="$(grep -l "$(sed -n 's/^[\t ]*\(.*_get_type\);/\1/p' "$SOURCEDIR/src/libnm-client-impl/libnm.ver" | word_regex)" \
            $(libnm_headers "$SOURCEDIR" "$BUILDDIR") \
       | sed 's,.*/\([^/]\+\)\.h$,\1,')"
 F2_EXTRA="
diff --git a/tools/check-tree.sh b/tools/check-tree.sh
index cff85c3e..b9504961 100755
--- a/tools/check-tree.sh
+++ b/tools/check-tree.sh
@@ -19,6 +19,6 @@ check_cmp() {
     die "files \"$a\" and \"$b\" differ!"
 }
 
-check_cmp shared/nm-base/nm-ethtool-utils-base.h libnm/nm-ethtool-utils.h
-check_cmp libnm-core/nm-meta-setting-base-impl.h clients/common/nm-meta-setting-base-impl.h
-check_cmp libnm-core/nm-meta-setting-base-impl.c clients/common/nm-meta-setting-base-impl.c
+check_cmp src/libnm-base/nm-ethtool-utils-base.h src/libnm-client-public/nm-ethtool-utils.h
+check_cmp src/libnm-core-intern/nm-meta-setting-base-impl.h src/libnmc-setting/nm-meta-setting-base-impl.h
+check_cmp src/libnm-core-impl/nm-meta-setting-base-impl.c src/libnmc-setting/nm-meta-setting-base-impl.c
diff --git a/tools/create-exports-NetworkManager.sh b/tools/create-exports-NetworkManager.sh
index f7fd3bab..21ba369a 100755
--- a/tools/create-exports-NetworkManager.sh
+++ b/tools/create-exports-NetworkManager.sh
@@ -35,15 +35,18 @@ _sort() {
 }
 
 call_nm() {
-    "${NM:-nm}" "$1" |
-        sed -n 's/.* \([^ ]\) \([^ ]*\)$/\1 \2/p'
+    if [ -n "$from_meson" ]; then
+        "${NM:-nm}" "$1" |
+            sed -n 's/.* \([^ ]\) \([^ ]*\)$/\1 \2/p'
+    else
+        libtool=(${LIBTOOL:-libtool})
+        ${libtool[@]} --mode=execute "${NM:-nm}" "$1" |
+            sed -n 's/.* \([^ ]\) \([^ ]*\)$/\1 \2/p'
+    fi
 }
 
 get_symbols_nm () {
-    base=./src/core/.libs/NetworkManager-all-sym
-    if ! test -f "$base"; then
-        base=./src/core/NetworkManager-all-sym
-    fi
+    base=./src/core/NetworkManager-all-sym
     call_nm "$base" |
         sed -n 's/^[tTDGRBS] //p' |
         _sort
@@ -85,6 +88,14 @@ do_update() {
     do_generate > ./src/core/NetworkManager.ver
 }
 
+if [ -f "build.ninja" ]; then
+    from_meson=1
+    libs=
+else
+    from_meson=
+    libs=.libs/
+fi
+
 SYMBOLS_MISSING="$(get_symbols_missing | pretty)"
 SYMBOLS_EXPLICIT="$(get_symbols_explicit | pretty)"
 
@@ -102,14 +113,6 @@ local:
 EOF
 }
 
-if [ -f "build.ninja" ]; then
-    from_meson=1
-    libs=
-else
-    from_meson=
-    libs=.libs/
-fi
-
 test -f ./src/core/${libs}libNetworkManager.a || die "must be called from NetworkManager top build dir after building the tree"
 
 case "$1" in
diff --git a/tools/generate-docs-nm-property-infos.pl b/tools/generate-docs-nm-property-infos.pl
deleted file mode 100755
index f850ee74..00000000
--- a/tools/generate-docs-nm-property-infos.pl
+++ /dev/null
@@ -1,159 +0,0 @@
-#!/usr/bin/env perl
-# SPDX-License-Identifier: GPL-2.0-or-later
-#
-# Copyright (C) 2014 Red Hat, Inc.
-#
-
-#
-# The script parses nm-setting-*.c files and extracts documentation related
-# to setting plugins. The documentation is in a simple format of lines
-# "keyword: value". The documentation is enclosed between tags
-# ---<plugin-name>--- and ---end---
-# Recognized keywords are:
-# "property: "     - property name
-# "variable: "     - name of the variable used by the plugin
-# "format: "       - format of the value in 'keyfile' plugin
-# "default: "      - default value when variable is not used
-# "values: "       - allowed values (e.g. for enumerations)
-# "example: "      - example(s)
-# "description: "  - description text
-# Value is an arbitrary string that can span over multiple lines.
-#
-# ifcfg-rh specifics:
-#  - mark NM extension variables with (+), e.g. variable: UUID(+)
-#
-
-use strict;
-use warnings;
-use v5.10;
-
-# global variables
-my @keywords = ("property", "variable", "format", "values", "default", "example", "description");
-my @data;
-my $fo;
-
-(scalar @ARGV >= 3) or die "Usage: $0 <plugin> <output-xml-file> <srcfiles>\n";
-my ($plugin, $output, (@source_files)) = @ARGV;
-my $start_tag = "---$plugin---\\s*\$";
-my $end_tag   = '---end---';
-
-# open output file
-open $fo, '>', $output or die "Can't open $output: $!";
-
-# write XML header
-write_header();
-
-# write generated documentation for each setting
-foreach my $c_file (@source_files) {
-  my $setting_name = get_setting_name($c_file);
-  if ($setting_name) {
-    write_item("<setting name=\"$setting_name\">");
-    scan_doc_comments($c_file, $start_tag, $end_tag);
-    write_item("</setting>");
-  }
-}
-
-# write XML footer
-write_footer();
-
-# close output file
-close $fo;
-
-
-### --- subroutines --- ###
-
-# get setting name from NM_SETTING_*_SETTING_NAME constant in C header file
-sub get_setting_name {
-  my $path = $_[0];
-  $path =~ s/c$/h/;  # use header file to find out setting name
-  open my $fh, '<', $path or die "Can't open $path: $!";
-  while (my $line = <$fh>) {
-    if ($line =~ /NM_SETTING_.+SETTING_NAME\s+\"(\S+)\"/) {
-      return $1;
-    }
-  }
-}
-
-# scan source setting file for documentation tags and write them to XML
-sub scan_doc_comments {
-  my($setting_file, $start, $end) = @_;
-  open my $fi, '<', $setting_file or die "Can't open $setting_file: $!";
-  while (<$fi>) {
-    if (/$start/ .. /$end/) {
-      next if /$start/;
-      if (/$end/) {
-        process_data();
-      } else {
-        push @data, $_;
-      }
-      next;
-    }
-    # ignore text not inside marks
-  }
-  close $fi;
-}
-
-# process plugin property documentation comments
-sub process_data {
-  return if not @data;
-  my $kwd_pat = join("|", @keywords);
-  my %parsed_data;
-  my $this_key;
-
-  foreach (@data) {
-    if (/^\s*\**\s+($kwd_pat):\s+(.*?)\s*$/) {
-      $this_key = $1;
-      $parsed_data{$this_key} = "$2\n";
-    } elsif (/^\s*\**\s+(.*?)\s*$/) {
-      die "Extra mess in a comment: $_" unless $this_key;
-      $parsed_data{$this_key} .= "$1\n";
-    }
-  }
-
-  # now write a line into the XML
-  my $name   = $parsed_data{property}    // "";
-  my $var    = $parsed_data{variable}    // $name;  # fallback to "property: "
-  my $format = $parsed_data{format}      // "";
-  my $values = $parsed_data{values}      // "";
-  my $def    = $parsed_data{default}     // "";
-  my $exam   = $parsed_data{example}     // "";
-  my $desc   = $parsed_data{description} // "";
-
-  chomp($name, $var, $format, $values, $def, $exam, $desc);
-  escape_xml_chars($name, $var, $format, $values, $def, $exam, $desc);
-  my $foo = sprintf("<property name=\"%s\" variable=\"%s\" format=\"%s\" values=\"%s\" ".
-                    "default=\"%s\" example=\"%s\" description=\"%s\"/>",
-                    $name, $var, $format, $values, $def, $exam, $desc);
-  write_item($foo);
-  @data = ();
-}
-
-# - XML handling -
-sub write_header {
-  (my $header =
-    qq{<nm-setting-docs>
-  }) =~ s/^ {7}//mg;
-  print {$fo} $header;
-}
-
-sub write_footer {
-  my $footer = "</nm-setting-docs>";
-  print {$fo} $footer;
-}
-
-sub write_item {
-  my $str = join("", @_);
-  print {$fo} $str, "\n";
-}
-
-sub escape_xml_chars {
-  # http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined%5Fentities%5Fin%5FXML
-  foreach my $val (@_) {
-    $val =~ s/&/&amp;/sg;
-    $val =~ s/</&lt;/sg;
-    $val =~ s/>/&gt;/sg;
-    $val =~ s/"/&quot;/sg;
-    $val =~ s/'/&apos;/sg;
-  }
-}
-
diff --git a/tools/generate-docs-nm-property-infos.py b/tools/generate-docs-nm-property-infos.py
new file mode 100755
index 00000000..fe2053a3
--- /dev/null
+++ b/tools/generate-docs-nm-property-infos.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+import re
+import sys
+import xml.etree.ElementTree as ET
+
+
+def get_setting_name(one_file):
+    setting_name = ""
+    assert re.match(r".*/libnm-core-impl/nm-setting-.*\.c$", one_file)
+    header_path = one_file.replace("libnm-core-impl", "libnm-core-public")
+    header_path = header_path.replace(".c", ".h")
+    try:
+        header_reader = open(header_path, "r")
+    except OSError:
+        print("Can not open header file: %s" % (header_path))
+        exit(1)
+
+    line = header_reader.readline()
+    while line != "":
+        setting_name_found = re.search(r"NM_SETTING_.+SETTING_NAME\s+\"(\S+)\"", line)
+        if setting_name_found:
+            setting_name = setting_name_found.group(1)
+            break
+        line = header_reader.readline()
+    header_reader.close()
+    return setting_name
+
+
+def scan_doc_comments(plugin, setting_node, file, start_tag, end_tag):
+    data = []
+    push_flag = 0
+    try:
+        file_reader = open(file, "r")
+    except OSError:
+        print("Can not open file: %s" % (file))
+        exit(1)
+
+    line = file_reader.readline()
+    while line != "":
+        if start_tag in line:
+            push_flag = 1
+        elif end_tag in line and push_flag == 1:
+            push_flag = 0
+            parsed_data = process_data(data)
+            if parsed_data:
+                write_data(setting_node, parsed_data)
+            data = []
+        elif push_flag == 1:
+            data.append(line)
+        line = file_reader.readline()
+    file_reader.close()
+    return
+
+
+def process_data(data):
+    parsed_data = {}
+    if not data:
+        return parsed_data
+    keywords = [
+        "property",
+        "variable",
+        "format",
+        "values",
+        "default",
+        "example",
+        "description",
+    ]
+    kwd_pat = "|".join(keywords)
+    keyword = ""
+    for line in data:
+        kwd_first_line_found = re.search(
+            r"^\s*\**\s+({}):\s+(.*?)\s*$".format(kwd_pat), line
+        )
+        kwd_more_line_found = re.search(r"^\s*\**\s+(.*?)\s*$", line)
+        if kwd_first_line_found:
+            keyword = kwd_first_line_found.group(1)
+            value = kwd_first_line_found.group(2) + " "
+            parsed_data[keyword] = value
+        elif kwd_more_line_found:
+            if not keyword:
+                print("Extra mess in a comment: %s" % (line))
+                exit(1)
+            else:
+                value = kwd_more_line_found.group(1) + " "
+                parsed_data[keyword] += value
+    for keyword in keywords:
+        if keyword == "variable" and keyword not in parsed_data:
+            parsed_data[keyword] = parsed_data["property"]
+        elif keyword not in parsed_data:
+            parsed_data[keyword] = ""
+    for key in parsed_data.keys():
+        parsed_data[key] = parsed_data[key].rstrip()
+    return parsed_data
+
+
+def write_data(setting_node, parsed_data):
+    property_node = ET.SubElement(setting_node, "property")
+    property_node.set("name", parsed_data["property"])
+    property_node.set("variable", parsed_data["variable"])
+    property_node.set("format", parsed_data["format"])
+    property_node.set("values", parsed_data["values"])
+    property_node.set("default", parsed_data["default"])
+    property_node.set("example", parsed_data["example"])
+    property_node.set("description", parsed_data["description"])
+
+
+def pretty_xml(element, newline, level=0):
+    if element:
+        if (element.text is None) or element.text.isspace():
+            element.text = newline
+        else:
+            element.text = newline + element.text.strip() + newline
+    temp = list(element)
+    for subelement in temp:
+        subelement.tail = newline
+        pretty_xml(subelement, newline, level=level + 1)
+
+
+if len(sys.argv) < 4:
+    print("Usage: %s [plugin] [output-xml-file] [srcfiles]" % (sys.argv[0]))
+    exit(1)
+
+argv = list(sys.argv[1:])
+plugin, output, source_files = argv[0], argv[1], argv[2:]
+start_tag = "---" + plugin + "---"
+end_tag = "---end---"
+root_node = ET.Element("nm-setting-docs")
+
+for one_file in source_files:
+    setting_name = get_setting_name(one_file)
+    if setting_name:
+        setting_node = ET.SubElement(root_node, "setting", name=setting_name)
+        setting_node.text = "\n"
+        scan_doc_comments(plugin, setting_node, one_file, start_tag, end_tag)
+
+pretty_xml(root_node, "\n")
+
+ET.ElementTree(root_node).write(output)
diff --git a/tools/generate-docs-nm-settings-docs-merge.py b/tools/generate-docs-nm-settings-docs-merge.py
index 5fe61997..a478ae75 100755
--- a/tools/generate-docs-nm-settings-docs-merge.py
+++ b/tools/generate-docs-nm-settings-docs-merge.py
@@ -3,9 +3,8 @@
 
 from __future__ import print_function
 
-import os
-import sys
 import collections
+import sys
 import xml.etree.ElementTree as ET
 
 ###############################################################################
diff --git a/tools/run-nm-test.sh b/tools/run-nm-test.sh
index 6d835a8f..81b94ec6 100755
--- a/tools/run-nm-test.sh
+++ b/tools/run-nm-test.sh
@@ -216,8 +216,8 @@ else
                 BUILDDIR="$(dirname "$BUILDDIR")"
                 [[ "$BUILDDIR" == / ]] && BUILDDIR=
                 [[ -z "$BUILDDIR" ]] && break
-                [[ -e "$BUILDDIR/libnm/.libs/libnm.so" ]] && break
-                [[ -e "$BUILDDIR/libnm/libnm.so" ]] && break
+                [[ -e "$BUILDDIR/src/libnm-client-impl/.libs/libnm.so" ]] && break
+                [[ -e "$BUILDDIR/src/libnm-client-impl/libnm.so" ]] && break
             done
         fi
     fi
@@ -244,7 +244,7 @@ TEST_NAME="${TEST##*/}"
 
 if [ -z "${NMTST_LAUNCH_DBUS}" ]; then
     # autodetect whether to launch D-Bus based on the test path.
-    if [[ $TEST_PATH == */libnm/tests ]]; then
+    if [[ $TEST_PATH == */src/libnm-client-impl/tests ]]; then
         NMTST_LAUNCH_DBUS=1
     else
         NMTST_LAUNCH_DBUS=0
@@ -270,12 +270,12 @@ fi
 [ -x "$TEST" ] || die "Cannot execute test \"$TEST\""
 
 if [[ -n "$BUILDDIR" ]]; then
-    if [[ -d "$BUILDDIR/libnm" ]]; then
-        export GI_TYPELIB_PATH="$BUILDDIR/libnm/${GI_TYPELIB_PATH:+:$GI_TYPELIB_PATH}"
-        if [[ -d "$BUILDDIR/libnm/.libs" ]]; then
-            export LD_LIBRARY_PATH="$BUILDDIR/libnm/.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
+    if [[ -d "$BUILDDIR/src/libnm-client-impl" ]]; then
+        export GI_TYPELIB_PATH="$BUILDDIR/src/libnm-client-impl/${GI_TYPELIB_PATH:+:$GI_TYPELIB_PATH}"
+        if [[ -d "$BUILDDIR/src/libnm-client-impl/.libs" ]]; then
+            export LD_LIBRARY_PATH="$BUILDDIR/src/libnm-client-impl/.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
         else
-            export LD_LIBRARY_PATH="$BUILDDIR/libnm${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
+            export LD_LIBRARY_PATH="$BUILDDIR/src/libnm-client-impl${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
         fi
     fi
 fi
diff --git a/tools/test-networkmanager-service.py b/tools/test-networkmanager-service.py
index fe5e4d44..66af0ede 100755
--- a/tools/test-networkmanager-service.py
+++ b/tools/test-networkmanager-service.py
@@ -623,9 +623,7 @@ class NmUtil:
 
 class ExportedObj(dbus.service.Object):
 
-    DBusInterface = collections.namedtuple(
-        "DBusInterface", ["dbus_iface", "props", "legacy_prop_changed_func"]
-    )
+    DBusInterface = collections.namedtuple("DBusInterface", ["dbus_iface", "props"])
 
     @staticmethod
     def create_path(klass, path_prefix=None):
@@ -673,10 +671,8 @@ class ExportedObj(dbus.service.Object):
         gl.object_manager.remove_object(self)
         self.remove_from_connection()
 
-    def dbus_interface_add(self, dbus_iface, props, legacy_prop_changed_func=None):
-        self._dbus_ifaces[dbus_iface] = ExportedObj.DBusInterface(
-            dbus_iface, props, legacy_prop_changed_func
-        )
+    def dbus_interface_add(self, dbus_iface, props):
+        self._dbus_ifaces[dbus_iface] = ExportedObj.DBusInterface(dbus_iface, props)
 
     def _dbus_interface_get(self, dbus_iface):
         if dbus_iface not in self._dbus_ifaces:
@@ -773,15 +769,6 @@ class ExportedObj(dbus.service.Object):
             prop = {propname: prop}
         ExportedObj.PropertiesChanged(self, dbus_iface, prop, [])
 
-        # the legacy_prop_changed_func signal is a legacy signal that got obsoleted by the standard
-        # PropertiesChanged signal. NetworkManager (and this stub) still emit it for backward
-        # compatibility reasons. Note that this stub server implementation gets this wrong,
-        # for example, it emits PropertiesChanged signal on org.freedesktop.NetworkManager.Device,
-        # which NetworkManager never did.
-        # See https://gitlab.freedesktop.org/NetworkManager/NetworkManager/blob/db80d5f62a1edf39c5970887ef7b9ec62dd4163f/src/nm-dbus-manager.c#L1274
-        if dbus_interface.legacy_prop_changed_func is not None:
-            dbus_interface.legacy_prop_changed_func(self, prop)
-
     @dbus.service.signal(dbus.PROPERTIES_IFACE, signature="sa{sv}as")
     def PropertiesChanged(self, iface, changed, invalidated):
         pass
@@ -996,7 +983,7 @@ class Device(ExportedObj):
             ),
         }
 
-        self.dbus_interface_add(IFACE_DEVICE, props, Device.PropertiesChanged)
+        self.dbus_interface_add(IFACE_DEVICE, props)
 
     def start(self):
         self.ip4_config = IP4Config()
@@ -1060,10 +1047,6 @@ class Device(ExportedObj):
     def StateChanged(self, new_state, old_state, reason):
         pass
 
-    @dbus.service.signal(IFACE_DEVICE, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
-
     def set_state(self, state, reason):
         # libnm is plugged on notify::state-reason and not on state-changed dbus signal
         # so we must simulate the change of property to emit a state-changed signal on libnm
@@ -1143,11 +1126,7 @@ class WiredDevice(Device):
             PRP_WIRED_S390_SUBCHANNELS: subchannels,
         }
 
-        self.dbus_interface_add(IFACE_WIRED, props, WiredDevice.PropertiesChanged)
-
-    @dbus.service.signal(IFACE_WIRED, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
+        self.dbus_interface_add(IFACE_WIRED, props)
 
 
 ###############################################################################
@@ -1167,11 +1146,7 @@ class ModemDevice(Device):
             PM_MODEM_CAPABILITIES: dbus.UInt32(0),
         }
 
-        self.dbus_interface_add(IFACE_MODEM, props, ModemDevice.PropertiesChanged)
-
-    @dbus.service.signal(IFACE_MODEM, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
+        self.dbus_interface_add(IFACE_MODEM, props)
 
 
 ###############################################################################
@@ -1191,11 +1166,7 @@ class VlanDevice(Device):
             PRP_VLAN_VLAN_ID: dbus.UInt32(1),
         }
 
-        self.dbus_interface_add(IFACE_VLAN, props, VlanDevice.PropertiesChanged)
-
-    @dbus.service.signal(IFACE_VLAN, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
+        self.dbus_interface_add(IFACE_VLAN, props)
 
 
 ###############################################################################
@@ -1270,11 +1241,7 @@ class WifiAp(ExportedObj):
             PRP_WIFI_AP_LAST_SEEN: dbus.Int32(NM.utils_get_timestamp_msec() / 1000),
         }
 
-        self.dbus_interface_add(IFACE_WIFI_AP, props, WifiAp.PropertiesChanged)
-
-    @dbus.service.signal(IFACE_WIFI_AP, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
+        self.dbus_interface_add(IFACE_WIFI_AP, props)
 
 
 ###############################################################################
@@ -1315,7 +1282,7 @@ class WifiDevice(Device):
             PRP_WIFI_LAST_SCAN: dbus.Int64(ts),
         }
 
-        self.dbus_interface_add(IFACE_WIFI, props, WifiDevice.PropertiesChanged)
+        self.dbus_interface_add(IFACE_WIFI, props)
 
     @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature="", out_signature="ao")
     def GetAccessPoints(self):
@@ -1375,10 +1342,6 @@ class WifiDevice(Device):
     def AccessPointRemoved(self, ap_path):
         pass
 
-    @dbus.service.signal(IFACE_WIFI, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
-
     def remove_ap_by_path(self, path):
         for ap in self.aps:
             if ap.path == path:
@@ -1446,9 +1409,7 @@ class ActiveConnection(ExportedObj):
             PRP_ACTIVE_CONNECTION_MASTER: ExportedObj.to_path(None),
         }
 
-        self.dbus_interface_add(
-            IFACE_ACTIVE_CONNECTION, props, ActiveConnection.PropertiesChanged
-        )
+        self.dbus_interface_add(IFACE_ACTIVE_CONNECTION, props)
 
         if self.is_vpn:
             props = {
@@ -1459,9 +1420,7 @@ class ActiveConnection(ExportedObj):
                 % (con_inst.get_id()),
             }
 
-            self.dbus_interface_add(
-                IFACE_VPN_CONNECTION, props, ActiveConnection.VpnPropertiesChanged
-            )
+            self.dbus_interface_add(IFACE_VPN_CONNECTION, props)
 
     def _set_state(self, state, reason):
         state = dbus.UInt32(state)
@@ -1543,16 +1502,6 @@ class ActiveConnection(ExportedObj):
         )
         self._deactivation_id = GLib.timeout_add(50, self._deactivation_step1)
 
-    @dbus.service.signal(IFACE_VPN_CONNECTION, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
-
-    VpnPropertiesChanged = PropertiesChanged
-
-    @dbus.service.signal(IFACE_ACTIVE_CONNECTION, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
-
     @dbus.service.signal(IFACE_ACTIVE_CONNECTION, signature="uu")
     def StateChanged(self, state, reason):
         pass
@@ -1609,7 +1558,7 @@ class NetworkManager(ExportedObj):
             PRP_NM_CONNECTIVITY: dbus.UInt32(NM.ConnectivityState.NONE),
         }
 
-        self.dbus_interface_add(IFACE_NM, props, NetworkManager.PropertiesChanged)
+        self.dbus_interface_add(IFACE_NM, props)
         self.export()
 
     @dbus.service.signal(IFACE_NM, signature="u")
@@ -1875,10 +1824,6 @@ class NetworkManager(ExportedObj):
     def DeviceRemoved(self, devpath):
         pass
 
-    @dbus.service.signal(IFACE_NM, signature="a{sv}")
-    def PropertiesChanged(self, changed):
-        pass
-
     @dbus.service.method(IFACE_TEST, in_signature="", out_signature="")
     def Quit(self):
         gl.mainloop.quit()
@@ -2177,7 +2122,7 @@ class Settings(ExportedObj):
             PRP_SETTINGS_CONNECTIONS: dbus.Array([], "o"),
         }
 
-        self.dbus_interface_add(IFACE_SETTINGS, props, Settings.PropertiesChanged)
+        self.dbus_interface_add(IFACE_SETTINGS, props)
         self.export()
 
     def auto_remove_next_connection(self):
@@ -2297,10 +2242,6 @@ class Settings(ExportedObj):
     def NewConnection(self, path):
         pass
 
-    @dbus.service.signal(IFACE_SETTINGS, signature="a{sv}")
-    def PropertiesChanged(self, path):
-        pass
-
     @dbus.service.method(IFACE_SETTINGS, in_signature="", out_signature="")
     def Quit(self):
         gl.mainloop.quit()
@@ -2333,7 +2274,7 @@ class IP4Config(ExportedObj):
             generate_seed = self.path
 
         props = self._props_generate(generate_seed)
-        self.dbus_interface_add(IFACE_IP4_CONFIG, props, IP4Config.PropertiesChanged)
+        self.dbus_interface_add(IFACE_IP4_CONFIG, props)
         self.export()
 
     def _props_generate(self, generate_seed):
@@ -2505,10 +2446,6 @@ class IP4Config(ExportedObj):
     def SetGateway(self, gateway):
         self._dbus_property_set(IFACE_IP4_CONFIG, PRP_IP4_CONFIG_GATEWAY, gateway)
 
-    @dbus.service.signal(IFACE_IP4_CONFIG, signature="a{sv}")
-    def PropertiesChanged(self, path):
-        pass
-
 
 ###############################################################################
 
@@ -2536,7 +2473,7 @@ class IP6Config(ExportedObj):
             generate_seed = self.path
 
         props = self._props_generate(generate_seed)
-        self.dbus_interface_add(IFACE_IP6_CONFIG, props, IP6Config.PropertiesChanged)
+        self.dbus_interface_add(IFACE_IP6_CONFIG, props)
         self.export()
 
     def _props_generate(self, generate_seed):
@@ -2692,10 +2629,6 @@ class IP6Config(ExportedObj):
         for k, v in props.items():
             self._dbus_property_set(IFACE_IP6_CONFIG, k, v)
 
-    @dbus.service.signal(IFACE_IP6_CONFIG, signature="a{sv}")
-    def PropertiesChanged(self, path):
-        pass
-
 
 ###############################################################################
 
@@ -2714,9 +2647,7 @@ class Dhcp4Config(ExportedObj):
             generate_seed = self.path
 
         props = self._props_generate(generate_seed)
-        self.dbus_interface_add(
-            IFACE_DHCP4_CONFIG, props, Dhcp4Config.PropertiesChanged
-        )
+        self.dbus_interface_add(IFACE_DHCP4_CONFIG, props)
         self.export()
 
     def _props_generate(self, generate_seed):
@@ -2739,10 +2670,6 @@ class Dhcp4Config(ExportedObj):
         for k, v in props.items():
             self._dbus_property_set(IFACE_DHCP4_CONFIG, k, v)
 
-    @dbus.service.signal(IFACE_DHCP4_CONFIG, signature="a{sv}")
-    def PropertiesChanged(self, path):
-        pass
-
 
 ###############################################################################
 
@@ -2761,9 +2688,7 @@ class Dhcp6Config(ExportedObj):
             generate_seed = self.path
 
         props = self._props_generate(generate_seed)
-        self.dbus_interface_add(
-            IFACE_DHCP6_CONFIG, props, Dhcp6Config.PropertiesChanged
-        )
+        self.dbus_interface_add(IFACE_DHCP6_CONFIG, props)
         self.export()
 
     def _props_generate(self, generate_seed):
@@ -2786,10 +2711,6 @@ class Dhcp6Config(ExportedObj):
         for k, v in props.items():
             self._dbus_property_set(IFACE_DHCP6_CONFIG, k, v)
 
-    @dbus.service.signal(IFACE_DHCP6_CONFIG, signature="a{sv}")
-    def PropertiesChanged(self, path):
-        pass
-
 
 ###############################################################################