Skip to content

Commit b58094b

Browse files
authored
Merge pull request #602 from ianmcorvidae/improve-acks
Improve ACK handling: pass to `onAckNak` and on request in sendData
2 parents a1021c4 + 23f41bf commit b58094b

2 files changed

Lines changed: 19 additions & 11 deletions

File tree

meshtastic/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class ResponseHandler(NamedTuple):
127127

128128
# requestId: int - used only as a key
129129
callback: Callable
130+
ackPermitted: bool = False
130131
# FIXME, add timestamp and age out old requests
131132

132133

meshtastic/mesh_interface.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ def sendData(
296296
wantAck: bool=False,
297297
wantResponse: bool=False,
298298
onResponse: Optional[Callable[[dict], Any]]=None,
299+
onResponseAckPermitted: bool=False,
299300
channelIndex: int=0,
300301
):
301302
"""Send a data packet to some other node
@@ -315,6 +316,10 @@ def sendData(
315316
onResponse -- A closure of the form funct(packet), that will be
316317
called when a response packet arrives (or the transaction
317318
is NAKed due to non receipt)
319+
onResponseAckPermitted -- should the onResponse callback be called
320+
for regular ACKs (True) or just data responses & NAKs (False)
321+
Note that if the onResponse callback is called 'onAckNak' this
322+
will implicitly be true.
318323
channelIndex - channel number to use
319324
320325
Returns the sent packet. The id field will be populated in this packet
@@ -346,7 +351,7 @@ def sendData(
346351

347352
if onResponse is not None:
348353
logging.debug(f"Setting a response handler for requestId {meshPacket.id}")
349-
self._addResponseHandler(meshPacket.id, onResponse)
354+
self._addResponseHandler(meshPacket.id, onResponse, ackPermitted=onResponseAckPermitted)
350355
p = self._sendPacket(meshPacket, destinationId, wantAck=wantAck)
351356
return p
352357

@@ -528,8 +533,8 @@ def onResponseTelemetry(self, p: dict):
528533
if p["decoded"]["routing"]["errorReason"] == 'NO_RESPONSE':
529534
our_exit("No response from node. At least firmware 2.1.22 is required on the destination node.")
530535

531-
def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any]):
532-
self.responseHandlers[requestId] = ResponseHandler(callback)
536+
def _addResponseHandler(self, requestId: int, callback: Callable[[dict], Any], ackPermitted: bool=False):
537+
self.responseHandlers[requestId] = ResponseHandler(callback=callback, ackPermitted=ackPermitted)
533538

534539
def _sendPacket(self, meshPacket: mesh_pb2.MeshPacket, destinationId: Union[int,str]=BROADCAST_ADDR, wantAck: bool=False):
535540
"""Send a MeshPacket to the specified node (or if unspecified, broadcast).
@@ -1129,16 +1134,18 @@ def _handlePacketFromRadio(self, meshPacket, hack=False):
11291134
requestId = decoded.get("requestId")
11301135
if requestId is not None:
11311136
logging.debug(f"Got a response for requestId {requestId}")
1132-
# We ignore ACK packets, but send NAKs and data responses to the handlers
1137+
# We ignore ACK packets unless the callback is named `onAckNak`
1138+
# or the handler is set as ackPermitted, but send NAKs and
1139+
# other, data-containing responses to the handlers
11331140
routing = decoded.get("routing")
11341141
isAck = routing is not None and ("errorReason" not in routing or routing["errorReason"] == "NONE")
1135-
if not isAck:
1136-
# we keep the responseHandler in dict until we get a non ack
1137-
handler = self.responseHandlers.pop(requestId, None)
1138-
if handler is not None:
1139-
if not isAck or (isAck and handler.__name__ == "onAckNak"):
1140-
logging.debug(f"Calling response handler for requestId {requestId}")
1141-
handler.callback(asDict)
1142+
# we keep the responseHandler in dict until we actually call it
1143+
handler = self.responseHandlers.get(requestId, None)
1144+
if handler is not None:
1145+
if (not isAck) or handler.callback.__name__ == "onAckNak" or handler.ackPermitted:
1146+
handler = self.responseHandlers.pop(requestId, None)
1147+
logging.debug(f"Calling response handler for requestId {requestId}")
1148+
handler.callback(asDict)
11421149

11431150
logging.debug(f"Publishing {topic}: packet={stripnl(asDict)} ")
11441151
publishingThread.queueWork(

0 commit comments

Comments
 (0)