Implemented advanced telemetry configuration

This commit is contained in:
Mark Qvist 2023-10-30 13:45:58 +01:00
parent a78a773886
commit ab15093ec8
7 changed files with 331 additions and 168 deletions

View File

@ -3200,9 +3200,12 @@ class SidebandApp(MDApp):
ok_button.bind(on_release=dl_ok) ok_button.bind(on_release=dl_ok)
result = self.sideband.send_latest_telemetry(to_addr=self.sideband.config["telemetry_collector"]) result = self.sideband.send_latest_telemetry(to_addr=self.sideband.config["telemetry_collector"])
if result == "destination_unknown": if result == "no_address":
title_str = "Invalid Address"
info_str = "You must specify a valid LXMF address for the collector you want to sent data to."
elif result == "destination_unknown":
title_str = "Unknown Destination" title_str = "Unknown Destination"
info_str = "No keys known for the destination. Connected reticules have been queried for the keys." info_str = "No keys known for the destination. Connected reticules have been queried for the keys. Try again when an announce for the destination has arrived."
elif result == "in_progress": elif result == "in_progress":
title_str = "Transfer In Progress" title_str = "Transfer In Progress"
info_str = "There is already an outbound telemetry transfer in progress to the collector." info_str = "There is already an outbound telemetry transfer in progress to the collector."
@ -3235,9 +3238,12 @@ class SidebandApp(MDApp):
result = self.sideband.request_latest_telemetry(from_addr=self.sideband.config["telemetry_collector"]) result = self.sideband.request_latest_telemetry(from_addr=self.sideband.config["telemetry_collector"])
if result == "destination_unknown": if result == "no_address":
title_str = "Invalid Address"
info_str = "You must specify a valid LXMF address for the collector you want to request data from."
elif result == "destination_unknown":
title_str = "Unknown Destination" title_str = "Unknown Destination"
info_str = "No keys known for the destination. Connected reticules have been queried for the keys." info_str = "No keys known for the destination. Connected reticules have been queried for the keys. Try again when an announce for the destination has arrived."
elif result == "in_progress": elif result == "in_progress":
title_str = "Transfer In Progress" title_str = "Transfer In Progress"
info_str = "There is already a telemetry request transfer in progress for this peer." info_str = "There is already a telemetry request transfer in progress for this peer."

View File

