From 83d36407ac1e73894d8cc4ab90e7fde950b927f1 Mon Sep 17 00:00:00 2001 From: Stuart Longland Date: Wed, 8 May 2024 11:52:08 +1000 Subject: [PATCH] peer: Re-instate `_ack_state`, use it for handling peer `N(R)` Now its purpose makes sense! Not part of the AX.25 2.0 spec, but it seems to make more sense than the other variables for tracking this point. --- aioax25/peer.py | 19 +++++++++++++------ tests/test_peer/test_connection.py | 13 ++++++++++--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/aioax25/peer.py b/aioax25/peer.py index 11112aa..bc8c132 100644 --- a/aioax25/peer.py +++ b/aioax25/peer.py @@ -201,6 +201,12 @@ def __init__( self._recv_seq = 0 self._recv_seq_name = "N(R)" + # ACK state number. + # Used to track the sequence number previously ACKed in an I or S + # frame N(R) field. + self._ack_state = 0 # AKA V(A) + self._ack_state_name = "V(A)" + self._local_busy = False # Local end busy, respond to # RR and I-frames with RNR. self._peer_busy = False # Peer busy, await RR. @@ -731,14 +737,14 @@ def _ack_outstanding(self, nr): """ Receive all frames up to N(R)-1 """ - self._log.debug("%d through to %d are received", self._recv_seq, nr) - while self._recv_seq != nr: + self._log.debug("%d through to %d are received", self._ack_state, nr) + while self._ack_state != nr: if self._log.isEnabledFor(logging.DEBUG): self._log.debug("Pending frames: %r", self._pending_iframes) - self._log.debug("ACKing N(R)=%s", self._recv_seq) + self._log.debug("ACKing N(R)=%s", self._ack_state) try: - frame = self._pending_iframes.pop(self._recv_seq) + frame = self._pending_iframes.pop(self._ack_state) if self._log.isEnabledFor(logging.DEBUG): self._log.debug( "Popped %s off pending queue, N(R)s pending: %r", @@ -749,12 +755,12 @@ def _ack_outstanding(self, nr): if self._log.isEnabledFor(logging.DEBUG): self._log.debug( "ACK to unexpected N(R) number %s, pending: %r", - self._recv_seq, + self._ack_state, self._pending_iframes, ) finally: self._update_state( - "_recv_seq", delta=1, comment="ACKed by peer N(R)" + "_ack_state", delta=1, comment="ACKed by peer N(R)" ) def _on_receive_test(self, frame): @@ -979,6 +985,7 @@ def _reset_connection_state(self): self._update_state("_send_seq", value=0, comment="reset") self._update_state("_recv_state", value=0, comment="reset") self._update_state("_recv_seq", value=0, comment="reset") + self._update_state("_ack_state", value=0, comment="reset") # Unacknowledged I-frames to be ACKed self._pending_iframes = {} diff --git a/tests/test_peer/test_connection.py b/tests/test_peer/test_connection.py index ec858df..16a9fa4 100644 --- a/tests/test_peer/test_connection.py +++ b/tests/test_peer/test_connection.py @@ -1466,7 +1466,8 @@ def _update_state(prop, **kwargs): {"comment": "reset", "prop": "_send_seq", "value": 0}, {"comment": "reset", "prop": "_recv_state", "value": 0}, {"comment": "reset", "prop": "_recv_seq", "value": 0}, - {"comment": "ACKed by peer N(R)", "delta": 1, "prop": "_recv_seq"}, + {"comment": "reset", "prop": "_ack_state", "value": 0}, + {"comment": "ACKed by peer N(R)", "delta": 1, "prop": "_ack_state"}, ] # We should send a RNR in reply @@ -1536,7 +1537,8 @@ def _update_state(prop, **kwargs): {"comment": "reset", "prop": "_send_seq", "value": 0}, {"comment": "reset", "prop": "_recv_state", "value": 0}, {"comment": "reset", "prop": "_recv_seq", "value": 0}, - {"comment": "ACKed by peer N(R)", "delta": 1, "prop": "_recv_seq"}, + {"comment": "reset", "prop": "_ack_state", "value": 0}, + {"comment": "ACKed by peer N(R)", "delta": 1, "prop": "_ack_state"}, ] # We should send a RR in reply @@ -1606,8 +1608,9 @@ def _update_state(prop, **kwargs): {"comment": "reset", "prop": "_send_seq", "value": 0}, {"comment": "reset", "prop": "_recv_state", "value": 0}, {"comment": "reset", "prop": "_recv_seq", "value": 0}, + {"comment": "reset", "prop": "_ack_state", "value": 0}, # Peer ACK - {"comment": "ACKed by peer N(R)", "delta": 1, "prop": "_recv_seq"}, + {"comment": "ACKed by peer N(R)", "delta": 1, "prop": "_ack_state"}, # REJ handling {"comment": "from REJ N(R)", "prop": "_send_state", "value": 2}, ] @@ -2138,6 +2141,7 @@ def test_init_connection_mod8(): peer._send_seq = 2 peer._recv_state = 3 peer._recv_seq = 4 + peer._ack_state = 5 peer._modulo = 6 peer._max_outstanding = 7 peer._IFrameClass = None @@ -2164,6 +2168,7 @@ def test_init_connection_mod8(): assert peer._send_seq == 0 assert peer._recv_state == 0 assert peer._recv_seq == 0 + assert peer._ack_state == 0 assert peer._pending_iframes == {} assert peer._pending_data == [] @@ -2187,6 +2192,7 @@ def test_init_connection_mod128(): peer._send_seq = 2 peer._recv_state = 3 peer._recv_seq = 4 + peer._ack_state = 5 peer._modulo = 6 peer._max_outstanding = 7 peer._IFrameClass = None @@ -2213,6 +2219,7 @@ def test_init_connection_mod128(): assert peer._send_seq == 0 assert peer._recv_state == 0 assert peer._recv_seq == 0 + assert peer._ack_state == 0 assert peer._pending_iframes == {} assert peer._pending_data == []