Fixed invalid link RSSI, SNR and Q data returned from API functions. Improved link physical layer stats updates.

This commit is contained in:
Mark Qvist 2024-10-20 13:34:02 +02:00
parent 5470f752b4
commit f5412f5c0b
2 changed files with 52 additions and 12 deletions

View File

@ -123,14 +123,14 @@ class Link:
link.request_time = time.time() link.request_time = time.time()
RNS.Transport.register_link(link) RNS.Transport.register_link(link)
link.last_inbound = time.time() link.last_inbound = time.time()
link.__update_phy_stats(packet, force_update=True)
link.start_watchdog() link.start_watchdog()
RNS.log("Incoming link request "+str(link)+" accepted on "+str(link.attached_interface), RNS.LOG_DEBUG) RNS.log("Incoming link request "+str(link)+" accepted on "+str(link.attached_interface), RNS.LOG_DEBUG)
return link return link
except Exception as e: except Exception as e:
RNS.log("Validating link request failed", RNS.LOG_VERBOSE) RNS.log(f"Validating link request failed: {e}", RNS.LOG_VERBOSE)
RNS.log("exc: "+str(e))
return None return None
else: else:
@ -309,6 +309,7 @@ class Link:
rtt_packet = RNS.Packet(self, rtt_data, context=RNS.Packet.LRRTT) rtt_packet = RNS.Packet(self, rtt_data, context=RNS.Packet.LRRTT)
rtt_packet.send() rtt_packet.send()
self.had_outbound() self.had_outbound()
self.__update_phy_stats(packet)
if self.callbacks.link_established != None: if self.callbacks.link_established != None:
thread = threading.Thread(target=self.callbacks.link_established, args=(self,)) thread = threading.Thread(target=self.callbacks.link_established, args=(self,))
@ -435,19 +436,28 @@ class Link:
""" """
:returns: The physical layer *Received Signal Strength Indication* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value. :returns: The physical layer *Received Signal Strength Indication* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
""" """
return self.rssi if self.__track_phy_stats:
return self.rssi
else:
return None
def get_snr(self): def get_snr(self):
""" """
:returns: The physical layer *Signal-to-Noise Ratio* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value. :returns: The physical layer *Signal-to-Noise Ratio* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
""" """
return self.rssi if self.__track_phy_stats:
return self.snr
else:
return None
def get_q(self): def get_q(self):
""" """
:returns: The physical layer *Link Quality* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value. :returns: The physical layer *Link Quality* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
""" """
return self.rssi if self.__track_phy_stats:
return self.q
else:
return None
def get_establishment_rate(self): def get_establishment_rate(self):
""" """
@ -640,9 +650,14 @@ class Link:
sleep(sleep_time) sleep(sleep_time)
if not self.__track_phy_stats:
self.rssi = None
self.snr = None
self.q = None
def __update_phy_stats(self, packet, query_shared = True):
if self.__track_phy_stats: def __update_phy_stats(self, packet, query_shared = True, force_update = False):
if self.__track_phy_stats or force_update:
if query_shared: if query_shared:
reticulum = RNS.Reticulum.get_instance() reticulum = RNS.Reticulum.get_instance()
if packet.rssi == None: packet.rssi = reticulum.get_packet_rssi(packet.packet_hash) if packet.rssi == None: packet.rssi = reticulum.get_packet_rssi(packet.packet_hash)
@ -778,6 +793,8 @@ class Link:
plaintext = self.decrypt(packet.data) plaintext = self.decrypt(packet.data)
packet.ratchet_id = self.link_id packet.ratchet_id = self.link_id
if plaintext != None: if plaintext != None:
self.__update_phy_stats(packet, query_shared=True)
if self.callbacks.packet != None: if self.callbacks.packet != None:
thread = threading.Thread(target=self.callbacks.packet, args=(plaintext, packet)) thread = threading.Thread(target=self.callbacks.packet, args=(plaintext, packet))
thread.daemon = True thread.daemon = True
@ -785,19 +802,15 @@ class Link:
if self.destination.proof_strategy == RNS.Destination.PROVE_ALL: if self.destination.proof_strategy == RNS.Destination.PROVE_ALL:
packet.prove() packet.prove()
should_query = True
elif self.destination.proof_strategy == RNS.Destination.PROVE_APP: elif self.destination.proof_strategy == RNS.Destination.PROVE_APP:
if self.destination.callbacks.proof_requested: if self.destination.callbacks.proof_requested:
try: try:
if self.destination.callbacks.proof_requested(packet): if self.destination.callbacks.proof_requested(packet):
packet.prove() packet.prove()
should_query = True
except Exception as e: except Exception as e:
RNS.log("Error while executing proof request callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR) RNS.log("Error while executing proof request callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
self.__update_phy_stats(packet, query_shared=should_query)
elif packet.context == RNS.Packet.LINKIDENTIFY: elif packet.context == RNS.Packet.LINKIDENTIFY:
plaintext = self.decrypt(packet.data) plaintext = self.decrypt(packet.data)
if plaintext != None: if plaintext != None:

View File

@ -341,6 +341,33 @@ class Packet:
return hashable_part return hashable_part
def get_rssi(self):
"""
:returns: The physical layer *Received Signal Strength Indication* if available, otherwise ``None``.
"""
if self.rssi != None:
return self.rssi
else:
return reticulum.get_packet_rssi(self.packet_hash)
def get_snr(self):
"""
:returns: The physical layer *Signal-to-Noise Ratio* if available, otherwise ``None``.
"""
if self.snr != None:
return self.snr
else:
return reticulum.get_packet_snr(self.packet_hash)
def get_q(self):
"""
:returns: The physical layer *Link Quality* if available, otherwise ``None``.
"""
if self.q != None:
return self.q
else:
return reticulum.get_packet_q(self.packet_hash)
class ProofDestination: class ProofDestination:
def __init__(self, packet): def __init__(self, packet):
self.hash = packet.get_hash()[:RNS.Reticulum.TRUNCATED_HASHLENGTH//8]; self.hash = packet.get_hash()[:RNS.Reticulum.TRUNCATED_HASHLENGTH//8];