@ -527,6 +527,7 @@ class SidebandCore():
self.config["telemetry_display_trusted_only"] = False self.config["telemetry_display_trusted_only"] = False
if not "telemetry_receive_trusted_only" in self.config: if not "telemetry_receive_trusted_only" in self.config:
self.config["telemetry_receive_trusted_only"] = False self.config["telemetry_receive_trusted_only"] = False
if not "telemetry_send_all_to_collector" in self.config: if not "telemetry_send_all_to_collector" in self.config:
self.config["telemetry_send_all_to_collector"] = False self.config["telemetry_send_all_to_collector"] = False
if not "telemetry_use_propagation_only" in self.config: if not "telemetry_use_propagation_only" in self.config:
@ -535,6 +536,10 @@ class SidebandCore():
self.config["telemetry_try_propagation_on_fail"] = True self.config["telemetry_try_propagation_on_fail"] = True
if not "telemetry_requests_only_send_latest" in self.config: if not "telemetry_requests_only_send_latest" in self.config:
self.config["telemetry_requests_only_send_latest"] = True self.config["telemetry_requests_only_send_latest"] = True
if not "telemetry_allow_requests_from_trusted" in self.config:
self.config["telemetry_allow_requests_from_trusted"] = False
if not "telemetry_allow_requests_from_anyone" in self.config:
self.config["telemetry_allow_requests_from_anyone"] = False
if not "telemetry_s_location" in self.config: if not "telemetry_s_location" in self.config:
self.config["telemetry_s_location"] = False self.config["telemetry_s_location"] = False
@ -740,8 +745,19 @@ class SidebandCore():
def requests_allowed_from(self, context_dest): def requests_allowed_from(self, context_dest):
try: try:
if self.config["telemetry_allow_requests_from_anyone"] == True:
return True
existing_conv = self._db_conversation(context_dest) existing_conv = self._db_conversation(context_dest)
if existing_conv != None: if existing_conv != None:
if existing_conv["trust"] == 1:
trusted = True
else:
trusted = False
if self.config["telemetry_allow_requests_from_trusted"] == True:
return trusted
cd = existing_conv["data"] cd = existing_conv["data"]
if cd != None and "allow_requests" in cd and cd["allow_requests"] == True: if cd != None and "allow_requests" in cd and cd["allow_requests"] == True:
return True return True
@ -908,114 +924,120 @@ class SidebandCore():
def request_latest_telemetry(self, from_addr=None): def request_latest_telemetry(self, from_addr=None):
if self.getstate(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.request_sending") == True: if from_addr == None:
RNS.log("Not sending new telemetry request, since an earlier transfer is already in progress", RNS.LOG_DEBUG) return "no_address"
return "in_progress" else:
if self.getstate(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.request_sending") == True:
RNS.log("Not sending new telemetry request, since an earlier transfer is already in progress", RNS.LOG_DEBUG)
return "in_progress"
if from_addr != None: if from_addr != None:
dest_identity = RNS.Identity.recall(from_addr) dest_identity = RNS.Identity.recall(from_addr)
if dest_identity == None: if dest_identity == None:
RNS.log("The identity for "+RNS.prettyhexrep(from_addr)+" could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG) RNS.log("The identity for "+RNS.prettyhexrep(from_addr)+" could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG)
RNS.Transport.request_path(from_addr) RNS.Transport.request_path(from_addr)
return "destination_unknown" return "destination_unknown"
else:
now = time.time()
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination
if self.config["telemetry_use_propagation_only"] == True:
desired_method = LXMF.LXMessage.PROPAGATED
else:
desired_method = LXMF.LXMessage.DIRECT
request_timebase = self.getpersistent(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.timebase") or now - self.telemetry_request_max_history
lxm_fields = { LXMF.FIELD_COMMANDS: [
{Commands.TELEMETRY_REQUEST: request_timebase},
]}
lxm = LXMF.LXMessage(dest, source, "", desired_method=desired_method, fields = lxm_fields)
lxm.request_timebase = request_timebase
lxm.register_delivery_callback(self.telemetry_request_finished)
lxm.register_failed_callback(self.telemetry_request_finished)
if self.message_router.get_outbound_propagation_node() != None:
if self.config["telemetry_try_propagation_on_fail"]:
lxm.try_propagation_on_fail = True
RNS.log(f"Sending telemetry request with timebase {request_timebase}", RNS.LOG_DEBUG)
self.setpersistent(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.last_request_attempt", time.time())
self.setstate(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.request_sending", True)
self.message_router.handle_outbound(lxm)
return "sent"
else: else:
now = time.time() return "not_sent"
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination
if self.config["telemetry_use_propagation_only"] == True:
desired_method = LXMF.LXMessage.PROPAGATED
else:
desired_method = LXMF.LXMessage.DIRECT
request_timebase = self.getpersistent(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.timebase") or now - self.telemetry_request_max_history
lxm_fields = { LXMF.FIELD_COMMANDS: [
{Commands.TELEMETRY_REQUEST: request_timebase},
]}
lxm = LXMF.LXMessage(dest, source, "", desired_method=desired_method, fields = lxm_fields)
lxm.request_timebase = request_timebase
lxm.register_delivery_callback(self.telemetry_request_finished)
lxm.register_failed_callback(self.telemetry_request_finished)
if self.message_router.get_outbound_propagation_node() != None:
if self.config["telemetry_try_propagation_on_fail"]:
lxm.try_propagation_on_fail = True
RNS.log(f"Sending telemetry request with timebase {request_timebase}", RNS.LOG_DEBUG)
self.setpersistent(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.last_request_attempt", time.time())
self.setstate(f"telemetry.{RNS.hexrep(from_addr, delimit=False)}.request_sending", True)
self.message_router.handle_outbound(lxm)
return "sent"
else:
return "not_sent"
def send_latest_telemetry(self, to_addr=None, stream=None): def send_latest_telemetry(self, to_addr=None, stream=None):
if self.getstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending") == True: if to_addr == None:
RNS.log("Not sending new telemetry update, since an earlier transfer is already in progress", RNS.LOG_DEBUG) return "no_address"
return "in_progress" else:
if self.getstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending") == True:
RNS.log("Not sending new telemetry update, since an earlier transfer is already in progress", RNS.LOG_DEBUG)
return "in_progress"
if to_addr != None and self.latest_packed_telemetry != None and self.latest_telemetry != None: if self.latest_packed_telemetry != None and self.latest_telemetry != None:
dest_identity = RNS.Identity.recall(to_addr) dest_identity = RNS.Identity.recall(to_addr)
if dest_identity == None: if dest_identity == None:
RNS.log("The identity for "+RNS.prettyhexrep(to_addr)+" could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG) RNS.log("The identity for "+RNS.prettyhexrep(to_addr)+" could not be recalled. Requesting identity from network...", RNS.LOG_DEBUG)
RNS.Transport.request_path(to_addr) RNS.Transport.request_path(to_addr)
return "destination_unknown" return "destination_unknown"
else:
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery")
source = self.lxmf_destination
if self.config["telemetry_use_propagation_only"] == True:
desired_method = LXMF.LXMessage.PROPAGATED
else:
desired_method = LXMF.LXMessage.DIRECT
lxm_fields = self.get_message_fields(to_addr)
if stream != None and len(stream) > 0:
lxm_fields[LXMF.FIELD_TELEMETRY_STREAM] = stream
if lxm_fields != None and (LXMF.FIELD_TELEMETRY in lxm_fields or LXMF.FIELD_TELEMETRY_STREAM in lxm_fields):
if LXMF.FIELD_TELEMETRY in lxm_fields:
telemeter = Telemeter.from_packed(lxm_fields[LXMF.FIELD_TELEMETRY])
telemetry_timebase = telemeter.read_all()["time"]["utc"]
elif LXMF.FIELD_TELEMETRY_STREAM in lxm_fields:
telemetry_timebase = 0
for te in lxm_fields[LXMF.FIELD_TELEMETRY_STREAM]:
ts = te[1]
telemetry_timebase = max(telemetry_timebase, ts)
if telemetry_timebase > (self.getpersistent(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.last_send_success_timebase") or 0):
lxm = LXMF.LXMessage(dest, source, "", desired_method=desired_method, fields = lxm_fields)
lxm.telemetry_timebase = telemetry_timebase
lxm.register_delivery_callback(self.outbound_telemetry_finished)
lxm.register_failed_callback(self.outbound_telemetry_finished)
if self.message_router.get_outbound_propagation_node() != None:
if self.config["telemetry_try_propagation_on_fail"]:
lxm.try_propagation_on_fail = True
RNS.log(f"Sending telemetry update with timebase {telemetry_timebase}", RNS.LOG_DEBUG)
self.setpersistent(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.last_send_attempt", time.time())
self.setstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending", True)
self.message_router.handle_outbound(lxm)
return "sent"
else:
RNS.log(f"Telemetry update with timebase {telemetry_timebase} was already successfully sent", RNS.LOG_DEBUG)
return "already_sent"
else:
return "not_sent"
else: else:
dest = RNS.Destination(dest_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "lxmf", "delivery") RNS.log("A telemetry update was requested, but there was nothing to send.", RNS.LOG_WARNING)
source = self.lxmf_destination return "not_sent"
if self.config["telemetry_use_propagation_only"] == True:
desired_method = LXMF.LXMessage.PROPAGATED
else:
desired_method = LXMF.LXMessage.DIRECT
lxm_fields = self.get_message_fields(to_addr)
if stream != None and len(stream) > 0:
lxm_fields[LXMF.FIELD_TELEMETRY_STREAM] = stream
if lxm_fields != None and (LXMF.FIELD_TELEMETRY in lxm_fields or LXMF.FIELD_TELEMETRY_STREAM in lxm_fields):
if LXMF.FIELD_TELEMETRY in lxm_fields:
telemeter = Telemeter.from_packed(lxm_fields[LXMF.FIELD_TELEMETRY])
telemetry_timebase = telemeter.read_all()["time"]["utc"]
elif LXMF.FIELD_TELEMETRY_STREAM in lxm_fields:
telemetry_timebase = 0
for te in lxm_fields[LXMF.FIELD_TELEMETRY_STREAM]:
ts = te[1]
telemetry_timebase = max(telemetry_timebase, ts)
if telemetry_timebase > (self.getpersistent(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.last_send_success_timebase") or 0):
lxm = LXMF.LXMessage(dest, source, "", desired_method=desired_method, fields = lxm_fields)
lxm.telemetry_timebase = telemetry_timebase
lxm.register_delivery_callback(self.outbound_telemetry_finished)
lxm.register_failed_callback(self.outbound_telemetry_finished)
if self.message_router.get_outbound_propagation_node() != None:
if self.config["telemetry_try_propagation_on_fail"]:
lxm.try_propagation_on_fail = True
RNS.log(f"Sending telemetry update with timebase {telemetry_timebase}", RNS.LOG_DEBUG)
self.setpersistent(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.last_send_attempt", time.time())
self.setstate(f"telemetry.{RNS.hexrep(to_addr, delimit=False)}.update_sending", True)
self.message_router.handle_outbound(lxm)
return "sent"
else:
RNS.log(f"Telemetry update with timebase {telemetry_timebase} was already successfully sent", RNS.LOG_DEBUG)
return "already_sent"
else:
return "not_sent"
else:
RNS.log("A telemetry update was requested, but there was nothing to send.", RNS.LOG_WARNING)
return "not_sent"
def list_telemetry(self, context_dest = None, after = None, before = None, limit = None): def list_telemetry(self, context_dest = None, after = None, before = None, limit = None):
@ -2931,7 +2953,10 @@ class SidebandCore():
else: else:
self.set_active_propagation_node(None) self.set_active_propagation_node(None)
def message_notification(self, message): def message_notification_no_display(self, message):
self.message_notification(message, no_display=True)
def message_notification(self, message, no_display=False):
if message.state == LXMF.LXMessage.FAILED and hasattr(message, "try_propagation_on_fail") and message.try_propagation_on_fail: if message.state == LXMF.LXMessage.FAILED and hasattr(message, "try_propagation_on_fail") and message.try_propagation_on_fail:
RNS.log("Direct delivery of "+str(message)+" failed. Retrying as propagated message.", RNS.LOG_VERBOSE) RNS.log("Direct delivery of "+str(message)+" failed. Retrying as propagated message.", RNS.LOG_VERBOSE)
message.try_propagation_on_fail = None message.try_propagation_on_fail = None
@ -2942,7 +2967,8 @@ class SidebandCore():
self._db_message_set_method(message.hash, LXMF.LXMessage.PROPAGATED) self._db_message_set_method(message.hash, LXMF.LXMessage.PROPAGATED)
self.message_router.handle_outbound(message) self.message_router.handle_outbound(message)
else: else:
self.lxm_ingest(message, originator=True) if not no_display:
self.lxm_ingest(message, originator=True)
def get_message_fields(self, context_dest, telemetry_update=False): def get_message_fields(self, context_dest, telemetry_update=False):
fields = {} fields = {}
@ -2987,7 +3013,7 @@ class SidebandCore():
RNS.log("Error while creating paper message: "+str(e), RNS.LOG_ERROR) RNS.log("Error while creating paper message: "+str(e), RNS.LOG_ERROR)
return False return False
def send_message(self, content, destination_hash, propagation, skip_fields=False): def send_message(self, content, destination_hash, propagation, skip_fields=False, no_display=False):
try: try:
if content == "": if content == "":
raise ValueError("Message content cannot be empty") raise ValueError("Message content cannot be empty")
@ -3007,15 +3033,21 @@ class SidebandCore():
fields = self.get_message_fields(destination_hash) fields = self.get_message_fields(destination_hash)
lxm = LXMF.LXMessage(dest, source, content, title="", desired_method=desired_method, fields = fields) lxm = LXMF.LXMessage(dest, source, content, title="", desired_method=desired_method, fields = fields)
lxm.register_delivery_callback(self.message_notification)
lxm.register_failed_callback(self.message_notification) if not no_display:
lxm.register_delivery_callback(self.message_notification)
lxm.register_failed_callback(self.message_notification)
else:
lxm.register_delivery_callback(self.message_notification_no_display)
lxm.register_failed_callback(self.message_notification_no_display)
if self.message_router.get_outbound_propagation_node() != None: if self.message_router.get_outbound_propagation_node() != None:
if self.config["lxmf_try_propagation_on_fail"]: if self.config["lxmf_try_propagation_on_fail"]:
lxm.try_propagation_on_fail = True lxm.try_propagation_on_fail = True
self.message_router.handle_outbound(lxm) self.message_router.handle_outbound(lxm)
self.lxm_ingest(lxm, originator=True) if not no_display:
self.lxm_ingest(lxm, originator=True)
return True return True
@ -3035,6 +3067,8 @@ class SidebandCore():
commands.append({Commands.ECHO: echo_content}) commands.append({Commands.ECHO: echo_content})
elif content.startswith("sig"): elif content.startswith("sig"):
commands.append({Commands.SIGNAL_REPORT: True}) commands.append({Commands.SIGNAL_REPORT: True})
elif content.startswith("ping"):
commands.append({Commands.PING: True})
if len(commands) == 0: if len(commands) == 0:
return False return False
@ -3307,6 +3341,10 @@ class SidebandCore():
if self.requests_allowed_from(context_dest): if self.requests_allowed_from(context_dest):
commands = message.fields[LXMF.FIELD_COMMANDS] commands = message.fields[LXMF.FIELD_COMMANDS]
self.handle_commands(commands, message) self.handle_commands(commands, message)
else:
# TODO: Add these event to built-in log/event viewer
# when it is implemented.
RNS.log("Unauthorized command received from "+RNS.prettyhexrep(context_dest), RNS.LOG_WARNING)
else: else:
self.lxm_ingest(message) self.lxm_ingest(message)
@ -3324,10 +3362,14 @@ class SidebandCore():
RNS.log("Handling telemetry request with timebase "+str(timebase), RNS.LOG_DEBUG) RNS.log("Handling telemetry request with timebase "+str(timebase), RNS.LOG_DEBUG)
self.create_telemetry_response(to_addr=context_dest, timebase=timebase) self.create_telemetry_response(to_addr=context_dest, timebase=timebase)
elif Commands.PING in command:
RNS.log("Handling ping request", RNS.LOG_DEBUG)
self.send_message("Ping reply", context_dest, False, skip_fields=True, no_display=True)
elif Commands.ECHO in command: elif Commands.ECHO in command:
msg_content = "Echo reply: "+command[Commands.ECHO].decode("utf-8") msg_content = "Echo reply: "+command[Commands.ECHO].decode("utf-8")
RNS.log("Handling echo request", RNS.LOG_DEBUG) RNS.log("Handling echo request", RNS.LOG_DEBUG)
self.send_message(msg_content, context_dest, False, skip_fields=True) self.send_message(msg_content, context_dest, False, skip_fields=True, no_display=True)
elif Commands.SIGNAL_REPORT in command: elif Commands.SIGNAL_REPORT in command:
RNS.log("Handling signal report", RNS.LOG_DEBUG) RNS.log("Handling signal report", RNS.LOG_DEBUG)
@ -3343,7 +3385,7 @@ class SidebandCore():
else: else:
phy_str = "No reception info available" phy_str = "No reception info available"
self.send_message(phy_str, context_dest, False, skip_fields=True) self.send_message(phy_str, context_dest, False, skip_fields=True, no_display=True)
except Exception as e: except Exception as e:
RNS.log("Error while handling commands: "+str(e), RNS.LOG_ERROR) RNS.log("Error while handling commands: "+str(e), RNS.LOG_ERROR)

View File

@ -10,8 +10,9 @@ from .geo import azalt, angle_to_horizon, radio_horizon, shared_radio_horizon
class Commands(): class Commands():
TELEMETRY_REQUEST = 0x01 TELEMETRY_REQUEST = 0x01
ECHO = 0x02 PING = 0x02
SIGNAL_REPORT = 0x03 ECHO = 0x03
SIGNAL_REPORT = 0x04
class Telemeter(): class Telemeter():
@staticmethod @staticmethod

View File

@ -472,7 +472,7 @@ Builder.load_string("""
height: dp(32) height: dp(32)
MDLabel: MDLabel:
id: telemetry_switch_label id: telemetry_switch_label
text: "Include Telemetry" text: "Send Telemetry"
font_style: "H6" font_style: "H6"
MDSwitch: MDSwitch:

View File

@ -71,15 +71,6 @@ MDNavigationLayout:
on_release: root.ids.screen_manager.app.map_action(self) on_release: root.ids.screen_manager.app.map_action(self)
OneLineIconListItem:
text: "Telemetry"
on_release: root.ids.screen_manager.app.telemetry_action(self)
IconLeftWidget:
icon: "map-marker-path"
on_release: root.ids.screen_manager.app.telemetry_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Announce Stream" text: "Announce Stream"
on_release: root.ids.screen_manager.app.announces_action(self) on_release: root.ids.screen_manager.app.announces_action(self)
@ -98,6 +89,15 @@ MDNavigationLayout:
on_release: root.ids.screen_manager.app.broadcasts_action(self) on_release: root.ids.screen_manager.app.broadcasts_action(self)
OneLineIconListItem:
text: "Telemetry"
on_release: root.ids.screen_manager.app.telemetry_action(self)
IconLeftWidget:
icon: "map-marker-path"
on_release: root.ids.screen_manager.app.telemetry_action(self)
OneLineIconListItem: OneLineIconListItem:
text: "Preferences" text: "Preferences"
on_release: root.ids.screen_manager.app.settings_action(self) on_release: root.ids.screen_manager.app.settings_action(self)

View File

@ -193,13 +193,18 @@ class Messages():
pass pass
if "lxm" in m and m["lxm"] != None and m["lxm"].fields != None and LXMF.FIELD_COMMANDS in m["lxm"].fields: if "lxm" in m and m["lxm"] != None and m["lxm"].fields != None and LXMF.FIELD_COMMANDS in m["lxm"].fields:
commands = m["lxm"].fields[LXMF.FIELD_COMMANDS] try:
for command in commands: commands = m["lxm"].fields[LXMF.FIELD_COMMANDS]
if Commands.ECHO in command: for command in commands:
extra_content = "[font=RobotoMono-Regular]> echo "+command[Commands.ECHO].decode("utf-8")+"[/font]\n" if Commands.ECHO in command:
if Commands.SIGNAL_REPORT in command: extra_content = "[font=RobotoMono-Regular]> echo "+command[Commands.ECHO].decode("utf-8")+"[/font]\n"
extra_content = "[font=RobotoMono-Regular]> sig[/font]\n" if Commands.PING in command:
extra_content = extra_content[:-1] extra_content = "[font=RobotoMono-Regular]> ping[/font]\n"
if Commands.SIGNAL_REPORT in command:
extra_content = "[font=RobotoMono-Regular]> sig[/font]\n"
extra_content = extra_content[:-1]
except Exception as e:
RNS.log("Error while generating command display: "+str(e), RNS.LOG_ERROR)
if telemeter == None and "lxm" in m and m["lxm"] and m["lxm"].fields != None and LXMF.FIELD_TELEMETRY in m["lxm"].fields: if telemeter == None and "lxm" in m and m["lxm"] and m["lxm"].fields != None and LXMF.FIELD_TELEMETRY in m["lxm"].fields:
try: try:

View File

@ -67,6 +67,22 @@ class Telemetry():
self.screen.ids.telemetry_send_all_to_collector.active = self.app.sideband.config["telemetry_send_all_to_collector"] self.screen.ids.telemetry_send_all_to_collector.active = self.app.sideband.config["telemetry_send_all_to_collector"]
self.screen.ids.telemetry_send_all_to_collector.bind(active=self.telemetry_save) self.screen.ids.telemetry_send_all_to_collector.bind(active=self.telemetry_save)
self.screen.ids.telemetry_use_propagation_only.active = self.app.sideband.config["telemetry_use_propagation_only"]
self.screen.ids.telemetry_use_propagation_only.bind(active=self.telemetry_save)
self.screen.ids.telemetry_try_propagation_on_fail.active = self.app.sideband.config["telemetry_try_propagation_on_fail"]
self.screen.ids.telemetry_try_propagation_on_fail.bind(active=self.telemetry_save)
self.screen.ids.telemetry_requests_only_send_latest.active = self.app.sideband.config["telemetry_requests_only_send_latest"]
self.screen.ids.telemetry_requests_only_send_latest.bind(active=self.telemetry_save)
self.screen.ids.telemetry_allow_requests_from_trusted.active = self.app.sideband.config["telemetry_allow_requests_from_trusted"]
self.screen.ids.telemetry_allow_requests_from_trusted.bind(active=self.telemetry_save)
self.screen.ids.telemetry_allow_requests_from_anyone.active = self.app.sideband.config["telemetry_allow_requests_from_anyone"]
self.screen.ids.telemetry_allow_requests_from_anyone.bind(active=self.telemetry_save)
self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect
info = "\nSideband allows you to securely share telemetry, such as location and sensor data, with people, custom programs, machines or other system over LXMF. You have complete control over what kind of telemetry to send, and who you share it with.\n\nTelemetry data is never sent to, via or processed by any external services or servers, but is carried exclusively within encrypted LXMF messages over Reticulum, and only to the destinations you define.\n\nWhen telemetry is enabled, it is possible to embed telemetry data in normal messages on a per-peer basis. You can control this from the [b]Conversations[/b] list, by selecting the [b]Edit[/b] option for the relevant peer.\n\nYou can also define a [b]Telemetry Collector[/b], that Sideband can automatically send telemetry to on a periodic basis. By default, only your own telemetry will be sent to the collector, but by enabling the [b]Send all known to collector[/b] option, you can forward all known telemetry to the collector. This can also be used to aggregate telemetry from multiple different collectors, or create chains of transmission.\n" info = "\nSideband allows you to securely share telemetry, such as location and sensor data, with people, custom programs, machines or other system over LXMF. You have complete control over what kind of telemetry to send, and who you share it with.\n\nTelemetry data is never sent to, via or processed by any external services or servers, but is carried exclusively within encrypted LXMF messages over Reticulum, and only to the destinations you define.\n\nWhen telemetry is enabled, it is possible to embed telemetry data in normal messages on a per-peer basis. You can control this from the [b]Conversations[/b] list, by selecting the [b]Edit[/b] option for the relevant peer.\n\nYou can also define a [b]Telemetry Collector[/b], that Sideband can automatically send telemetry to on a periodic basis. By default, only your own telemetry will be sent to the collector, but by enabling the [b]Send all known to collector[/b] option, you can forward all known telemetry to the collector. This can also be used to aggregate telemetry from multiple different collectors, or create chains of transmission.\n"
if self.app.theme_cls.theme_style == "Dark": if self.app.theme_cls.theme_style == "Dark":
@ -89,9 +105,9 @@ class Telemetry():
interval_text = RNS.prettytime(interval) interval_text = RNS.prettytime(interval)
if self.screen.ids.telemetry_send_to_collector.active: if self.screen.ids.telemetry_send_to_collector.active:
self.screen.ids.telemetry_send_to_collector_label.text = "Auto send to collector every "+interval_text self.screen.ids.telemetry_send_to_collector_label.text = "Auto sync to collector every "+interval_text
else: else:
self.screen.ids.telemetry_send_to_collector_label.text = "Auto send to collector" self.screen.ids.telemetry_send_to_collector_label.text = "Auto sync to collector"
if save: if save:
self.app.sideband.config["telemetry_send_interval"] = interval self.app.sideband.config["telemetry_send_interval"] = interval
@ -135,9 +151,9 @@ class Telemetry():
interval_text = RNS.prettytime(interval) interval_text = RNS.prettytime(interval)
if self.screen.ids.telemetry_request_from_collector.active: if self.screen.ids.telemetry_request_from_collector.active:
self.screen.ids.telemetry_request_from_collector_label.text = "Auto request from collector every "+interval_text self.screen.ids.telemetry_request_from_collector_label.text = "Auto sync from collector every "+interval_text
else: else:
self.screen.ids.telemetry_request_from_collector_label.text = "Auto request from collector" self.screen.ids.telemetry_request_from_collector_label.text = "Auto sync from collector"
if save: if save:
self.app.sideband.config["telemetry_request_interval"] = interval self.app.sideband.config["telemetry_request_interval"] = interval
@ -220,6 +236,11 @@ class Telemetry():
self.app.sideband.config["telemetry_send_appearance"] = self.screen.ids.telemetry_send_appearance.active self.app.sideband.config["telemetry_send_appearance"] = self.screen.ids.telemetry_send_appearance.active
self.app.sideband.config["telemetry_receive_trusted_only"] = self.screen.ids.telemetry_receive_trusted_only.active self.app.sideband.config["telemetry_receive_trusted_only"] = self.screen.ids.telemetry_receive_trusted_only.active
self.app.sideband.config["telemetry_send_all_to_collector"] = self.screen.ids.telemetry_send_all_to_collector.active self.app.sideband.config["telemetry_send_all_to_collector"] = self.screen.ids.telemetry_send_all_to_collector.active
self.app.sideband.config["telemetry_use_propagation_only"] = self.screen.ids.telemetry_use_propagation_only.active
self.app.sideband.config["telemetry_try_propagation_on_fail"] = self.screen.ids.telemetry_try_propagation_on_fail.active
self.app.sideband.config["telemetry_requests_only_send_latest"] = self.screen.ids.telemetry_requests_only_send_latest.active
self.app.sideband.config["telemetry_allow_requests_from_trusted"] = self.screen.ids.telemetry_allow_requests_from_trusted.active
self.app.sideband.config["telemetry_allow_requests_from_anyone"] = self.screen.ids.telemetry_allow_requests_from_anyone.active
self.app.sideband.save_configuration() self.app.sideband.save_configuration()
if run_telemetry_update: if run_telemetry_update:
@ -570,37 +591,6 @@ MDScreen:
pos_hint: {"center_y": 0.3} pos_hint: {"center_y": 0.3}
active: False active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Send telemetry to all trusted"
font_style: "H6"
MDSwitch:
id: telemetry_send_to_trusted
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
id: telemetry_send_all_to_collector_label
text: "Send all known to collector"
font_style: "H6"
MDSwitch:
id: telemetry_send_all_to_collector
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout: MDBoxLayout:
orientation: "horizontal" orientation: "horizontal"
size_hint_y: None size_hint_y: None
@ -609,7 +599,7 @@ MDScreen:
MDLabel: MDLabel:
id: telemetry_send_to_collector_label id: telemetry_send_to_collector_label
text: "Auto send to collector" text: "Auto sync to collector"
font_style: "H6" font_style: "H6"
MDSwitch: MDSwitch:
@ -640,7 +630,7 @@ MDScreen:
MDLabel: MDLabel:
id: telemetry_request_from_collector_label id: telemetry_request_from_collector_label
text: "Auto request from collector" text: "Auto sync from collector"
font_style: "H6" font_style: "H6"
MDSwitch: MDSwitch:
@ -797,7 +787,7 @@ MDScreen:
MDBoxLayout: MDBoxLayout:
orientation: "vertical" orientation: "vertical"
size_hint_y: None size_hint_y: None
padding: [dp(0),dp(24),dp(0),dp(12)] padding: [dp(0),dp(24),dp(0),dp(60)]
height: self.minimum_height height: self.minimum_height
MDBoxLayout: MDBoxLayout:
@ -827,6 +817,125 @@ MDScreen:
size_hint: [1.0, None] size_hint: [1.0, None]
on_release: root.delegate.telemetry_bg_color(self) on_release: root.delegate.telemetry_bg_color(self)
disabled: False disabled: False
MDLabel:
text: "Advanced Configuration"
font_style: "H6"
MDLabel:
id: telemetry_info5
markup: True
text: "\\n[i]Read this section before enabling any advanced configuration options[/i]\\n\\nBy using the following options in combination with the basic settings above, it is possible to achieve a broad variety of telemetry collection, sharing and distribution systems. Both distributed, centralised, private and public configurations are possible. This section briefly explains the available options. For more details, refer to the full manual.\\n\\nIf the [b]Embed telemetry to all trusted[/b] option is enabled, Sideband will automatically embed telemetry data in outgoing messages to all peers marked as trusted.\\n\\nWith the [b]Sync all known telemetry to collector[/b] option enabled, Sideband will send not only its own, but all collected telemetry data to the specified collector address. This can be useful for aggregating data from many different areas onto collectors, and for distributed configurations.\\n\\nIf the [b]Always use propagation for telemetry[/b] option is enabled, Sideband will never attempt to directly delivery outbound telemetry, but will always send it via the active propagation node.\\n\\nThe [b]Try propagation if direct delivery fails[/b] option will make Sideband attempt to send outbound telemetry via the active propagation node, if direct delivery to the recipient fails.\\n\\nIf [b]Allow requests from all trusted[/b] is enabled, any peer marked as trusted will be able to perform requests on this Sideband instance.\\n\\n[b]Warning![/b] If the option [b]Allow requests from anyone[/b] is enabled, [i]any peer[/i], on [i]all reachable reticules[/i] will be able to query and access telemetry data stored on this instance. This can be very useful for emergency situations, rescue operations and public coordination, but should be used with [b]extreme caution[/b].\\n\\n[b]Requests[/b] enables remote peers to query telemetry data collected by this instance, and to run available statistics commands. Available commands are currently [b]ping[/b], which requests a small response message, [b]echo[/b] which requests an echo reply of the specified text, and [b]sig[/b] which requests a sigal report, if available.\\n"
size_hint_y: None
text_size: self.width, None
height: self.texture_size[1]
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Embed telemetry to all trusted"
font_style: "H6"
MDSwitch:
id: telemetry_send_to_trusted
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Sync all known telemetry to collector"
font_style: "H6"
MDSwitch:
id: telemetry_send_all_to_collector
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Always use propagation for telemetry"
font_style: "H6"
MDSwitch:
id: telemetry_use_propagation_only
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Try propagation if direct delivery fails"
font_style: "H6"
MDSwitch:
id: telemetry_try_propagation_on_fail
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Requests receive only latest"
font_style: "H6"
MDSwitch:
id: telemetry_requests_only_send_latest
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Allow requests from all trusted"
font_style: "H6"
MDSwitch:
id: telemetry_allow_requests_from_trusted
pos_hint: {"center_y": 0.3}
active: False
MDBoxLayout:
orientation: "horizontal"
size_hint_y: None
padding: [0,0,dp(24),dp(0)]
height: dp(48)
MDLabel:
text: "Allow requests from anyone"
font_style: "H6"
MDSwitch:
id: telemetry_allow_requests_from_anyone
pos_hint: {"center_y": 0.3}
active: False
""" """
layout_sensors_screen = """ layout_sensors_screen = """