diff --git a/python/PiFinder/server.py b/python/PiFinder/server.py index 8fdc9e45..04d5298c 100644 --- a/python/PiFinder/server.py +++ b/python/PiFinder/server.py @@ -88,7 +88,7 @@ def home(): return template( "index", software_version=software_version, - wifi_mode="AP" if self.network.wifi_mode() == "AP" else "Client", + wifi_mode=self.network.wifi_mode(), ip=self.network.local_ip(), network_name=self.network.get_connected_ssid(), gps_icon=gps_icon, @@ -116,14 +116,32 @@ def network_page(): show_new_form=show_new_form, ) - @app.route("/network/delete/") + @app.route("/network/add", method="post") + def network_update(): + ssid = request.forms.get("ssid") + psk = request.forms.get("psk") + if len(psk) < 8: + key_mgmt = "NONE" + else: + key_mgmt = "WPA-PSK" + + self.network.add_wifi_network(ssid, key_mgmt, psk) + return network_page() + + @app.route("/network/delete/") def network_delete(network_id): self.network.delete_wifi_network(network_id) return network_page() - @app.route("/network/undelete/") - def network_undelete(network_id): - self.network.undelete_wifi_network(network_id) + @app.route("/network/update", method="post") + def network_update(): + wifi_mode = request.forms.get("wifi_mode") + ap_name = request.forms.get("ap_name") + host_name = request.forms.get("host_name") + + self.network.set_wifi_mode(wifi_mode) + self.network.set_ap_name(ap_name) + self.network.set_host_name(host_name) return network_page() @app.route("/key_callback", method="POST") diff --git a/python/PiFinder/sys_utils.py b/python/PiFinder/sys_utils.py index f3d61a87..4c267620 100644 --- a/python/PiFinder/sys_utils.py +++ b/python/PiFinder/sys_utils.py @@ -18,100 +18,85 @@ def __init__(self): def populate_wifi_networks(self): """ - Uses wpa_cli to get current network config + Parses wpa_supplicant.conf to get current config """ self._wifi_networks = [] - _net_list = wpa_cli("list_networks").split("\n") - - # skip first two lines - for net in _net_list[2:]: - _net = net.split() - if len(_net) > 2: - self._wifi_networks.append( - { - "id": _net[0], - "ssid": _net[1], - "password": None, + with open("/etc/wpa_supplicant/wpa_supplicant.conf", "r") as wpa_conf: + network_id = 0 + in_network_block = False + for l in wpa_conf: + if l.startswith("network={"): + in_network_block = True + network_dict = { + "id": network_id, + "ssid": None, + "psk": None, "key_mgmt": None, - "status": "saved", } - ) - # need to call wpa_cli for each network to get key type - for net in self._wifi_networks: - _output = wpa_cli("get_network", net["id"], "key_mgmt") - net["key_mgmt"] = _output.split("\n")[-1].strip() + elif l.strip() == "}" and in_network_block: + in_network_block = False + self._wifi_networks.append(network_dict) + network_id += 1 + + elif in_network_block: + key, value = l.strip().split("=") + network_dict[key] = value.strip('"') def get_wifi_networks(self): return self._wifi_networks - def save_wifi_config(self): + def delete_wifi_network(self, network_id): """ - Iterates through all wifi networks - actions changes indicated - saves config file - reconfigures wpi_supplicatn + Immediately deletes a wifi network """ + self._wifi_networks.pop(network_id) + + with open("/etc/wpa_supplicant/wpa_supplicant.conf", "r") as wpa_conf: + wpa_contents = list(wpa_conf) + + with open("/etc/wpa_supplicant/wpa_supplicant.conf", "w") as wpa_conf: + in_networks = False + for l in wpa_contents: + if not in_networks: + if l.startswith("network={"): + in_networks = True + else: + wpa_conf.write(l) + + for network in self._wifi_networks: + ssid = network["ssid"] + key_mgmt = network["key_mgmt"] + psk = network["psk"] - # Update networks - for network in self._wifi_networks: - if network["status"] == "deleted": - net_id = network["id"] - wpa_cli("disable_network", net_id) - wpa_cli("remove_network", net_id) - - if network["status"] == "new": - new_id = wpa_cli("add_network").split("\n")[1].strip() - wpa_cli("set_network", new_id, "ssid", f'"{network["ssid"]}"') - print(wpa_cli("set_network", new_id, "key_mgmt", network["key_mgmt"])) - if network["key_mgmt"] == "WPA-PSK": - print( - wpa_cli( - "set_network", new_id, "psk", f'"{network["password"]}"' - ) - ) - wpa_cli("enable_network", new_id) - - # Save config - wpa_cli("save_config") - - # Reconfigure - wpa_cli("reconfigure") + wpa_conf.write("\nnetwork={\n") + wpa_conf.write(f'\tssid="{ssid}"\n') + if key_mgmt == "WPA-PSK": + wpa_conf.write(f'\tpsk="{psk}"\n') + wpa_conf.write(f"\tkey_mgmt={key_mgmt}\n") + + wpa_conf.write("}\n") self.populate_wifi_networks() - def undelete_wifi_network(self, network_id): + def add_wifi_network(self, ssid, key_mgmt, psk=None): """ - Marks a wifi network as not deleted! + Add a wifi network """ - for network in self._wifi_networks: - if int(network["id"]) == int(network_id): - network["status"] = "saved" + with open("/etc/wpa_supplicant/wpa_supplicant.conf", "a") as wpa_conf: + wpa_conf.write("\nnetwork={\n") + wpa_conf.write(f'\tssid="{ssid}"\n') + if key_mgmt == "WPA-PSK": + wpa_conf.write(f'\tpsk="{psk}"\n') + wpa_conf.write(f"\tkey_mgmt={key_mgmt}\n") - def delete_wifi_network(self, network_id): - """ - Marks a wifi network for deletion - Deletion happens on 'save' - """ - for network in self._wifi_networks: - if int(network["id"]) == int(network_id): - network["status"] = "deleted" + wpa_conf.write("}\n") - def add_wifi_network(self, ssid, key_mgmt, password=None): - """ - Add a wifi network to the network dictionary. - Creation happens on 'save' - """ - self._wifi_networks.append( - { - "id": len(self._wifi_networks), - "ssid": ssid, - "key_mgmt": key_mgmt, - "password": password, - "status": "new", - } - ) + self.populate_wifi_networks() + if self._wifi_mode == "Client": + # Restart the supplicant + wpa_cli("reconfigure") def get_ap_name(self): with open(f"/etc/hostapd/hostapd.conf", "r") as conf: @@ -121,6 +106,8 @@ def get_ap_name(self): return "UNKN" def set_ap_name(self, ap_name): + if ap_name == self.get_ap_name(): + return with open(f"/tmp/hostapd.conf", "w") as new_conf: with open(f"/etc/hostapd/hostapd.conf", "r") as conf: for l in conf: @@ -142,11 +129,22 @@ def get_connected_ssid(self): return _t.split(":")[-1].strip('"') def set_host_name(self, hostname): + if hostname == self.get_host_name(): + return sh.sudo("hostname", hostname) def wifi_mode(self): return self._wifi_mode + def set_wifi_mode(self, mode): + if mode == self._wifi_mode: + return + if mode == "AP": + go_wifi_ap() + + if mode == "Client": + go_wifi_cli() + def local_ip(self): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: @@ -188,6 +186,14 @@ def restart_pifinder(): return True +def restart_system(): + """ + Restarts the system + """ + print("SYS: Initiating System Restart") + sh.sudo("shutdown", "-r", "now") + + def go_wifi_ap(): print("SYS: Switching to AP") sh.sudo("/home/pifinder/PiFinder/switch-ap.sh") diff --git a/python/PiFinder/ui/status.py b/python/PiFinder/ui/status.py index 51d8dc9c..ec190525 100644 --- a/python/PiFinder/ui/status.py +++ b/python/PiFinder/ui/status.py @@ -51,7 +51,7 @@ class UIStatus(UIModule): "WiFi Mode": { "type": "enum", "value": "UNK", - "options": ["AP", "Cli", "CANCEL"], + "options": ["AP", "Client", "CANCEL"], "callback": "wifi_switch", }, "Mnt Side": { @@ -206,9 +206,11 @@ def wifi_switch(self, option): self.message("Switch to AP", 10) sys_utils.go_wifi_ap() else: - self.message("Switch to Cli", 10) + self.message("Switch to Client", 10) sys_utils.go_wifi_cli() + sys_utils.restart_system() + def shutdown(self, option): if option == "System": self.message("Shutting down", 10) diff --git a/python/views/network.tpl b/python/views/network.tpl index b678acc0..e0b0f502 100644 --- a/python/views/network.tpl +++ b/python/views/network.tpl @@ -6,17 +6,17 @@
-
+
- +
- +
+
+
@@ -47,7 +58,9 @@
Wifi Networks
+% if not show_new_form: add +% end
@@ -59,14 +72,16 @@
- +
- + + Min 8 Characters or leave None +
@@ -81,15 +96,17 @@ % include("network_item", network=network) % end -
% include("footer.tpl") diff --git a/python/views/network_item.tpl b/python/views/network_item.tpl index bf586a42..db23813f 100644 --- a/python/views/network_item.tpl +++ b/python/views/network_item.tpl @@ -1,36 +1,21 @@ -%if network["status"] == "new": - -
-
-
- - -
-
-
- - - cancel - save - - -%else: -
{{network["ssid"]}}
Security: {{network["key_mgmt"]}} - %if network["status"] != "deleted": - delete - %else: - restore - %end + + + delete + + -%end +