Fix #7: Properly decode OPAQUE binary packets...

and add binary sending to the integration tests
This commit is contained in:
geeksville
2020-08-11 18:16:57 -07:00
parent 9da57e2d12
commit 0c9c8bca57
2 changed files with 35 additions and 9 deletions

View File

@@ -135,7 +135,7 @@ class MeshInterface:
meshPacket.decoded.position.altitude = int(altitude)
if timeSec == 0:
timeSec = time.time() # returns unix timestamp in seconds
timeSec = time.time() # returns unix timestamp in seconds
meshPacket.decoded.position.time = int(timeSec)
meshPacket.decoded.want_response = wantResponse
@@ -306,6 +306,12 @@ class MeshInterface:
if meshPacket.decoded.HasField("data"):
topic = "meshtastic.receive.data"
# OPAQUE is the default protobuf typ value, and therefore if not set it will not be populated at all
# to make API usage easier, set it to prevent confusion
if not "typ" in asDict["decoded"]["data"]:
asDict["decoded"]["data"]["typ"] = "OPAQUE"
# For text messages, we go ahead and decode the text to ascii for our users
if asDict["decoded"]["data"]["typ"] == "CLEAR_TEXT":
asDict["decoded"]["data"]["text"] = meshPacket.decoded.data.payload.decode(
@@ -361,7 +367,7 @@ class BLEInterface(MeshInterface):
class StreamInterface(MeshInterface):
"""Interface class for meshtastic devices over a stream link (serial, TCP, etc)"""
def __init__(self, devPath=None, debugOut=None, noProto=False):
def __init__(self, devPath=None, debugOut=None, noProto=False, connectNow=True):
"""Constructor, opens a connection to a specified serial port, or if unspecified try to
find one Meshtastic device by probing
@@ -392,14 +398,24 @@ class StreamInterface(MeshInterface):
devPath, 921600, exclusive=True, timeout=0.5)
self._rxThread = threading.Thread(target=self.__reader, args=())
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
# Start the reader thread after superclass constructor completes init
if connectNow:
self.connect()
def connect(self):
"""Connect to our radio
Normally this is called automatically by the constructor, but if you passed in connectNow=False you can manually
start the reading thread later.
"""
# Send some bogus UART characters to force a sleeping device to wake
self.stream.write(bytes([START1, START1, START1, START1]))
self.stream.flush()
time.sleep(0.1) # wait 100ms to give device time to start running
MeshInterface.__init__(self, debugOut=debugOut, noProto=noProto)
# Start the reader thread after superclass constructor completes init
self._rxThread.start()
def _sendToRadio(self, toRadio):

View File

@@ -39,7 +39,7 @@ def subscribe():
pub.subscribe(onNode, "meshtastic.node")
def testSend(fromInterface, toInterface, isBroadcast=False):
def testSend(fromInterface, toInterface, isBroadcast=False, asBinary=False):
"""
Sends one test packet between two nodes and then returns success or failure
@@ -60,7 +60,12 @@ def testSend(fromInterface, toInterface, isBroadcast=False):
toNode = toInterface.myInfo.my_node_num
logging.info(f"Sending test packet from {fromNode} to {toNode}")
fromInterface.sendText(f"Test {testNumber}", toNode, wantAck=True)
wantAck = True
if not asBinary:
fromInterface.sendText(f"Test {testNumber}", toNode, wantAck=wantAck)
else:
fromInterface.sendData((f"Binary {testNumber}").encode(
"utf-8"), toNode, wantAck=wantAck)
time.sleep(45)
return (len(receivedPackets) >= 1)
@@ -73,7 +78,8 @@ def testThread(numTests=50):
global testNumber
testNumber = testNumber + 1
isBroadcast = True
success = testSend(interfaces[0], interfaces[1], isBroadcast)
success = testSend(
interfaces[0], interfaces[1], isBroadcast, asBinary=(i % 2 == 0))
if not success:
numFail = numFail + 1
logging.error(
@@ -95,6 +101,7 @@ def onConnection(topic=pub.AUTO_TOPIC):
print(f"Connection changed: {topic.getName()}")
global testsRunning
global interfaces
if (all(iface.isConnected for iface in interfaces) and not testsRunning):
testsRunning = True
t = threading.Thread(target=testThread, args=())
@@ -122,5 +129,8 @@ def testAll():
pub.subscribe(onReceive, "meshtastic.receive")
global interfaces
interfaces = list(map(lambda port: StreamInterface(
port, debugOut=openDebugLog(port)), ports))
port, debugOut=openDebugLog(port), connectNow=False), ports))
for i in interfaces:
i.connect()
logging.info("Ports opened, waiting for device to complete connection")