diff --git a/RNS/Discovery.py b/RNS/Discovery.py index 62eafe1b..6f66fabf 100644 --- a/RNS/Discovery.py +++ b/RNS/Discovery.py @@ -99,6 +99,33 @@ class InterfaceAnnouncer(): if not interface_type in self.DISCOVERABLE_INTERFACE_TYPES: return None else: + if not RNS.vendor.platformutils.is_windows() and interface.discovery_location: + try: + discovery_location = self.sanitize(interface.discovery_location) + exec_path = os.path.expanduser(discovery_location) + if os.path.isfile(exec_path) and os.access(exec_path, os.X_OK): + RNS.log(f"Evaluating discovery location from executable at {exec_path}", RNS.LOG_DEBUG) + exec_result = subprocess.run([exec_path], stdout=subprocess.PIPE) + exec_stdout = exec_result.stdout.decode("utf-8") + if exec_result.returncode != 0: raise ValueError("Non-zero exit code from subprocess") + discovery_location = self.sanitize(exec_stdout) + location_components = discovery_location.replace(" ", "").split(",") + if len(location_components) != 3: raise ValueError(f"Invalid location component count: {len(location_components)}") + dlat = float(location_components[0]) + dlon = float(location_components[1]) + dhgt = float(location_components[2]) + if dlat < -90 or dlat > 90: raise ValueError(f"Invalid latitude: {dlat}") + if dlon < -180 or dlat > 180: raise ValueError(f"Invalid longitude: {dlon}") + if dhgt < -4000 or dhgt > 1e6: raise ValueError(f"Invalid height: {dhgt}") + interface.discovery_latitude = dlat + interface.discovery_longitude = dlon + interface.discovery_height = dhgt + + except Exception as e: + RNS.log(f"Error while getting reachable_on from executable at {interface.reachable_on}: {e}", RNS.LOG_ERROR) + RNS.log(f"Aborting discovery announce", RNS.LOG_ERROR) + return None + flags = 0x00 info = {INTERFACE_TYPE: interface_type, TRANSPORT: RNS.Reticulum.transport_enabled(), diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index d944ed0d..faf54736 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -829,6 +829,7 @@ class Reticulum: latitude = None longitude = None height = None + discovery_location = None discovery_frequency = None discovery_bandwidth = None discovery_modulation = None @@ -846,6 +847,7 @@ class Reticulum: if "discovery_encrypt" in c: discovery_encrypt = c.as_bool("discovery_encrypt") if "reachable_on" in c: reachable_on = c["reachable_on"] if "publish_ifac" in c: publish_ifac = c.as_bool("publish_ifac") + if "location_cmd" in c: discovery_location = c["location_cmd"] if "latitude" in c: latitude = c.as_float("latitude") if "longitude" in c: longitude = c.as_float("longitude") if "height" in c: height = c.as_float("height") @@ -884,6 +886,7 @@ class Reticulum: interface.discovery_name = discovery_name interface.discovery_encrypt = discovery_encrypt interface.discovery_stamp_value = discovery_stamp_value + interface.discovery_location = discovery_location interface.discovery_latitude = latitude interface.discovery_longitude = longitude interface.discovery_height = height