Say what the serial number messages do

The README and the comments said the pool "goes out" and named it in
places where the reader cannot tell what is sent. They now name the
message and what it holds: the highest number taken on each band.

One of them was also wrong. The pool has not been sent on a reset since
the reset started counting from the log, and the README still said it was.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015NZkFxHde1iifAQemFTHxf
This commit is contained in:
2026-09-10 12:54:18 +00:00
co-authored by Claude Opus 5
parent 980ddb586f
commit 66e9a0ab65
4 changed files with 28 additions and 24 deletions
+15 -12
View File
@@ -920,24 +920,27 @@ An incoming edit or delete is matched by contact id first. N1MM does not know
our ids, so the call and the timestamp are the fallback — that is the pair N1MM
itself keys a contact on.
**Serial numbers are taken from a pool the whole entry shares.** A number is
taken at the first character of the callsign, not when the contact is logged,
and `ReserveNr` tells the other stations at once, so two operators typing at the
same moment do not send the same number. A station whose number is one this
station has already used is answered with the whole pool — N1MM's `QSONRS`, one
number per band — and counts on from there. The pool goes out when a contest is
opened and when the numbers are started again, so a station joining a contest
already under way counts from the same place.
**Every station of the entry counts serial numbers from the same list.** Each
station holds the highest number taken on each band. A number is taken at the
first character of the callsign rather than when the contact is logged, and the
`ReserveNr` message tells the other stations at once, so two operators typing at
the same moment do not send the same number.
A station that claims a number this one has already used is sent a `QSONRS`
message, which holds the highest number for each band. Both ends keep the higher
of the two numbers for each band, so the station that was behind counts on from
the right number. The same message is sent when a contest is opened, so a
station that joins a contest already under way starts where the others are.
Most contests run one sequence for the whole station. CQ WPX runs one per band
for a multi-two and a multi-multi, which is the class the entry declares in
contest setup, and N1MM decides it the same way.
**Reset Serial Numbers at all Stations** is for a pool that has gone wrong — a
station that was logging another contest, or numbers claimed and never used.
**Reset Serial Numbers at all Stations** is for numbers that have gone wrong —
a station that was logging another contest, or numbers claimed and never used.
Every station counts from its own log again, so the next number is the highest
one logged plus one and no number that has gone out is sent twice. The contacts
already logged keep the numbers they were sent with.
one in the log plus one and no number already sent is sent a second time. The
contacts already logged keep the numbers they were sent with.
A contact that arrives is put into the log where its timestamp says it belongs
and the log is scored again, so of two stations that worked the same multiplier
+9 -8
View File
@@ -234,9 +234,9 @@ public sealed class AppSession : IDisposable
// the other stations refuse to resynchronise with a station on another
// contest, and say so, which is only any use if they are told
_ = link?.SendContestNameAsync();
// and where this station's serial numbers have got to, so a station
// joining a contest already under way counts from the same place.
// N1MM sends the pool at the same point
// and the highest serial number taken on each band, so a station that
// joins a contest already under way starts where the others are. N1MM
// sends the same message at the same point
_ = link?.SendSerialNumbersAsync(Logging.Numbers.Snapshot());
Logging.Changed += (_, _) => Changed?.Invoke(this, EventArgs.Empty);
Logging.Logged += (_, qso) =>
@@ -413,8 +413,8 @@ public sealed class AppSession : IDisposable
/// Starts the serial numbers again from the log: the next number becomes
/// the highest one in it plus one. The contacts already logged keep the
/// numbers they were sent with. N1MM sends no pool with this — every
/// station works the same number out of its own copy of the log.
/// numbers they were sent with. Nothing is sent but `RESETQSONRS`, as in
/// N1MM: each station works the same number out of its own copy of the log.
public void ResetSerialNumbers()
{
if (Logging is not null)
@@ -425,9 +425,10 @@ public sealed class AppSession : IDisposable
}
/// A serial number another station has taken. It is noted here so this
/// station counts past it. A number at or below what this station has
/// already used says the other one is behind, and the whole pool goes back
/// so it can catch up, which is what N1MM answers with.
/// station counts past it. A number at or below one this station has
/// already used says the sender is behind, and it is sent the highest
/// number for each band so it can count on from the right one, which is
/// what N1MM answers with.
private void TakeReservedNumber(ReservedNumberMessage taken)
{
if (Logging is not { } logging)
+2 -2
View File
@@ -443,8 +443,8 @@ public sealed class StationLink : IDisposable
StationMessages.ReserveNumber(number, frequency, StationNumber, computerName),
cancellation);
/// Sends the whole pool, which is what a station answers with when the
/// number another one has taken is one this station has already used.
/// Sends the highest serial number taken on each band, which is the answer
/// to a station that has claimed a number this one has already used.
public Task<int> SendSerialNumbersAsync(
IReadOnlyList<int> numbers,
CancellationToken cancellation = default) =>
+2 -2
View File
@@ -36,8 +36,8 @@ public sealed class SerialNumberPool
}
/// A number another station has taken. False when it clashes with what is
/// held here — the other station is behind, and the caller answers with the
/// whole pool so it can catch up.
/// held here: the other station is behind, and the caller answers it with
/// `Snapshot`.
public bool Note(int number, Band? band)
{
int at = N1mmBandIndex.Of(band);