You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeDMR/docs/freedmr-2/02-state-model.md

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:

  • NamedTuple or tuple keys for hot dict/set indexes.
  • dataclass(slots=True) for mutable state records.
  • heapq expiry 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.

Powered by TurnKey Linux.