Added signal stats to announce stream

This commit is contained in:
Mark Qvist 2024-12-11 19:25:46 +01:00
parent 887c0a9a16
commit 15600d5172
3 changed files with 76 additions and 23 deletions

View File

@ -45,7 +45,7 @@ class PropagationNodeDetector():
aspect_filter = "lxmf.propagation"
def received_announce(self, destination_hash, announced_identity, app_data):
def received_announce(self, destination_hash, announced_identity, app_data, announce_packet_hash):
try:
if app_data != None and len(app_data) > 0:
if pn_announce_data_is_valid(app_data):
@ -64,8 +64,12 @@ class PropagationNodeDetector():
# age = 0
pass
link_stats = {"rssi": self.reticulum.get_packet_rssi(announce_packet_hash),
"snr": self.reticulum.get_packet_snr(announce_packet_hash),
"q": self.reticulum.get_packet_q(announce_packet_hash)}
RNS.log("Detected active propagation node "+RNS.prettyhexrep(destination_hash)+" emission "+str(age)+" seconds ago, "+str(hops)+" hops away")
self.owner.log_announce(destination_hash, app_data, dest_type=PropagationNodeDetector.aspect_filter)
self.owner.log_announce(destination_hash, app_data, dest_type=PropagationNodeDetector.aspect_filter, link_stats=link_stats)
if self.owner.config["lxmf_propagation_node"] == None:
if self.owner.active_propagation_node == None:
@ -114,10 +118,14 @@ class SidebandCore():
LOG_DEQUE_MAXLEN = 128
aspect_filter = "lxmf.delivery"
def received_announce(self, destination_hash, announced_identity, app_data):
def received_announce(self, destination_hash, announced_identity, app_data, announce_packet_hash):
# Add the announce to the directory announce
# stream logger
link_stats = {"rssi": self.reticulum.get_packet_rssi(announce_packet_hash),
"snr": self.reticulum.get_packet_snr(announce_packet_hash),
"q": self.reticulum.get_packet_q(announce_packet_hash)}
# This reformats the new v0.5.0 announce data back to the expected format
# for Sidebands database and other handling functions.
dn = LXMF.display_name_from_app_data(app_data)
@ -126,7 +134,7 @@ class SidebandCore():
if dn != None:
app_data = dn.encode("utf-8")
self.log_announce(destination_hash, app_data, dest_type=SidebandCore.aspect_filter, stamp_cost=sc)
self.log_announce(destination_hash, app_data, dest_type=SidebandCore.aspect_filter, stamp_cost=sc, link_stats=link_stats)
def __init__(self, owner_app, config_path = None, is_service=False, is_client=False, android_app_dir=None, verbose=False, owner_service=None, service_context=None, is_daemon=False, load_config_only=False):
self.is_service = is_service
@ -961,14 +969,14 @@ class SidebandCore():
else:
plyer.notification.notify(title, content, app_icon=self.icon_32)
def log_announce(self, dest, app_data, dest_type, stamp_cost=None):
def log_announce(self, dest, app_data, dest_type, stamp_cost=None, link_stats=None):
try:
if app_data == None:
app_data = b""
if type(app_data) != bytes:
app_data = msgpack.packb([app_data, stamp_cost])
RNS.log("Received "+str(dest_type)+" announce for "+RNS.prettyhexrep(dest)+" with data: "+str(app_data), RNS.LOG_DEBUG)
self._db_save_announce(dest, app_data, dest_type)
self._db_save_announce(dest, app_data, dest_type, link_stats)
self.setstate("app.flags.new_announces", True)
except Exception as e:
@ -1980,10 +1988,10 @@ class SidebandCore():
# TODO: Remove this again at some point in the future
db = self.__db_connect()
dbc = db.cursor()
dbc.execute("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'lxm' AND sql LIKE '%extra%'")
dbc.execute("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'announce' AND sql LIKE '%extra%'")
result = dbc.fetchall()
if len(result) == 0:
dbc.execute("ALTER TABLE lxm ADD COLUMN extra BLOB")
dbc.execute("ALTER TABLE announce ADD COLUMN extra BLOB")
db.commit()
def _db_initstate(self):
@ -2540,8 +2548,16 @@ class SidebandCore():
for entry in result:
try:
if not entry[2] in added_dests:
app_data = entry[3]
app_data = entry[3]
dest_type = entry[4]
if entry[5] != None:
try:
extras = msgpack.unpackb(entry[5])
except Exception as e:
RNS.log(f"Error while unpacking extras from announce: {e}", RNS.LOG_ERROR)
extras = None
else:
extras = None
if dest_type == "lxmf.delivery":
announced_name = LXMF.display_name_from_app_data(app_data)
announced_cost = self.message_router.get_outbound_stamp_cost(entry[2])
@ -2549,11 +2565,12 @@ class SidebandCore():
announced_name = None
announced_cost = None
announce = {
"dest": entry[2],
"name": announced_name,
"cost": announced_cost,
"time": entry[1],
"type": dest_type
"dest" : entry[2],
"name" : announced_name,
"cost" : announced_cost,
"time" : entry[1],
"type" : dest_type,
"extras": extras,
}
added_dests.append(entry[2])
announces.append(announce)
@ -2967,7 +2984,7 @@ class SidebandCore():
self.__event_conversation_changed(context_dest)
def _db_save_announce(self, destination_hash, app_data, dest_type="lxmf.delivery"):
def _db_save_announce(self, destination_hash, app_data, dest_type="lxmf.delivery", link_stats = None):
with self.db_lock:
db = self.__db_connect()
dbc = db.cursor()
@ -2981,14 +2998,16 @@ class SidebandCore():
now = time.time()
hash_material = str(time).encode("utf-8")+destination_hash+app_data+dest_type.encode("utf-8")
announce_hash = RNS.Identity.full_hash(hash_material)
extras = msgpack.packb({"link_stats": link_stats})
query = "INSERT INTO announce (id, received, source, data, dest_type) values (?, ?, ?, ?, ?)"
query = "INSERT INTO announce (id, received, source, data, dest_type, extra) values (?, ?, ?, ?, ?, ?)"
data = (
announce_hash,
now,
destination_hash,
app_data,
dest_type,
extras,
)
dbc.execute(query, data)

