fix(transmit): route Quindar outro timer through dispatchMoxOff()#3317
Merged
Conversation
The PttOffHook was only consulted on the synchronous exit path of requestPttOff(). The deferred path — the Quindar outro timer callback — called setMox(false) directly, bypassing the hook. Extract a private dispatchMoxOff() helper that centralises the hook-or-setMox decision and route both sites through it. As a bonus, the synchronous path is simplified: the previously inline hook check is replaced by the single dispatchMoxOff() call. Latent today (RADE is excluded from the Quindar phone-mode allowlist), but immediately live for any future FreeDV EOO hook since FDV/FDVU/FDVL are already in isPhoneModeForQuindar(). Fixes aethersdr#3224. Principle VIII. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced May 31, 2026
jensenpat
approved these changes
May 31, 2026
jensenpat
left a comment
Collaborator
There was a problem hiding this comment.
No findings.
I traced both requestPttOff() exits through the Quindar coordinator, the PttOffHook contract, and the current RADE hook installation/cleanup path. The extracted dispatchMoxOff() preserves the existing synchronous behavior and routes the deferred Quindar outro timer through the same hook-or-setMox(false) decision, which is the missing case this PR is fixing.
The current RADE path remains unaffected because RADE is still on DIGU/DIGL and therefore excluded from isPhoneModeForQuindar(). For future FDV/FDVU/FDVL hook users, the timer path now correctly honors the hook after the outro completes.
CI, macOS/Windows checks, and CodeQL are green on db5ae23.
6 tasks
G6PWY-Chris
pushed a commit
to G6PWY-Chris/AetherSDR
that referenced
this pull request
Jun 22, 2026
…thersdr#3317) The PttOffHook was only consulted on the synchronous exit path of requestPttOff(). The deferred Quindar outro timer callback now routes through dispatchMoxOff(), centralizing the hook-or-setMox(false) decision. Latent today because RADE is excluded from the Quindar phone-mode allowlist, but live for future FDV/FDVU/FDVL hook users. Fixes aethersdr#3224. Principle VIII. Co-authored-by: Claude Sonnet 4.6 <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.
Summary
Closes #3224.
TransmitModel::requestPttOff()had two exit paths that reachsetMox(false):Synchronous bypass path — when Quindar is disabled, not in a phone mode, or
the outro is already in flight. This path correctly consulted
m_pttOffHookbefore dropping MOX.
Quindar outro timer callback — when the outro tone must play to completion
before the carrier drops. This path called
setMox(false)directly, silentlybypassing any installed
PttOffHook.Fix
Extract a private
dispatchMoxOff()helper that owns the hook-or-setMox decisionand route both call sites through it. As a bonus, the previously inline hook check
in the synchronous path is replaced by the single
dispatchMoxOff()call.Impact today
Latent — RADE (the only current
PttOffHookconsumer) uses DIGU/DIGL, whichisPhoneModeForQuindar()excludes, so the timer path cannot fire while RADE'shook is installed. No user-observable behaviour changes.
Why it still matters
FreeDV modes (FDV/FDVU/FDVL) are already in the
isPhoneModeForQuindar()allowlist.Any future FreeDV EOO hook wired through
setPttOffHook()would be silently bypassedthe moment a Quindar-enabled user releases PTT — no additional configuration change
required. The fix eliminates that foot-gun before the wiring is ever attempted.
Test plan
installed — exercises
dispatchMoxOff()→setMox(false)path)fires as before via the sync branch)
Refs
PttOffHookTransmitModel.cpp:842— newdispatchMoxOff()helper🤖 Generated with Claude Code