8.7 KiB
FreeDMR 2 State Model
The FreeDMR 2 state model separates listener identity, client identity, subscription state, stream state, mesh peer state, and reporting/export views. The legacy BRIDGES dict is not the authoritative FreeDMR 2 model.
Recommended hot-path structures:
NamedTupleor tuple keys for hot dict/set indexes.dataclass(slots=True)for mutable state records.heapqexpiry queue with lazy invalidation.- Local in-memory packet-plane state.
- No packet-path dependency on external databases or reporting consumers.
Suggested indexes:
subscriptions_by_conference_tg[conference_tg] -> set[SubscriptionKey]
subscription_by_rf[(client_id, slot, rf_tg)] -> SubscriptionKey
subscriptions_by_client_slot[(client_id, slot)] -> set[SubscriptionKey]
expiry_heap -> (expires_at, generation, SubscriptionKey)
AccessSession
Purpose: Represents a live client/repeater session.
Owner: Access layer.
Key: Client DMR ID plus listener/session endpoint data.
Mutable fields: Authentication state, options, keepalive time, endpoint, active slots, supported protocol features.
Expiry/timer behaviour: Keepalive/session timeout expires the session and resets session-scoped options to system defaults.
Packet-plane rules: Read for packet admission, option interpretation, slot state, and source identity. Writes only minimal hot state such as last packet/keepalive.
Control-plane rules: API may read and update bounded session options.
Reporting/export view: Client connected/disconnected/options/state events.
Compatibility mapping: Current configured MASTER/SYSTEM session fields and peer status entries.
Listener
Purpose: Owns a UDP socket/service endpoint.
Owner: Access layer or transport shell.
Key: Listener name or bind address/port.
Mutable fields: Socket state, configured admission policy, active access sessions.
Expiry/timer behaviour: None beyond transport lifecycle.
Packet-plane rules: Receives and sends packets; should not be treated as client identity.
Control-plane rules: Configuration and lifecycle only.
Reporting/export view: Listener up/down and session counts.
Compatibility mapping: Current MASTER stanza.
ClientSlotState
Purpose: Tracks per-client per-slot RF-facing state.
Owner: Access and subscription layers.
Key: (client_id, slot).
Mutable fields: RF-visible TG activity, current stream, hang/timeout state, default reflector, static and dial subscriptions.
Expiry/timer behaviour: Stream timers, dial/default reflector expiry, session reset on disconnect.
Packet-plane rules: Read for RF-visible TG mapping and stream admission. Writes current stream and observed activity.
Control-plane rules: API may activate/deactivate subscriptions and defaults.
Reporting/export view: Slot activity and active subscription state.
Compatibility mapping: Existing slot options, dial-a-TG state, timeout fields.
TalkgroupSubscription
Purpose: Represents membership of a client slot/RF TG in a conference TG.
Owner: Subscription layer.
Key: Stable SubscriptionKey, likely (client_id, slot, rf_tg, conference_tg, mode).
Mutable fields: Active flag, source, expiry, generation, priority/policy metadata.
Expiry/timer behaviour: Static subscriptions normally session-bound; dial/default/user subscriptions may expire.
Packet-plane rules: Read heavily for routing. Writes should be explicit activation/deactivation/expiry only.
Control-plane rules: API and bridge control may create/remove/update subscriptions subject to policy.
Reporting/export view: Subscription activated/deactivated/expired events.
Compatibility mapping: Current BRIDGES entries and # reflector export names.
StreamState
Purpose: Tracks voice stream lifecycle and packet ordering.
Owner: Packet/stream layer.
Key: Stream ID plus source identity and direction namespace where needed.
Mutable fields: Source ID, destination/conference TG, RF-visible TG when relevant, slot, last sequence, last packet time, LC state, source server/repeater metadata, loop-control state.
Expiry/timer behaviour: Explicit terminator is strong end; timeout is softer, especially on HBP.
Packet-plane rules: Read/write in packet path. Must be local and fast.
Control-plane rules: Normally read-only, except explicit reset/debug operations.
Reporting/export view: Call started/ended/lost events.
Compatibility mapping: Current stream tracking dicts and report socket call state.
MeshPeerState
Purpose: Tracks a peer server/link.
Owner: Mesh layer.
Key: Peer/server ID and authenticated endpoint/session where available.
Mutable fields: Protocol version, endpoint, auth state, last seen, stun/quench state, supported metadata layout, send/receive counters.
Expiry/timer behaviour: Peer keepalive/control timeout; auth renewal timers.
Packet-plane rules: Read for admission, protocol layout, and source metadata. Writes last-seen counters and cached safety state only.
Control-plane rules: API/BCXX may stun, clear stun, authenticate, or update policy.
Reporting/export view: Peer up/down/stun/source-quench events.
Compatibility mapping: Current OBP/FBP peer entries.
BridgeControlState
Purpose: Holds bridge-control effects such as source quench, STUN, and authentication state.
Owner: Mesh/control layer.
Key: Peer ID plus control scope, for example (peer_id, stream_id, conference_tg) for BCSQ.
Mutable fields: Active flag, reason, expiry, generation, authenticated issuer.
Expiry/timer behaviour: Source quench and soft controls should expire; hard policy blocks may persist until cleared.
Packet-plane rules: Read for admission/suppression. Writes only when handling bridge-control packets.
Control-plane rules: API/BCXX may set or clear controls.
Reporting/export view: Mesh control events.
Compatibility mapping: Current BCSQ/BCST handling.
ReportingState
Purpose: Tracks reporting pipeline health and retained current state.
Owner: Reporting layer.
Key: Event family or retained state identity.
Mutable fields: Queue depth, dropped counts, publisher connected state, last emitted state.
Expiry/timer behaviour: Retained state refresh and reconnect backoff.
Packet-plane rules: Packet path may enqueue non-blocking events only.
Control-plane rules: API may read reporting health.
Reporting/export view: Native v2 reporting state.
Compatibility mapping: Current dashboard socket state, preferably through a sidecar adapter.
CompatibilityExportState
Purpose: Derived legacy-shaped view for old dashboard/API/HBLink-compatible consumers.
Owner: Compatibility adapter.
Key: Consumer-specific.
Mutable fields: Cached translated state.
Expiry/timer behaviour: Follows source state; may drop stale export entries.
Packet-plane rules: Must not be read by packet routing.
Control-plane rules: May expose old-compatible admin views if required.
Reporting/export view: Legacy compatibility only.
Compatibility mapping: BRIDGES, SYSTEM, MASTER, and # reflector names.
Worker Ownership Considerations
Authoritative packet-plane state must have one owner. Reporting/export state is derived and must not drive routing. External stores may distribute snapshots or control-plane updates, but they are not per-packet routing dependencies.
Process boundaries must preserve the same state ownership rules as in-process modules.
AccessSession:
- Classification: Access/session state with packet-plane admission impact.
- Likely owner: Transport/listener process initially.
- Future ownership: May be assigned to a routing worker once admitted.
ClientSlotState:
- Classification: Packet-plane authoritative state.
- Likely owner: Single routing owner for that client/slot.
TalkgroupSubscription:
- Classification: Packet-plane authoritative state.
- Likely owner: Single routing/subscription owner.
StreamState:
- Classification: Packet-plane authoritative state.
- Likely owner: Single stream owner; all packets for a given stream should be handled by one owner.
MeshPeerState:
- Classification: Split transport/session state and routing policy state.
- Likely owner: Transport/session owner for socket/auth/session facts; routing policy owner for cached packet decisions.
- Rule: Authenticated peer/session state must be cached locally for packet decisions.
BridgeControlState:
- Classification: Control-plane input with packet-plane effect.
- Likely owner: Relevant packet/routing owner for active BCSQ/STUN effects.
- Rule: BCSQ/STUN state used by the packet path must be local to the relevant packet owner.
ReportingState:
- Classification: Reporting/export snapshot and event state.
- Likely owner: Reporting worker.
- Rule: Not authoritative for packet routing.
CompatibilityExportState:
- Classification: Derived compatibility state.
- Likely owner: Compatibility adapter/export worker.
- Rule: Never authoritative.