about summary refs log tree commit diff
path: root/examples/python
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2023-08-09 21:55:35 +0200
committerMichael Biebl <biebl@debian.org>2023-08-09 21:55:35 +0200
commit05e4a733f2141995181a551854d5df929f084adf (patch)
tree83bb937740a6667525ba0df046748ecaa829c269 /examples/python
parent14b0f3a9dc9ea90d60a3b057350fd4d637dc021a (diff)
New upstream version 1.44.0 upstream/1.44.0
Diffstat (limited to 'examples/python')
-rwxr-xr-xexamples/python/gi/ovs-external-ids.py41
-rwxr-xr-xexamples/python/gi/show-wifi-networks.py249
2 files changed, 183 insertions, 107 deletions
diff --git a/examples/python/gi/ovs-external-ids.py b/examples/python/gi/ovs-external-ids.py
index fe4fbd9d..0a03c9c5 100755
--- a/examples/python/gi/ovs-external-ids.py
+++ b/examples/python/gi/ovs-external-ids.py
@@ -236,11 +236,13 @@ DataTypeE = DataTypeTuple(
     NM.SettingOvsExternalIDs,
     NM.SETTING_OVS_EXTERNAL_IDS_DATA,
 )
+
+o = getattr(NM, "SettingOvsOtherConfig", None)
 DataTypeO = DataTypeTuple(
     "other-config",
     "ovs-other-config",
-    NM.SettingOvsOtherConfig,
-    NM.SETTING_OVS_OTHER_CONFIG_DATA,
+    o,
+    NM.SETTING_OVS_OTHER_CONFIG_DATA if o else None,
 )
 
 
@@ -420,12 +422,13 @@ def ids_select(ids, mode, ids_arg):
 
 def connection_print(connection, mode, ids_arg, dbus_path, prefix=""):
     def _num_str(connection, data_type):
+        if data_type.setting_type is None:
+            return "n/a"
         sett = connection.get_setting(data_type.setting_type)
