handleAckFrame method

List<int> handleAckFrame(
  1. AckFrame frame
)

Processes an incoming AckFrame, marking packets as acknowledged. Returns a list of sequence numbers that were successfully acknowledged by this frame.

Implementation

List<int> handleAckFrame(AckFrame frame) {
  final newlyAckedSequences = <int>[];

  // Process the first range (ending at largestAcked)
  // largestAcked is inclusive. firstAckRangeLength is the count of packets in this range.
  // So, the smallest sequence in this range is largestAcked - firstAckRangeLength + 1.
  if (frame.firstAckRangeLength > 0) {
    for (int i = 0; i < frame.firstAckRangeLength; i++) {
      final seq = frame.largestAcked - i;
      if (_sentPackets.containsKey(seq)) {
        final packet = _sentPackets.remove(seq);
        packet?.isAcked = true;
        _retransmitTimers[seq]?.cancel();
        _retransmitTimers.remove(seq);
        newlyAckedSequences.add(seq);
      }
    }
  }


  // Process additional ACK ranges
  // Ranges are ordered from highest sequence numbers to lowest.
  // `gap` is relative to the *start* of the previously processed (higher sequence) range.
  int currentSeq = frame.largestAcked - frame.firstAckRangeLength; // Sequence just below the first range

  for (final rangeBlock in frame.ackRanges) {
    // The current range's highest packet (rangeEnd) is `rangeBlock.gap` packets below `currentSeq`.
    // `currentSeq` represents the packet number immediately preceding the lowest packet of the previously acked block.
    final rangeEnd = currentSeq - rangeBlock.gap; // CORRECTED

    for (int i = 0; i < rangeBlock.ackRangeLength; i++) {
      final seq = rangeEnd - i;
      if (_sentPackets.containsKey(seq)) {
        final packet = _sentPackets.remove(seq);
        packet?.isAcked = true;
        _retransmitTimers[seq]?.cancel();
        _retransmitTimers.remove(seq);
        newlyAckedSequences.add(seq);
      }
    }
    // Update currentSeq for the next iteration: it should be the packet number
    // immediately preceding the lowest packet of the range just processed.
    // Lowest packet in current range = rangeEnd - rangeBlock.ackRangeLength + 1.
    currentSeq = (rangeEnd - rangeBlock.ackRangeLength + 1) - 1; // CORRECTED
  }
  return newlyAckedSequences;
}