mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-23 06:00:18 +00:00
Added RSSI and SNR reporting to packets on supported interfaces
This commit is contained in:
parent
c37533d2c7
commit
1cf6570c2d
@ -283,6 +283,8 @@ class RNodeInterface(Interface):
|
|||||||
def processIncoming(self, data):
|
def processIncoming(self, data):
|
||||||
self.rxb += len(data)
|
self.rxb += len(data)
|
||||||
self.owner.inbound(data, self)
|
self.owner.inbound(data, self)
|
||||||
|
self.r_stat_rssi = None
|
||||||
|
self.r_stat_snr = None
|
||||||
|
|
||||||
|
|
||||||
def processOutgoing(self,data):
|
def processOutgoing(self,data):
|
||||||
|
@ -113,6 +113,8 @@ class Packet:
|
|||||||
|
|
||||||
self.attached_interface = attached_interface
|
self.attached_interface = attached_interface
|
||||||
self.receiving_interface = None
|
self.receiving_interface = None
|
||||||
|
self.rssi = None
|
||||||
|
self.snr = None
|
||||||
|
|
||||||
def get_packed_flags(self):
|
def get_packed_flags(self):
|
||||||
if self.context == Packet.LRPROOF:
|
if self.context == Packet.LRPROOF:
|
||||||
@ -328,6 +330,7 @@ class PacketReceipt:
|
|||||||
self.destination = packet.destination
|
self.destination = packet.destination
|
||||||
self.callbacks = PacketReceiptCallbacks()
|
self.callbacks = PacketReceiptCallbacks()
|
||||||
self.concluded_at = None
|
self.concluded_at = None
|
||||||
|
self.proof_packet = None
|
||||||
|
|
||||||
if packet.destination.type == RNS.Destination.LINK:
|
if packet.destination.type == RNS.Destination.LINK:
|
||||||
self.timeout = packet.destination.rtt * packet.destination.traffic_timeout_factor
|
self.timeout = packet.destination.rtt * packet.destination.traffic_timeout_factor
|
||||||
@ -344,12 +347,12 @@ class PacketReceipt:
|
|||||||
# Validate a proof packet
|
# Validate a proof packet
|
||||||
def validate_proof_packet(self, proof_packet):
|
def validate_proof_packet(self, proof_packet):
|
||||||
if hasattr(proof_packet, "link") and proof_packet.link:
|
if hasattr(proof_packet, "link") and proof_packet.link:
|
||||||
return self.validate_link_proof(proof_packet.data, proof_packet.link)
|
return self.validate_link_proof(proof_packet.data, proof_packet.link, proof_packet)
|
||||||
else:
|
else:
|
||||||
return self.validate_proof(proof_packet.data)
|
return self.validate_proof(proof_packet.data, proof_packet)
|
||||||
|
|
||||||
# Validate a raw proof for a link
|
# Validate a raw proof for a link
|
||||||
def validate_link_proof(self, proof, link):
|
def validate_link_proof(self, proof, link, proof_packet=None):
|
||||||
# TODO: Hardcoded as explicit proofs for now
|
# TODO: Hardcoded as explicit proofs for now
|
||||||
if True or len(proof) == PacketReceipt.EXPL_LENGTH:
|
if True or len(proof) == PacketReceipt.EXPL_LENGTH:
|
||||||
# This is an explicit proof
|
# This is an explicit proof
|
||||||
@ -361,6 +364,8 @@ class PacketReceipt:
|
|||||||
self.status = PacketReceipt.DELIVERED
|
self.status = PacketReceipt.DELIVERED
|
||||||
self.proved = True
|
self.proved = True
|
||||||
self.concluded_at = time.time()
|
self.concluded_at = time.time()
|
||||||
|
self.proof_packet = proof_packet
|
||||||
|
|
||||||
if self.callbacks.delivery != None:
|
if self.callbacks.delivery != None:
|
||||||
self.callbacks.delivery(self)
|
self.callbacks.delivery(self)
|
||||||
return True
|
return True
|
||||||
@ -388,7 +393,7 @@ class PacketReceipt:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Validate a raw proof
|
# Validate a raw proof
|
||||||
def validate_proof(self, proof):
|
def validate_proof(self, proof, proof_packet=None):
|
||||||
if len(proof) == PacketReceipt.EXPL_LENGTH:
|
if len(proof) == PacketReceipt.EXPL_LENGTH:
|
||||||
# This is an explicit proof
|
# This is an explicit proof
|
||||||
proof_hash = proof[:RNS.Identity.HASHLENGTH//8]
|
proof_hash = proof[:RNS.Identity.HASHLENGTH//8]
|
||||||
@ -399,6 +404,8 @@ class PacketReceipt:
|
|||||||
self.status = PacketReceipt.DELIVERED
|
self.status = PacketReceipt.DELIVERED
|
||||||
self.proved = True
|
self.proved = True
|
||||||
self.concluded_at = time.time()
|
self.concluded_at = time.time()
|
||||||
|
self.proof_packet = proof_packet
|
||||||
|
|
||||||
if self.callbacks.delivery != None:
|
if self.callbacks.delivery != None:
|
||||||
self.callbacks.delivery(self)
|
self.callbacks.delivery(self)
|
||||||
return True
|
return True
|
||||||
@ -417,6 +424,8 @@ class PacketReceipt:
|
|||||||
self.status = PacketReceipt.DELIVERED
|
self.status = PacketReceipt.DELIVERED
|
||||||
self.proved = True
|
self.proved = True
|
||||||
self.concluded_at = time.time()
|
self.concluded_at = time.time()
|
||||||
|
self.proof_packet = proof_packet
|
||||||
|
|
||||||
if self.callbacks.delivery != None:
|
if self.callbacks.delivery != None:
|
||||||
self.callbacks.delivery(self)
|
self.callbacks.delivery(self)
|
||||||
return True
|
return True
|
||||||
|
@ -511,6 +511,12 @@ class Reticulum:
|
|||||||
if path == "next_hop":
|
if path == "next_hop":
|
||||||
rpc_connection.send(self.get_next_hop(call["destination_hash"]))
|
rpc_connection.send(self.get_next_hop(call["destination_hash"]))
|
||||||
|
|
||||||
|
if path == "packet_rssi":
|
||||||
|
rpc_connection.send(self.get_packet_rssi(call["packet_hash"]))
|
||||||
|
|
||||||
|
if path == "packet_snr":
|
||||||
|
rpc_connection.send(self.get_packet_snr(call["packet_hash"]))
|
||||||
|
|
||||||
rpc_connection.close()
|
rpc_connection.close()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("An error ocurred while handling RPC call from local client: "+str(e), RNS.LOG_ERROR)
|
RNS.log("An error ocurred while handling RPC call from local client: "+str(e), RNS.LOG_ERROR)
|
||||||
@ -545,6 +551,7 @@ class Reticulum:
|
|||||||
rpc_connection.send({"get": "next_hop_if_name", "destination_hash": destination})
|
rpc_connection.send({"get": "next_hop_if_name", "destination_hash": destination})
|
||||||
response = rpc_connection.recv()
|
response = rpc_connection.recv()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return str(RNS.Transport.next_hop_interface(destination))
|
return str(RNS.Transport.next_hop_interface(destination))
|
||||||
|
|
||||||
@ -554,9 +561,38 @@ class Reticulum:
|
|||||||
rpc_connection.send({"get": "next_hop", "destination_hash": destination})
|
rpc_connection.send({"get": "next_hop", "destination_hash": destination})
|
||||||
response = rpc_connection.recv()
|
response = rpc_connection.recv()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return RNS.Transport.next_hop(destination)
|
return RNS.Transport.next_hop(destination)
|
||||||
|
|
||||||
|
def get_packet_rssi(self, packet_hash):
|
||||||
|
if self.is_connected_to_shared_instance:
|
||||||
|
rpc_connection = multiprocessing.connection.Client(self.rpc_addr, authkey=self.rpc_key)
|
||||||
|
rpc_connection.send({"get": "packet_rssi", "packet_hash": packet_hash})
|
||||||
|
response = rpc_connection.recv()
|
||||||
|
return response
|
||||||
|
|
||||||
|
else:
|
||||||
|
for entry in RNS.Transport.local_client_rssi_cache:
|
||||||
|
if entry[0] == packet_hash:
|
||||||
|
return entry[1]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_packet_snr(self, packet_hash):
|
||||||
|
if self.is_connected_to_shared_instance:
|
||||||
|
rpc_connection = multiprocessing.connection.Client(self.rpc_addr, authkey=self.rpc_key)
|
||||||
|
rpc_connection.send({"get": "packet_snr", "packet_hash": packet_hash})
|
||||||
|
response = rpc_connection.recv()
|
||||||
|
return response
|
||||||
|
|
||||||
|
else:
|
||||||
|
for entry in RNS.Transport.local_client_snr_cache:
|
||||||
|
if entry[0] == packet_hash:
|
||||||
|
return entry[1]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def should_use_implicit_proof():
|
def should_use_implicit_proof():
|
||||||
|
@ -76,6 +76,10 @@ class Transport:
|
|||||||
# Reticulum instance
|
# Reticulum instance
|
||||||
local_client_interfaces = []
|
local_client_interfaces = []
|
||||||
|
|
||||||
|
local_client_rssi_cache = []
|
||||||
|
local_client_snr_cache = []
|
||||||
|
LOCAL_CLIENT_CACHE_MAXSIZE = 512
|
||||||
|
|
||||||
jobs_locked = False
|
jobs_locked = False
|
||||||
jobs_running = False
|
jobs_running = False
|
||||||
job_interval = 0.250
|
job_interval = 0.250
|
||||||
@ -583,10 +587,29 @@ class Transport:
|
|||||||
packet.receiving_interface = interface
|
packet.receiving_interface = interface
|
||||||
packet.hops += 1
|
packet.hops += 1
|
||||||
|
|
||||||
if len(Transport.local_client_interfaces) > 0:
|
if interface != None:
|
||||||
|
if hasattr(interface, "r_stat_rssi"):
|
||||||
|
if interface.r_stat_rssi != None:
|
||||||
|
packet.rssi = interface.r_stat_rssi
|
||||||
|
if len(Transport.local_client_interfaces) > 0:
|
||||||
|
Transport.local_client_rssi_cache.append([packet.packet_hash, packet.rssi])
|
||||||
|
|
||||||
|
while len(Transport.local_client_rssi_cache) > Transport.LOCAL_CLIENT_CACHE_MAXSIZE:
|
||||||
|
Transport.local_client_rssi_cache.pop()
|
||||||
|
|
||||||
|
if hasattr(interface, "r_stat_snr"):
|
||||||
|
if interface.r_stat_rssi != None:
|
||||||
|
packet.snr = interface.r_stat_snr
|
||||||
|
if len(Transport.local_client_interfaces) > 0:
|
||||||
|
Transport.local_client_snr_cache.append([packet.packet_hash, packet.snr])
|
||||||
|
|
||||||
|
while len(Transport.local_client_snr_cache) > Transport.LOCAL_CLIENT_CACHE_MAXSIZE:
|
||||||
|
Transport.local_client_snr_cache.pop()
|
||||||
|
|
||||||
|
if len(Transport.local_client_interfaces) > 0:
|
||||||
if Transport.is_local_client_interface(interface):
|
if Transport.is_local_client_interface(interface):
|
||||||
packet.hops -= 1
|
packet.hops -= 1
|
||||||
|
|
||||||
elif Transport.interface_to_shared_instance(interface):
|
elif Transport.interface_to_shared_instance(interface):
|
||||||
packet.hops -= 1
|
packet.hops -= 1
|
||||||
|
|
||||||
|
@ -101,11 +101,31 @@ def program_setup(configdir, destination_hexhash, size=DEFAULT_PROBE_SIZE, full_
|
|||||||
rtt = round(rtt*1000, 3)
|
rtt = round(rtt*1000, 3)
|
||||||
rttstring = str(rtt)+" milliseconds"
|
rttstring = str(rtt)+" milliseconds"
|
||||||
|
|
||||||
|
reception_stats = ""
|
||||||
|
if reticulum.is_connected_to_shared_instance:
|
||||||
|
reception_rssi = reticulum.get_packet_rssi(receipt.proof_packet.packet_hash)
|
||||||
|
reception_snr = reticulum.get_packet_snr(receipt.proof_packet.packet_hash)
|
||||||
|
|
||||||
|
if reception_rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(reception_rssi)+" dBm]"
|
||||||
|
|
||||||
|
if reception_snr != None:
|
||||||
|
reception_stats += " [SNR "+str(reception_snr)+" dBm]"
|
||||||
|
|
||||||
|
else:
|
||||||
|
if receipt.proof_packet != None:
|
||||||
|
if receipt.proof_packet.rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(receipt.proof_packet.rssi)+" dBm]"
|
||||||
|
|
||||||
|
if receipt.proof_packet.snr != None:
|
||||||
|
reception_stats += " [SNR "+str(receipt.proof_packet.snr)+" dBm]"
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"Valid reply received from "+
|
"Valid reply received from "+
|
||||||
RNS.prettyhexrep(receipt.destination.hash)+
|
RNS.prettyhexrep(receipt.destination.hash)+
|
||||||
"\nRound-trip time is "+rttstring+
|
"\nRound-trip time is "+rttstring+
|
||||||
" over "+str(hops)+" hop"+ms
|
" over "+str(hops)+" hop"+ms+
|
||||||
|
reception_stats
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
__version__ = "0.2.8"
|
__version__ = "0.2.9"
|
Loading…
Reference in New Issue
Block a user