mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-04 15:21:12 +00:00
examples: rework "python/gi/show-wifi-networks.py" example
- only printing the scan list is not gonna cut it. It's usually stale, and we need to request a new scan. - don't hard-code the GEnum and GFlags values that we understand. We have libnm, which provides us some meta information about the data. Use it. - Some code cleanup. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1531
This commit is contained in:
parent
a798b4f3f6
commit
004ffb91cf
|
@ -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))
|
||||
main_loop = GLib.MainLoop()
|
||||
|
||||
|
||||
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"
|
||||
|
||||
|
||||
def flags_to_string(flags):
|
||||
if flags & getattr(NM, "80211ApFlags").PRIVACY:
|
||||
return "PRIVACY"
|
||||
return "NONE"
|
||||
|
||||
|
||||
def security_flags_to_string(flags):
|
||||
NM_AP_FLAGS = getattr(NM, "80211ApSecurityFlags")
|
||||
def gflags_to_str(flags_type, value):
|
||||
if value == 0:
|
||||
return "none"
|
||||
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"
|
||||
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 flags_to_security(flags, wpa_flags, rsn_flags):
|
||||
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 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()
|
||||
|
|
Loading…
Reference in a new issue