zerodds-c-api v1.0 — Spec Coverage
Audit of the vendor spec docs/specs/zerodds-c-api-1.0.md against the code in
crates/zerodds-c-api/. The generated C header include/zerodds.h is the
normative contract document; every requirement is checked item by item with
spec reference, repo path, test path and status.
Source: docs/specs/zerodds-c-api-1.0.md (ZeroDDS vendor spec).
§1 Architecture
§1.1 Opaque handle hierarchy + lifetime
Spec: §1 — “Every entity is an opaque handle (zerodds_*). Lifetime via a
*_create/*_destroy pair.” Hierarchy DPF → DP → {Topic, Publisher,
Subscriber} → {DataWriter, DataReader}.
Repo: crates/zerodds-c-api/src/entities.rs (opaque structs
ZeroDdsDomainParticipant/ZeroDdsPublisher/ZeroDdsSubscriber/
ZeroDdsTopic/ZeroDdsDataWriter/ZeroDdsDataReader); factory root in
factory_ffi.rs. Each type has a *_create/*_delete pair.
Tests: factory_ffi::tests::create_and_delete_participant_clean_lifecycle,
participant_ffi::tests::delete_contained_entities_drops_all.
Status: done
§1.2 Stable wire form (#[repr(C)])
Spec: §1 / §3 — “Stable wire form: ABI-stable structs for QoS, SampleInfo, Status; opaque handles for entity lifecycle.”
Repo: all QoS, SampleInfo and status structs are #[repr(C)] in
qos_ffi.rs, subscriber_ffi.rs, publisher_ffi.rs, topic_ffi.rs.
Tests: qos_ffi::tests::duration_roundtrip,
qos_ffi::tests::dw_qos_default_from_null.
Status: done
§2 Entity hierarchy
§2.1 DomainParticipantFactory
Spec: §2.1 — get_instance, create_participant, delete_participant,
lookup_participant, get/set_default_participant_qos, get/set_qos.
Repo: crates/zerodds-c-api/src/factory_ffi.rs
(zerodds_dpf_get_instance + _create_participant/_delete_participant/
_lookup_participant/_get/_set_default_participant_qos/_get/_set_qos).
Tests: factory_ffi::tests::factory_singleton_returns_non_null_stable_ptr,
create_and_delete_participant_clean_lifecycle,
delete_with_null_handles_returns_bad_handle.
Status: done
§2.2 DomainParticipant
Spec: §2.2 — create/delete Topic+Publisher+Subscriber+ContentFilteredTopic,
find_topic, get_builtin_subscriber, ignore_*, get_domain_id,
assert_liveliness, get_current_time, get/set_qos, default_*_qos,
delete_contained_entities, get_discovered_*, contains_entity.
Repo: crates/zerodds-c-api/src/participant_ffi.rs +
extra_ffi.rs (QoS round-trip + contains_entity) + builtin_ffi.rs
(get_discovered_*). zerodds_dp_get_current_time writes the wall-clock time
via zerodds_dcps::get_current_time() into a zerodds_ZeroDdsTime out buffer.
Tests: participant_ffi::tests::create_topic_then_find_then_delete,
domain_id_roundtrip, get_current_time_returns_nonzero,
delete_contained_entities_drops_all;
extra_ffi::tests::dp_get_set_qos_roundtrip_default;
builtin_ffi::tests::discovered_topics_empty_initially.
Status: done
§2.3 Publisher
Spec: §2.3 — create/delete_datawriter, lookup_datawriter,
suspend/resume_publications, begin/end_coherent_changes,
wait_for_acknowledgments, get/set_qos, get/set_default_datawriter_qos,
copy_from_topic_qos, delete_contained_entities, get_participant.
Repo: crates/zerodds-c-api/src/publisher_ffi.rs + extra_ffi.rs
(pub_copy_from_topic_qos, QoS conversion).
Tests: publisher_ffi::tests::create_delete_datawriter_roundtrip,
lookup_datawriter_finds_existing, pub_suspend_resume_clean,
dw_get_topic_publisher_roundtrip.
Status: done
§2.4 Subscriber
Spec: §2.4 — create/delete_datareader, lookup_datareader,
begin/end_access, get_datareaders, notify_datareaders, get/set_qos,
get/set_default_datareader_qos, copy_from_topic_qos,
delete_contained_entities, get_participant.
Repo: crates/zerodds-c-api/src/subscriber_ffi.rs + extra_ffi.rs
(sub_copy_from_topic_qos, QoS conversion).
Tests: subscriber_ffi::tests::create_delete_datareader,
lookup_datareader_finds_existing.
Status: done
§2.5 Topic
Spec: §2.5 — get/set_qos, get_inconsistent_topic_status, get_name,
get_type_name, get_participant.
Repo: crates/zerodds-c-api/src/topic_ffi.rs. get/set_qos via the
topic_qos_to_c/from_c round-trip; get_inconsistent_topic_status returns
the counter from the DCPS topic (0 unless a type mismatch is active,
spec-conformant).
Tests: topic_ffi::tests::topic_get_name_and_type_roundtrip,
inconsistent_topic_status_default.
Status: done
§2.6 DataWriter
Spec: §2.6 — register/unregister_instance (+_w_timestamp),
get_key_value, lookup_instance, write (+_w_timestamp), dispose
(+_w_timestamp), wait_for_acknowledgments, assert_liveliness,
get/set_qos, 4 status getters, get_matched_subscriptions(_data),
get_topic, get_publisher, wait_for_matched, loan API
(loan_message/commit_loan/discard_loan).
Repo: crates/zerodds-c-api/src/publisher_ffi.rs (writer statuses,
get_matched_subscriptions from reader_proxies) + extra_ffi.rs
(instance ops, loan hooks) + shm_loan_ffi.rs (zero-copy backend). The loan
API has two transparently selected paths: heap box without activation; real
same-host zero-copy with the flatdata-loan feature + zerodds_dw_enable_shm_loan.
Both paths follow the byte-oriented FFI contract (spec non-goal “the C FFI is
byte-oriented”): the caller writes the serialized CDR payload into the loan
buffer — identical to zerodds_dw_write. loan_message returns a pointer into
a POSIX SHM slot for that, commit_loan finalizes the slot in place with no
staging copy (commit_in_place) and publishes it over RTPS
(write_user_sample_borrowed frames it with the encapsulation header → CDR
wire, interop-safe for cross-host/cross-vendor). A same-host reader reads the
same CDR body zero-copy from the segment. The loan state is keyed by
(runtime, EntityId), so it is also usable via the runtime FFI
(zerodds_writer_*) the ROS-2 RMW bridge uses.
Tests: extra_ffi::tests::dw_register_unregister_lookup_instance,
dw_get_key_value_buffer_too_small, dw_loan_message_then_commit_or_discard;
shm_loan_e2e::shm_loan_writer_to_reader_zero_copy,
shm_loan_runtime_path_writer_to_reader_zero_copy,
loan_without_shm_falls_back_to_heap.
Status: done
§2.7 DataReader
Spec: §2.7 — read/take (+_w_condition, _next_sample, _instance,
_next_instance), return_loan, get_key_value, lookup_instance,
create/delete_readcondition, create_querycondition, 6 status getters,
wait_for_historical_data, get_matched_publications(_data),
get_topicdescription, get_subscriber, get/set_qos, wait_for_matched.
Repo: crates/zerodds-c-api/src/subscriber_ffi.rs (reader statuses,
read non-destructive via a local read_cache,
read/take_instance/_next_instance via sample_array_filter_*,
_w_condition via condition state mask) + extra_ffi.rs
(get_matched_publications). wait_for_historical_data: Volatile returns Ok
immediately, TransientLocal via crates/dcps/src/durability_service.rs.
Tests: subscriber_ffi::tests::take_on_empty_returns_no_data,
return_loan_clears_array, statuses_default_ok,
cft_filter_active_passes_untyped_samples;
extra_ffi::tests::dr_get_matched_publications_empty.
Status: done
§3 QoS structures
§3.1 22 policy structs + composite sets (#[repr(C)])
Spec: §3 — all 22 normative DDS QoS policies plus the 6 composite QoS sets
(DP/DPF/Topic/Publisher/Subscriber/DataWriter/DataReader) as #[repr(C)] with
exact field layout.
Repo: crates/zerodds-c-api/src/qos_ffi.rs defines all 22 policy structs +
the composite sets.
Tests: qos_ffi::tests::duration_roundtrip, duration_infinite_roundtrip,
dw_qos_default_from_null.
Status: done
§3.2 Conversion C → Rust
Spec: §3 — *_qos_from_c convert the caller buffer into DCPS QoS.
Repo: qos_ffi::{dpf_qos_from_c, dp_qos_from_c, topic_qos_from_c, pub_qos_from_c, sub_qos_from_c, dw_qos_from_c, dr_qos_from_c}.
Tests: qos_ffi::tests::dp_qos_userdata_passthrough,
partition_cstring_array_passthrough.
Status: done
§3.3 Conversion Rust → C
Spec: §3 — implicit in the *_get_qos path: Rust QoS snapshot into the
caller buffer.
Repo: qos_ffi::{dp/topic/pub/sub/dw/dr_qos_to_c} — all 6 with a
variable-length buffer path for UserData/TopicData/GroupData (caller buffer +
OutOfResources if too small).
Tests: extra_ffi::tests::dp_set_get_qos_userdata_roundtrip.
Status: done
§4 Status structures
§4.1 13 status structures (#[repr(C)])
Spec: §4 — all normative status structures (Inconsistent, SampleLost, SampleRejected, LivelinessLost/Changed, Requested/Offered Deadline, Requested/Offered IncompatibleQos, Subscription/Publication matched).
Repo: topic_ffi.rs (Inconsistent), publisher_ffi.rs (writer statuses),
subscriber_ffi.rs (reader statuses) — all #[repr(C)].
Tests: subscriber_ffi::tests::statuses_default_ok,
topic_ffi::tests::inconsistent_topic_status_default.
Status: done
§5 Sample API
§5.1 SampleInfo + SampleArray
Spec: §5 — SampleInfo as #[repr(C)] with all 13 fields; SampleArray
with buffers + lengths + infos + count + loan_token.
Repo: subscriber_ffi.rs::ZeroDdsSampleInfo (13 fields) +
ZeroDdsSampleArray.
Tests: subscriber_ffi::tests::take_on_empty_returns_no_data,
return_loan_clears_array.
Status: done
§5.2 Loan-token contract
Spec: §5 — loan_token refers to an internal allocation block, freed via
dr_return_loan.
Repo: subscriber_ffi.rs — internal LoanMemory struct
(payloads + buffers + lengths + infos), zerodds_dr_return_loan frees it.
Tests: subscriber_ffi::tests::return_loan_clears_array.
Status: done
§6 Conditions + WaitSet
§6.1 GuardCondition + StatusCondition + WaitSet
Spec: §6 — Guard/Status conditions + WaitSet with
attach/detach/wait/get_conditions.
Repo: crates/zerodds-c-api/src/condition_ffi.rs (GuardCondition,
StatusCondition, ReadCondition, QueryCondition, WaitSet + waitset_wait).
Tests: condition_ffi::tests::guardcondition_lifecycle_and_trigger,
statuscondition_lifecycle_and_mask, condition_header_at_offset_zero.
Status: done
§6.2 ReadCondition + QueryCondition
Spec: §6/§2.7 — dr_create_readcondition + dr_create_querycondition with
state mask and (Query) filter expression + parameters.
Repo: condition_ffi.rs (structs + create) + subscriber_ffi.rs (trigger
evaluates the state mask against the reader cache; QueryCondition additionally
the filter expression via zerodds-sql-filter).
Tests: subscriber_ffi::tests::cft_filter_active_passes_untyped_samples.
Status: done
§7 Built-in topic data
§7.1 4 BuiltinTopicData structures
Spec: §7 — Participant, Topic, Publication, Subscription as #[repr(C)];
the discovery/matched getters fill them.
Repo: builtin_ffi.rs (4 structs + get_discovered_*);
dw_get_matched_subscription_data / dr_get_matched_publication_data via the
BuiltinSubscriber cache (subscription_reader().read() /
publication_reader().read()).
Tests: builtin_ffi::tests::discovered_topics_empty_initially,
discovered_publications_count_starts_zero,
discovered_participant_data_unknown_handle_returns_error.
Status: done
§8 Status codes
§8.1 15 status codes
Spec: §8 — 15 status codes (0=OK, -1..-14).
Repo: lib.rs::ZeroDdsStatus enum with all 15 codes.
Tests: used across the whole suite, e.g.
factory_ffi::tests::delete_with_null_handles_returns_bad_handle
(checks BadHandle).
Status: done
§9 Memory-ownership contract
§9.1 Paired allocation/free paths
Spec: §9 — ownership table: *_create pairs with *_destroy,
dr_take payloads with return_loan, *_get_qos strings static (no free),
topic_get_name/version static.
Repo: one dedicated free path per allocation function
(zerodds_dpf_create_participant/_delete_participant,
zerodds_dr_take/_return_loan, zerodds_topic_get_name/zerodds_string_free).
Tests: factory_ffi::tests::create_and_delete_participant_clean_lifecycle,
subscriber_ffi::tests::return_loan_clears_array.
Status: done
§10 Stability
§10.1 ABI stability from 1.0.0-rc.3
Spec: §10 — include/zerodds.h is ABI-stable from 1.0.0-rc.3;
#[repr(C)] layouts; function/status-code additions are additive, layout
breaks only on a major bump.
Repo: crates/zerodds-c-api/include/zerodds.h (cbindgen-generated); symbol
snapshot tests/abi.snapshot.json (additive enforced, removal = audit fail).
Tests: abi_compat::abi_snapshot_matches.
Status: done
§11 Test obligation
§11.1 Round-trip + header-compile tests
Spec: §11 — at least one round-trip test per function against a two-participant setup; header-compile test.
Repo: unit tests in every *_ffi module; integration smoke_ffi.rs
(two-participant pub-sub round-trip); header compile in the C++/C# smoke
(crates/cpp/).
Tests: smoke_ffi::ffi_pub_sub_roundtrip,
abi_compat::abi_snapshot_matches, cargo test -p zerodds-c-api.
Status: done
§12 Cross-reference to related vendor specs
§12.1 Cross-reference list
Spec: §12 — references to zerodds-listener-callbacks-1.1.md,
zerodds-async-1.0.md, zerodds-java-omgdds-1.0.md.
Repo: docs/specs/zerodds-c-api-1.0.md §12 (documentation cross-reference,
no code requirement).
Tests: —
Status: n/a (informative) — a pure documentation cross-reference with no implementable normative requirement.
§13 FFI surface status
§13.1 Full surface delivered
Spec: §13 — the exposed FFI surface (DPF/DP/Topic/Pub+DW/Sub+DR/QoS/ Conditions/Built-in/Listener/instance ops/loan/matched listings); the authoritative item status lives in this coverage audit.
Repo: crates/zerodds-c-api/ — all surface groups are exposed, incl. the
loan API (§2.6, real SHM zero-copy), matched pubs/subs listings (§2.6/§2.7),
listener wire-up (zerodds_poll_listeners, see zerodds-listener-callbacks-1.1.md)
and split read/take via the reader read cache (§2.7).
Tests: abi_compat::abi_snapshot_matches (surface snapshot);
smoke_ffi::ffi_pub_sub_roundtrip.
Status: done
§13.2 Runtime FFI: delivery modes + zero-copy + event-driven raw readiness
Spec: a ZeroDDS extension beyond the OMG DCPS-PSM-C, normative in
docs/specs/zerodds-delivery-modes-1.0.md; consumed by the ROS-2 RMW bridge
(see the ros2-rmw coverage). The runtime path (zerodds_writer_*/
zerodds_reader_*) picks a per-endpoint delivery mode and offers real same-host
zero-copy on both sides plus a blocking raw-readiness source.
Repo: crates/zerodds-c-api/src/lib.rs + shm_loan_ffi.rs:
zerodds_writer_set_delivery_mode(w, mode)—0=Portable (default, interop-safe, CDR on the wire),1=RawSameHost (zero-copy/zero-serialize, same-host, no RTPS),2=Iceoryx returnsUnsupported(Iceoryx runs through the dedicatedzerodds_writer_enable_iceoryx/zerodds_reader_enable_iceoryx, featuredelivery-iceoryx).zerodds_writer_enable_shm_loan— enables the writer’s POSIX-SHM loan path.zerodds_reader_enable_shm/zerodds_reader_take_shm/zerodds_reader_release_shm— reader-side zero-copy take:take_shmreturns a pointer into the SHM slot (valid untilrelease_shm),NoDatawhen nothing is pending.zerodds_reader_raw_wait(reader, timeout_ms)— blocks event-driven on the reader’s raw source (RawSameHost SHM change-generation futex or iceoryx2 listener),Okon a real wake,NoDataon timeout; lock-free (clones the backend/subscriber handle before parking). The RMW bridge folds this intormw_waitvia a doorbell thread.
Tests: shm_loan_e2e::delivery_mode_setter_validation,
raw_same_host_mode_writer_to_reader, shm_loan_writer_to_reader_zero_copy,
shm_loan_runtime_path_writer_to_reader_zero_copy,
loan_without_shm_falls_back_to_heap.
Status: done
Audit status
24 done / 0 partial / 0 open / 1 n/a (informative) / 0 n/a (rejected).
Test run: cargo test -p zerodds-c-api — 136 tests green, 0 failed.
Open items: none. Decision records: none.
zerodds-c-api v1.0 — Spec-Coverage
Audit der Vendor-Spec docs/specs/zerodds-c-api-1.0.md gegen den Code in
crates/zerodds-c-api/. Der generierte C-Header include/zerodds.h ist das
normative Vertragsdokument; jede Anforderung wird Item-für-Item mit
Spec-Bezug, Repo-Pfad, Test-Pfad und Status geprüft.
Quelle: docs/specs/zerodds-c-api-1.0.md (ZeroDDS Vendor-Spec).
§1 Architektur
§1.1 Opaque-Handle-Hierarchie + Lifetime
Spec: §1 — “Jede Entity ist ein opaque Handle (zerodds_*). Lifetime per
*_create/*_destroy-Pair.” Hierarchie DPF → DP → {Topic, Publisher,
Subscriber} → {DataWriter, DataReader}.
Repo: crates/zerodds-c-api/src/entities.rs (opaque Structs
ZeroDdsDomainParticipant/ZeroDdsPublisher/ZeroDdsSubscriber/
ZeroDdsTopic/ZeroDdsDataWriter/ZeroDdsDataReader); Factory-Wurzel in
factory_ffi.rs. Jeder Typ hat ein *_create/*_delete-Paar.
Tests: factory_ffi::tests::create_and_delete_participant_clean_lifecycle,
participant_ffi::tests::delete_contained_entities_drops_all.
Status: done
§1.2 Stabile Wire-Form (#[repr(C)])
Spec: §1 / §3 — “Stabile Wire-Form: ABI-stabile Strukturen für QoS, SampleInfo, Status; opaque Handles für Entity-Lifecycle.”
Repo: alle QoS-, SampleInfo- und Status-Strukturen sind #[repr(C)] in
qos_ffi.rs, subscriber_ffi.rs, publisher_ffi.rs, topic_ffi.rs.
Tests: qos_ffi::tests::duration_roundtrip,
qos_ffi::tests::dw_qos_default_from_null.
Status: done
§2 Entity-Hierarchie
§2.1 DomainParticipantFactory
Spec: §2.1 — get_instance, create_participant, delete_participant,
lookup_participant, get/set_default_participant_qos, get/set_qos.
Repo: crates/zerodds-c-api/src/factory_ffi.rs
(zerodds_dpf_get_instance + _create_participant/_delete_participant/
_lookup_participant/_get/_set_default_participant_qos/_get/_set_qos).
Tests: factory_ffi::tests::factory_singleton_returns_non_null_stable_ptr,
create_and_delete_participant_clean_lifecycle,
delete_with_null_handles_returns_bad_handle.
Status: done
§2.2 DomainParticipant
Spec: §2.2 — create/delete Topic+Publisher+Subscriber+ContentFilteredTopic,
find_topic, get_builtin_subscriber, ignore_*, get_domain_id,
assert_liveliness, get_current_time, get/set_qos, default_*_qos,
delete_contained_entities, get_discovered_*, contains_entity.
Repo: crates/zerodds-c-api/src/participant_ffi.rs +
extra_ffi.rs (QoS-Roundtrip + contains_entity) + builtin_ffi.rs
(get_discovered_*). zerodds_dp_get_current_time schreibt die
Wall-Clock-Zeit über zerodds_dcps::get_current_time() in einen
zerodds_ZeroDdsTime-Out-Buffer.
Tests: participant_ffi::tests::create_topic_then_find_then_delete,
domain_id_roundtrip, get_current_time_returns_nonzero,
delete_contained_entities_drops_all;
extra_ffi::tests::dp_get_set_qos_roundtrip_default;
builtin_ffi::tests::discovered_topics_empty_initially.
Status: done
§2.3 Publisher
Spec: §2.3 — create/delete_datawriter, lookup_datawriter,
suspend/resume_publications, begin/end_coherent_changes,
wait_for_acknowledgments, get/set_qos, get/set_default_datawriter_qos,
copy_from_topic_qos, delete_contained_entities, get_participant.
Repo: crates/zerodds-c-api/src/publisher_ffi.rs + extra_ffi.rs
(pub_copy_from_topic_qos, QoS-Konvertierung).
Tests: publisher_ffi::tests::create_delete_datawriter_roundtrip,
lookup_datawriter_finds_existing, pub_suspend_resume_clean,
dw_get_topic_publisher_roundtrip.
Status: done
§2.4 Subscriber
Spec: §2.4 — create/delete_datareader, lookup_datareader,
begin/end_access, get_datareaders, notify_datareaders, get/set_qos,
get/set_default_datareader_qos, copy_from_topic_qos,
delete_contained_entities, get_participant.
Repo: crates/zerodds-c-api/src/subscriber_ffi.rs + extra_ffi.rs
(sub_copy_from_topic_qos, QoS-Konvertierung).
Tests: subscriber_ffi::tests::create_delete_datareader,
lookup_datareader_finds_existing.
Status: done
§2.5 Topic
Spec: §2.5 — get/set_qos, get_inconsistent_topic_status, get_name,
get_type_name, get_participant.
Repo: crates/zerodds-c-api/src/topic_ffi.rs. get/set_qos über
topic_qos_to_c/from_c-Roundtrip; get_inconsistent_topic_status liefert
den Counter aus dem DCPS-Topic (0 außer bei aktivem Type-Mismatch,
spec-konform).
Tests: topic_ffi::tests::topic_get_name_and_type_roundtrip,
inconsistent_topic_status_default.
Status: done
§2.6 DataWriter
Spec: §2.6 — register/unregister_instance (+_w_timestamp),
get_key_value, lookup_instance, write (+_w_timestamp), dispose
(+_w_timestamp), wait_for_acknowledgments, assert_liveliness,
get/set_qos, 4 Status-Getter, get_matched_subscriptions(_data),
get_topic, get_publisher, wait_for_matched, Loan-API
(loan_message/commit_loan/discard_loan).
Repo: crates/zerodds-c-api/src/publisher_ffi.rs (Writer-Statuses,
get_matched_subscriptions aus reader_proxies) + extra_ffi.rs
(Instance-Ops, Loan-Hooks) + shm_loan_ffi.rs (Zero-Copy-Backend). Die
Loan-API hat zwei transparent gewählte Pfade: ohne Aktivierung Heap-Box;
mit Feature flatdata-loan + zerodds_dw_enable_shm_loan echtes
Same-Host-Zero-Copy. In beiden Pfaden gilt der byte-orientierte
FFI-Kontrakt (Spec-Nichtziel “das C-FFI ist byte-orientiert”): der
Caller schreibt die serialisierte CDR-Payload in den Loan-Buffer —
identisch zu zerodds_dw_write. loan_message liefert dafür einen Zeiger
in einen POSIX-SHM-Slot, commit_loan finalisiert den Slot in-place ohne
Staging-Copy (commit_in_place) und publiziert ihn über RTPS
(write_user_sample_borrowed rahmt mit dem Encapsulation-Header → CDR-wire,
interop-sicher für Cross-Host/Cross-Vendor). Ein Same-Host-Reader liest
denselben CDR-Body zero-copy aus dem Segment. Loan-State auf
(Runtime, EntityId) geschlüsselt, daher auch über die Runtime-FFI
(zerodds_writer_*) der ROS-2-RMW-Bridge nutzbar.
Tests: extra_ffi::tests::dw_register_unregister_lookup_instance,
dw_get_key_value_buffer_too_small, dw_loan_message_then_commit_or_discard;
shm_loan_e2e::shm_loan_writer_to_reader_zero_copy,
shm_loan_runtime_path_writer_to_reader_zero_copy,
loan_without_shm_falls_back_to_heap.
Status: done
§2.7 DataReader
Spec: §2.7 — read/take (+_w_condition, _next_sample, _instance,
_next_instance), return_loan, get_key_value, lookup_instance,
create/delete_readcondition, create_querycondition, 6 Status-Getter,
wait_for_historical_data, get_matched_publications(_data),
get_topicdescription, get_subscriber, get/set_qos, wait_for_matched.
Repo: crates/zerodds-c-api/src/subscriber_ffi.rs (Reader-Statuses,
read non-destruktiv über lokalen read_cache,
read/take_instance/_next_instance über sample_array_filter_*,
_w_condition über Condition-State-Mask) + extra_ffi.rs
(get_matched_publications). wait_for_historical_data: Volatile sofort Ok,
TransientLocal über crates/dcps/src/durability_service.rs.
Tests: subscriber_ffi::tests::take_on_empty_returns_no_data,
return_loan_clears_array, statuses_default_ok,
cft_filter_active_passes_untyped_samples;
extra_ffi::tests::dr_get_matched_publications_empty.
Status: done
§3 QoS-Strukturen
§3.1 22 Policy-Strukturen + Composite-Sets (#[repr(C)])
Spec: §3 — alle 22 normativen DDS-QoS-Policies sowie die 6
Composite-QoS-Sets (DP/DPF/Topic/Publisher/Subscriber/DataWriter/DataReader)
als #[repr(C)] mit exaktem Field-Layout.
Repo: crates/zerodds-c-api/src/qos_ffi.rs definiert alle 22 Policy-
Strukturen + die Composite-Sets.
Tests: qos_ffi::tests::duration_roundtrip, duration_infinite_roundtrip,
dw_qos_default_from_null.
Status: done
§3.2 Konvertierung C → Rust
Spec: §3 — *_qos_from_c konvertieren Caller-Buffer in DCPS-QoS.
Repo: qos_ffi::{dpf_qos_from_c, dp_qos_from_c, topic_qos_from_c, pub_qos_from_c, sub_qos_from_c, dw_qos_from_c, dr_qos_from_c}.
Tests: qos_ffi::tests::dp_qos_userdata_passthrough,
partition_cstring_array_passthrough.
Status: done
§3.3 Konvertierung Rust → C
Spec: §3 — implizit im *_get_qos-Pfad: Rust-QoS-Snapshot in
Caller-Buffer.
Repo: qos_ffi::{dp/topic/pub/sub/dw/dr_qos_to_c} — alle 6 mit
Variable-Length-Buffer-Pfad für UserData/TopicData/GroupData (Caller-Buffer +
OutOfResources bei zu klein).
Tests: extra_ffi::tests::dp_set_get_qos_userdata_roundtrip.
Status: done
§4 Status-Strukturen
§4.1 13 Status-Strukturen (#[repr(C)])
Spec: §4 — alle normativen Status-Strukturen (Inconsistent, SampleLost, SampleRejected, LivelinessLost/Changed, Requested/Offered Deadline, Requested/Offered IncompatibleQos, Subscription/Publication-Matched).
Repo: topic_ffi.rs (Inconsistent), publisher_ffi.rs (Writer-Statuses),
subscriber_ffi.rs (Reader-Statuses) — alle #[repr(C)].
Tests: subscriber_ffi::tests::statuses_default_ok,
topic_ffi::tests::inconsistent_topic_status_default.
Status: done
§5 Sample-API
§5.1 SampleInfo + SampleArray
Spec: §5 — SampleInfo als #[repr(C)] mit allen 13 Feldern;
SampleArray mit buffers + lengths + infos + count + loan_token.
Repo: subscriber_ffi.rs::ZeroDdsSampleInfo (13 Felder) +
ZeroDdsSampleArray.
Tests: subscriber_ffi::tests::take_on_empty_returns_no_data,
return_loan_clears_array.
Status: done
§5.2 Loan-Token-Kontrakt
Spec: §5 — loan_token verweist auf internen Allokations-Block,
freigegeben via dr_return_loan.
Repo: subscriber_ffi.rs — interne LoanMemory-Struktur
(payloads + buffers + lengths + infos), zerodds_dr_return_loan gibt frei.
Tests: subscriber_ffi::tests::return_loan_clears_array.
Status: done
§6 Conditions + WaitSet
§6.1 GuardCondition + StatusCondition + WaitSet
Spec: §6 — Guard/Status-Conditions + WaitSet mit
attach/detach/wait/get_conditions.
Repo: crates/zerodds-c-api/src/condition_ffi.rs (GuardCondition,
StatusCondition, ReadCondition, QueryCondition, WaitSet + waitset_wait).
Tests: condition_ffi::tests::guardcondition_lifecycle_and_trigger,
statuscondition_lifecycle_and_mask, condition_header_at_offset_zero.
Status: done
§6.2 ReadCondition + QueryCondition
Spec: §6/§2.7 — dr_create_readcondition + dr_create_querycondition
mit State-Mask und (Query) Filter-Expression + Parametern.
Repo: condition_ffi.rs (Strukturen + create) +
subscriber_ffi.rs (Trigger evaluiert State-Mask gegen Reader-Cache;
QueryCondition zusätzlich Filter-Expression über zerodds-sql-filter).
Tests: subscriber_ffi::tests::cft_filter_active_passes_untyped_samples.
Status: done
§7 Built-in Topic Data
§7.1 4 BuiltinTopicData-Strukturen
Spec: §7 — Participant, Topic, Publication, Subscription als #[repr(C)];
Discovery-/Matched-Getter füllen sie.
Repo: builtin_ffi.rs (4 Strukturen + get_discovered_*);
dw_get_matched_subscription_data / dr_get_matched_publication_data über den
BuiltinSubscriber-Cache (subscription_reader().read() /
publication_reader().read()).
Tests: builtin_ffi::tests::discovered_topics_empty_initially,
discovered_publications_count_starts_zero,
discovered_participant_data_unknown_handle_returns_error.
Status: done
§8 Status-Codes
§8.1 15 Status-Codes
Spec: §8 — 15 Status-Codes (0=OK, -1..-14).
Repo: lib.rs::ZeroDdsStatus enum mit allen 15 Codes.
Tests: in der gesamten Suite verwendet, z. B.
factory_ffi::tests::delete_with_null_handles_returns_bad_handle
(prüft BadHandle).
Status: done
§9 Memory-Ownership-Vertrag
§9.1 Paarweise Allokations-/Free-Pfade
Spec: §9 — Ownership-Tabelle: *_create paart mit *_destroy,
dr_take-Payloads mit return_loan, *_get_qos-Strings statisch (kein
Free), topic_get_name/version statisch.
Repo: pro Allokations-Funktion ein dedizierter Free-Pfad
(zerodds_dpf_create_participant/_delete_participant,
zerodds_dr_take/_return_loan, zerodds_topic_get_name/zerodds_string_free).
Tests: factory_ffi::tests::create_and_delete_participant_clean_lifecycle,
subscriber_ffi::tests::return_loan_clears_array.
Status: done
§10 Stabilität
§10.1 ABI-Stabilität ab 1.0.0-rc.3
Spec: §10 — include/zerodds.h ist ABI-stable ab 1.0.0-rc.3;
#[repr(C)]-Layouts; Funktions-/Status-Code-Zusätze additiv,
Layout-Breaking nur bei Major-Bump.
Repo: crates/zerodds-c-api/include/zerodds.h (cbindgen-generiert);
Symbol-Snapshot tests/abi.snapshot.json (additiv erzwungen, Entfernung =
Audit-Fail).
Tests: abi_compat::abi_snapshot_matches.
Status: done
§11 Test-Pflicht
§11.1 Round-Trip- + Header-Compile-Tests
Spec: §11 — pro Funktion mindestens ein Round-Trip-Test gegen ein Zwei-Participant-Setup; Header-Compile-Test.
Repo: Unit-Tests in jedem *_ffi-Modul; Integration smoke_ffi.rs
(Zwei-Participant-Pub-Sub-Roundtrip); Header-Compile in C++/C#-Smoke
(crates/cpp/).
Tests: smoke_ffi::ffi_pub_sub_roundtrip,
abi_compat::abi_snapshot_matches, cargo test -p zerodds-c-api.
Status: done
§12 Cross-Reference auf zugehörige Vendor-Specs
§12.1 Cross-Reference-Liste
Spec: §12 — Verweise auf zerodds-listener-callbacks-1.1.md,
zerodds-async-1.0.md, zerodds-java-omgdds-1.0.md.
Repo: docs/specs/zerodds-c-api-1.0.md §12 (Doku-Querverweis, keine
Code-Anforderung).
Tests: —
Status: n/a (informative) — reiner Doku-Querverweis ohne implementierbare normative Anforderung.
§13 FFI-Surface-Status
§13.1 Vollständige Surface ausgeliefert
Spec: §13 — exponierte FFI-Surface (DPF/DP/Topic/Pub+DW/Sub+DR/QoS/ Conditions/Built-in/Listener/Instance-Ops/Loan/Matched-Listings); der authoritative Item-Status liegt in diesem Coverage-Audit.
Repo: crates/zerodds-c-api/ — alle Surface-Gruppen sind exponiert, inkl.
Loan-API (§2.6, echtes SHM-Zero-Copy), Matched-Pubs/Subs-Listings (§2.6/§2.7),
Listener-Wireup (zerodds_poll_listeners, siehe zerodds-listener-callbacks-1.1.md)
und getrenntem read/take über den Reader-Read-Cache (§2.7).
Tests: abi_compat::abi_snapshot_matches (Surface-Snapshot);
smoke_ffi::ffi_pub_sub_roundtrip.
Status: done
§13.2 Runtime-FFI: Delivery-Modes + Zero-Copy + event-driven Raw-Readiness
Spec: ZeroDDS-Extension über den OMG-DCPS-PSM-C hinaus, normativ in
docs/specs/zerodds-delivery-modes-1.0.md; konsumiert von der ROS-2-RMW-Bridge
(siehe ros2-rmw Coverage). Der Runtime-Pfad (zerodds_writer_*/
zerodds_reader_*) wählt pro Endpoint einen Delivery-Mode und bietet beidseitig
echtes Same-Host-Zero-Copy plus eine blockierende Raw-Readiness-Quelle.
Repo: crates/zerodds-c-api/src/lib.rs + shm_loan_ffi.rs:
zerodds_writer_set_delivery_mode(w, mode)—0=Portable (Default, interop-sicher, CDR auf dem Draht),1=RawSameHost (Zero-Copy/Zero-Serialize, same-host, kein RTPS),2=Iceoryx liefertUnsupported(Iceoryx läuft über die dediziertenzerodds_writer_enable_iceoryx/zerodds_reader_enable_iceoryx, Featuredelivery-iceoryx).zerodds_writer_enable_shm_loan— aktiviert den POSIX-SHM-Loan-Pfad des Writers.zerodds_reader_enable_shm/zerodds_reader_take_shm/zerodds_reader_release_shm— reader-seitiges Zero-Copy-Take:take_shmliefert einen Zeiger in den SHM-Slot (gültig bisrelease_shm),NoDatawenn nichts ansteht.zerodds_reader_raw_wait(reader, timeout_ms)— blockiert event-getrieben auf der Raw-Quelle des Readers (RawSameHost-SHM-Change-Generation-Futex bzw. iceoryx2-Listener),Okbei echtem Wake,NoDatabei Timeout; lock-free (klont den Backend-/Subscriber-Handle vor dem Parken). Die RMW-Bridge faltet das über einen Doorbell-Thread inrmw_waitein.
Tests: shm_loan_e2e::delivery_mode_setter_validation,
raw_same_host_mode_writer_to_reader, shm_loan_writer_to_reader_zero_copy,
shm_loan_runtime_path_writer_to_reader_zero_copy,
loan_without_shm_falls_back_to_heap.
Status: done
Audit-Status
24 done / 0 partial / 0 open / 1 n/a (informative) / 0 n/a (rejected).
Test-Lauf: cargo test -p zerodds-c-api — 136 Tests grün, 0 failed.
Offene Punkte: keine. Decision-Records: keine.