View File

@ -18,9 +18,9 @@ from kivy.lang.builder import Builder
from kivy.utils import escape_markup
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import multilingual_markup
from ui.helpers import multilingual_markup, sig_icon_for_q
else:
from .helpers import multilingual_markup
from .helpers import multilingual_markup, sig_icon_for_q
if RNS.vendor.platformutils.get_platform() == "android":
from ui.helpers import ts_format
@ -92,6 +92,25 @@ class Announces():
a_name = announce["name"]
a_cost = announce["cost"]
dest_type = announce["type"]
a_rssi = None
a_snr = None
a_q = None
link_extras_str = ""
link_extras_full = ""
if "extras" in announce and announce["extras"] != None:
extras = announce["extras"]
RNS.log("Announce has extras: "+str(announce["extras"]))
if "link_stats" in extras:
link_stats = extras["link_stats"]
if "rssi" in link_stats and "snr" in link_stats and "q" in link_stats:
a_rssi = link_stats["rssi"]
a_snr = link_stats["snr"]
a_q = link_stats["q"]
link_extras_str = f" ([b]RSSI[/b] {a_rssi} [b]SNR[/b] {a_snr})"
link_extras_full = f"\n[b]Link Quality[/b] {a_q}%[/b]\n[b]RSSI[/b] {a_rssi}\n[b]SNR[/b] {a_snr}"
sig_icon = multilingual_markup(sig_icon_for_q(a_q).encode("utf-8")).decode("utf-8")
if not context_dest in self.added_item_dests:
if self.app.sideband.is_trusted(context_dest):
@ -99,16 +118,16 @@ class Announces():
else:
trust_icon = "account-question"
def gen_info(ts, dest, name, cost, dtype):
def gen_info(ts, dest, name, cost, dtype, link_extras):
name = multilingual_markup(escape_markup(str(name)).encode("utf-8")).decode("utf-8")
cost = str(cost)
def x(sender):
yes_button = MDRectangleFlatButton(text="OK",font_size=dp(18))
if dtype == "lxmf.delivery":
ad_text = "[size=22dp]LXMF Peer[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)+"\n[b]Name[/b] "+name+"\n[b]Stamp Cost[/b] "+cost
ad_text = "[size=22dp]LXMF Peer[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)+"\n[b]Name[/b] "+name+"\n[b]Stamp Cost[/b] "+cost+link_extras
if dtype == "lxmf.propagation":
ad_text = "[size=22dp]LXMF Propagation Node[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)
ad_text = "[size=22dp]LXMF Propagation Node[/size]\n\n[b]Received[/b] "+ts+"\n[b]Address[/b] "+RNS.prettyhexrep(dest)+link_extras
dialog = MDDialog(
text=ad_text,
@ -123,7 +142,8 @@ class Announces():
dialog.open()
return x
time_string = time.strftime(ts_format, time.localtime(ts))
time_string = sig_icon + " " + time.strftime(ts_format, time.localtime(ts)) + link_extras_str
time_string_plain = time.strftime(ts_format, time.localtime(ts))
if dest_type == "lxmf.delivery":
disp_name = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(context_dest))).encode("utf-8")).decode("utf-8")
@ -137,7 +157,7 @@ class Announces():
disp_name = "Unknown Announce"
iconl = IconLeftWidget(icon="progress-question")
item = TwoLineAvatarIconListItem(text=time_string, secondary_text=disp_name, on_release=gen_info(time_string, context_dest, a_name, a_cost, dest_type))
item = TwoLineAvatarIconListItem(text=time_string, secondary_text=disp_name, on_release=gen_info(time_string_plain, context_dest, a_name, a_cost, dest_type, link_extras_full))
item.add_widget(iconl)
item.sb_uid = context_dest
item.ts = ts

View File

@ -111,6 +111,20 @@ def multilingual_markup(data):
return do.encode("utf-8")
def sig_icon_for_q(q):
if q == None:
return "󰴽"
elif q > 90:
return "󰣺"
elif q > 70:
return "󰣸"
elif q > 50:
return "󰣶"
elif q > 30:
return "󰣴"
elif q > 10:
return "󰣾"
persistent_fonts = ["nf", "term"]
nf_mapped = "nf"