Review of #141:
- The quiet window is a voice-announcements option, tg_quiet_s
(config.yaml, default 3 s; 0 turns it off), not the MASTER's
GROUP_HANGTIME, which is 15 s in the example yaml and would have kept
announcements retrying through normal pauses until they were dropped.
- Routing keeps a per-TG record of when an over last started or ended
(_tg_last_heard, written on voice headers and terminators only, from
any ingress but the server's own voice, pruned past 2048 TGs / 600 s).
On the shared SYSTEM the slot's flat RX_TGID / RX_TIME only remember
the latest stream, so a hotspot keying TG 91 erased the pause of a QSO
on TG 213 on the same slot; the record does not.
- RoutingUseCases.tg_quiet_for(tg): 0.0 while a stream on the TG is live
anywhere (tg_has_active_conversation), else seconds since the record,
inf if never heard. Offered to plugins as ServerContext.tg_quiet_for
(PluginDmrdSender: granted talkgroups only), next to voice_slot_for_tg,
which is back to develop's.
- The announcer waits before choosing a slot while quiet < tg_quiet_s:
every 5 s while voice is live, else right when it has been quiet long
enough. tg_voice_heard_within and the own-stream list are gone.
Tests: routing (never heard, from the end of a mesh over, live, another
MASTER, TG 91 on the same slot keeps the 213 trace, own voice not
counted), sender (granted TGs only), announcer (waits through a QSO,
a short pause keeps it waiting, 0 turns it off, no tg_quiet_for = as
before). 10 fail on develop.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnjAx7G27d9q88j9PFLj11