Added connectivity settings

This commit is contained in:
Mark Qvist 2022-07-06 12:19:05 +02:00
parent 33d31b453f
commit 1471876f89
3 changed files with 355 additions and 24 deletions

80
main.py
View File

@ -2,6 +2,9 @@ import RNS
import LXMF import LXMF
import time import time
from kivy.logger import Logger, LOG_LEVELS
Logger.setLevel(LOG_LEVELS["error"])
from sideband.core import SidebandCore from sideband.core import SidebandCore
from kivymd.app import MDApp from kivymd.app import MDApp
@ -478,6 +481,69 @@ class SidebandApp(MDApp):
self.open_conversations(direction="right") self.open_conversations(direction="right")
### Connectivity screen
######################################
def connectivity_action(self, sender=None):
def save_connectivity(sender=None, event=None):
RNS.log("Save connectivity")
self.sideband.config["connect_local"] = self.root.ids.connectivity_use_local.active
self.sideband.config["connect_local_groupid"] = self.root.ids.connectivity_local_groupid.text
self.sideband.config["connect_local_ifac_netname"] = self.root.ids.connectivity_local_ifac_netname.text
self.sideband.config["connect_local_ifac_passphrase"] = self.root.ids.connectivity_local_ifac_passphrase.text
self.sideband.config["connect_tcp"] = self.root.ids.connectivity_use_tcp.active
self.sideband.config["connect_tcp_host"] = self.root.ids.connectivity_tcp_host.text
self.sideband.config["connect_tcp_port"] = self.root.ids.connectivity_tcp_port.text
self.sideband.config["connect_tcp_ifac_netname"] = self.root.ids.connectivity_tcp_ifac_netname.text
self.sideband.config["connect_tcp_ifac_passphrase"] = self.root.ids.connectivity_tcp_ifac_passphrase.text
self.sideband.config["connect_i2p"] = self.root.ids.connectivity_use_i2p.active
self.sideband.config["connect_i2p_b32"] = self.root.ids.connectivity_i2p_b32.text
self.sideband.config["connect_i2p_ifac_netname"] = self.root.ids.connectivity_i2p_ifac_netname.text
self.sideband.config["connect_i2p_ifac_passphrase"] = self.root.ids.connectivity_i2p_ifac_passphrase.text
self.sideband.save_configuration()
info = "By default, sideband will try to discover and connect to any available Reticulum network via active WiFi and/or Ethernet interfaces. If any Reticulum Transport Instances are found, Sideband will use these to connect to wider Reticulum networks. You can disable this behaviour if you don't want it.\n\n"
info += "You can connect also connect to a network via a remote or local Reticulum instance using TCP or I2P. [b]Please Note![/b] Connecting via I2P requires that you already have I2P running on your device, and the SAM API enabled.\n\n"
info += "For changes to connectivity to take effect, you must shut down and restart Sideband."
self.root.ids.connectivity_info.text = info
self.root.ids.connectivity_use_local.active = self.sideband.config["connect_local"]
self.root.ids.connectivity_local_groupid.text = self.sideband.config["connect_local_groupid"]
self.root.ids.connectivity_local_ifac_netname.text = self.sideband.config["connect_local_ifac_netname"]
self.root.ids.connectivity_local_ifac_passphrase.text = self.sideband.config["connect_local_ifac_passphrase"]
self.root.ids.connectivity_use_tcp.active = self.sideband.config["connect_tcp"]
self.root.ids.connectivity_tcp_host.text = self.sideband.config["connect_tcp_host"]
self.root.ids.connectivity_tcp_port.text = self.sideband.config["connect_tcp_port"]
self.root.ids.connectivity_tcp_ifac_netname.text = self.sideband.config["connect_tcp_ifac_netname"]
self.root.ids.connectivity_tcp_ifac_passphrase.text = self.sideband.config["connect_tcp_ifac_passphrase"]
self.root.ids.connectivity_use_i2p.active = self.sideband.config["connect_i2p"]
self.root.ids.connectivity_i2p_b32.text = self.sideband.config["connect_i2p_b32"]
self.root.ids.connectivity_i2p_ifac_netname.text = self.sideband.config["connect_i2p_ifac_netname"]
self.root.ids.connectivity_i2p_ifac_passphrase.text = self.sideband.config["connect_i2p_ifac_passphrase"]
self.root.ids.connectivity_use_local.bind(active=save_connectivity)
self.root.ids.connectivity_local_groupid.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_local_ifac_netname.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_local_ifac_passphrase.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_use_tcp.bind(active=save_connectivity)
self.root.ids.connectivity_tcp_host.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_tcp_port.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_tcp_ifac_netname.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_tcp_ifac_passphrase.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_use_i2p.bind(active=save_connectivity)
self.root.ids.connectivity_i2p_b32.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_i2p_ifac_netname.bind(on_text_validate=save_connectivity)
self.root.ids.connectivity_i2p_ifac_passphrase.bind(on_text_validate=save_connectivity)
self.root.ids.screen_manager.transition.direction = "left"
self.root.ids.screen_manager.current = "connectivity_screen"
self.root.ids.nav_drawer.set_state("closed")
def close_connectivity_action(self, sender=None):
self.open_conversations(direction="right")
### Announce Stream screen ### Announce Stream screen
###################################### ######################################
def announces_action(self, sender=None): def announces_action(self, sender=None):
@ -531,20 +597,6 @@ class SidebandApp(MDApp):
self.root.ids.screen_manager.current = "map_screen" self.root.ids.screen_manager.current = "map_screen"
self.root.ids.nav_drawer.set_state("closed") self.root.ids.nav_drawer.set_state("closed")
def connectivity_action(self, sender=None):
def link_exec(sender=None, event=None):
RNS.log("Click")
import webbrowser
webbrowser.open("https://unsigned.io/sideband")
info = "The [b]Connectivity[/b] feature will allow you use LoRa and radio interfaces directly on Android over USB or Bluetooth, through a simple and user-friendly setup process. It will also let you view advanced connectivity stats and options.\n\nThis feature is not yet implemented in Sideband.\n\nWant it faster? Go to [u][ref=link]https://unsigned.io/sideband[/ref][/u] to support the project."
self.root.ids.connectivity_info.text = info
self.root.ids.connectivity_info.bind(on_ref_press=link_exec)
self.root.ids.screen_manager.transition.direction = "left"
self.root.ids.screen_manager.current = "connectivity_screen"
self.root.ids.nav_drawer.set_state("closed")
def broadcasts_action(self, sender=None): def broadcasts_action(self, sender=None):
def link_exec(sender=None, event=None): def link_exec(sender=None, event=None):
RNS.log("Click") RNS.log("Click")

