Summary
TransmitModel::setCwSidetone(bool on) sends the radio command but never updates its local member m_cwSidetone, so transmitModel().cwSidetone() returns a stale value until the radio's status echo arrives. Same defect class as the AM carrier bug fixed in #3712.
Location
src/models/TransmitModel.cpp:705:
void TransmitModel::setCwSidetone(bool on)
{
emit commandReady(QString("cw sidetone %1").arg(on ? 1 : 0)); // <-- m_cwSidetone never set
}
m_cwSidetone is declared at TransmitModel.h:327 (default true).
Why it's a bug
Sibling setters update their member optimistically — e.g. setSpeechProcessorEnable (TransmitModel.cpp:536: m_speechProcEnable = on; emit micStateChanged();) — and #3712 (setAmCarrierLevel) established the canonical pattern. setCwSidetone is missing it, so any reader right after a change (GUI re-read, TCI client, the agent automation bridge's get transmit) sees the old value.
Impact
Severity: low. The command is sent and the radio applies it; the model lags the widget until the radio echoes cw sidetone. Measured live on a FLEX-8400M via the agent automation bridge: after toggling "CW sidetone", transmit.cwSidetone did not converge within a 416 ms poll window, vs ~0 ms for the optimistic setters.
Steps to reproduce
- Connect to a radio.
- Toggle CW sidetone in the Phone/CW applet (or send
cw sidetone 0).
- Immediately read
transmitModel().cwSidetone() — it still reports the old state.
Suggested fix
void TransmitModel::setCwSidetone(bool on)
{
if (m_cwSidetone != on) {
m_cwSidetone = on; // optimistic — radio status echo supersedes
emit phoneStateChanged();
}
emit commandReady(QString("cw sidetone %1").arg(on ? 1 : 0));
}
Verify before committing: (1) confirm phoneStateChanged() is the signal the "CW sidetone" button's model-sync listener binds to (control lives in PhoneCwApplet, alongside the other CW setters); (2) ensure no feedback loop — the applet's model→widget sync must be guarded (m_updatingFromModel / QSignalBlocker) so the optimistic update doesn't re-emit the command, as the #3712 fix verified for the PhoneApplet.
How it was found
Surfaced during a control-surface validation sweep on a FLEX-8400M using the agent automation bridge (get transmit model cross-check).
Summary
TransmitModel::setCwSidetone(bool on)sends the radio command but never updates its local memberm_cwSidetone, sotransmitModel().cwSidetone()returns a stale value until the radio's status echo arrives. Same defect class as the AM carrier bug fixed in #3712.Location
src/models/TransmitModel.cpp:705:m_cwSidetoneis declared atTransmitModel.h:327(defaulttrue).Why it's a bug
Sibling setters update their member optimistically — e.g.
setSpeechProcessorEnable(TransmitModel.cpp:536:m_speechProcEnable = on; emit micStateChanged();) — and #3712 (setAmCarrierLevel) established the canonical pattern.setCwSidetoneis missing it, so any reader right after a change (GUI re-read, TCI client, the agent automation bridge'sget transmit) sees the old value.Impact
Severity: low. The command is sent and the radio applies it; the model lags the widget until the radio echoes
cw sidetone. Measured live on a FLEX-8400M via the agent automation bridge: after toggling "CW sidetone",transmit.cwSidetonedid not converge within a 416 ms poll window, vs ~0 ms for the optimistic setters.Steps to reproduce
cw sidetone 0).transmitModel().cwSidetone()— it still reports the old state.Suggested fix
Verify before committing: (1) confirm
phoneStateChanged()is the signal the "CW sidetone" button's model-sync listener binds to (control lives inPhoneCwApplet, alongside the other CW setters); (2) ensure no feedback loop — the applet's model→widget sync must be guarded (m_updatingFromModel/QSignalBlocker) so the optimistic update doesn't re-emit the command, as the #3712 fix verified for the PhoneApplet.How it was found
Surfaced during a control-surface validation sweep on a FLEX-8400M using the agent automation bridge (
get transmitmodel cross-check).