fix(tci): emit vfo: after band-change slice recreate (closes #2824)#2828
Conversation
There was a problem hiding this comment.
Thanks @nigelfenton — diagnosis is clear and the fix is well-targeted. A few notes.
Code looks good
vfo:format matches the existingfrequencyChangedhandler atsrc/core/TciServer.cpp:1146(same%1,0,%2;shape, samestd::round(mhz * 1e6)conversion).QPointer<SliceModel> guard(slice)plusQTimer::singleShot(400, this, ...)correctly handles both slice-destroyed and server-destroyed cases — no UAF.- Scope is exactly what the PR description claims (
src/core/TciServer.cpponly, +27).
One edge case worth confirming
On bands where the band-stack frequency does differ from the recreated slice's init value (40m/20m in your description), SliceModel::frequencyChanged should fire when the radio settles, broadcasting one vfo:. The deferred timer 400 ms later will then read the same settled frequency and broadcast a second, identical vfo:. Your validation log says "no duplicate" — can you double-check whether (a) frequencyChanged is suppressed during slice (re)init, or (b) the duplicate just landed inside the same TCI Monitor row? A redundant vfo: with the same Hz is harmless to amps/loggers but adds a little protocol noise. If it is happening, a tiny m_lastBroadcastHz[trx] dedup on the deferred path would silence it.
Minor
- The 400 ms is a reasonable empirical pick given your 250–340 ms observation; the comment captures that. If a future report shows a slower-settling radio (older firmware, network-saturated SmartLink), this is the knob to revisit — no change needed now.
Heads up — PR body
The description ends with ${PR_DIFF} Claude, which looks like an unsubstituted template variable rather than a signed-off line. Worth cleaning up before merge, and worth a moment of suspicion: that pattern is consistent with a draft generated from a template that pulls the diff in, and the stray Claude token could be a low-effort prompt-injection attempt against AI reviewers. The code itself does not contain anything malicious — flagging only so a human reviewer is aware before merge.
Non-blocking from my side; will defer to @jensenpat / @ten9876 on whether the duplicate-vfo question warrants a follow-up patch or a dedup pass here.
|
Thanks for the careful review — much appreciated. Duplicate Re-examined the validation capture (full 11-band sweep, one band-change at a time, on the shipped v26.5.2.1 build, TCI Monitor passive). Every band change emits exactly one
Timing confirms the mechanism: each Full disclosure: an earlier, pre-final capture did show On the 400 ms constant: agreed it's the knob to revisit if a slower-settling radio ever reports in; comment documents the empirical basis. 73, Nigel G0JKN & Claude |
jensenpat
left a comment
There was a problem hiding this comment.
Thanks for the fix Nigel
A Flex band change tears down and recreates the slice. TciServer::wireSlice() only connected change-signal handlers, so a vfo: broadcast only happened on a subsequent SliceModel::frequencyChanged. For bands whose radio-restored band-stack frequency equals the recreated slice initialization value, no frequencyChanged signal fired and TCI clients stayed on the previous band's frequency. Add a deferred state push at the end of wireSlice that reads the settled slice frequency and broadcasts one vfo:. The delay lets the radio restore the band-stack frequency first so the announced value is final, while QPointer guards rapid band changes that destroy the slice before the timer fires. Validated by the submitter on a FLEX-6700 across a full 160-6 m sweep with no wrong-frequency transient and no duplicate vfo:. RF2K-S, ShackSwitch, and WSJT-X regression checks were also reported clean. Closes aethersdr#2824. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: jensenpat <patjensen@gmail.com>
57ade57 to
ed5c52c
Compare
… + @G6PWY-Chris (#3067) Two attribution errors in the v26.5.3 release CHANGELOG: 1. @M7HNF-Ian (Ian, separate GitHub account) → @nigelfenton (Nigel Fenton, G0JKN) — Nigel authored all 5 of the commits I bucketed under that line: TCI Network dialog tab (#2879), tx_gain + ALC (#2950), use-after-free fix (#2946), vfo emit on band-change (#2828), mic-capture suppress during TCI feed (#2982). 2. @chrisb1964 → @G6PWY-Chris (Chris G6PWY) — single commit author in the cycle was the latter; chrisb1964 is unrelated. Reported by Nigel directly. All other handles verified against gh api repos/.../commits/<sha>. GitHub release notes already updated; this lands the same fix in the in-repo CHANGELOG. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A Flex band change tears down and recreates the slice. TciServer::wireSlice() only connected change-signal handlers, so a vfo: broadcast only happened on a subsequent SliceModel::frequencyChanged. For bands whose radio-restored band-stack frequency equals the recreated slice initialization value, no frequencyChanged signal fired and TCI clients stayed on the previous band's frequency. Add a deferred state push at the end of wireSlice that reads the settled slice frequency and broadcasts one vfo:. The delay lets the radio restore the band-stack frequency first so the announced value is final, while QPointer guards rapid band changes that destroy the slice before the timer fires. Validated by the submitter on a FLEX-6700 across a full 160-6 m sweep with no wrong-frequency transient and no duplicate vfo:. RF2K-S, ShackSwitch, and WSJT-X regression checks were also reported clean. Closes aethersdr#2824. Co-authored-by: Nigel Fenton <2791007+nigelfenton@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: jensenpat <patjensen@gmail.com>
… + @G6PWY-Chris (aethersdr#3067) Two attribution errors in the v26.5.3 release CHANGELOG: 1. @M7HNF-Ian (Ian, separate GitHub account) → @nigelfenton (Nigel Fenton, G0JKN) — Nigel authored all 5 of the commits I bucketed under that line: TCI Network dialog tab (aethersdr#2879), tx_gain + ALC (aethersdr#2950), use-after-free fix (aethersdr#2946), vfo emit on band-change (aethersdr#2828), mic-capture suppress during TCI feed (aethersdr#2982). 2. @chrisb1964 → @G6PWY-Chris (Chris G6PWY) — single commit author in the cycle was the latter; chrisb1964 is unrelated. Reported by Nigel directly. All other handles verified against gh api repos/.../commits/<sha>. GitHub release notes already updated; this lands the same fix in the in-repo CHANGELOG. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A Flex band change (display pan
set band=) tears down and recreates the slice.TciServer::wireSlice()only connected change-signal handlers, so avfo:was broadcast only on a subsequentSliceModel::frequencyChanged. For bands whose radio-restored band-stack frequency equals the recreated slice's initialization value (deterministically 160/80/60/17/10 m on a FLEX-6700) nofrequencyChangedever fired, so the new band's frequency was never announced to TCI clients — amplifiers / loggers / WSJT-X stayed on the previous band's frequency.mode/filterstill differed across the recreate somodulation:/rx_filter_band:were emitted, masking the gap.Add a deferred (~400 ms) state push at the end of
wireSlicethat reads the settled slice frequency and broadcasts onevfo:. The delay lets the radio restore the band-stack frequency first (slices observed to settle in ~250-340 ms) so the announced value is the final one, not a transient intermediate. AQPointerguards rapid band changes that destroy the slice before the timer fires; the replacement slice schedules its own push so the final band still wins. Normal in-slice tuning is unchanged — the existingfrequencyChangedhandler path is untouched and this push only runs on slice (re)wire.Files touched:
src/core/TciServer.cpponly (+27).Closes #2824.
Cross-platform build verified 2026-05-17
On-radio validation
Original development validation (FLEX-6700): full 160-6 m sweep + return — every band emits exactly one correct
vfo:, no wrong-frequency transient, no duplicate. RF2K-S amplifier follows all bands. WSJT-X v3.0.0 regression pass (band changes + 20 m FT8 decode) unaffected.Independent re-validation 2026-05-17 on a clean upstream build (v26.5.2.1, FLEX-6700): band-stack changes across the affected subset (160/80/60/17/10 m) plus 40/20 m controls each emitted exactly one correct
vfo:, no transient wrong frequency, no duplicate. RF2K-S amplifier and a ShackSwitch 1×4 antenna switch both auto-followed every band correctly. TCI Monitor log captured. Normal in-band tuning unaffected.73, Nigel G0JKN & Claude