mirror of
https://github.com/markqvist/Reticulum.git
synced 2024-11-26 15:30:18 +00:00
Added support for fragmenting packets
Packets larger the HW_MTU will be fragmented on transmit and reassembled on receive.
This commit is contained in:
parent
ec3ce575f6
commit
1b6db308c9
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
from .Interface import Interface
|
from .Interface import Interface
|
||||||
from pubsub import pub
|
from pubsub import pub
|
||||||
import time
|
import os
|
||||||
import sys
|
import struct
|
||||||
import RNS
|
import RNS
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -11,6 +11,9 @@ try:
|
|||||||
|
|
||||||
class MeshtasticInterface(Interface):
|
class MeshtasticInterface(Interface):
|
||||||
|
|
||||||
|
FLAG_SPLIT = 0x01
|
||||||
|
SEQ_UNSET = 0xFF
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def onReceive(packet, interface):
|
def onReceive(packet, interface):
|
||||||
if packet['decoded']['portnum'] == "PRIVATE_APP":
|
if packet['decoded']['portnum'] == "PRIVATE_APP":
|
||||||
@ -38,6 +41,10 @@ try:
|
|||||||
self.bitrate = 5469
|
self.bitrate = 5469
|
||||||
self.bitrate_kbps = 5.47
|
self.bitrate_kbps = 5.47
|
||||||
|
|
||||||
|
self.buffer = None
|
||||||
|
self.sequence = 0xFF
|
||||||
|
self.ready = False
|
||||||
|
|
||||||
self.interface = None
|
self.interface = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -62,20 +69,106 @@ try:
|
|||||||
RNS.log("Initialized Meshtastic interface!", RNS.LOG_DEBUG)
|
RNS.log("Initialized Meshtastic interface!", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
def processIncoming(self, data):
|
def processIncoming(self, data):
|
||||||
RNS.log("Received Meshtastic packet "+RNS.prettyhexrep(data), RNS.LOG_DEBUG)
|
RNS.log("Received Meshtastic packet of "+str(len(data))+" bytes: "+RNS.prettyhexrep(data), RNS.LOG_DEBUG)
|
||||||
|
|
||||||
self.rxb += len(data)
|
self.rxb += len(data)
|
||||||
self.owner.inbound(data, self)
|
|
||||||
|
# check for fragmented packet
|
||||||
|
header = data[0]
|
||||||
|
split = (header & self.FLAG_SPLIT) == self.FLAG_SPLIT
|
||||||
|
sequence = header >> 1
|
||||||
|
RNS.log("incoming sequence: "+str(sequence), RNS.LOG_DEBUG)
|
||||||
|
|
||||||
|
if split and self.sequence == self.SEQ_UNSET:
|
||||||
|
# This is the first part of a split
|
||||||
|
# packet, so we set the self.sequence variable
|
||||||
|
# and add the data to the buffer.
|
||||||
|
self.buffer = data[1:]
|
||||||
|
self.sequence = sequence
|
||||||
|
|
||||||
|
#last_rssi = LoRa.packetRssi();
|
||||||
|
#last_snr_raw = LoRa.packetSnrRaw();
|
||||||
|
|
||||||
|
elif split and self.sequence == sequence:
|
||||||
|
# This is subsequent part of a split
|
||||||
|
# packet, so we add it to the buffer.
|
||||||
|
self.buffer += data[1:]
|
||||||
|
|
||||||
|
#last_rssi = (last_rssi+LoRa.packetRssi())/2;
|
||||||
|
#last_snr_raw = (last_snr_raw+LoRa.packetSnrRaw())/2;
|
||||||
|
|
||||||
|
elif not split and self.sequence == sequence:
|
||||||
|
# This is not a split packet but it carries
|
||||||
|
# the last sequence id, so it must be the
|
||||||
|
# last part of a split packet.
|
||||||
|
self.buffer += data[1:]
|
||||||
|
self.sequence = self.SEQ_UNSET
|
||||||
|
|
||||||
|
#last_rssi = LoRa.packetRssi();
|
||||||
|
#last_snr_raw = LoRa.packetSnrRaw();
|
||||||
|
|
||||||
|
# pass the buffer on to RNS
|
||||||
|
RNS.log("Received Reticulum packet of "+str(len(self.buffer))+" bytes over Meshtastic interface", RNS.LOG_DEBUG)
|
||||||
|
self.owner.inbound(self.buffer, self)
|
||||||
|
self.buffer = None
|
||||||
|
|
||||||
|
elif split and self.sequence != sequence:
|
||||||
|
# This split packet does not carry the
|
||||||
|
# same sequence id, so we must assume
|
||||||
|
# that we are seeing the first part of
|
||||||
|
# a new split packet.
|
||||||
|
# If we already had part of a split
|
||||||
|
# packet in the buffer then we clear it.
|
||||||
|
if self.buffer != None:
|
||||||
|
RNS.log("Discarding incomplete buffer from previous split packet!", RNS.LOG_ERROR)
|
||||||
|
self.buffer = data[1:]
|
||||||
|
self.sequence = sequence
|
||||||
|
|
||||||
|
#last_rssi = LoRa.packetRssi();
|
||||||
|
#last_snr_raw = LoRa.packetSnrRaw();
|
||||||
|
|
||||||
|
elif not split:
|
||||||
|
# This is not a split packet, so we
|
||||||
|
# just read it whole
|
||||||
|
self.buffer = data[1:]
|
||||||
|
self.sequence = self.SEQ_UNSET
|
||||||
|
|
||||||
|
#last_rssi = LoRa.packetRssi();
|
||||||
|
#last_snr_raw = LoRa.packetSnrRaw();
|
||||||
|
|
||||||
|
# pass the buffer on to RNS
|
||||||
|
RNS.log("Received Reticulum packet of "+str(len(self.buffer))+" bytes over Meshtastic interface", RNS.LOG_DEBUG)
|
||||||
|
self.owner.inbound(self.buffer, self)
|
||||||
|
self.buffer = None
|
||||||
|
|
||||||
def processOutgoing(self, data):
|
def processOutgoing(self, data):
|
||||||
if self.interface == None:
|
if self.interface == None:
|
||||||
return
|
return
|
||||||
RNS.log("Sending Meshtastic packet "+RNS.prettyhexrep(data), RNS.LOG_DEBUG)
|
RNS.log("Sending Reticulum packet of "+str(len(data))+" bytes over Meshtastic interface", RNS.LOG_DEBUG)
|
||||||
try:
|
|
||||||
#self.interface.sendData(data)
|
header = int.from_bytes(os.urandom(1), "big") & 0xFE
|
||||||
self.interface.sendData(data, portNum=256, channelIndex=self.channel)
|
RNS.log("outgoing sequence: "+str(header >> 1), RNS.LOG_DEBUG)
|
||||||
self.txb += len(data)
|
if len(data) > self.HW_MTU-1:
|
||||||
except Exception as e:
|
header |= self.FLAG_SPLIT
|
||||||
RNS.log("Could not transmit on "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
|
||||||
|
sent = 0
|
||||||
|
while sent < len(data):
|
||||||
|
size = len(data) - sent
|
||||||
|
if size > self.HW_MTU-1:
|
||||||
|
size = self.HW_MTU-1
|
||||||
|
# clear split flag for last part
|
||||||
|
if sent+size >= len(data):
|
||||||
|
header &= ~self.FLAG_SPLIT
|
||||||
|
buffer = struct.pack("!B", header) + data[sent:sent+size]
|
||||||
|
sent += size
|
||||||
|
|
||||||
|
RNS.log("Sending Meshtastic packet of "+str(len(buffer))+" bytes: "+RNS.prettyhexrep(buffer), RNS.LOG_DEBUG)
|
||||||
|
try:
|
||||||
|
#self.interface.sendData(buffer)
|
||||||
|
self.interface.sendData(buffer, portNum=256, channelIndex=self.channel)
|
||||||
|
self.txb += len(buffer)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Could not transmit on "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
if self.port == None:
|
if self.port == None:
|
||||||
|
Loading…
Reference in New Issue
Block a user