View File

@ -72,7 +72,8 @@ class SidebandCore():
self.app_dir = plyer.storagepath.get_application_dir() self.app_dir = plyer.storagepath.get_application_dir()
self.rns_configdir = None self.rns_configdir = None
if RNS.vendor.platformutils.get_platform() == "android": # TODO: Reset
if RNS.vendor.platformutils.get_platform() == "android" or True:
self.app_dir = self.app_dir+"/io.unsigned.sideband/files/" self.app_dir = self.app_dir+"/io.unsigned.sideband/files/"
self.rns_configdir = self.app_dir+"/app_storage/reticulum" self.rns_configdir = self.app_dir+"/app_storage/reticulum"
@ -97,7 +98,8 @@ class SidebandCore():
# Initialise Reticulum configuration # Initialise Reticulum configuration
if RNS.vendor.platformutils.get_platform() == "android": # TODO: Reset
if RNS.vendor.platformutils.get_platform() == "android" or True:
try: try:
self.rns_configdir = self.app_dir+"/app_storage/reticulum" self.rns_configdir = self.app_dir+"/app_storage/reticulum"
if not os.path.isdir(self.rns_configdir): if not os.path.isdir(self.rns_configdir):
@ -132,6 +134,7 @@ class SidebandCore():
self.identity.to_file(self.identity_path) self.identity.to_file(self.identity_path)
self.config = {} self.config = {}
# Settings
self.config["display_name"] = "Anonymous Peer" self.config["display_name"] = "Anonymous Peer"
self.config["start_announce"] = False self.config["start_announce"] = False
self.config["propagation_by_default"] = False self.config["propagation_by_default"] = False
@ -142,6 +145,21 @@ class SidebandCore():
self.config["lxmf_sync_max"] = 3 self.config["lxmf_sync_max"] = 3
self.config["last_lxmf_propagation_node"] = None self.config["last_lxmf_propagation_node"] = None
self.config["nn_home_node"] = None self.config["nn_home_node"] = None
# Connectivity
self.config["connect_local"] = True
self.config["connect_local_groupid"] = ""
self.config["connect_local_ifac_netname"] = ""
self.config["connect_local_ifac_passphrase"] = ""
self.config["connect_tcp"] = False
self.config["connect_tcp_host"] = "sideband.connect.reticulum.network"
self.config["connect_tcp_port"] = "7822"
self.config["connect_tcp_ifac_netname"] = ""
self.config["connect_tcp_ifac_passphrase"] = ""
self.config["connect_i2p"] = False
self.config["connect_i2p_b32"] = "mrwqlsioq4hoo2lmeeud7dkfscnm7yxak7dmiyvsrnpfag3z5tsq.b32.i2p"
self.config["connect_i2p_ifac_netname"] = ""
self.config["connect_i2p_ifac_passphrase"] = ""
self.__save_config() self.__save_config()
if not os.path.isfile(self.db_path): if not os.path.isfile(self.db_path):
@ -152,7 +170,7 @@ class SidebandCore():
RNS.log("Loading Sideband identity...") RNS.log("Loading Sideband identity...")
self.identity = RNS.Identity.from_file(self.identity_path) self.identity = RNS.Identity.from_file(self.identity_path)
RNS.log("Loading Sideband configuration...") RNS.log("Loading Sideband configuration... "+str(self.config_path))
config_file = open(self.config_path, "rb") config_file = open(self.config_path, "rb")
self.config = msgpack.unpackb(config_file.read()) self.config = msgpack.unpackb(config_file.read())
config_file.close() config_file.close()
@ -684,6 +702,118 @@ class SidebandCore():
self.reticulum = RNS.Reticulum(configdir=self.rns_configdir) self.reticulum = RNS.Reticulum(configdir=self.rns_configdir)
RNS.log("Reticulum started, activating LXMF...") RNS.log("Reticulum started, activating LXMF...")
if RNS.vendor.platformutils.get_platform() == "android" or True:
if not self.reticulum.is_connected_to_shared_instance:
RNS.log("Running as master or standalone instance, adding interfaces")
self.interface_local = None
self.interface_tcp = None
self.interface_i2p = None
if self.config["connect_local"]:
try:
RNS.log("Adding Auto Interface...")
if self.config["connect_local_groupid"] == "":
group_id = None
else:
group_id = self.config["connect_local_groupid"]
if self.config["connect_local_ifac_netname"] == "":
ifac_netname = None
else:
ifac_netname = self.config["connect_local_ifac_netname"]
if self.config["connect_local_ifac_passphrase"] == "":
ifac_netkey = None
else:
ifac_netkey = self.config["connect_local_ifac_passphrase"]
autointerface = RNS.Interfaces.AutoInterface.AutoInterface(
RNS.Transport,
name = "AutoInterface",
group_id = group_id
)
autointerface.OUT = True
self.reticulum._add_interface(autointerface,ifac_netname=ifac_netname,ifac_netkey=ifac_netkey)
self.interface_local = autointerface
except Exception as e:
RNS.log("Error while adding AutoInterface. The contained exception was: "+str(e))
self.interface_local = None
if self.config["connect_tcp"]:
try:
RNS.log("Adding TCP Interface...")
if self.config["connect_tcp_host"] != "":
tcp_host = self.config["connect_tcp_host"]
tcp_port = int(self.config["connect_tcp_port"])
if tcp_port > 0 and tcp_port <= 65536:
if self.config["connect_tcp_ifac_netname"] == "":
ifac_netname = None
else:
ifac_netname = self.config["connect_tcp_ifac_netname"]
if self.config["connect_tcp_ifac_passphrase"] == "":
ifac_netkey = None
else:
ifac_netkey = self.config["connect_tcp_ifac_passphrase"]
tcpinterface = RNS.Interfaces.TCPInterface.TCPClientInterface(
RNS.Transport,
"TCPClientInterface",
tcp_host,
tcp_port,
kiss_framing = False,
i2p_tunneled = False
)
tcpinterface.OUT = True
self.reticulum._add_interface(tcpinterface,ifac_netname=ifac_netname,ifac_netkey=ifac_netkey)
self.interface_tcp = tcpinterface
except Exception as e:
RNS.log("Error while adding TCP Interface. The contained exception was: "+str(e))
self.interface_tcp = None
if self.config["connect_i2p"]:
try:
RNS.log("Adding I2P Interface...")
if self.config["connect_i2p_b32"].endswith(".b32.i2p"):
if self.config["connect_i2p_ifac_netname"] == "":
ifac_netname = None
else:
ifac_netname = self.config["connect_i2p_ifac_netname"]
if self.config["connect_i2p_ifac_passphrase"] == "":
ifac_netkey = None
else:
ifac_netkey = self.config["connect_i2p_ifac_passphrase"]
i2pinterface = I2PInterface.I2PInterface(
RNS.Transport,
"I2PInterface",
RNS.Reticulum.storagepath,
self.config["connect_i2p_b32"],
connectable = False,
)
i2pinterface.OUT = True
self.reticulum._add_interface(i2pinterface,ifac_netname=ifac_netname,ifac_netkey=ifac_netkey)
self.interface_i2p = i2pinterface
except Exception as e:
RNS.log("Error while adding I2P Interface. The contained exception was: "+str(e))
self.interface_i2p = None
RNS.log(str(RNS.Transport.interfaces))
self.message_router = LXMF.LXMRouter(identity = self.identity, storagepath = self.lxmf_storage, autopeer = True) self.message_router = LXMF.LXMRouter(identity = self.identity, storagepath = self.lxmf_storage, autopeer = True)
self.message_router.register_delivery_callback(self.lxmf_delivery) self.message_router.register_delivery_callback(self.lxmf_delivery)
@ -879,10 +1009,7 @@ instance_control_port = 37429
panic_on_interface_error = No panic_on_interface_error = No
[logging] [logging]
loglevel = 3 # TODO: Reset to 3
loglevel = 6
[interfaces]
[[Default Interface]]
type = AutoInterface
interface_enabled = True
""".encode("utf-8") """.encode("utf-8")

