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.
252 lines
8.7 KiB
252 lines
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:
|
|
|
|
```python
|
|
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.
|