Summary
TransmitModel::setSbMonitor(bool on) sends the radio command but never updates its local member m_sbMonitor, so transmitModel().sbMonitor() 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:561:
void TransmitModel::setSbMonitor(bool on)
{
emit commandReady(QString("transmit set mon=%1").arg(on ? 1 : 0)); // <-- m_sbMonitor never set
}
m_sbMonitor is declared at TransmitModel.h:305 (default false).
Why it's a bug
Sibling setters update their member optimistically before/with the command, e.g. setSpeechProcessorEnable (TransmitModel.cpp:536) does m_speechProcEnable = on; emit micStateChanged();, and the AM carrier fix #3712 (setAmCarrierLevel, ~line 618) established the canonical pattern. setSbMonitor is missing that, 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 correctly and the radio applies it; the model just lags the widget until the radio echoes mon=. Measured live on a FLEX-8400M via the agent automation bridge: after toggling "TX monitor", transmit.monitor did not converge within a 410 ms poll window, whereas the optimistic setters converge in ~0 ms.
Steps to reproduce
- Connect to a radio.
- Toggle TX monitor in the Phone/CW applet (or send
transmit set mon=1).
- Immediately read
transmitModel().sbMonitor() — it still reports the old state.
Suggested fix
Mirror #3712 / the sibling pattern:
void TransmitModel::setSbMonitor(bool on)
{
if (m_sbMonitor != on) {
m_sbMonitor = on; // optimistic — radio status echo supersedes
emit phoneStateChanged();
}
emit commandReady(QString("transmit set mon=%1").arg(on ? 1 : 0));
}
Verify before committing: (1) confirm phoneStateChanged() is the signal the "TX monitor" button's model-sync listener binds to (the control lives in PhoneCwApplet); (2) ensure no feedback loop — the applet's model→widget sync must be guarded (e.g. m_updatingFromModel / QSignalBlocker) so the optimistic update doesn't re-emit the command, exactly as the #3712 fix checked for the PhoneApplet AM-carrier slider.
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::setSbMonitor(bool on)sends the radio command but never updates its local memberm_sbMonitor, sotransmitModel().sbMonitor()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:561:m_sbMonitoris declared atTransmitModel.h:305(defaultfalse).Why it's a bug
Sibling setters update their member optimistically before/with the command, e.g.
setSpeechProcessorEnable(TransmitModel.cpp:536) doesm_speechProcEnable = on; emit micStateChanged();, and the AM carrier fix #3712 (setAmCarrierLevel, ~line 618) established the canonical pattern.setSbMonitoris missing that, 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 correctly and the radio applies it; the model just lags the widget until the radio echoes
mon=. Measured live on a FLEX-8400M via the agent automation bridge: after toggling "TX monitor",transmit.monitordid not converge within a 410 ms poll window, whereas the optimistic setters converge in ~0 ms.Steps to reproduce
transmit set mon=1).transmitModel().sbMonitor()— it still reports the old state.Suggested fix
Mirror #3712 / the sibling pattern:
Verify before committing: (1) confirm
phoneStateChanged()is the signal the "TX monitor" button's model-sync listener binds to (the control lives inPhoneCwApplet); (2) ensure no feedback loop — the applet's model→widget sync must be guarded (e.g.m_updatingFromModel/QSignalBlocker) so the optimistic update doesn't re-emit the command, exactly as the #3712 fix checked for the PhoneApplet AM-carrier slider.How it was found
Surfaced during a control-surface validation sweep on a FLEX-8400M using the agent automation bridge (
get transmitmodel cross-check).