diff --git a/sbapp/sideband/core.py b/sbapp/sideband/core.py index 70f0be3..2690fde 100644 --- a/sbapp/sideband/core.py +++ b/sbapp/sideband/core.py @@ -172,6 +172,7 @@ class SidebandCore(): self.owner_service = owner_service self.allow_service_dispatch = True self.version_str = "" + self.config_template = rns_config if config_path == None: self.app_dir = plyer.storagepath.get_home_dir()+"/.config/sideband" @@ -276,6 +277,29 @@ class SidebandCore(): if load_config_only: return + if RNS.vendor.platformutils.is_android(): + if self.config["config_template"] != None: + try: + if not os.path.isfile(self.rns_configdir+"/config_template_invalid"): + if self.is_service: + with open(self.rns_configdir+"/config_template_invalid", "w") as invalidation_file: + invalidation_file.write("\n") + + ct = self.config["config_template"] + RNS.log(f"Loading modified RNS config template", RNS.LOG_WARNING) + self.config_template = ct + + else: + RNS.log("Custom configuration template invalid, using default configuration template", RNS.LOG_WARNING) + self.config_template = rns_config + if self.is_service: + self.setstate("hardware_operation.error", "At the previous start, Sideband could not initialise Reticulum. Custom configuration template loading has been temporarily disabled. Please check and fix any errors in your configuration template.") + + except Exception as e: + RNS.log(f"An error occurred while setting RNS configuration template: {e}", RNS.LOG_ERROR) + RNS.log(f"Using default configuration template", RNS.LOG_ERROR) + self.config_template = rns_config + # Initialise Reticulum configuration if RNS.vendor.platformutils.get_platform() == "android": try: @@ -286,11 +310,10 @@ class SidebandCore(): RNS.log("Configuring Reticulum instance...") if self.config["connect_transport"]: RNS.log("Enabling Reticulum Transport") - generated_config = rns_config.replace("TRANSPORT_IS_ENABLED", "Yes") + generated_config = self.config_template.replace("TRANSPORT_IS_ENABLED", "Yes") else: RNS.log("Not enabling Reticulum Transport") - generated_config = rns_config.replace("TRANSPORT_IS_ENABLED", "No") - + generated_config = self.config_template.replace("TRANSPORT_IS_ENABLED", "No") config_file = open(self.rns_configdir+"/config", "wb") config_file.write(generated_config.encode("utf-8")) @@ -567,6 +590,8 @@ class SidebandCore(): if not "block_predictive_text" in self.config: self.config["block_predictive_text"] = False + if not "config_template" in self.config: + self.config["config_template"] = None if not "connect_transport" in self.config: self.config["connect_transport"] = False if not "connect_rnode" in self.config: @@ -801,9 +826,8 @@ class SidebandCore(): time.sleep(0.15) try: self.saving_configuration = True - config_file = open(self.config_path, "wb") - config_file.write(msgpack.packb(self.config)) - config_file.close() + with open(self.config_path, "wb") as config_file: + config_file.write(msgpack.packb(self.config)) self.saving_configuration = False except Exception as e: self.saving_configuration = False @@ -3753,7 +3777,20 @@ class SidebandCore(): selected_level = 2 self.setstate("init.loadingstate", "Substantiating Reticulum") - self.reticulum = RNS.Reticulum(configdir=self.rns_configdir, loglevel=selected_level, logdest=self._log_handler) + + try: + self.reticulum = RNS.Reticulum(configdir=self.rns_configdir, loglevel=selected_level, logdest=self._log_handler) + if RNS.vendor.platformutils.is_android(): + if self.is_service: + if os.path.isfile(self.rns_configdir+"/config_template_invalid"): + os.unlink(self.rns_configdir+"/config_template_invalid") + else: + pass + + except Exception as e: + RNS.log(f"Error while instantiating Reticulum: {e}", RNS.LOG_ERROR) + RNS.log(f"Local configuration template changes will be ignored on next start", RNS.LOG_ERROR) + exit(255) if self.is_service: self.__start_rpc_listener() @@ -4889,15 +4926,41 @@ class SidebandCore(): if not self.reticulum.is_connected_to_shared_instance: RNS.Transport.detach_interfaces() -rns_config = """ +rns_config = """# This template is used to generate a +# running configuration for Sideband's +# internal RNS instance. Incorrect changes +# or addition here may cause Sideband to +# fail starting up or working properly. +# +# If Sideband detects that Reticulum +# aborts at startup, due to an error in +# configuration, any template changes +# will be reset to this default. + [reticulum] -enable_transport = TRANSPORT_IS_ENABLED -share_instance = Yes -shared_instance_port = 37428 -instance_control_port = 37429 -panic_on_interface_error = No + # Don't change this line, use the UI + # setting for selecting whether RNS + # transport is enabled or disabled + enable_transport = TRANSPORT_IS_ENABLED + # Changing this setting will cause + # Sideband to not work. + share_instance = Yes + + # Changing these options should only + # be done if you know what you're doing. + shared_instance_port = 37428 + instance_control_port = 37429 + panic_on_interface_error = No + +# Logging is controlled by settings +# in the UI, so this section is mostly +# not relevant in Sideband. [logging] -loglevel = 3 + loglevel = 3 +# No additional interfaces are currently +# defined, but you can use this section +# to do so. +[interfaces] """ diff --git a/sbapp/ui/layouts.py b/sbapp/ui/layouts.py index 1ea51bf..1404f63 100644 --- a/sbapp/ui/layouts.py +++ b/sbapp/ui/layouts.py @@ -1583,7 +1583,7 @@ MDScreen: height: dp(48) MDLabel: - text: "Announce Automatically" + text: "Announce automatically" font_style: "H6" MDSwitch: @@ -1598,7 +1598,7 @@ MDScreen: height: dp(48) MDLabel: - text: "Try propagation on direct delivery failure" + text: "Try propagation automatically" font_style: "H6" MDSwitch: diff --git a/sbapp/ui/utilities.py b/sbapp/ui/utilities.py index 66a6559..9776df8 100644 --- a/sbapp/ui/utilities.py +++ b/sbapp/ui/utilities.py @@ -116,6 +116,35 @@ class Utilities(): if self.app.root.ids.screen_manager.current == "rnstatus_screen": Clock.schedule_once(self.update_rnstatus, 1) + ### Advanced Configuration screen + ###################################### + + def advanced_action(self, sender=None): + if not self.app.root.ids.screen_manager.has_screen("advanced_screen"): + self.advanced_screen = Builder.load_string(layout_advanced_screen) + self.advanced_screen.app = self.app + self.advanced_screen.delegate = self + self.app.root.ids.screen_manager.add_widget(self.advanced_screen) + + self.app.root.ids.screen_manager.transition.direction = "left" + self.app.root.ids.screen_manager.current = "advanced_screen" + self.app.sideband.setstate("app.displaying", self.app.root.ids.screen_manager.current) + + self.update_advanced() + + def update_advanced(self, sender=None): + ct = self.app.sideband.config["config_template"] + self.advanced_screen.ids.config_template.text = f"[font=RobotoMono-Regular][size={int(dp(12))}]{ct}[/size][/font]" + + def copy_config(self, sender=None): + Clipboard.copy(self.app.sideband.config_template) + + def paste_config(self, sender=None): + self.app.sideband.config_template = Clipboard.paste() + self.app.sideband.config["config_template"] = self.app.sideband.config_template + self.app.sideband.save_configuration() + self.update_advanced() + ### Log viewer screen ###################################### @@ -331,4 +360,77 @@ MDScreen: size_hint_y: None text_size: self.width, None height: self.texture_size[1] -""" \ No newline at end of file +""" + +layout_advanced_screen = """ +MDScreen: + name: "advanced_screen" + + BoxLayout: + orientation: "vertical" + + MDTopAppBar: + id: top_bar + title: "RNS Configuration" + anchor_title: "left" + elevation: 0 + left_action_items: + [['menu', lambda x: root.app.nav_drawer.set_state("open")]] + right_action_items: + [ + # ['refresh', lambda x: root.delegate.update_rnstatus()], + ['close', lambda x: root.app.close_sub_utilities_action(self)], + ] + + MDScrollView: + id: advanced_scrollview + size_hint_x: 1 + size_hint_y: None + size: [root.width, root.height-root.ids.top_bar.height] + do_scroll_x: False + do_scroll_y: True + + MDGridLayout: + cols: 1 + padding: [dp(28), dp(14), dp(28), dp(28)] + size_hint_y: None + height: self.minimum_height + + MDBoxLayout: + orientation: "horizontal" + spacing: dp(24) + size_hint_y: None + height: self.minimum_height + padding: [dp(0), dp(14), dp(0), dp(24)] + + MDRectangleFlatIconButton: + id: telemetry_button + icon: "content-copy" + text: "Copy Configuration" + padding: [dp(0), dp(14), dp(0), dp(14)] + icon_size: dp(24) + font_size: dp(16) + size_hint: [1.0, None] + on_release: root.delegate.copy_config(self) + disabled: False + + MDRectangleFlatIconButton: + id: coordinates_button + icon: "download" + text: "Paste Configuration" + padding: [dp(0), dp(14), dp(0), dp(14)] + icon_size: dp(24) + font_size: dp(16) + size_hint: [1.0, None] + on_release: root.delegate.paste_config(self) + disabled: False + + + MDLabel: + id: config_template + markup: True + text: "" + size_hint_y: None + text_size: self.width, None + height: self.texture_size[1] +"""