DeviceConfig — env-free library, config struct at the factory#208
Merged
Conversation
The library read 46 distinct DEVOURER_* environment variables at 72 call
sites to select runtime behaviour (bring-up gates, beamforming arming,
calibration skips, debug dumps, USB tuning). A library must not read CLI
env vars; consumers get an explicit API instead:
- src/DeviceConfig.h — construction-time config struct (rx / tx / bf /
tuning / debug / usb sections, every field doc-tagged with its env-var
spelling and value grammar), passed as CreateRtlDevice's defaulted
fourth argument. Includes a MacAddr POD + parse_mac() that replaces the
per-site sscanf MAC parsing.
- Every component (EepromManager, RadioManagementModule, HalModule,
FirmwareManager, HalJaguar2, HalJaguar3, RadioManagementJaguar3,
Halrf8822e, RtlUsbAdapter, HopProf, ToneMask) takes the config at
construction; static-cached getenv lambdas become plain members
(per-process knobs become per-device — strictly more correct).
- parse_tx_mode_env moves out of the library; BfReportDetect.h (a
demo-side per-packet debug hook) moves to examples/common/.
- The TMPDIR read in UsbDeviceLock becomes usb.lock_dir, threaded through
claim_interface_then_reset.
- examples/common/env_config.{h,cpp} — the demos' env translator: every
DEVOURER_* var maps onto DeviceConfig there, so all env-driven test
scripts run unchanged. grep getenv src/ hal/ returns nothing.
Semantic change: per-channel-set re-read knobs (DUMP_CANARY, SKIP_TXPWR,
FORCE_IQK, ...) are fixed at construction; scripts export before launch,
so none break.
Validated: full + gated builds, ctest 10/10; on-air d/d 8100/8000
(8822CU->8812EU ch36); tone_mask_regcheck 6/6; rx_path_mask_check 2/2;
txpwr_offset_regcheck 49 PASS / 0 FAIL with the bring-up canary
byte-identical to master on all 7 plugged DUTs; Jaguar2 single-radio BF
self-sounding 85k reports (armed 880 vs unarmed 0); HOP_PROF emits with
the flag and stays silent without. The regcheck's first run caught a real
bug — RtlJaguarDevice initialised _eepromManager/_radioManagement from
_cfg before _cfg's declaration-order construction (UB) — fixed by
declaring _cfg first.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
What
The library read 46 distinct
DEVOURER_*environment variables at 72 call sites to select runtime behaviour — bring-up gates, beamforming arming, calibration skips, debug dumps, USB tuning. A library should not read CLI env vars to decide its behaviour; consumers get an explicit API instead.src/DeviceConfig.h— construction-time configuration struct (rx/tx/bf/tuning/debug/usbsections), passed asCreateRtlDevice's defaulted fourth argument, so existing callers compile unchanged:Every field is doc-tagged with its env-var spelling and value grammar. A
MacAddrPOD +parse_mac()replaces four copies of inlinesscanfMAC parsing. Knobs that change mid-session remain runtime setters onIRtlDevice(SetTxMode,SetTxPowerOffsetQdb,SetRxPathMask,SetCcaMode, ...).Plumbing — each component (
EepromManager,RadioManagementModule,HalModule,FirmwareManager,HalJaguar2,HalJaguar3,RadioManagementJaguar3,Halrf8822e,RtlUsbAdapter,HopProf,ToneMask) takes the config at construction. Static-cached getenv lambdas (TX_EP, TX_TIMEOUT_MS, LOG_WRITES, TX_NDPA) become plain members — per-process knobs become per-device.parse_tx_mode_envleaves the library;BfReportDetect.h(demo-side per-packet debug hook) moves toexamples/common/; theTMPDIRread inUsbDeviceLockbecomesusb.lock_dir.examples/common/env_config.{h,cpp}— the demos' env translator: every library-levelDEVOURER_*var maps onto aDeviceConfigfield there, so all env-driven test scripts run unchanged. The gate holds:grep -rn getenv src/ hal/returns nothing.Semantic note: per-channel-set re-read knobs (
DUMP_CANARY,SKIP_TXPWR,FORCE_IQK, ...) are fixed at construction. Scripts export env before launch, so none break.Validation
ctestgreen on eachtxpwr_offset_regcheck: 49 PASS / 0 FAIL — bring-up register canary byte-identical to master on all 7 plugged DUTs (8812AU, 8821AU, 8814AU, 8822BU, 8811CU, 8822CU, 8812EU), the key no-regression invarianttone_mask_regcheck6/6 (CSI mask + NBI land on every generation incl. 80 MHz)rx_path_mask_check2/2 (mask spec incl. toggle grammar; functional + sticky)enable_with_tx+ sounder + NDPA in one process)DEVOURER_HOP_PROFemits per-hop lines with the flag, silent withoutThe regcheck's first run caught a real bug this PR also fixes:
RtlJaguarDeviceinitialised_eepromManager/_radioManagementfrom_cfgbefore_cfg's declaration-order construction (UB, flaky per-process)._cfgis now declared first, with a comment pinning the ordering contract.🤖 Generated with Claude Code