""" Add the networks saved in wireless_networks to wpa_supplicant, without restarting it or touching its config file. """ import json import os import re import subprocess NETWORKS_FILE = "/etc/keys/wireless_networks.json" def wpa_cli(command: list[str]) -> list[bytes]: command.insert(0, "wpa_cli") process = subprocess.run(command, stdout=subprocess.PIPE) process.check_returncode() lines = process.stdout.splitlines() while lines[0].startswith(b"Selected interface"): lines.pop(0) return lines network_numbers: dict[str, int] = dict() networks_tsv = wpa_cli(["list_networks"]) networks_tsv.pop(0) for network_line in networks_tsv: split = network_line.split(b"\t") number = int(split[0]) ssid_bytes = split[1] ssid = re.sub( rb"\\x([0-9a-f]{2})", lambda d: int(d[1], base=16).to_bytes(), ssid_bytes, ).decode() network_numbers[ssid] = number if os.path.isfile(NETWORKS_FILE): with open(NETWORKS_FILE) as fd: networks = json.load(fd) for network in networks: ssid = network["ssid"] if ssid in network_numbers: number = network_numbers[ssid] else: number = int(wpa_cli(["add_network"])[0]) number_str = str(number) for key, value in network.items(): if isinstance(value, str): value_str = f'"{value}"' elif isinstance(value, list): value_str = " ".join(value) else: value_str = str(value) ret = wpa_cli(["set_network", number_str, key, value_str]) if ret[0] != b"OK": raise RuntimeError(f"Couldn't set {key} for {ssid}, got {ret}")