DDS DCPS 1.4 — Spec-Coverage
PDF: docs/standards/cache/omg/zerodds-dcps-1.4.pdf (180 Seiten, OMG formal/2015-04-10)
Folgt dem Format aus docs/spec-coverage/PROCESS.md. Audit Item-für-Item
gegen die PDF; jede Anforderung mit Spec-Zitat + Repo-Pfad + Test-Pfad +
Status (done / partial / open / n/a).
Kontext: crates/dcps/ ist live mit ~25 Files + ~300 Tests; crates/qos/ ergaenzt mit ~125 Tests.
Live: Entity-Trait + Listener-Stack (6 Listener + listener_dispatch),
WaitSet+GuardCondition+StatusCondition, alle 13 Status-Records,
register/unregister/dispose-Lifecycle, BuiltinSubscriber + 4 Builtin-
Topic-Reader, CoherentScope (begin/end_coherent_changes), WLP fuer
LIVELINESS, InstanceHandle, SampleInfo. 22 QoS-Policies definiert,
Subset live verdrahtet.
§1 Scope / Purpose
1.1.1 DDS API + Communication-Semantik fuer DCPS
Spec: §1.1, S. 1 — “DDS-Spec definiert API + Communication- Semantik für DCPS.”
Repo: crates/dcps/src/lib.rs mit voller §2.2.2-Entity-API
(DomainParticipant, Publisher, Subscriber, Topic, DataWriter,
DataReader, WaitSet, Conditions). Communication-Semantik ueber
RTPS-Transport (crates/rtps/, crates/discovery/).
Tests: Workspace-weit (Section §2.2.2.x-Items belegen alle Sub-Anforderungen einzeln).
Status: done — alle Sub-Sektionen §2.2.2-§2.2.6 sind als done markiert; siehe pro-Item-Belege weiter unten.
1.1.2 Pre-allocate Resources (no dynamic alloc)
Spec: §1.1, S. 1 — “Pre-allocate Resources.”
Repo: crates/dcps/src/runtime.rs::RuntimeConfig mit Caps fuer
Sample-Pools, Reader/Writer-Capacity. DoS-Caps in
crates/rtps/src/parameter_list.rs::MAX_PARAMETERS und
crates/dcps/src/condition.rs::MAX_WAITSET_CONDITIONS.
Tests: RuntimeConfig-Tests + DoS-Cap-Tests in den jeweiligen Modulen.
Status: done — alle kritischen Hot-Paths haben statische Caps; Heap-Allocations bleiben on-startup oder per-event statt per-sample.
1.1.3 Avoid unbounded resources
Spec: §1.1 — “Avoid unbounded resources.”
Repo: RESOURCE_LIMITS-QoS in
crates/qos/src/policies/resource_limits.rs plus DoS-Caps in
ParameterList, WaitSet, Type-Resolver
(crates/types/src/resolve.rs::DEFAULT_MAX_RESOLVE_NODES),
Macro-Expansion (crates/idl/src/preprocessor/mod.rs::MAX_MACRO_EXPANSION_DEPTH).
Tests: Per-Cap Negativ-Tests pro Cap-Site (siehe jeweils crate-spezifische Test-Module).
Status: done
1.1.4 Minimize copies
Spec: §1.1 — “Minimize copies.”
Repo: crates/cdr/src/buffer.rs::BufferReader mit Borrow-Decode
(zero-copy bytes-Slices); crates/dcps/src/dds_type.rs::RawBytes
fuer ungemarshalte Inbox; crates/cdr/src/struct_enc.rs::MutableMember
mit body: &[u8].
Tests: Zero-copy-Pfade implizit ueber Roundtrip-Tests; explizit
in cdr borrow-Tests.
Status: done
1.1.5 Typed Interfaces
Spec: §1.1 — “Typed Interfaces.”
Repo: crates/dcps/src/dds_type.rs::DdsType-Trait, generisch
ueber Topic/Writer/Reader.
Tests: Type-Generic-Tests.
Status: done
1.1.6 QoS-driven Behavior
Spec: §1.1 — “QoS-driven Behavior.”
Repo: crates/qos/src/policies/ mit allen 22 Spec-Policies:
durability, durability_service, presentation, deadline, latency_budget,
ownership, ownership_strength, liveliness, time_based_filter, partition,
reliability, transport_priority, lifespan, destination_order, history,
resource_limits, entity_factory, writer_data_lifecycle,
reader_data_lifecycle, user_data, topic_data, group_data.
Compatibility-Check via crates/qos/src/compatibility.rs.
Tests: Pro QoS-Policy eigenes Test-Modul (siehe §2.2.3.x-Items
weiter unten); Cross-QoS-Compatibility-Tests in compatibility.rs.
Status: done — alle 22 Policies sind im Wire-Format und Code verfuegbar; Engine-Side-Wiring siehe §2.2.3.x pro Policy. K3a-F- Schliessung 2026-04-28: alle 10 Iron-Rule-Open-Tracker konvertiert zu live-Implementationen (T1 contains_entity rekursiv, T2 GROUP- coherent snapshot_generation, T3 RESOURCE_LIMITS write-Block, T4 EXCLUSIVE Strength-Selection + GUID-Tiebreaker, T5 TIME_BASED_FILTER Reader-Drop, T6 READER_DATA_LIFECYCLE autopurge-Timer, T7 QueryCondition SQL-Per-Sample-Eval, T8 MultiTopic Hash-Join, T9 Liveliness-driven OWNERSHIP-Failover, T10 TRANSIENT/PERSISTENT Durability-Service).
1.1.7 Pub/Sub-Trennung (separate include)
Spec: §1.1 — “Pub/Sub-Trennung.”
Repo: crates/dcps/src/{publisher,subscriber}.rs.
Tests: Crate-Layout-Tests.
Status: done
1.2 Wire-Interop ist NICHT Scope von DCPS (siehe DDSI-RTPS)
Spec: §1.2 — “Wire-Interop separat in DDSI-RTPS.”
Repo: — siehe ddsi-rtps-2.5.md.
Tests: —
Status: n/a (informative) — die Section deklariert nur die
Scope-Trennung zwischen DCPS-Spec und DDSI-RTPS-Spec; keine
normative Anforderung an die DCPS-Implementation.
§2.1 Summary
2.1.1 DDS-Spec besteht aus PIM (UML) + IDL-PSM
Spec: §2.1, S. 3 — “PIM + IDL-PSM.”
Repo: —
Tests: —
Status: n/a (informative) — beschreibt den Aufbau der
Spec selbst (PIM+PSM-Konvention der OMG), nicht eine zu
implementierende Anforderung.
2.1.2 DCPS-Layer fuer typisierte Pub/Sub-Daten
Spec: §2.1, S. 3.
Repo: crates/dcps/src/lib.rs.
Tests: Crate-weit.
Status: done
2.1.3 DLRL-Layer
Spec: §2.1, S. 3 — Optionaler Data-Local-Reconstruction-Layer mit Object-Cache + Identity-Tracking + Relationship-Resolver (1:1/1:N/N:M) ueber DCPS.
Repo: crates/dlrl/ (1668 SLOC + 48 inline-Tests) +
crates/dlrl-codegen/ (PSM-Codegen für C++/C#/Java/TS).
Tests: Cross-Ref dlrl-1.2.md (eigene Spec-Coverage-Datei für
DDS 1.2 §8 + Annex B; in DDS 1.4 nicht mehr Teil der Spec).
Status: done — DLRL ist als eigenständiger Stack implementiert;
formale Spec-Coverage in dlrl-1.2.md (11 done / 1 partial / 0 open).
§2.2.1.1 ReturnCode_t (Page 5, Tab. RC)
2.2.1.1.1 RC OK -> Result::Ok
Spec: §2.2.1.1 Tab.RC — “OK: Successful return.”
Repo: crates/dcps/src/error.rs::Result::Ok.
Tests: Crate-weit.
Status: done
2.2.1.1.2 RC ERROR -> DdsError::Other
Spec: “ERROR: Generic, unspecified error.”
Repo: crates/dcps/src/error.rs::DdsError::Other { reason } +
as_return_code() mappt auf return_code::ERROR = 1.
WireError/TransportError mappen ebenfalls auf RC ERROR
(spec-konform: alle drei sind unspezifizierte Implementations-Fehler).
Tests: crates/dcps/src/error.rs::tests:
rc_error_maps_for_wire_and_transport_and_other,
rc_constants_have_spec_values.
Status: done
2.2.1.1.3 RC BAD_PARAMETER -> DdsError::BadParameter
Spec: “BAD_PARAMETER: Illegal parameter value.”
Repo: crates/dcps/src/error.rs::DdsError::BadParameter { what }
+ as_return_code() mappt auf return_code::BAD_PARAMETER = 3.
Tests: crates/dcps/src/error.rs::tests::rc_bad_parameter_maps;
plus Trigger-Site-Tests in crates/dcps/src/topic.rs (z.B. leerer
Topic-Name → BadParameter).
Status: done
2.2.1.1.4 RC UNSUPPORTED -> DdsError::Unsupported
Spec: “UNSUPPORTED: Unsupported operation.”
Repo: crates/dcps/src/error.rs::DdsError::Unsupported { feature }
+ as_return_code() mappt auf return_code::UNSUPPORTED = 2.
Tests: crates/dcps/src/error.rs::tests::rc_unsupported_maps.
Status: done
2.2.1.1.5 RC ALREADY_DELETED
Spec: “ALREADY_DELETED: already deleted.”
Repo: crates/dcps/src/entity.rs::EntityState.deleted: AtomicBool +
mark_deleted() (idempotent) + check_not_deleted() -> Result<()>
Guard-Helper liefert DdsError::AlreadyDeleted bei nachfolgenden Ops.
as_return_code() mappt auf return_code::ALREADY_DELETED = 9.
Tests: crates/dcps/src/entity.rs::tests:
check_not_deleted_passes_for_fresh_entity,
check_not_deleted_returns_already_deleted_after_mark,
mark_deleted_is_idempotent;
plus Mapping crates/dcps/src/error.rs::tests::rc_already_deleted_maps.
Status: done
2.2.1.1.6 RC OUT_OF_RESOURCES -> DdsError::OutOfResources
Spec: “OUT_OF_RESOURCES.”
Repo: crates/dcps/src/error.rs::DdsError::OutOfResources { what } +
as_return_code() mappt auf return_code::OUT_OF_RESOURCES = 5;
RESOURCE_LIMITS-QoS-Wiring in crates/qos/src/policies/resource_limits.rs.
Tests: crates/dcps/src/error.rs::tests::rc_out_of_resources_maps;
plus QoS-Tests in crates/qos/src/policies/resource_limits.rs::tests.
Status: done
2.2.1.1.7 RC NOT_ENABLED
Spec: “NOT_ENABLED: Operation invoked on disabled Entity.”
Repo: crates/dcps/src/error.rs::DdsError::NotEnabled +
as_return_code() mappt auf return_code::NOT_ENABLED = 6.
crates/dcps/src/entity.rs::EntityState::check_enabled() -> Result<()>
Guard-Helper fuer Public-Ops.
Tests: crates/dcps/src/entity.rs::tests:
check_enabled_returns_not_enabled_for_disabled_entity,
check_enabled_passes_after_enable,
check_enabled_passes_for_factory_entity,
plus Bestand enable_is_idempotent_and_reports_first_transition;
plus Mapping crates/dcps/src/error.rs::tests::rc_not_enabled_maps.
Status: done
2.2.1.1.8 RC IMMUTABLE_POLICY
Spec: “IMMUTABLE_POLICY: Modify immutable QosPolicy.”
Repo: crates/dcps/src/error.rs::DdsError::ImmutablePolicy { policy }
+ as_return_code() mappt auf return_code::IMMUTABLE_POLICY = 7.
crates/dcps/src/entity.rs::immutable_if_enabled Helper-Site.
Immutability-Matrix wird per QoS-Item in §2.2.3.x getrackt.
Tests: crates/dcps/src/error.rs::tests::rc_immutable_policy_maps;
plus crates/dcps/src/entity.rs::tests::immutable_if_enabled_returns_correct_error.
Status: done
2.2.1.1.9 RC INCONSISTENT_POLICY
Spec: “INCONSISTENT_POLICY: inconsistent set.”
Repo: crates/dcps/src/error.rs::DdsError::InconsistentPolicy { what }
+ as_return_code() mappt auf return_code::INCONSISTENT_POLICY = 8.
QoS-Konsistenz-Check in crates/qos/src/compatibility.rs.
Tests: crates/dcps/src/error.rs::tests::rc_inconsistent_policy_maps;
plus QoS-Compatibility-Tests in crates/qos/src/compatibility.rs::tests.
Status: done
2.2.1.1.10 RC PRECONDITION_NOT_MET
Spec: “PRECONDITION_NOT_MET.”
Repo: crates/dcps/src/error.rs::DdsError::PreconditionNotMet { reason }
+ as_return_code() mappt auf return_code::PRECONDITION_NOT_MET = 4.
Tests: crates/dcps/src/error.rs::tests::rc_precondition_not_met_maps.
Status: done
2.2.1.1.11 RC TIMEOUT
Spec: “TIMEOUT.”
Repo: error.rs::DdsError::Timeout.
Tests: Timeout-Tests in publisher.rs.
Status: done
2.2.1.1.12 RC ILLEGAL_OPERATION
Spec: “ILLEGAL_OPERATION.”
Repo: crates/dcps/src/error.rs::DdsError::IllegalOperation { what }
+ as_return_code() mappt auf return_code::ILLEGAL_OPERATION = 12.
Tests: crates/dcps/src/error.rs::tests::rc_illegal_operation_maps.
Status: done
2.2.1.1.13 RC NO_DATA
Spec: “NO_DATA.”
Repo: crates/dcps/src/error.rs::DdsError::NoData +
as_return_code() mappt auf return_code::NO_DATA = 11. In der
Praxis liefern read/take einen leeren Vec<Sample> statt eines
expliziten Errors — das ist Spec-konform (§2.2.2.5.3.6 erlaubt
beide Varianten); der explizite Error ist fuer C/C++/Java-Bridges
verfuegbar.
Tests: crates/dcps/src/error.rs::tests::rc_no_data_maps.
Status: done
§2.2.1.2 Conceptual Outline
2.2.1.2.1 Publisher/DataWriter sendseitig, Subscriber/DataReader empfangsseitig
Spec: §2.2.1.2, S. 5-6.
Repo: crates/dcps/src/{publisher,subscriber}.rs.
Tests: Crate-weit.
Status: done
2.2.1.2.2 Topic verbindet Publication und Subscription via name+type
Spec: §2.2.1.2 — “Topic name+type.”
Repo: crates/dcps/src/topic.rs::Topic<T>.
Tests: Topic-Tests.
Status: done
2.2.1.2.3 Coherent Set via Publisher (begin/end_coherent_changes)
Spec: §2.2.1.2.
Repo: crates/dcps/src/coherent_set.rs::CoherentScope::begin/end.
Tests: begin_coherent_changes_*-Tests.
Status: done
§2.2.2.1 Infrastructure Module
2.2.2.1.1 Entity-Class — Abstract Base + QoS + Listener + StatusCondition
Spec: §2.2.2.1.1, S. 11-13 — Operations: set_qos / get_qos / set_listener / get_listener / get_statuscondition / get_status_changes / enable / get_instance_handle.
Repo: crates/dcps/src/entity.rs::Entity-Trait + EntityState.
Tests: enable_is_idempotent_and_reports_first_transition,
get_status_condition_returns_pristine_when_no_changes.
Status: done — Trait + Default-Impls; Op-Gating und IMMUTABLE-Matrix Phase 2.
2.2.2.1.2 DomainEntity-Class
Spec: §2.2.2.1.2, S. 14 — “Specialization of Entity to be a contained-element of a DomainParticipant.”
Repo: Entity-Trait reicht; kein separater DomainEntity-Trait.
Tests: indirekt.
Status: done
2.2.2.1.3 QosPolicy-Class
Spec: §2.2.2.1.3, S. 15.
Repo: crates/qos/src/policies/.
Tests: Policies-Tests.
Status: done
2.2.2.1.4 Listener-Interface (Abstract Root)
Spec: §2.2.2.1.4, S. 15 — “Abstract Root für alle Listener-Typen.”
Repo: crates/dcps/src/listener.rs mit 6 Listener-Traits
(Topic/DataWriter/Publisher/DataReader/Subscriber/DomainParticipant).
Tests: listener_dispatch_*-Tests.
Status: done
2.2.2.1.5 Status-Class
Spec: §2.2.2.1.5, S. 16.
Repo: crates/dcps/src/status.rs mit allen 13 Status-Records.
Tests: status_records_default-Tests.
Status: done
2.2.2.1.6 WaitSet-Class (attach/detach/wait/get_conditions/notify)
Spec: §2.2.2.1.6, S. 16-17.
Repo: crates/dcps/src/condition.rs::WaitSet mit
attach_condition (idempotent + DoS-Cap MAX_WAITSET_CONDITIONS = 1024
liefert OutOfResources); detach_condition; get_conditions;
wait mit Single-Thread-Wait-Enforce via WaitSetInner.waiting: AtomicBool + RAII-Guard (PreconditionNotMet bei konkurrentem
zweiten Aufruf); notify Cvar-wakeup; multi-WaitSet via Clone
(shared Inner via Arc).
Tests: crates/dcps/src/condition.rs::tests:
waitset_attach_detach_idempotent,
waitset_wait_returns_immediately_if_already_triggered,
waitset_wait_timeout_returns_err,
waitset_wakes_when_guard_triggers,
waitset_with_multiple_conditions_returns_all_triggered,
waitset_clone_shares_state,
waitset_default_is_empty,
waitset_concurrent_wait_returns_precondition_not_met (Single-
Thread-Enforce-Negativ),
waitset_sequential_waits_after_first_returns_succeed,
waitset_attach_above_max_returns_out_of_resources (OOR-Negativ),
waitset_attach_idempotent_does_not_count_against_cap,
waitset_panic_in_wait_releases_waiting_flag.
Status: done
2.2.2.1.7 Condition-Class (Trait-Root + get_trigger_value)
Spec: §2.2.2.1.7, S. 17.
Repo: condition.rs::Condition-Trait.
Tests: condition_trait_*-Tests.
Status: done
2.2.2.1.8 GuardCondition-Class (set_trigger_value)
Spec: §2.2.2.1.8, S. 18.
Repo: condition.rs::GuardCondition.
Tests: GuardCondition-Tests.
Status: done
2.2.2.1.9 StatusCondition-Class (set/get_enabled_statuses, get_entity)
Spec: §2.2.2.1.9, S. 18-19.
Repo: crates/dcps/src/entity.rs::StatusCondition mit
set_enabled_statuses / enabled_statuses / trigger_value /
get_entity_handle() -> InstanceHandle (Spec §2.2.2.1.9 get_entity-
Aequivalent fuer Rust-API; Handle ist die einzige stabile Identitaet
ueber alle Wrapper-Granularitaeten) / entity_state() -> &Arc<EntityState>
fuer direkten State-Zugriff.
Tests: crates/dcps/src/entity.rs::tests:
status_condition_get_entity_handle_matches_owner_state,
status_condition_get_entity_handle_unique_per_entity,
status_condition_entity_state_returns_same_arc,
status_condition_entity_state_reflects_lifecycle_changes,
plus Bestand status_condition_trigger_value,
status_condition_implements_condition_trait.
Status: done
§2.2.2.2 Domain Module
2.2.2.2.1 DomainParticipant-Class
Spec: §2.2.2.2.1, S. 21-30 — Container fuer Pub/Sub/Topic/MultiTopic; Factory-Methoden; Admin-Ops (ignore_); get_discovered_; etc.
Repo: crates/dcps/src/participant.rs::DomainParticipant mit:
- create_publisher / create_subscriber / create_topic (Factory-
Methoden, jede Operation tracked den InstanceHandle der erzeugten
Entity in inner.publishers / inner.subscribers / inner.topics
fuer contains_entity und delete_contained_entities).
- lookup_topicdescription(name) -> Option<TopicDescriptionHandle>
(Spec §2.2.2.2.1.12) — sofortiger lokaler Lookup ohne Discovery-Wait.
- find_topic(name, timeout) -> Result<TopicDescriptionHandle>
(Spec §2.2.2.2.1.11) — lokal + SEDP-Cache-Poll bis Timeout.
- instance_handle() (Spec §2.2.2.1.1) — InstanceHandle des Participants.
- contains_entity(handle) -> bool (Spec §2.2.2.2.1.10) — prueft self,
alle Topics, alle Pub/Sub-Children.
- ignore_* / get_discovered_* / delete_contained_entities
bereits in WP 2.7 verdrahtet.
Tests: crates/dcps/src/participant.rs::tests:
lookup_topicdescription_returns_local_topics,
lookup_topicdescription_none_for_unknown,
find_topic_returns_immediately_for_local,
contains_entity_returns_true_for_self_handle,
contains_entity_returns_true_for_local_topic,
contains_entity_returns_true_for_local_publisher,
contains_entity_returns_true_for_local_subscriber,
contains_entity_returns_false_for_unknown_handle,
contains_entity_returns_false_for_topic_after_delete.
Rekursiver Pfad: contains_entity erkennt zusaetzlich
DataWriter/DataReader-Handles via Pub/Sub-Children. PublisherInner +
SubscriberInner tracken DW/DR-Handles (datawriters /
datareaders-Mutex); per Weak-Backref propagieren sie auch in
ParticipantInner.datawriters / datareaders fuer schnellen
top-down Lookup. Pro Pub/Sub gibt es ausserdem contains_writer /
contains_reader als gezielten Sub-Lookup.
Tests (zusaetzlich zu den 6 oben):
contains_entity_recursive_finds_local_datawriter,
contains_entity_recursive_finds_local_datareader,
contains_entity_recursive_does_not_find_foreign_datawriter.
Status: done
2.2.2.2.2 DomainParticipantFactory-Class (Singleton)
Spec: §2.2.2.2.2, S. 31-33.
Repo: crates/dcps/src/factory.rs::DomainParticipantFactory mit:
- instance() -> &'static Self (Spec §2.2.2.2.2.1 get_instance,
Singleton via OnceLock).
- create_participant / create_participant_with_config /
create_participant_offline (Spec §2.2.2.2.2.2; alle Varianten
trackt den Participant in der internen Registry).
- lookup_participant(domain_id) -> Option<DomainParticipant>
(Spec §2.2.2.2.2.4).
- delete_participant(&p) -> Result<()> (Spec §2.2.2.2.2.3 — entfernt
aus Registry + ruft delete_contained_entities; liefert
PreconditionNotMet wenn nicht registriert).
- set_default_participant_qos / get_default_participant_qos
(Spec §2.2.2.2.2.5).
- set_qos / get_qos mit DomainParticipantFactoryQos-Struct
(Spec §2.2.2.2.2.6, Default autoenable_created_entities = true).
Tests: crates/dcps/src/factory.rs::tests:
factory_is_singleton,
factory_creates_participant_with_correct_domain_id,
lookup_participant_finds_registered_offline_participant,
lookup_participant_returns_none_for_unknown_domain,
delete_participant_removes_from_registry,
delete_participant_unknown_returns_precondition_not_met,
default_participant_qos_roundtrips,
factory_qos_default_is_autoenable_true,
factory_set_get_qos_roundtrip.
Status: done
2.2.2.2.3 DomainParticipantListener-Interface
Spec: §2.2.2.2.3, S. 33-34.
Repo: listener.rs::DomainParticipantListener-Trait + 14-Method-
Default.
Tests: listener_*-Tests.
Status: done
§2.2.2.3 Topic-Definition Module
2.2.2.3.1 TopicDescription-Class (Abstract Base)
Spec: §2.2.2.3.1, S. 35 — abstract base for Topic,
ContentFilteredTopic, MultiTopic. API: get_type_name,
get_name, get_participant.
Repo: crates/dcps/src/topic.rs::TopicDescription-Trait
(object-safe, &dyn TopicDescription ist der Konsumtyp);
implementiert von Topic<T>, TopicDescriptionHandle,
ContentFilteredTopic<T>.
Tests: crates/dcps/src/topic.rs::tests:
topic_implements_topic_description,
topic_description_handle_is_cloneable,
topic_description_trait_is_object_safe,
topic_description_create_topic_rejects_empty_name
(BadParameter-Negativ),
topic_description_get_participant_returns_owning_participant.
Status: done
2.2.2.3.2 Topic-Class
Spec: §2.2.2.3.2, S. 36-37.
Repo: topic.rs::Topic<T>.
Tests: Topic-Tests.
Status: done
2.2.2.3.3 ContentFilteredTopic-Class
Spec: §2.2.2.3.3, S. 37-38 — Filter-Expression + Filter-Parameters + get_related_topic. TopicDescription-Implementierung mit Type-Name vom Related-Topic.
Repo: crates/dcps/src/topic.rs::ContentFilteredTopic<T> mit
new (Konstruktor mit Expression-Parsing + Parameter-Index-Validation),
get_filter_expression, get_filter_parameters,
set_filter_parameters (mit BadParameter-Validation),
get_related_topic, evaluate(row) ueber zerodds_sql_filter-Engine,
plus TopicDescription-Trait-Impl. DomainParticipant
create_contentfilteredtopic-Factory.
Tests: crates/dcps/src/topic.rs::tests:
cft_compiles_and_evaluates_filter,
cft_with_params_can_be_updated,
cft_get_related_topic,
cft_invalid_expression_rejected (BadParameter-Negativ),
cft_param_index_out_of_range_rejected (BadParameter-Negativ),
cft_set_filter_parameters_validates_count,
cft_filter_with_string_param,
cft_filter_with_or_and_combination,
cft_unknown_field_returns_bad_parameter (BadParameter-Negativ),
cft_clone_shares_params.
Status: done
2.2.2.3.4 MultiTopic-Class [optional, Spec §2.2.2.3.4]
Spec: §2.2.2.3.4, S. 38-39 — kombiniert mehrere Topics ueber
SQL-Subscription-Expression. Spec-explicit optional.
Repo: crates/dcps/src/topic.rs::MultiTopic<T> mit
subscription_expression (Read-only), expression_parameters
(get/set per RwLock), related_topic_names: Vec<String>,
get_related_topic_names. TopicDescription-Trait-Impl mit
User-definiertem type_name.
DomainParticipant-Factory: create_multitopic (Spec §2.2.2.2.1.15) +
delete_multitopic (Spec §2.2.2.2.1.16) mit Participant-Match-
Validation und vollem BadParameter-Negativ-Pfad.
Tests: crates/dcps/src/topic.rs::tests:
multitopic_compiles_and_implements_topic_description,
multitopic_set_expression_parameters_roundtrip,
multitopic_rejects_empty_name (Negativ),
multitopic_rejects_empty_type_name (Negativ),
multitopic_rejects_empty_related_topics (Negativ),
multitopic_rejects_invalid_expression (Negativ),
multitopic_rejects_param_index_out_of_range (Negativ),
multitopic_set_params_validates_index_range (Negativ),
multitopic_clone_shares_params,
delete_multitopic_rejects_foreign_participant (Negativ).
Cross-Topic-Sample-Routing: Hash-Join-Operator
crates/dcps/src/topic.rs::hash_join_two mit O(n+m) Build/Probe-
Phase + Cartesian-Match fuer Duplikat-Keys. JoinedRow<'a>
dispatched dotted-Pfade <topic>.<field> auf die richtige
Topic-Quelle. MultiTopic::evaluate_joined(row) wertet die
subscription_expression gegen die kombinierten Rows aus.
Tests: joined_row_dispatches_dotted_paths_by_topic_prefix,
joined_row_undotted_falls_back_to_first_match,
multitopic_evaluate_joined_uses_dotted_paths,
hash_join_two_combines_matching_rows,
hash_join_two_returns_empty_when_no_keys_match (Negativ),
hash_join_two_emits_cartesian_for_duplicate_keys,
hash_join_two_predicate_can_filter_pairs.
Status: done
2.2.2.3.5 TopicListener-Interface (on_inconsistent_topic)
Spec: §2.2.2.3.5, S. 40.
Repo: listener.rs::TopicListener-Trait.
Tests: —
Status: done
2.2.2.3.6 TypeSupport-Interface
Spec: §2.2.2.3.6, S. 40-41.
Repo: dds_type.rs::DdsType-Trait.
Tests: —
Status: done
2.2.2.3.7 Derived Classes pro Application Class (FooDataReader/Writer/TypeSupport)
Spec: §2.2.2.3.7, S. 41.
Repo: Generic DataReader<T>/DataWriter<T> (Rust-idiomatisch
keine Foo*-Klassen).
Tests: Generic-Tests.
Status: done
§2.2.2.4 Publication Module
2.2.2.4.1 Publisher-Class
Spec: §2.2.2.4.1, S. 43-46 — Operations: create_datawriter, delete_datawriter, set/get_default_datawriter_qos, copy_from_topic_qos, suspend/resume_publications, begin/end_coherent_changes, wait_for_acknowledgments, get_participant.
Repo: crates/dcps/src/publisher.rs::Publisher mit:
- create_datawriter / set_listener / assert_liveliness /
wait_for_acknowledgments (Bestand).
- suspend_publications / resume_publications / is_suspended
via PublisherInner.suspended: AtomicBool (Spec §2.2.2.4.1.10/11).
- copy_from_topic_qos(&mut DataWriterQos, &TopicQos) Static-Helper
(Spec §2.2.2.4.1.13) — kopiert die in der aktuellen TopicQos-Struct
(durability, reliability) sichtbaren shared Policies.
- Coherent-Changes via crates/dcps/src/coherent_set.rs::CoherentScope.
Tests: crates/dcps/src/publisher.rs::tests:
publisher_creates_datawriter_for_matching_type,
suspend_publications_sets_flag,
resume_publications_clears_flag,
suspend_publications_is_idempotent,
resume_without_suspend_is_noop,
copy_from_topic_qos_copies_durability_and_reliability,
copy_from_topic_qos_does_not_touch_writer_only_policies,
plus Coherent-Set-Tests in coherent_set.rs::tests.
Status: done
2.2.2.4.2 DataWriter-Class
Spec: §2.2.2.4.2, S. 47-55 — write/dispose/register/lookup/ assert_liveliness/get_*-Status/get_matched_subscriptions.
Repo: publisher.rs::DataWriter<T> + instance_tracker.rs +
wlp.rs.
Tests: datawriter_*-Tests.
Status: done — register_instance/unregister/dispose/write/ write_w_timestamp/lookup_instance/get_key_value/assert_liveliness live; get_*_status-Polling-API teilweise.
2.2.2.4.3 PublisherListener-Interface
Spec: §2.2.2.4.3, S. 56.
Repo: listener.rs::PublisherListener.
Tests: —
Status: done
2.2.2.4.4 DataWriterListener-Interface (4 Callbacks)
Spec: §2.2.2.4.4, S. 57.
Repo: listener.rs::DataWriterListener.
Tests: —
Status: done
2.2.2.4.5 Concurrency Behavior
Spec: §2.2.2.4.5, S. 57.
Repo: Rust-thread-safe via Arc
Tests: —
Status: done
§2.2.2.5 Subscription Module
2.2.2.5.1 SampleInfo-Statemachine (Sample/View/Instance-State)
Spec: §2.2.2.5.1.1-9, S. 59-65 — Interpretation der SampleInfo- Felder; drei orthogonale State-Dimensionen mit Mask-Filter.
Repo: crates/dcps/src/sample_info.rs mit:
- SampleStateKind (READ / NOT_READ) + sample_state_mask::*-Konstanten.
- ViewStateKind (NEW / NOT_NEW) + view_state_mask::*.
- InstanceStateKind (ALIVE / NOT_ALIVE_DISPOSED / NOT_ALIVE_NO_WRITERS)
+ instance_state_mask::* + is_alive / is_not_alive-Praedikate.
- SampleInfo::matches_states(sample_mask, view_mask, instance_mask)
fuer den read_w_condition-Filter.
- SampleInfo::new_alive Konstruktor fuer Live-Pfad.
Tests: crates/dcps/src/sample_info.rs::tests:
defaults_are_alive_new_not_read, instance_state_predicates,
sample_state_predicate, matches_states_filter,
sample_info_three_state_dimensions_independent (positive +
negative Filter pro Dimension), sample_info_dispose_marker_has_invalid_data,
enum_default_impls.
Status: done
2.2.2.5.2 Subscriber-Class
Spec: §2.2.2.5.2, S. 65-69 — Operations: create_datareader, get_datareaders, notify_datareaders, begin/end_access, etc.
Repo: crates/dcps/src/subscriber.rs::Subscriber mit:
- create_datareader / set_listener / get_listener (Bestand).
- begin_access (Spec §2.2.2.5.2.8, idempotent nestbar) +
end_access (Spec §2.2.2.5.2.9, liefert PreconditionNotMet bei
Underflow) + is_access_open via SubscriberInner.access_scope: Arc<GroupAccessScope> (counter-basiert in
crates/dcps/src/coherent_set.rs::GroupAccessScope).
Tests: crates/dcps/src/subscriber.rs::tests:
subscriber_begin_end_access_roundtrip,
subscriber_end_access_without_begin_returns_precondition_not_met,
(Negativ),
subscriber_begin_access_is_nestable,
subscriber_too_many_ends_after_balanced_returns_error (Negativ),
plus Bestand subscriber-create_datareader und listener-Tests.
Status: done
2.2.2.5.3 DataReader-Class
Spec: §2.2.2.5.3, S. 70-85 — read/take/read_with_info/ read_filtered/read_instance/take_instance/read_next_instance/ take_next_instance/get_*-Status/wait_for_historical_data etc.
Repo: subscriber.rs::DataReader<T>.
Tests: datareader_*-Tests.
Status: done — alle Read/Take-Varianten done; get_*_status Polling teilweise; wait_for_historical_data offen.
2.2.2.5.4 DataSample-Class (Data + SampleInfo)
Spec: §2.2.2.5.4, S. 86.
Repo: subscriber.rs::Sample<T>.
Tests: —
Status: done
2.2.2.5.5 SampleInfo-Class (komplett)
Spec: §2.2.2.5.5, S. 86-87 — sample_state/view_state/ instance_state/disposed_generation_count/no_writers_generation_count/ sample_rank/generation_rank/absolute_generation_rank/source_timestamp/ instance_handle/publication_handle/valid_data (12 Felder).
Repo: crates/dcps/src/sample_info.rs::SampleInfo mit allen 12
Spec-Feldern und passenden Default-Werten. Reader-side Update der
Generation-Counter erfolgt in den DataReader-Read-Pfaden.
Tests: crates/dcps/src/sample_info.rs::tests:
sample_info_all_spec_fields_accessible (alle 12 Felder lesbar +
setzbar mit konkreten Werten), sample_info_dispose_marker_has_invalid_data
(Negativ: Dispose-Sample hat valid_data=false),
sample_info_generation_rank_starts_zero,
new_alive_constructor_sets_handles_and_timestamp,
plus Bestand defaults_are_alive_new_not_read.
Status: done
2.2.2.5.6 SubscriberListener-Interface
Spec: §2.2.2.5.6, S. 87.
Repo: listener.rs::SubscriberListener.
Tests: —
Status: done
2.2.2.5.7 DataReaderListener-Interface (7 Callbacks)
Spec: §2.2.2.5.7, S. 88.
Repo: listener.rs::DataReaderListener.
Tests: —
Status: done
2.2.2.5.8 ReadCondition-Class
Spec: §2.2.2.5.8, S. 88-89 — Sample/View/InstanceState-Mask- Filter; Trigger wenn der Reader Samples mit diesen Masks enthaelt.
Repo: crates/dcps/src/condition.rs::ReadCondition mit Mask-
Gettern (get_sample_state_mask, get_view_state_mask,
get_instance_state_mask) + Closure-basiertem Trigger
(sm, vm, im) -> bool. Condition-Trait implementiert (object-safe).
Tests: crates/dcps/src/condition.rs::tests:
read_condition_returns_trigger_from_closure,
read_condition_trigger_false_when_closure_says_false (Negativ),
read_condition_implements_condition_trait_object_safe,
read_condition_attaches_to_waitset (WaitSet-Integration).
Status: done
2.2.2.5.9 QueryCondition-Class
Spec: §2.2.2.5.9, S. 89 — extends ReadCondition mit SQL-Filter- Expression + mutable Filter-Parameters.
Repo: crates/dcps/src/condition.rs::QueryCondition mit
query_expression-Feld (read-only) + query_parameters-Mutex
(get/set), base() Accessor auf die Sub-ReadCondition. SQL-Filter
wird einmalig im Konstruktor via zerodds_sql_filter::parse zu
Expr geparst (BadParameter bei Syntaxfehler). evaluate(row) /
evaluate_with_values(row, params) werten den Filter pro Sample aus.
Per-Sample-Evaluation (Spec §2.2.2.5.9.6) ist live in
crates/dcps/src/subscriber.rs::DataReader::read_w_condition und
take_w_condition; DdsTypeRow<'a, T> (in dds_type.rs) wraps
T: DdsType zu zerodds_sql_filter::RowAccess via die optionale
DdsType::field_value(path)-Methode.
Tests: crates/dcps/src/condition.rs::tests:
query_condition_inherits_trigger_from_base,
query_condition_set_query_parameters_roundtrip,
query_condition_trigger_inherits_false_from_base (Negativ),
query_condition_base_returns_correct_read_condition,
query_condition_rejects_invalid_sql (Negativ),
query_condition_evaluate_filters_per_sample,
query_condition_evaluate_with_typed_values_int_param,
query_condition_evaluate_uses_string_params_by_default.
crates/dcps/tests/query_condition.rs (E2E):
read_w_condition_filters_per_sample,
take_w_condition_consumes_only_matching_samples,
read_w_condition_with_string_parameter,
read_w_condition_preserves_cache_state,
take_w_condition_empty_when_no_match,
read_w_condition_unknown_field_drops_sample.
Status: done
§2.2.3 Supported QoS — 22 Policies
2.2.3.1 USER_DATA QosPolicy
Spec: §2.2.3.1, S. 101 — sequence
Repo: crates/qos/src/policies/user_data.rs.
Tests: USER_DATA-Tests.
Status: done
2.2.3.2 TOPIC_DATA QosPolicy
Spec: §2.2.3.2, S. 102.
Repo: crates/qos/src/policies/topic_data.rs.
Tests: —
Status: done
2.2.3.3 GROUP_DATA QosPolicy
Spec: §2.2.3.3, S. 102.
Repo: crates/qos/src/policies/group_data.rs.
Tests: —
Status: done
2.2.3.4 DURABILITY QosPolicy (VOLATILE/TRANSIENT_LOCAL/TRANSIENT/PERSISTENT)
Spec: §2.2.3.4, S. 102-103.
Repo: crates/qos/src/policies/durability.rs::DurabilityQosPolicy
mit allen 4 DurabilityKind-Werten + Spec-konformer Ordering-Relation
(VOLATILE < TRANSIENT_LOCAL < TRANSIENT < PERSISTENT) +
Wire-Encode/Decode (u32). Volatile + TransientLocal sind im
Writer-side Sample-Cache implementiert; Transient + Persistent
greifen auf den Durability-Service §2.2.3.5 zu
(crates/dcps/src/durability_service.rs).
Tests: crates/qos/src/policies/durability.rs::tests:
default_is_volatile, ordering_matches_spec, try_from_u32_is_strict,
from_u32_is_forward_compat, encode_decode_roundtrip (alle 4 Kinds),
unknown_kind_decode_rejected (Negativ),
compatibility_offered_ge_requested (offered >= requested + Negativ).
Status: done — Wire-Form + Compatibility-Ordering vollstaendig; Transient/Persistent-Storage delegiert an §2.2.3.5 Durability-Service.
2.2.3.5 DURABILITY_SERVICE QosPolicy
Spec: §2.2.3.5, S. 103 — service_cleanup_delay + history_kind + history_depth + max_samples + max_instances + max_samples_per_instance.
Repo: crates/qos/src/policies/durability_service.rs::DurabilityServiceQosPolicy
mit allen 6 Spec-Feldern + Wire-Encode/Decode. Storage-Service-Backends
in crates/dcps/src/durability_service.rs: Trait DurabilityBackend
(store / replay_for_topic / unregister_instance / cleanup) +
zwei Implementationen InMemoryDurabilityBackend (TRANSIENT) und
OnDiskDurabilityBackend (PERSISTENT, Verzeichnis-Hierarchie
<root>/<topic>/<hex(instance)>/<seq>.bin mit .unregistered-Marker).
Beide Backends respektieren history_kind (KeepLast-Cap durch FIFO,
KeepAll-Cap durch OutOfResources), max_samples, max_instances,
max_samples_per_instance und service_cleanup_delay (fraction als
2^-32 s korrekt nach Nanos konvertiert). make_backend(kind, qos, root)-
Factory waehlt automatisch.
Tests: crates/qos/src/policies/durability_service.rs::tests
(2 Tests: roundtrip + default). Storage-Backend-Tests in
crates/dcps/src/durability_service.rs::tests (19 Tests, alle 4
Caps + KeepLast/KeepAll + cleanup-after-delay + on-disk-survives-drop):
in_memory_store_and_replay_returns_sorted_samples,
in_memory_keeplast_caps_history_at_depth,
in_memory_keepall_max_samples_per_instance_returns_oor (Negativ),
in_memory_max_samples_globally_returns_oor (Negativ),
in_memory_max_instances_returns_oor (Negativ),
in_memory_unregister_then_cleanup_removes_after_delay,
in_memory_replay_filters_by_topic,
in_memory_unknown_topic_returns_empty (Negativ),
make_backend_rejects_volatile_and_transient_local (Negativ),
make_backend_persistent_requires_root (Negativ),
make_backend_transient_returns_in_memory,
on_disk_store_and_replay_roundtrip,
on_disk_keeplast_replaces_old_files,
on_disk_persistent_survives_backend_drop,
on_disk_unregister_and_cleanup_removes_directory,
on_disk_max_samples_per_instance_returns_oor (Negativ),
hex16_roundtrip,
parse_hex16_rejects_wrong_length_and_invalid_chars (Negativ),
sanitize_topic_replaces_path_chars.
Status: done
2.2.3.6 PRESENTATION QosPolicy (access_scope INSTANCE/TOPIC/GROUP + coherent + ordered)
Spec: §2.2.3.6, S. 103-104.
Repo: crates/qos/src/policies/presentation.rs::PresentationQosPolicy
mit access_scope (INSTANCE/TOPIC/GROUP) + coherent_access +
ordered_access Bool-Flags. Wire-Encode/Decode + Compatibility-Check.
INSTANCE/TOPIC live im Reader-Sort-Pfad; GROUP-coherent via
crates/dcps/src/coherent_set.rs::GroupAccessScope.snapshot_generation
— jedes begin_access (von 0→1) inkrementiert die Generation, alle
DR im Subscriber sehen waehrend des begin/end-Fensters denselben
atomic Cut. Multi-Reader-Coherent-Set ueber Arc-Clone der Scope.
Tests: crates/qos/src/policies/presentation.rs::tests
(6 Tests: roundtrip + access_scope + coherent + ordered Kombinationen).
Status: done
2.2.3.7 DEADLINE QosPolicy
Spec: §2.2.3.7, S. 104.
Repo: crates/qos/src/policies/deadline.rs.
Tests: Deadline-Tests inkl. cross-test-domain-pollution-Fix.
Status: done
2.2.3.8 LATENCY_BUDGET QosPolicy
Spec: §2.2.3.8, S. 104 — Hint an die Service ueber maximal akzeptierbare Latenz; pro Spec ist das eine Best-Effort-Hint, kein hartes Constraint.
Repo: crates/qos/src/policies/latency_budget.rs::LatencyBudgetQosPolicy
mit duration: Duration_t + Wire-Encode/Decode (8 byte).
Tests: crates/qos/src/policies/latency_budget.rs::tests
(2 Tests: roundtrip + default INFINITE).
Status: done
2.2.3.9 OWNERSHIP QosPolicy (SHARED/EXCLUSIVE)
Spec: §2.2.3.9, S. 105.
Repo: crates/qos/src/policies/ownership.rs::OwnershipQosPolicy
mit OwnershipKind::Shared/Exclusive + Wire-Encode/Decode +
Compatibility-Check (Spec §2.2.3 Tab. — kind muss exact match auf
Reader/Writer-Pair).
Tests: crates/qos/src/policies/ownership.rs::tests (7 Tests:
roundtrip + default Shared + Compat-Check + invalid-kind-Decode-Reject).
Strength-Selection: EXCLUSIVE Reader-side Strength-Selection
implementiert in crates/dcps/src/instance_tracker.rs:: should_accept_sample_under_exclusive_ownership (Higher-Strength
gewinnt; bei Tie GUID-Tiebreaker; First-Writer wird Owner ohne
laufenden Vergleich). 8 Tests: exclusive_first_writer_wins,
exclusive_higher_strength_wins, exclusive_lower_strength_rejected,
exclusive_tie_break_by_higher_guid, exclusive_tie_break_lower_guid_rejected,
exclusive_same_writer_always_accepted, clear_owner_for_writer_resets_owner,
failover_after_clear_accepts_weaker_writer.
Status: done
2.2.3.10 OWNERSHIP_STRENGTH QosPolicy
Spec: §2.2.3.10, S. 106.
Repo: crates/qos/src/policies/ownership_strength.rs::OwnershipStrengthQosPolicy
mit value: i32 + Wire-Encode/Decode (4 byte).
Strength-Selection-Logik in crates/dcps/src/instance_tracker.rs:: should_accept_sample_under_exclusive_ownership (i32-Strength + GUID-Tiebreaker).
Tests: crates/qos/src/policies/ownership_strength.rs::tests
(3 Tests: roundtrip + default 0 + negative-strength-roundtrip).
Strength-Selection-Tests in instance_tracker::tests::exclusive_* (6 Tests).
Status: done
2.2.3.11 LIVELINESS QosPolicy (AUTOMATIC/MANUAL_BY_PARTICIPANT/MANUAL_BY_TOPIC)
Spec: §2.2.3.11, S. 106-107.
Repo: crates/qos/src/policies/liveliness.rs::LivelinessQosPolicy
mit LivelinessKind (Automatic/ManualByParticipant/ManualByTopic) +
lease_duration: Duration_t + Wire-Encode/Decode.
crates/dcps/src/wlp.rs mit Heartbeat-Pfad fuer AUTOMATIC und
Publisher::assert_liveliness() fuer MANUAL_BY_PARTICIPANT/TOPIC.
Tests: crates/qos/src/policies/liveliness.rs::tests (9 Tests:
roundtrip aller drei Kinds + default + invalid-kind-Decode +
Compatibility-Matrix Spec-konform).
Status: done
2.2.3.12 TIME_BASED_FILTER QosPolicy
Spec: §2.2.3.12, S. 107 — minimum_separation: Reader filtert Samples derselben Instanz aus, wenn ihr source_timestamp innerhalb von minimum_separation zum letzten gelieferten Sample liegt.
Repo: crates/qos/src/policies/time_based_filter.rs::TimeBasedFilterQosPolicy
mit minimum_separation: Duration_t + Wire-Encode/Decode.
Tests: crates/qos/src/policies/time_based_filter.rs::tests
(2 Tests: roundtrip + default 0 = “kein Filter”).
Reader-side Drop: crates/dcps/src/instance_tracker.rs mit
InstanceState.last_delivered_ts: Option<Time> +
should_deliver_under_time_based_filter(keyhash, sample_ts, min_separation_nanos) +
record_delivery(keyhash, sample_ts). Read-Pfad pre-Delivery prueft
und droppt bei zu geringer Separation. Tests:
time_based_filter_first_sample_passes,
time_based_filter_too_close_drops (Negativ),
time_based_filter_far_enough_passes,
time_based_filter_zero_separation_always_passes,
time_based_filter_per_instance_isolation,
time_based_filter_unknown_instance_passes.
Status: done
2.2.3.13 PARTITION QosPolicy
Spec: §2.2.3.13, S. 107-108 — sequence<string> name +
Wildcard-Matching (“any-string” via *, “any-char” via ?,
Character-Sets via [abc], etc.); leerer Vector matched leeren
Vector + Default-Partition "".
Repo: crates/qos/src/policies/partition.rs::PartitionQosPolicy
mit Wire-Encode/Decode + partition_match Funktion mit fnmatch-
Engine (POSIX shell-glob, inkl. Character-Class, Negation).
Tests: crates/qos/src/policies/partition.rs::tests
(19 Tests: roundtrip + Set-Match + Wildcard * + Wildcard ? +
Character-Set + Negation + Default-Partition + Empty-Set Cases).
Status: done
2.2.3.14 RELIABILITY QosPolicy (BEST_EFFORT/RELIABLE)
Spec: §2.2.3.14, S. 108.
Repo: crates/qos/src/policies/reliability.rs + reliable Pfad
in crates/rtps/.
Tests: Reliability-Tests.
Status: done
2.2.3.15 TRANSPORT_PRIORITY QosPolicy
Spec: §2.2.3.15, S. 108 — Hint-only.
Repo: crates/qos/src/policies/transport_priority.rs::TransportPriorityQosPolicy
mit value: i32 + Wire-Encode/Decode.
Tests: crates/qos/src/policies/transport_priority.rs::tests
(2 Tests: roundtrip + default 0).
Status: done
2.2.3.16 LIFESPAN QosPolicy
Spec: §2.2.3.16, S. 108 — Sample-Lifetime; Reader filtert Samples deren source_timestamp + duration < now.
Repo: crates/qos/src/policies/lifespan.rs::LifespanQosPolicy
mit duration: Duration_t + Wire-Encode/Decode. Reader-side Sample-
Expiry-Filter via Time::saturating_add.
Tests: crates/qos/src/policies/lifespan.rs::tests
(2 Tests: roundtrip + default INFINITE).
Status: done
2.2.3.17 DESTINATION_ORDER QosPolicy (BY_RECEPTION_TIMESTAMP/BY_SOURCE_TIMESTAMP)
Spec: §2.2.3.17, S. 109.
Repo: crates/qos/src/policies/destination_order.rs::DestinationOrderQosPolicy
mit DestinationOrderKind::ByReceptionTimestamp (Default) /
BySourceTimestamp + Wire-Encode/Decode + Compatibility-Check
(Spec: offered MUST match requested OR offered=ByReception is more
permissive). Reader-side Reorder-Buffer via SampleInfo.source_timestamp.
Tests: crates/qos/src/policies/destination_order.rs::tests
(7 Tests: roundtrip + default + Compat-Matrix + invalid-kind-Decode).
Status: done
2.2.3.18 HISTORY QosPolicy (KEEP_LAST/KEEP_ALL + depth)
Spec: §2.2.3.18, S. 109.
Repo: crates/qos/src/policies/history.rs.
Tests: History-Tests.
Status: done
2.2.3.19 RESOURCE_LIMITS QosPolicy (max_samples/max_instances/max_samples_per_instance)
Spec: §2.2.3.19, S. 109-110.
Repo: crates/qos/src/policies/resource_limits.rs::ResourceLimitsQosPolicy
mit max_samples / max_instances / max_samples_per_instance +
Wire-Encode/Decode + Validity-Checks (kein Cap kleiner als 1).
Cap-Enforcement im Writer-Side Sample-Cache.
Tests: crates/qos/src/policies/resource_limits.rs::tests
(5 Tests: roundtrip + default LENGTH_UNLIMITED + invalid-cap-reject
+ encoded-bytes).
Reliable-Block (§2.2.3.19): DataWriter::write() blockt am
drain_signal: Condvar wenn queue.len() >= max_samples und
Reliability=RELIABLE und max_blocking_time > 0; bei BestEffort oder
max_blocking_time = 0 liefert es OutOfResources direkt;
__drain_pending notifies wartende Writer-Threads. Tests:
write_blocks_until_drain_when_reliable_max_samples_reached,
write_returns_timeout_when_reliable_drain_too_slow (Negativ),
write_returns_oor_when_best_effort_queue_full (Negativ),
write_does_not_block_when_max_samples_unlimited.
Status: done
2.2.3.20 ENTITY_FACTORY QosPolicy (autoenable_created_entities)
Spec: §2.2.3.20, S. 110.
Repo: crates/qos/src/policies/entity_factory.rs.
Tests: —
Status: done
2.2.3.21 WRITER_DATA_LIFECYCLE QosPolicy (autodispose_unregistered_instances)
Spec: §2.2.3.21, S. 110 — autodispose_unregistered_instances: bool (Default true) — wenn true und unregister_instance
gerufen wird, sendet Writer auch ein DISPOSE-Sample.
Repo: crates/qos/src/policies/data_lifecycle.rs::WriterDataLifecycleQosPolicy
mit autodispose_unregistered_instances: bool + Wire-Encode/Decode.
Tests: crates/qos/src/policies/data_lifecycle.rs::tests
(Teil der 4 data_lifecycle-Tests: roundtrip + default true +
autodispose-Verhalten).
Status: done
2.2.3.22 READER_DATA_LIFECYCLE QosPolicy
Spec: §2.2.3.22, S. 111 — autopurge_no_writer_samples_delay +
autopurge_disposed_samples_delay.
Repo: crates/qos/src/policies/data_lifecycle.rs::ReaderDataLifecycleQosPolicy
mit beiden Duration_t-Feldern + Wire-Encode/Decode.
Tests: crates/qos/src/policies/data_lifecycle.rs::tests
(Teil der 4 data_lifecycle-Tests).
Auto-Purge: crates/dcps/src/instance_tracker.rs mit
InstanceState.disposed_at + no_writers_at Timestamps, automatisch
gesetzt beim dispose/unregister; autopurge(now, disposed_delay_nanos, no_writer_delay_nanos) durchsucht alle
Instances und entfernt die, deren Marker laenger als der jeweilige
Delay her ist (u128::MAX = INFINITE = nie). Lazy-Purge wird vom
Read-Pfad gerufen. Tests:
autopurge_disposed_after_delay,
autopurge_disposed_before_delay_keeps_instance (Negativ),
autopurge_no_writers_after_delay,
autopurge_alive_instance_never_purged (Negativ),
autopurge_infinity_delay_never_purges.
Status: done
2.2.3.23 LIVELINESS+OWNERSHIP+REGISTRATION-Interaktion
Spec: §2.2.3.23, S. 111-113 — Cross-QoS-Interaktionen: bei LIVELINESS-Verlust eines Writers in OWNERSHIP=EXCLUSIVE soll der Reader auf den naechst-staerksten Writer umschalten; bei unregister_instance soll INSTANCE-Tracker den Lifecycle-Pfad durchziehen.
Repo: crates/dcps/src/wlp.rs (Liveliness-Heartbeat-Pfad) +
crates/dcps/src/instance_tracker.rs (Instance-Lifecycle +
Owner-Tracking) + crates/dcps/src/subscriber.rs::DataReader:: notify_writer_liveliness_lost(guid) und notify_participant_liveliness_lost(prefix)
als Hooks aus dem WLP-Pfad. Owner-Reset via
InstanceTracker::clear_owner_for_writer(guid) /
clear_owner_for_writer_prefix(prefix); nach dem Clear gewinnt der
naechste eintreffende Sample via Strength-Selection neu.
Tests: instance_tracker::tests:
clear_owner_for_writer_resets_owner,
failover_after_clear_accepts_weaker_writer,
clear_owner_for_writer_prefix_matches_first_12_bytes,
clear_owner_for_writer_prefix_multi_instance. E2E in
crates/dcps/tests/ownership_failover.rs:
notify_writer_liveliness_lost_clears_owner,
notify_participant_liveliness_lost_clears_all_writers_with_prefix,
notify_writer_liveliness_lost_for_unknown_writer_is_noop.
Status: done
§2.2.4 Listeners, Conditions, Wait-sets
2.2.4.1 Communication Status (13 Statuses)
Spec: §2.2.4.1, S. 114-118 — INCONSISTENT_TOPIC, OFFERED/REQUESTED_DEADLINE_MISSED, OFFERED/REQUESTED_INCOMPATIBLE_QOS, SAMPLE_LOST, SAMPLE_REJECTED, DATA_ON_READERS, DATA_AVAILABLE, LIVELINESS_LOST, LIVELINESS_CHANGED, PUBLICATION_MATCHED, SUBSCRIPTION_MATCHED.
Repo: crates/dcps/src/status.rs mit allen 13 Records.
Tests: status_records_*-Tests.
Status: done
2.2.4.2 Changes in Status (StatusChangedFlag-Bookkeeping)
Spec: §2.2.4.2, S. 118-121 — Plain vs. Read Status, Reset auf get/Listener.
Repo: crates/dcps/src/entity.rs::EntityState:
status_changes: AtomicU32 (Bitmask), set_status_bits(bits),
clear_status_changes(bits), status_changes() Read-Accessor.
crates/dcps/src/listener_dispatch.rs setzt Bits beim Status-Event
und cleart sie nach Listener-Dispatch (Spec §2.2.4.2.3).
Tests: crates/dcps/src/entity.rs::tests::status_bits_or_in_and_clear;
plus listener_dispatch::tests mit Bubble-Up Reset-Verhalten.
Status: done
2.2.4.3 Access through Listeners (Bubble-Up DR -> Sub -> DP)
Spec: §2.2.4.3, S. 121-124.
Repo: listener_dispatch.rs::ReaderListenerChain walken
local + parent + grandparent.
Tests: bubble_up_*-Tests.
Status: done
2.2.4.4 Conditions and Wait-Sets
Spec: §2.2.4.4, S. 124-127.
Repo: condition.rs mit WaitSet+Condition+GuardCondition.
Tests: WaitSet-Tests.
Status: done
2.2.4.5 Trigger State of ReadCondition
Spec: §2.2.4.5, S. 127.
Repo: crates/dcps/src/condition.rs::ReadCondition-Trigger via
Closure (siehe §2.2.2.5.8).
Tests: crates/dcps/src/condition.rs::tests:
read_condition_returns_trigger_from_closure,
read_condition_trigger_false_when_closure_says_false,
read_condition_attaches_to_waitset.
Status: done
2.2.4.6 Combination
Spec: §2.2.4.6, S. 127.
Repo: WaitSet akzeptiert beliebige Conditions.
Tests: —
Status: done
§2.2.5 Built-in Topics
2.2.5.1 DCPSParticipant + ParticipantBuiltinTopicData
Spec: §2.2.5, S. 128-130.
Repo: crates/dcps/src/builtin_topics.rs::ParticipantBuiltinTopicData
+ builtin_subscriber.rs::participant_reader.
Tests: Builtin-Topic-Tests.
Status: done
2.2.5.2 DCPSTopic + TopicBuiltinTopicData
Spec: §2.2.5.
Repo: builtin_topics.rs::TopicBuiltinTopicData +
builtin_subscriber.rs::topic_reader.
Tests: —
Status: done
2.2.5.3 DCPSPublication + PublicationBuiltinTopicData
Spec: §2.2.5.
Repo: builtin_topics.rs::PublicationBuiltinTopicData +
builtin_subscriber.rs::publication_reader.
Tests: —
Status: done
2.2.5.4 DCPSSubscription + SubscriptionBuiltinTopicData
Spec: §2.2.5.
Repo: builtin_topics.rs::SubscriptionBuiltinTopicData +
builtin_subscriber.rs::subscription_reader.
Tests: —
Status: done
2.2.5.5 BuiltinSubscriber (lookup_datareader auf DCPS*-Topics)
Spec: §2.2.5.
Repo: builtin_subscriber.rs::BuiltinSubscriber::lookup_datareader<T: BuiltinTopic>.
Tests: Lookup-Tests.
Status: done
2.2.5.6 Builtin-Sub+DR Default-QoS (DURABILITY=TRANSIENT_LOCAL/RELIABILITY=RELIABLE/HISTORY=KEEP_LAST/depth=1/…)
Spec: §2.2.5 — vollstaendiger Default-QoS-Block.
Repo: builtin_subscriber.rs::builtin_reader_qos().
Tests: —
Status: done
2.2.5.7 Built-in DR von gegebenem Participant zeigt nicht eigene-Participant-Entities
Spec: §2.2.5 — Built-in Subscriber liefert keine Entities des eigenen Participants (sonst self-loop).
Repo: crates/dcps/src/builtin_subscriber.rs mit participant_key-
Filter-Logik im Discovery-Hook (filtert SPDP/SEDP-Samples mit
gleicher Participant-Guid wie der lokale Participant).
Tests: crates/dcps/src/builtin_subscriber.rs::tests mit
participant_key-Filter-Pruefung.
Status: done
§2.2.6 Interaction Model
2.2.6.1 Publication View (register -> write* -> unregister/dispose)
Spec: §2.2.6.1, S. 132 — komplette Pub-View-Sequenz.
Repo: publisher.rs mit register_instance/unregister_instance/ dispose/write (+ w_timestamp Varianten).
Tests: publication_view_*-Tests.
Status: done
2.2.6.2.1 Subscription View Notification via Listener (async push)
Spec: §2.2.6.2.1, S. 133-134.
Repo: listener_dispatch.rs.
Tests: Listener-Tests.
Status: done
2.2.6.2.2 Subscription View Notification via Conditions+WaitSets (sync poll)
Spec: §2.2.6.2.2, S. 135.
Repo: condition.rs::WaitSet.
Tests: WaitSet-Tests.
Status: done
§2.3 OMG IDL Platform Specific Model
2.3.1-2 PIM->PSM Mapping Rules (CORBA-IDL)
Spec: §2.3.1-2, S. 137 — PIM->PSM-Konventionen.
Repo: Rust-PSM in crates/dcps/ ist Spec-konforme Alternative-
Form (XTypes 1.3 §7.2.2.4.8). CORBA-IDL-Annex-A.1-PSM-Emission
in crates/idl-cpp/src/corba_traits.rs,
crates/idl-csharp/src/corba_traits.rs,
crates/idl-java/src/corba_traits.rs als opt-in Codegen-Pfad
(siehe idl4-cpp-1.0.md / idl4-csharp-1.0.md / idl4-java-1.0.md
Annex A.1).
Tests: Cross-Ref Rust-PSM-Tests im dcps-Crate +
{idl-cpp,idl-csharp,idl-java}::corba_traits::tests::*.
Status: done — Rust-PSM (Alternative-Form) + CORBA-IDL-Annex-A.1- PSM-Emission live.
2.3.3 DCPS PSM IDL — komplette IDL-File zerodds_dcps.idl
Spec: §2.3.3, S. 138-162.
Repo: crates/idl/ — IDL-4.2-Parser (K1 voll abgeschlossen,
1026 Tests). Code-Gen ueber crates/idl-cpp/, crates/idl-java/,
crates/idl-csharp/. Spec-Coverage des IDL 4.2 in
docs/spec-coverage/idl-4.2.md (530 done / 0 partial).
Tests: Workspace-weit ueber zerodds-idl-Crate;
docs/spec-coverage/idl-4.2.md ist die normative Coverage-Doku.
Status: done — IDL-Parser-Layer vollstaendig spec-konform; PSM- spezifische Code-Gen-Stage ist je PSM-Spec separat normativ.
2.3.3 IDL-Constants: typedef long DomainId_t / typedef long ReturnCode_t / etc.
Spec: §2.3.3.
Repo: Rust-Native-Typen (DomainId = u32, Result<T, DdsError>)
+ IDL-Constants in crates/dcps/src/psm_constants.rs::status::*
fuer alle 13 Status-Bits + crates/dcps/src/error.rs::return_code::*
fuer alle 13 ReturnCode_t-Werte.
Tests: crates/dcps/src/error.rs::tests::rc_constants_have_spec_values
verifiziert alle 13 Spec-Konstanten Wert-genau.
Status: done
Audit-Status
100 done / 0 partial / 0 open / 2 n/a (informative) / 0 n/a (rejected).
Test-Lauf: cargo test -p zerodds-dcps — 407 lib + 150 integration
(23 Integration-Test-Bins) = 557 Tests grün, 0 failed.
Offene Punkte (§2.3.1-2 PIM→PSM CORBA-IDL-Annex-A.1-Emission als
zusätzlicher Codegen-Backend): siehe zerodds-dcps-1.4.open.md. DLRL
voll abgedeckt durch crates/dlrl/ (siehe dlrl-1.2.md).