View File

@ -136,6 +136,10 @@ MDNavigationLayout:
pos_hint: {"top": 1} pos_hint: {"top": 1}
left_action_items: left_action_items:
[['menu', lambda x: nav_drawer.set_state("open")]] [['menu', lambda x: nav_drawer.set_state("open")]]
right_action_items:
[
['close', lambda x: root.ids.screen_manager.app.close_connectivity_action(self)],
]
ScrollView: ScrollView:
id: connectivity_scrollview id: connectivity_scrollview
@ -145,7 +149,15 @@ MDNavigationLayout:
spacing: "24dp" spacing: "24dp"
size_hint_y: None size_hint_y: None
height: self.minimum_height height: self.minimum_height
padding: dp(64) padding: dp(16)
MDLabel:
text: ""
font_style: "H6"
MDLabel:
text: "Configuring Connectivity"
font_style: "H6"
MDLabel: MDLabel:
id: connectivity_info id: connectivity_info
@ -156,6 +168,146 @@ MDNavigationLayout:
height: self.texture_size[1] height: self.texture_size[1]
MDBoxLayout:
orientation: "horizontal"
# spacing: "24dp"
size_hint_y: None
height: dp(48)
MDLabel:
text: "Connect via local WiFi/Ethernet"
font_style: "H6"
MDSwitch:
id: connectivity_use_local
active: False
MDLabel:
text: ""
font_size: dp(16)
MDTextField:
id: connectivity_local_groupid
hint_text: "Optional WiFi/Ethernet Group ID"
text: ""
max_text_length: 128
font_size: dp(24)
MDTextField:
id: connectivity_local_ifac_netname
hint_text: "Optional IFAC network name"
text: ""
font_size: dp(24)
MDTextField:
id: connectivity_local_ifac_passphrase
hint_text: "Optional IFAC passphrase"
text: ""
font_size: dp(24)
MDBoxLayout:
orientation: "horizontal"
# spacing: "24dp"
size_hint_y: None
height: dp(48)
MDLabel:
text: "Connect via TCP"
font_style: "H6"
MDSwitch:
id: connectivity_use_tcp
active: False
MDTextField:
id: connectivity_tcp_host
hint_text: "TCP Host"
text: ""
font_size: dp(24)
MDTextField:
id: connectivity_tcp_port
hint_text: "TCP Port"
text: ""
font_size: dp(24)
MDTextField:
id: connectivity_tcp_ifac_netname
hint_text: "Optional IFAC network name"
text: ""
font_size: dp(24)
MDTextField:
id: connectivity_tcp_ifac_passphrase
hint_text: "Optional IFAC passphrase"
text: ""
font_size: dp(24)
MDBoxLayout:
orientation: "horizontal"
# spacing: "24dp"
size_hint_y: None
height: dp(48)
MDLabel:
text: "Connect via I2P"
font_style: "H6"
MDSwitch:
id: connectivity_use_i2p
active: False
MDTextField:
id: connectivity_i2p_b32
hint_text: "I2P B32"
text: ""
font_size: dp(24)
MDTextField:
id: connectivity_i2p_ifac_netname
hint_text: "Optional IFAC network name"
text: ""
font_size: dp(24)
MDTextField:
id: connectivity_i2p_ifac_passphrase
hint_text: "Optional IFAC passphrase"
text: ""
font_size: dp(24)
MDBoxLayout:
orientation: "horizontal"
# spacing: "24dp"
size_hint_y: None
height: dp(48)
MDLabel:
text: "Connect via RNode"
font_style: "H6"
disabled: True
MDSwitch:
id: connectivity_use_rnode
active: False
disabled: True
MDTextField:
id: connectivity_rnode_cid
hint_text: "RNode Pairing ID"
text: ""
font_size: dp(24)
disabled: True
MDScreen: MDScreen:
name: "guide_screen" name: "guide_screen"