Skip to content

Commit

Permalink
peer: Re-instate _ack_state, use it for handling peer N(R)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sjlongland committed May 8, 2024
1 parent c11b587 commit 83d3640
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
19 changes: 13 additions & 6 deletions aioax25/peer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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",
Expand All @@ -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):
Expand Down Expand Up @@ -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 = {}
Expand Down
13 changes: 10 additions & 3 deletions tests/test_peer/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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},
]
Expand Down Expand Up @@ -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
Expand All @@ -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 == []

Expand All @@ -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
Expand All @@ -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 == []

Expand Down

0 comments on commit 83d3640

Please sign in to comment.