Skip to content

fix(nets): restore 'band not available' feedback when net-tuning an unconfigured transverter band (#3930)#3992

Merged
jensenpat merged 1 commit into
aethersdr:mainfrom
Ozy311:fix/3930-net-tune-xvtr-feedback
Jul 3, 2026
Merged

fix(nets): restore 'band not available' feedback when net-tuning an unconfigured transverter band (#3930)#3992
jensenpat merged 1 commit into
aethersdr:mainfrom
Ozy311:fix/3930-net-tune-xvtr-feedback

Conversation

@Ozy311

@Ozy311 Ozy311 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

PR #3921 correctly routed tuneToNet() through applyTuneRequest(..., TuneIntent::AbsoluteJump, "net-tune") to fix the VFO-display desync — but applyTuneRequest() only runs preselectBandStackForTune() (home of the XvtrPolicy support check and its "band isn't available" status-bar feedback) for CommandedTargetCenter. A net scheduled on a band the radio can't reach (no native coverage, no matching XVTR) therefore silently issued the slice tune + recenter with no feedback. This implements the issue's Option 1: a scoped pre-check in tuneToNet() that mirrors the preselectBandStackForTune() guard exactly and refuses — with the status-bar message — before touching the radio.

Why

  • Restores the pre-fix(nets): route cross-band net tune through canonical tune policy (#3918) #3921 "Can't tune … — Band …" feedback family for net tunes without re-introducing the band-stack-reload desync that fix(nets): route cross-band net tune through canonical tune policy (#3918) #3921 fixed.
  • The guard is a faithful mirror of MainWindow::preselectBandStackForTune(): same HF↔HF and same-band early-outs, same XvtrPolicy::resolveBandStackKey() decision (capabilities-aware, so 2 m on a FLEX-6700 stays native and is never over-blocked), same no-XVTR wording, same lcProtocol warning shape.
  • Deliberately scoped to the net path (Option 1). The DX-cluster spot path (MainWindow_Menus.cpp, same AbsoluteJump, same gap) and typed-VFO consolidation into the canonical tune policy (the issue's Option 2) are a natural follow-up.

Scope

  • +36 lines in src/gui/MainWindow_Nets.cpp (pre-check + core/LogManager.h include for lcProtocol)
  • +29 lines in tests/xvtr_policy_test.cpp (new testNetTunePrecheckBandSupport() pinning the decision matrix)
  • No protocol / persistence / UX-layout change; one new user-visible status-bar message on the refusal path (pre-fix(nets): route cross-band net tune through canonical tune policy (#3918) #3921 wording family)

Constitution principle honored

Principle XI — Fixes Are Demonstrated. Bug and fix verified A/B on a live FLEX-6700 (via the automation bridge, RX-only), plus new unit tests pinning the decision core.

Test plan

  • xvtr_policy_test green (37/37 incl. 4 new cases: 440-no-XVTR unsupported, 440-with-XVTR resolves, 2m native on has2Meters models, HF control)
  • Local incremental ninja -C build clean on Linux (Nobara 43, Qt 6.10.3, gcc 15.2.1)
  • Live A/B on a FLEX-6700 (SmartSDR v1.4.0.0), nets seeded at 432.100 FM / 7.200 LSB / 144.200 USB, slice parked on 20 m:
Net (Tune Now) Baseline v26.7.1 tip This PR
432.100 (no usable XVTR mapping) silently tunes to 432.1 — no message refuses, slice unchanged, status bar: "Can't tune 70cm Test Net — Band 440 has no Flex display pan band= mapping" + lcProtocol warning
7.200 (HF control) tunes tunes (early-out, check skipped)
144.200 (native 2 m on 6700) tunes tunes (native-band branch — no over-blocking)
  • Manual GUI repro against a real FlexRadio: verified on Linux (Nobara 43) against the FLEX-6700 — baseline v26.7.1 reproduces the silent 432.1 jump; this branch refuses with the status-bar message; the 7.200 and 144.200 nets tune normally on both builds

Observed while verifying, pre-existing and unchanged by this PR: resolveBandStackKey() matches XVTR entries by name against the BandSettings band name — the lab 6700 reports an XVTR entry named 70CM, which does not match band 440, so the tune refuses on the canonical preselect path too (typed VFO, spot recall). Whether name-matching should become frequency-range matching is a separate policy question worth its own issue.

Checklist

  • Commits are signed (docs/COMMIT-SIGNING.md)
  • No new flat-key AppSettings calls (Principle V)
  • All meter UI uses MeterSmoother (Principle II) — n/a, no meter code touched

Closes #3930


73, Ozy K6OZY
AI compute partnership: cloaked.agency — (model: claude-fable-5)

…nconfigured transverter band (aethersdr#3930) — Principle XI.

PR aethersdr#3921 correctly routed tuneToNet() through applyTuneRequest(AbsoluteJump)
to fix the VFO-display desync, but applyTuneRequest() only runs
preselectBandStackForTune() — home of the XvtrPolicy support check and its
"band isn't available" status-bar feedback — for CommandedTargetCenter.
A net scheduled on a band the radio can't reach (no native coverage, no
matching XVTR entry) therefore silently issued the slice tune + recenter
with no feedback.

Scoped fix per the issue's Option 1: pre-check the target band in
tuneToNet() before the tune, mirroring the preselectBandStackForTune()
guard exactly — same HF↔HF and same-band early-outs, same
XvtrPolicy::resolveBandStackKey() decision, same no-XVTR wording, same
lcProtocol warning shape — and refuse before touching the radio.

New xvtr_policy_test cases pin the decision matrix the pre-check relies
on: 440 with no XVTR is unsupported (the repro), 440 with a covering XVTR
resolves, 2m resolves natively on has2Meters models (no over-blocking),
and plain HF stays native.

Co-authored-by: Don @ cloaked.agency <don@cloaked.agency>
@Ozy311 Ozy311 marked this pull request as ready for review July 3, 2026 08:15
@Ozy311 Ozy311 requested review from a team as code owners July 3, 2026 08:15

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, @Ozy311 — well-diagnosed and cleanly scoped. The root cause is right: applyTuneRequest() only runs preselectBandStackForTune() for CommandedTargetCenter, so the AbsoluteJump net path skipped the XVTR support check entirely.

I verified the pre-check against the real preselectBandStackForTune() at MainWindow.cpp:5771 and it's a faithful mirror:

  • The guard freqMhz > 54.0 || slice->frequency() > 54.0 is the exact De Morgan equivalent of the original's mhz <= 54.0 && slice->frequency() <= 54.0 early-out.
  • Same targetBand != currentBand gate, same resolveBandStackKey() call, same no-XVTR reason override (freqMhz > 54.0 && xvtrs.isEmpty()).
  • xvtrPolicyBandsFrom / xvtrListSummary are declared in the public MainWindowHelpers.h (already included here), and XvtrPolicy / BandSettings are pulled in — so it compiles cleanly, and CI is green on all three platforms + CodeQL.

Two small observations, neither blocking:

  1. Guard duplication risk. This is now the third copy of the same XVTR-support decision (this net path, preselectBandStackForTune, and the wiring path around MainWindow_Wiring.cpp:2835). They can drift — if the canonical guard ever changes its threshold or reason wording, this copy won't follow. Your test pinning resolveBandStackKey() mitigates the decision core, but the surrounding guard (thresholds, message shape) is still copy-pasted. The Option 2 consolidation you flagged as follow-up is the real fix; worth a tracking issue so this doesn't quietly diverge.

  2. Minor behavioral divergence on empty pan. The original returns NotNeeded when slice->panId().isEmpty() (skips the check, allows the tune). The net pre-check has no such early-out, so a slice with an empty panId on a VHF+ band would be refused here where the canonical path would proceed. This is an unusual/transient slice state and low-risk, but it's the one spot where the mirror isn't 1:1.

The test pins the decision matrix rather than tuneToNet() itself, which is a reasonable limitation given the GUI coupling — and the honest note about resolveBandStackKey() matching XVTRs by name vs. frequency range is a good separate-issue callout. Nice work. 73


🤖 aethersdr-agent · cost: $4.4216 · model: claude-opus-4-8

@jensenpat jensenpat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the net reminder XVTR fix, Ozy (and for testing w/ automation bridge!)

@jensenpat jensenpat merged commit 4e8d1b6 into aethersdr:main Jul 3, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nets: restore 'band not available' feedback when net-tuning to an unconfigured transverter band

2 participants