Texas QSO Party Integration - #47
Open
kt3xradio wants to merge 14 commits into
Open
Conversation
Implements a new Special Operating Activity for the Texas QSO Party (TxQP)
across the message codec, configuration UI, message generation, logging,
and Cabrillo export.
- lib/77bit/packjt77.f90: new pack77_txqp / unpack (i3=3, n3=5) message
type carrying two callsigns, an implied "+00" report, an optional Roger
flag, and a 13-bit exchange index covering Texas counties, US states,
Canadian provinces, and "DX"; adds county/state/province lookup tables.
- Configuration.hpp/.cpp/.ui: adds the TXQP enum value, the "Texas QSO
Party" radio button (rbTxQP) and exchange field (TXQP_Exchange) with a
validator, persistence, slots, and visibility handling.
- widgets/mainwindow.cpp: CQ TQP generation, TxQP standard-message
exchange ("+00 <location>"), received-exchange parsing, QSO logging,
and the on-air status label.
- logbook/logbook.cpp: ADIF contest_id TEXAS-QSO-PARTY and exchange fields.
- widgets/ExportCabrillo.cpp: default CONTEST header to TEXAS-QSO-PARTY.
- logbook.cpp: write <stx_string> for the TxQP sent exchange (county/ state/province/DX). Previously only numeric serials were logged, so the sent exchange was dropped from the ADIF record. - mainwindow.cpp: populate m_xSent from the configured TxQP exchange at log time so the sent exchange reaches the logger. - packjt77.f90: add pack77_txqpvar and register it in the pack77var dispatcher so TxQP messages with compound (/prefix or /suffix) callsigns pack via the hashed-call path and round-trip correctly.
The original implementation had only 224 counties + 30 blank placeholders. This commit replaces the county table with the complete, official Texas QSO Party county list (all 254 counties). Changes: - lib/77bit/packjt77.f90: Updated txqp_tables() DATA statement with all 254 official county abbreviations from the TxQP website - Configuration.cpp: Updated TXQP_exchange_re validator regex to match all 254 official counties + 50 US states + 13 Canadian provinces + DX Corrected abbreviations (examples): - ARM → ARMS (Armstrong), AUS → AUST (Austin), BEXR → BEXA (Bexar) - DALL → DALS (Dallas), and 100+ other corrections/additions The full official county list is now encoded and validated correctly.
- pack77_txqpvar: accept bracketed <...> hashed compound calls as-is instead of rejecting them via chkcall, so prefix (9A/WT3STT) and suffix (KT3STT/VP9) callsigns round-trip through pack28var's 22-bit hash. Fixes exchange failing to send/receive with compound callsigns. - genCQMsg: for compound/nonstandard callsigns, fall back to a plain 'CQ <call>' when the frequency-prefixed CQ is enabled, since Type 4 messages cannot carry a frequency/grid/contest word and would otherwise fail to encode.
The previous compound-call fix was applied to pack77_txqpvar, but the actual FT8/FT4 transmit path (genft8/genft4 -> pack77) uses the non-var pack77_txqp, which still ran chkcall() on the bracketed <call> token the app builds for a compound MYCALL (e.g. 'K5ABC <9A/WT3STT> +00 HARR'). chkcall rejects the brackets, so the message fell through to free text (i3=0) and the exchange was sent/received as a plain text string. Apply the same bracket-handling to pack77_txqp: a word wrapped in <...> is accepted as-is and hashed by pack28 (22-bit), so prefix (9A/WT3STT) and suffix (KT3STT/VP9) compound calls now encode as TxQP (i3=3 n3=5) and round-trip. Verified full QSO flow: receiver learns the hash from the Type 4 Tx1 and then resolves <9A/WT3STT> to the full call in the exchange. Standard calls and non-TxQP messages are unaffected.
The TxQP exchange frame (i3=3, n3=5) packs two callsigns plus a county/state/province/DX location with an implied +00 report. When BOTH callsigns are compound/nonstandard they are displayed hashed and bracketed (e.g. '<KT3STT/VP9> <9A/WT3STT> +00 DX'). pack77_txqp / pack77_txqpvar rejected any input where both words were wrapped in <...>, so DecodedText's stdmsg_ round-trip failed and is_standard_ was FALSE for these messages only. That single asymmetry is why regular-call QSOs auto-sequenced and logged correctly while compound-vs-compound QSOs did not: the standard auto-sequence, state-transition and logging paths all key off isStandardMessage(), and m_xRcvd (the received exchange used for logging) was never populated. Relaxing the both-bracketed guard in pack77_txqp and pack77_txqpvar lets these exchanges pack as i3=3 again. The exchange-token validation (valid county/state/province/DX with +00 or R+00) still guards against false positives, and pack28/pack28var already hash both compound calls into the frame. The equivalent RTTY guards in pack77_3/pack77_3var are intentionally left unchanged.
The TxQP location multiplier (county / state / province / DX) was written to the ADIF-standard <srx_string> (received) and <stx_string> (sent) fields. N1MM only imports the <srx> and <stx> tags when receiving pushed QSO data, so the exchange was being dropped on import. Write the sent/received location to <stx>/<srx> instead. The received side still also emits <state> for general logging/awards tracking, and the ARRL Field Day <SRX_STRING> path is left unchanged.
…ross-tool compatibility N1MM only imports the numeric <srx>/<stx> tags (non-standard behavior for non-numeric contest exchange data), while N3FJP follows the ADIF standard and expects non-numeric exchange data in <srx_string>/<stx_string>. Now write the TxQP location multiplier to BOTH sets of tags: - Sent: <stx> + <stx_string> - Received: <srx> + <srx_string> This ensures the exchange is correctly imported by both N1MM and N3FJP (and other ADIF-compliant logging software). ADIF validators may flag a warning (non-numeric data in numeric-only fields), but no data is lost.
The received TxQP location was landing in N1MM's 'Sect' column (from the standard <state> tag) while the 'Exch' column stayed empty. Per N1MM's technical docs, N1MM stores/restores its 'Exchange1' database field (the Exch column) via its application-specific <app_n1mm_exchange1> ADIF tag, not via <state>/<srx>. Add that tag (with the county/state/province/DX location) to the TxQP received-exchange ADIF record so N1MM captures the exchange in the correct field. Standard tags are still written for other loggers: <srx> (numeric-style, also accepted by N1MM), <srx_string> (N3FJP / ADIF-standard) and <state> (general logging/awards).
Restore CI.yml to produce all install packages
Feature/txqp contest mode
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.
Texas QSO Party (TxQP) Contest Mode Implementation
Overview
This branch adds full support for the Texas QSO Party contest in FT8/FT4 modes, including exchange validation, auto-sequencing, and proper logging for popular contest loggers (N1MM, N3FJP).
Core Feature Implementation
File: lib/77bit/packjt77.f90
Changes:
Added pack77_txqp() and pack77_txqpvar() subroutines (i3=3, n3=5)
Implemented 13-bit exchange encoding: 254 Texas counties (0-253), 50 US states (254-303), 13 Canadian provinces (304-316), DX (317)
Fixed validation regex to accept both-bracketed compound callsigns in exchanges
Added unpacking logic in unpack77() and unpack77var()
Arrays: txqp_counties(254), txqp_states(50), txqp_provinces(13)
Files: Configuration.hpp, Configuration.cpp, Configuration.ui
Changes:
Added TXQP to SpecialOperatingActivity enum (index 10)
New UI controls: rbTxQP radio button, labTxQP label, TXQP_Exchange QLineEdit
Validation regex accepts: 224 TX counties + 50 states + 13 provinces + "DX"
Auto-uppercase input, saved to persistent settings
File: widgets/mainwindow.cpp (genStdMsgs)
Changes:
TxQP exchange format: "+00 " + m_config.TXQP_Exchange()
Compound-callsign Tx4/Tx5 generation for both-compound scenarios
Bug Fixes (Compound Callsigns)
File: widgets/mainwindow.cpp
Issues Fixed:
a) TxQP exchanges (+00/R+00) now bypass early-return in processMessage()
b) TxQP messages added to auto_sequence() standard-message allowlist
c) CQ auto-reply enabled for TxQP regardless of "CQ: None" setting
d) Roger-exchange (R+00) correctly triggers ROGERS state
e) Compound-callsign CQ auto-respond: 8 fixes for bracketed detection
f) Both-compound Tx4/Tx5 generation ( call2 RR73/73)
File: lib/77bit/packjt77.f90
Issue: When both callsigns were compound, TxQP exchanges displayed as +00 DX but the both-bracketed guard rejected them on re-packing → is_standard_ = FALSE → auto-sequence/logging broke
Fix: Removed both-bracketed guard in pack77_txqp (line ~1456) and pack77_txqpvar (line ~1550). Exchange-token validation still prevents false positives.
File: widgets/mainwindow.cpp (genCQMsg)
Issue: "CQ with Frequency" for compound calls produced invalid CQ 025 → encoder crash
Fix: Compound calls always generate plain CQ (Type 4 protocol constraint)
Logging & ADIF Export
Files: logbook/logbook.cpp, widgets/logqso.cpp
Changes:
TxQP QSOs auto-log (no user prompt)
ADIF export includes contest_id:TEXAS-QSO-PARTY
Exchange written to 4 tags for cross-logger compatibility:
<app_n1mm_exchange1> → N1MM "Exch" column
/ → N1MM also accepts
<srx_string> / <stx_string> → N3FJP / ADIF-compliant loggers
→ general logging/awards
File: widgets/ExportCabrillo.cpp
Changes: Auto-populates CONTEST: header with "TEXAS-QSO-PARTY"
Validation
Windows package is fully operable. Confirmed integration with N1MM and export to correct fields.