[xvtr] Clamp XVTR Max Power before sending#3273
Conversation
Co-authored-by: Codex <noreply@openai.com>
There was a problem hiding this comment.
Nice, focused change — thanks @jensenpat. The split between XvtrPolicy (pure policy logic, easy to test) and the dialog wiring is clean, and the test coverage hits the four FlexLib boundary points called out in the description.
A few small observations, none blocking:
-
submitMaxPower(false)change-detection. UsingqFuzzyCompare(requested + 1.0, clamped + 1.0)works, but sincestd::clampreturns the input value verbatim when it's already in range, a directrequested == clampedwould be equivalent here (no intervening fp arithmetic) and reads more clearly. Pure nit — feel free to leave as-is. -
Empty / invalid
maxPwrEditon IF edit. When IF changes andmaxPwrEditis blank or non-numeric,toDouble(&ok)returns false andsubmitMaxPower(false)no-ops without sending. That's the right call (don't synthesize a value the user never entered), just worth a quick sanity-check that the field is always populated by the load path before this becomes user-visible. -
usesLegacyLowIfMaxPowermodel match. Uppercase+trim on the exact stringsFLEX-6400/6400M/6600/6600Mis what FlexLib reports, so this should be fine, but it's strict — ifRadioModel::model()ever returns something with extra suffixes or a different separator for a future variant, it'll silently fall back to the +15 dBm default. The tests pin the current set, so easy to revisit if/when needed. -
80 MHz boundary.
>= 80.0puts exactly-80 MHz IF on the high-IF +8 dBm rail, which matches your "high IF caps max power at +8 dBm" test at IF=80.0. Worth confirming this matches FlexLib's>=vs>at the exact boundary, since we're mirroring their behavior.
Conventions look good — XvtrPolicy namespace + free functions consistent with the existing file, QDoubleValidator parented to maxPwrEdit (RAII fine), no QSettings introduced, validator updates pair correctly with the IF-edit handler. Ship it.
🤖 aethersdr-agent · cost: $5.3302 · model: claude-opus-4-7
|
@AetherClaude are we good to merge this one? |
|
@ten9876 I reviewed the diff against What's solid
Minor, non-blocking nits (fine to land as-is or fold into a follow-up):
None of these change correctness, so I'd be comfortable merging once you're happy with the cosmetic decimal point. 73, Jeremy KK7GWY & Claude (AI dev partner) 🤖 aethersdr-agent · cost: $3.0873 · model: claude-opus-4-8 |
|
@AetherClaude push a fix for the nits on top of the PR |
|
@ten9876 I went back through the three nits against the PR diff. Only nit #1 is an actual code change; #2 and #3 were confirmations/notes. Here's the concrete fix. Nit #1 — decimal display consistency (the real one) The field is still initialized with one decimal, while the validator and
// before
auto* maxPwrEdit = addField(4, 0, "Max Power (dBm):", QString::number(x.maxPower, 'f', 1));
// after
auto* maxPwrEdit = addField(4, 0, "Max Power (dBm):", QString::number(x.maxPower, 'f', 2));That's a one-character change ( Nit #2 — 80 MHz inclusive boundary
Nit #3 — empty/non-numeric IF text Empty IF text falls through So the only fix to land is the The 73, Jeremy KK7GWY & Claude (AI dev partner) 🤖 aethersdr-agent · cost: $1.9395 · model: claude-opus-4-8 |
## Summary - Mirror FlexLib XVTR MaxPower bounds in `XvtrPolicy` so AetherSDR clamps before sending `xvtr set ... max_power=`. - Add a `QDoubleValidator` to the Radio Setup XVTR Max Power field using the active radio model and IF-frequency-dependent dBm range. - Clamp again on submit, including after IF frequency edits that tighten the allowed Max Power ceiling. - Add focused `xvtr_policy_test` coverage for the FlexLib ranges: -10 dBm floor, +8 dBm high IF ceiling, +10 dBm 6400/6600 low IF ceiling, and +15 dBm default low IF ceiling. Refs aethersdr#3246 (fix aethersdr#3 only: XVTR Max Power clamp). ## Test Plan - `cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk` - `cmake --build build -j22` - `./build/xvtr_policy_test` - Built app: `/Users/patj/.codex/worktrees/145c/AetherSDR/build/AetherSDR.app` - Deploy attempted with `$deploy-aethersdr-test-build`; upload reached the remote, but replacing `/Users/patj/Desktop/AetherSDR.app` failed repeatedly because remote `rm` returned `Operation not permitted` for the existing app bundle contents. 👨🏼💻 Generated with OpenAI Codex (GPT-5.5 Pro 4/23) and tested by @jensenpat Co-authored-by: Codex <noreply@openai.com>
Summary
XvtrPolicyso AetherSDR clamps before sendingxvtr set ... max_power=.QDoubleValidatorto the Radio Setup XVTR Max Power field using the active radio model and IF-frequency-dependent dBm range.xvtr_policy_testcoverage for the FlexLib ranges: -10 dBm floor, +8 dBm high IF ceiling, +10 dBm 6400/6600 low IF ceiling, and +15 dBm default low IF ceiling.Refs #3246 (fix #3 only: XVTR Max Power clamp).
Test Plan
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdkcmake --build build -j22./build/xvtr_policy_test/Users/patj/.codex/worktrees/145c/AetherSDR/build/AetherSDR.app$deploy-aethersdr-test-build; upload reached the remote, but replacing/Users/patj/Desktop/AetherSDR.appfailed repeatedly because remotermreturnedOperation not permittedfor the existing app bundle contents.👨🏼💻 Generated with OpenAI Codex (GPT-5.5 Pro 4/23) and tested by @jensenpat