You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(hl2): declare the modes this radio cannot transmit in — Principle II.
Hl2Backend declared an empty receiveOnlyModes list under a comment that the
host TX chain was WDSP. It is not: Hl2TxDsp is a phasing SSB modulator whose
mode is read only by isLowerSideband(), so AM/SAM/DSB/FM/NFM/WBFM/WFM/DRM
would key as USB. This PR lists those modes (both spellings) so
RadioModel::refuseKeyInReceiveOnlyMode() refuses MOX, CW keying, and TUNE.
SSB and CW stay off the list. TUNE withdrawal is accepted as the existing
capability contract (same as IC-705 WFM); per-activity granularity is left
to a maintainer.
Tests pin bit-identical IQ vs USB, the live capability list, and TUNE
refusal above the seam.
Squashed-from: #5680
Co-authored-by: on8st <258096273+on8st@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|`receiveOnlyModes`| — (empty) | — (empty) | — (empty) |`RadioModel::refuseKeyInReceiveOnlyMode` (MOX / TUNE / CW-key / `setTransmit`) | Modes the radio **demodulates but will not transmit in**, in the neutral vocabulary. Empty = transmits in everything it receives. Refusing here (not in the backend) is what rolls back `TransmitModel`'s optimistic MOX/TUNE state — a backend cannot reach `TransmitModel`, so a refusal made down there leaves the TX indicator lit and TUNE latched. Icom: `["WFM"]` on the IC-705, which receives 76–108 MHz broadcast and does not transmit there (#5040) |
80
+
| `receiveOnlyModes` | — (empty) | AM · SAM · DSB · FM · NFM · WBFM · WFM · DRM | — (empty) | `RadioModel::refuseKeyInReceiveOnlyMode` (MOX / TUNE / CW-key / `setTransmit`) | Modes the radio **demodulates but will not transmit in**, in the neutral vocabulary. Empty = transmits in everything it receives. Refusing here (not in the backend) is what rolls back `TransmitModel`'s optimistic MOX/TUNE state — a backend cannot reach `TransmitModel`, so a refusal made down there leaves the TX indicator lit and TUNE latched. Icom: `["WFM"]` on the IC-705, which receives 76–108 MHz broadcast and does not transmit there (#5040). HL2: `Hl2TxDsp` is a phasing SSB modulator whose stored mode is read only by `isLowerSideband()`, so every mode above takes the USB branch and would go on the air as SSB announcing nothing — both spellings of each alias are listed because the guard compares the string the slice holds. **Note what a non-empty list costs:** `beginLocalTxActivity` runs this guard for EVERY `TxActivity`, so it withdraws TUNE in those modes as well as MOX and CW keying, even where the tune carrier itself would be clean |
81
81
|`hostModulates`| — (❌) | ✅ | — (❌) |`TciServer`, `MainWindow_Session`| Mic source collapses to PC; PC-audio lock. **Not the same question as `takesTxAudioOverSeam`** — see below |
82
82
|`takesTxAudioOverSeam`| ❌ | ✅ | ❌ |`MainWindow_Session` (capture, TX stream, PC-audio lock), `AudioEngine::setHostModulation`, `RadioModel::ensureDaxTxStream`| Whether transmit audio leaves through `submitTxAudio` rather than a DAX/VITA-49 stream. Icom: ✅ |
83
83
|`hasRadioPttReadback`| ❌ | ❌ | ❌ |`RadioModel::publishCommandedBackendTransmitEdge`, `Ax25HfPacketDecodeDialog::beginTransmitWhenReady`| The backend's `transmitChanged` / `keyingStateConfirmed` carry the **radio's own** PTT readback and `setKeying()` is intent only. True suppresses RadioModel's command-edge fallback, and makes AetherModem wait for `radioTransmittingChanged` / `radioTransmitConfirmed` (or an already-keyed radio) before releasing sample zero. Flex: ❌ because its interlock edge is decoded inside RadioModel, not through the seam. Icom: ✅ (decoded CI-V `1C 00`, #5311) |
@@ -538,7 +538,11 @@ predicates the readouts ask before printing. See [`HERMES.md`](../HERMES.md)
538
538
(Principle I). That is derived-from-name truth being used to *seed*
539
539
reported-by-backend truth; the two remain distinct concepts.
540
540
-**Hl2Backend** reports `canTransmit` from its own TX gate (`m_txAllowed`) so a
541
-
build with transmit disabled looks RX-only from above the seam.
541
+
build with transmit disabled looks RX-only from above the seam. Its
542
+
`receiveOnlyModes` is hand-listed rather than derived, and the evidence for the
543
+
list is a test, not the list: `tests/hl2_txdsp_test.cpp` asserts each declared
544
+
mode produces IQ **bit-identical** to USB, and `tests/hl2_family_transition_test.cpp`
545
+
asserts the live backend still declares every one of them.
542
546
-**IcomCivBackend** derives `receiveOnlyModes` from `modeListFor()` filtered by
543
547
`modeIsReceiveOnly()` rather than listing it a third time, so a mode cannot be
544
548
offered in the combo without a consistent transmit answer for it. It also
0 commit comments