iOS: classify RR73 sign-off before grid so answered QSOs complete and log#596
Open
patrickrb wants to merge 1 commit into
Open
iOS: classify RR73 sign-off before grid so answered QSOs complete and log#596patrickrb wants to merge 1 commit into
patrickrb wants to merge 1 commit into
Conversation
… log
`QsoEngine.classify` checked the decoded message's `grid` field before the
RR73/RRR/73 sign-off switch. "RR73" is a valid 4-char Maidenhead-shaped token
(R,R in A..R + two digits), so the decoder copies it into `grid`
(`looksLikeGrid("RR73")` is true) — meaning a partner's standard final "RR73"
arrives at the engine with both `extra == "RR73"` and `grid == "RR73"`.
Checking grid first classified it as `Content.grid`, which falls through the
`.rReport` stage's `default: break`: the auto-sequencer never completed the
QSO, retransmitted our R-report forever, and never logged the contact — for
essentially every answered QSO, since RR73 is the most common FT8 sign-off.
Both reference ports already guard this: desktop `qso.rs` matches the sign-offs
before the grid check (with a comment describing this exact regression), and
Android `GeneralVariables` excludes "RR73" from its grid classification. The iOS
port was the divergent one; this reorders classify to match, without touching
`looksLikeGrid` (the map/distance code relies on its shape test).
Added `testRr73WithDecoderGridStillCompletesQso` (ported from desktop
`rr73_with_decoder_grid_still_completes_qso`), which feeds the RR73 slot with
`grid == "RR73"` exactly as the decoder emits it live; it fails pre-fix
("RR73 sign-off must complete the QSO") and passes after. A companion
assertion confirms a genuine 4-char grid reply still advances the CQ
initiator to send a report. FT8AFKit `swift test` 132/132 green on Linux.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
QsoEngine.classify(ios/FT8AFKit/Sources/FT8Engine/QsoEngine.swift) checked the decoded message'sgridfield before the RR73/RRR/73 sign-off switch:"RR73"is a valid 4-char Maidenhead-shaped token (R,R fall in the A..R field range; 7,3 are digits), solooksLikeGrid("RR73")istrueand the decoder copies it into thegridfield (FT8Decoder.buildMessage:if looksLikeGrid(m.extra) { m.grid = m.extra }). A partner's standard closing "RR73" therefore reaches the engine with bothextra == "RR73"andgrid == "RR73", andclassifyreturnedContent.grid("RR73")instead of.rr73.In
processRx, the.rReportstage only completes on.rr73/.rrr/.bye73content; a.gridhitsdefault: breakand returnsnil. So the auto-sequencer never completed the QSO, retransmitted our R-report forever, and never logged the contact — for essentially every answered QSO, since RR73 is the most common FT8 sign-off.Fix
Match the sign-offs before the grid check, so a sign-off is never mistaken for a grid report. This mirrors the two reference ports, which already order it this way:
desktop/src-tauri/src/qso.rs— sign-off switch first, with a comment describing this exact regression.GeneralVariables— classifies a token as a grid only when it matches the Maidenhead shape and!= "RR73".iOS was the 1-of-3 divergent port.
looksLikeGridis untouched (the map/distance code relies on its shape test), and behavior is byte-identical for every non-sign-off input (genuine grids, reports, R-reports).Testing
testRr73WithDecoderGridStillCompletesQso(ported from desktoprr73_with_decoder_grid_still_completes_qso), which feeds the RR73 slot withgrid == "RR73"exactly as the decoder emits it live. Fails pre-fix ("RR73 sign-off must complete the QSO"), passes after — verified by reverting only the source reorder. A companion assertion confirms a genuine 4-char grid reply still advances the CQ initiator to send a report.testAnswererFullSequenceLogsQsomasked the bug by feeding the RR73 slot withgrid == ""(not what the decoder emits).swift teston the FT8AFKit package: 132/132 green (built on Linux; the Kit is Foundation-only).Risk
Low. Localized reordering of two lines in one classification function; no DSP, protocol, or interop change. The
.bye73finish path and all other stages are untouched. iOS app-target wiring (LiveEngine) is unchanged; only the Kit engine logic is affected.🤖 Generated with Claude Code