-        num_str = "none"
-        if sett is not None:
-            all_ids = list(sett.get_data_keys())
-            num_str = "%s" % (len(all_ids))
-        return num_str
+        if sett is None:
+            return "none"
+        all_ids = list(sett.get_data_keys())
+        return "%s" % (len(all_ids),)
 
     _print(
         "%s%s [e:%s, o:%s]"
@@ -441,18 +444,17 @@ def connection_print(connection, mode, ids_arg, dbus_path, prefix=""):
 
     for data_type in [DataTypeE, DataTypeO]:
 
+        if data_type.setting_type is None:
+            continue
+
         sett = connection.get_setting(data_type.setting_type)
-        if sett is not None:
-            all_ids = list(sett.get_data_keys())
-            keys, requested = ids_select(all_ids, mode, ids_arg)
-        else:
-            keys = []
-            requested = []
+        if sett is None:
+            continue
 
-        if sett is not None:
-            dd = sett.get_property(data_type.property_name)
-        else:
-            dd = {}
+        all_ids = list(sett.get_data_keys())
+        keys, requested = ids_select(all_ids, mode, ids_arg)
+
+        dd = sett.get_property(data_type.property_name)
         for k in keys:
             v = sett.get_data(k)
             assert v is not None
@@ -478,6 +480,11 @@ def sett_update(connection, ids_arg):
         else:
             data_type = DataTypeE
 
+        if data_type.setting_type is None:
+            raise Exception(
+                "%s is not supported by this version of libnm" % (data_type.name,)
+            )
+
         sett = connection.get_setting(data_type.setting_type)
 
         oldval = None
diff --git a/examples/python/gi/show-wifi-networks.py b/examples/python/gi/show-wifi-networks.py
index eb71c4c4..edc712a0 100755
--- a/examples/python/gi/show-wifi-networks.py
+++ b/examples/python/gi/show-wifi-networks.py
@@ -5,10 +5,17 @@
 #
 
 import locale
+import math
+import os
+import re
+import time
+
 import gi
 
 gi.require_version("NM", "1.0")
-from gi.repository import NM
+from gi.repository import NM, GLib, Gio
+
+SCAN_THRESHOLD_MSEC = 10000
 
 #
 # This example lists Wi-Fi access points NetworkManager scanned on Wi-Fi devices.
@@ -19,116 +26,165 @@ from gi.repository import NM
 # an error without it: http://www.python.org/dev/peps/pep-0263/
 #
 
+NM80211Mode = getattr(NM, "80211Mode")
+NM80211ApFlags = getattr(NM, "80211ApFlags")
+NM80211ApSecurityFlags = getattr(NM, "80211ApSecurityFlags")
 
-def clamp(value, minvalue, maxvalue):
-    return max(minvalue, min(value, maxvalue))
-
-
-def ssid_to_utf8(ap):
-    ssid = ap.get_ssid()
-    if not ssid:
-        return ""
-    return NM.utils_ssid_to_utf8(ap.get_ssid().get_data())
-
-
-def print_device_info(device):
-    active_ap = dev.get_active_access_point()
-    ssid = None
-    if active_ap is not None:
-        ssid = ssid_to_utf8(active_ap)
-    info = "Device: %s | Driver: %s | Active AP: %s" % (
-        dev.get_iface(),
-        dev.get_driver(),
-        ssid,
-    )
-    print(info)
-    print("=" * len(info))
-
-
-def mode_to_string(mode):
-    if mode == getattr(NM, "80211Mode").INFRA:
-        return "INFRA"
-    if mode == getattr(NM, "80211Mode").ADHOC:
-        return "ADHOC"
-    if mode == getattr(NM, "80211Mode").AP:
-        return "AP"
-    return "UNKNOWN"
+main_loop = GLib.MainLoop()
 
 
-def flags_to_string(flags):
-    if flags & getattr(NM, "80211ApFlags").PRIVACY:
-        return "PRIVACY"
-    return "NONE"
+def gflags_to_str(flags_type, value):
+    if value == 0:
+        return "none"
+    str = ""
+    for n in sorted(dir(flags_type)):
+        if not re.search("^[A-Z0-9_]+$", n):
+            continue
+        flag_value = getattr(flags_type, n)
+        if value & flag_value:
+            value &= ~flag_value
+            str += " " + n
+            if value == 0:
+                break
+    if value:
+        str += " (0x%0x)" % (value,)
+    return str.lstrip()
 
 
-def security_flags_to_string(flags):
-    NM_AP_FLAGS = getattr(NM, "80211ApSecurityFlags")
-    str = ""
-    if flags & NM_AP_FLAGS.PAIR_WEP40:
-        str = str + " PAIR_WEP40"
-    if flags & NM_AP_FLAGS.PAIR_WEP104:
-        str = str + " PAIR_WEP104"
-    if flags & NM_AP_FLAGS.PAIR_TKIP:
-        str = str + " PAIR_TKIP"
-    if flags & NM_AP_FLAGS.PAIR_CCMP:
-        str = str + " PAIR_CCMP"
-    if flags & NM_AP_FLAGS.GROUP_WEP40:
-        str = str + " GROUP_WEP40"
-    if flags & NM_AP_FLAGS.GROUP_WEP104:
-        str = str + " GROUP_WEP104"
-    if flags & NM_AP_FLAGS.GROUP_TKIP:
-        str = str + " GROUP_TKIP"
-    if flags & NM_AP_FLAGS.GROUP_CCMP:
-        str = str + " GROUP_CCMP"
-    if flags & NM_AP_FLAGS.KEY_MGMT_PSK:
-        str = str + " KEY_MGMT_PSK"
-    if flags & NM_AP_FLAGS.KEY_MGMT_802_1X:
-        str = str + " KEY_MGMT_802_1X"
-    if str:
-        return str.lstrip()
-    else:
-        return "NONE"
+def genum_to_str(enum_type, value):
+    for n in sorted(dir(enum_type)):
+        if not re.search("^[A-Z0-9_]+$", n):
+            continue
+        enum_value = getattr(enum_type, n)
+        if value == enum_value:
+            return n
+    return "(%d" % (value,)
 
 
-def flags_to_security(flags, wpa_flags, rsn_flags):
+def ap_security_flags_to_security(flags, wpa_flags, rsn_flags):
     str = ""
-    if (
-        (flags & getattr(NM, "80211ApFlags").PRIVACY)
-        and (wpa_flags == 0)
-        and (rsn_flags == 0)
-    ):
+    if (flags & NM80211ApFlags.PRIVACY) and (wpa_flags == 0) and (rsn_flags == 0):
         str = str + " WEP"
     if wpa_flags != 0:
         str = str + " WPA1"
     if rsn_flags != 0:
         str = str + " WPA2"
-    if (wpa_flags & getattr(NM, "80211ApSecurityFlags").KEY_MGMT_802_1X) or (
-        rsn_flags & getattr(NM, "80211ApSecurityFlags").KEY_MGMT_802_1X
+    if (wpa_flags & NM80211ApSecurityFlags.KEY_MGMT_802_1X) or (
+        rsn_flags & NM80211ApSecurityFlags.KEY_MGMT_802_1X
     ):
         str = str + " 802.1X"
     return str.lstrip()
 
 
+def ap_get_ssid(ap):
+    if ap is None:
+        return "not connected"
+    ssid = ap.get_ssid()
+    if ssid is None:
+        return "no ssid"
+    return '"%s"' % (NM.utils_ssid_to_utf8(ssid.get_data()),)
+
+
+def print_device_info(device):
+    if device.get_client() is None:
+        last_scan = "device disappeared"
+    else:
+        t = device.get_last_scan()
+        if t == 0:
+            last_scan = "no scan completed"
+        else:
+            t = (NM.utils_get_timestamp_msec() - t) / 1000.0
+            last_scan = "%0.2f sec ago" % (t,)
+            if device_needs_scan(device):
+                last_scan += " (stale)"
+
+    ap = device.get_active_access_point()
+    if ap is None:
+        active_ap = "none"
+    else:
+        active_ap = "%s (%s)" % (ap_get_ssid(ap), ap.get_path())
+
+    print("Device:     %s" % (device.get_iface(),))
+    print("D-Bus path: %s" % (NM.Object.get_path(device),))
+    print("Driver:     %s" % (device.get_driver(),))
+    print("Active AP:  %s" % (active_ap,))
+    print("Last scan:  %s" % (last_scan,))
+
+
 def print_ap_info(ap):
     strength = ap.get_strength()
     frequency = ap.get_frequency()
     flags = ap.get_flags()
     wpa_flags = ap.get_wpa_flags()
     rsn_flags = ap.get_rsn_flags()
-    print("SSID:      %s" % (ssid_to_utf8(ap)))
-    print("BSSID:     %s" % (ap.get_bssid()))
-    print("Frequency: %s" % (frequency))
-    print("Channel:   %s" % (NM.utils_wifi_freq_to_channel(frequency)))
-    print("Mode:      %s" % (mode_to_string(ap.get_mode())))
-    print("Flags:     %s" % (flags_to_string(flags)))
-    print("WPA flags: %s" % (security_flags_to_string(wpa_flags)))
-    print("RSN flags: %s" % (security_flags_to_string(rsn_flags)))
-    print("Security:  %s" % (flags_to_security(flags, wpa_flags, rsn_flags)))
-    print("Strength:  %s %s%%" % (NM.utils_wifi_strength_bars(strength), strength))
-    print
+
+    t = ap.get_last_seen()
+    if t < 0:
+        last_seen = "never"
+    else:
+        t = time.clock_gettime(time.CLOCK_BOOTTIME) - t
+        last_seen = "%s sec ago" % (math.ceil(t),)
+
+    print("  - D-Bus path: %s" % (ap.get_path(),))
+    print("    SSID:       %s" % (ap_get_ssid(ap),))
+    print("    BSSID:      %s" % (ap.get_bssid(),))
+    print("    Last seen:  %s" % (last_seen,))
+    print("    Frequency:  %s" % (frequency,))
+    print("    Channel:    %s" % (NM.utils_wifi_freq_to_channel(frequency),))
+    print("    Mode:       %s" % (genum_to_str(NM80211Mode, ap.get_mode()),))
+    print("    Flags:      %s" % (gflags_to_str(NM80211ApFlags, flags),))
+    print("    WPA flags:  %s" % (gflags_to_str(NM80211ApSecurityFlags, wpa_flags),))
+    print("    RSN flags:  %s" % (gflags_to_str(NM80211ApSecurityFlags, rsn_flags),))
+    print(
+        "    Security:   %s"
+        % (ap_security_flags_to_security(flags, wpa_flags, rsn_flags),)
+    )
+    print(
+        "    Strength:   %s%% : %s"
+        % (
+            strength,
+            NM.utils_wifi_strength_bars(strength),
+        )
+    )
 
 
-if __name__ == "__main__":
+def device_needs_scan(device):
+    if device.get_client() is None:
+        # the device got deleted. We can forget about it.
+        return False
+    t = device.get_last_scan()
+    return t == 0 or t < NM.utils_get_timestamp_msec() - SCAN_THRESHOLD_MSEC
+
+
+def device_ensure_scanned(device):
+    if os.getenv("NO_SCAN") == "1":
+        return
+
+    if not device_needs_scan(device):
+        return
+
+    # kick off a new scan.
+    device.request_scan_async(None)
+
+    def cb():
+        main_loop.quit()
+
+    timeout_source = GLib.timeout_source_new(10 * 1000)
+    timeout_source.set_callback(cb)
+    timeout_source.attach(main_loop.get_context())
+
+    def cb(device, prop):
+        if not device_needs_scan(device):
+            main_loop.quit()
+
+    device.connect("notify", cb)
+
+    main_loop.run()
+
+    timeout_source.destroy()
+
+
+def main():
     # Python apparently doesn't call setlocale() on its own? We have to call this or else
     # NM.utils_wifi_strength_bars() will think the locale is ASCII-only, and return the
     # fallback characters rather than the unicode bars
@@ -137,8 +193,21 @@ if __name__ == "__main__":
     nmc = NM.Client.new(None)
     devs = nmc.get_devices()
 
-    for dev in devs:
-        if dev.get_device_type() == NM.DeviceType.WIFI:
-            print_device_info(dev)
-            for ap in dev.get_access_points():
-                print_ap_info(ap)
+    is_first = True
+    for device in devs:
+        if device.get_device_type() != NM.DeviceType.WIFI:
+            continue
+
+        if not is_first:
+            print("")
+        else:
+            is_first = False
+
+        device_ensure_scanned(device)
+        print_device_info(device)
+        for ap in device.get_access_points():
+            print_ap_info(ap)
+
+
+if __name__ == "__main__":
+    main()