Skip to main content

CffiSession

Struct CffiSession 

Source
pub struct CffiSession { /* private fields */ }
Expand description

Session backed by a C vtable.

Implementations§

Source§

impl CffiSession

Source

pub fn domain_id(&self) -> u32

Domain this session was opened on. Authoritative: it is the value the backend actually got, not a re-derivation that can disagree with it.

Source

pub fn serialization_format_cstr(&self) -> *const c_char

RFC-0088 D4 / phase-421 W2 — the serialization format THIS session’s backend speaks, as a NUL-terminated C string with 'static lifetime, or NULL when the backend does not declare one.

Not <Self as Session>::SERIALIZATION_FORMAT. That const is the trait default, "cdr", and it is a lie for this type specifically: CffiSession is the one session that does not know its own backend at compile time — the vtable arrives at run time through nros_rmw_cffi_register_named, and an image may register several. The per-session answer therefore has to come from the vtable, which is the whole reason the slot got a body.

A NULL slot answers NULL rather than "cdr": a backend that declines to say what it speaks has not said "cdr", and guessing on its behalf is the mistake get_implementation_identifier’s doc made for two phases (corrected phase-393 W2). Every in-tree backend fills the slot, so NULL means a foreign or pre-phase-421 vtable.

Source

pub fn serialization_format(&self) -> Option<&'static str>

serialization_format_cstr as a Rust string. None for a NULL slot or a non-UTF-8 answer.

Source

pub fn node_name(&self) -> &str

Node name passed at session-open time.

Source

pub fn open( locator: &str, mode: u8, domain_id: u32, node_name: &str, ) -> Result<Self, TransportError>

Open a new session via the default registered vtable (first entry in the registry — the RMW_IMPLEMENTATION-style fast path for single-backend builds).

For explicit backend selection in multi-backend (bridge) binaries, use open_named.

Source

pub fn open_with_properties( locator: &str, mode: u8, domain_id: u32, node_name: &str, properties: &[(&str, &str)], ) -> Result<Self, TransportError>

phase-206 W3 — open a session carrying backend-specific configuration properties (RmwConfig::properties across the C seam).

This is the rung that was missing. RmwConfig has carried properties since it existed and every Rust backend reads them, but nothing between the runtime and the vtable passed them on: this function’s non-properties sibling handed create_session a NULL options pointer, and the Rust-backend adapter on the far side built properties: &[] unconditionally. So the only way to set a zenoh listen endpoint, a TLS certificate or a scouting timeout was to build an RmwConfig by hand in hosted Rust — a C or C++ image could state none of it, on any platform.

Refused, never truncated: more than RMW_SESSION_MAX_PROPERTIES entries, an empty key or value, or either longer than SESSION_PROPERTY_BUF_LEN. All are TransportError::InvalidArgument.

Source

pub fn open_named( rmw_name: &str, locator: &str, mode: u8, domain_id: u32, node_name: &str, ) -> Result<Self, TransportError>

Phase 104.C.1 — open a new session against a named backend. Resolves rmw_name against the registry (Phase 104.B.2), returns Err(TransportError::InvalidArgument) if no backend is registered under that name.

Source

pub fn open_named_with_properties( rmw_name: &str, locator: &str, mode: u8, domain_id: u32, node_name: &str, properties: &[(&str, &str)], ) -> Result<Self, TransportError>

open_named carrying backend-specific configuration properties — see open_with_properties.

Trait Implementations§

Source§

impl Drop for CffiSession

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Session for CffiSession

Source§

fn serialization_format(&self) -> &'static str

The backend is chosen at run time here, so the trait’s compile-time default would be a guess. Ask the vtable, and fall back to the constant only for a backend that installed no body — which reads as “this backend has not said”, not as “cdr”.

Source§

fn get_node_names( &mut self, visit: &mut dyn FnMut(&str, &str, Option<&str>) -> bool, ) -> Result<(), TransportError>

phase-381 W5/W6 — forward to the backend’s slot; NULL means UNSUPPORTED.

Without this the graph slots were unreachable for every C backend: the trait default returns Unsupported, so a wired slot — cyclone’s, as of W5 — would never be called and would look implemented while being dead code. That is exactly the “a slot exists, therefore it works” overstatement issue 0800 measured, one layer above where 0800 found it.

NULL surfaces Unsupported rather than an empty enumeration, which is W6’s requirement: XRCE has no graph and must say “cannot tell you”, not “nothing is there”.

Source§

fn get_topic_names_and_types( &mut self, visit: &mut dyn FnMut(&str, &[&str]) -> bool, ) -> Result<(), TransportError>

phase-381 / issue 0903 — the REST of the graph family.

W5 added get_node_names here and stopped, which made this the same defect one method wide: every other graph call fell through to the trait default and returned Unsupported, so the zenoh backend — which reaches the runtime through this vtable — answered node names and NOTHING else. Measured against a live rmw_zenoh_cpp talker: node enumeration worked and get_topic_names_and_types returned empty, because the entity query was never even STARTED.

Fixing one method of eleven is how the first version passed every unit test in the phase.

Source§

fn get_names_and_types_by_node( &mut self, kind: GraphEntityKind, node_name: &str, node_namespace: &str, visit: &mut dyn FnMut(&str, &[&str]) -> bool, ) -> Result<(), TransportError>

phase-381 W4, wired here by the live acceptance run.

The zenoh shim implemented this and get_endpoint_info_by_topic all along; CffiSession never dispatched them, so both fell through to the trait default and every caller got Unsupported. That is issue 0903’s third defect for the SIX slots the 0903 fix did not cover — it wired the five that had a failing symptom in front of it and left these, and check-rmw-slot-producers calls them produced either way because it asks whether a slot has a producer, not whether anything reaches it.

Found by graph_interop.rs on its first run against a real peer, which is the only place it could have been found.

Source§

fn get_endpoint_info_by_topic( &mut self, publishers: bool, topic_name: &str, visit: &mut dyn FnMut(&GraphEndpointInfo<'_>) -> bool, ) -> Result<(), TransportError>

The endpoints on a topic — see Self::get_names_and_types_by_node for why this was unreachable until the live run.

Source§

fn supported_qos_policies(&self) -> QoSPolicyMask

Phase 115.K.2.5.1.2 — declare a permissive QoS-policy mask here so backends behind the cffi vtable don’t get rejected by the runtime’s pre-validate step before they ever see the create_publisher / create_subscription call. The vtable doesn’t expose a per-backend policy mask yet; until it does, the cffi route has to assume the registered backend supports the union of every policy any nros-supported RMW honours. Backends that don’t support a policy MUST surface NROS_RMW_RET_INCOMPATIBLE_QOS from create_publisher etc. to keep the no-silent-degradation contract.

TODO 115.K.2.x: extend nros_rmw_vtable_t with a supported_qos_policies() callback so the runtime queries the backend instead of guessing.

Source§

type Error = TransportError

Error type for this session
Source§

type PublisherHandle = CffiPublisher

Publisher handle type
Source§

type SubscriptionHandle = CffiSubscription

Subscription handle type
Source§

type ServiceHandle = CffiService

Service server handle type
Source§

type ClientHandle = CffiClient

Service client handle type
Source§

fn create_publisher( &mut self, topic: &TopicInfo<'_>, qos: QoSProfile, ) -> Result<CffiPublisher, TransportError>

Create a publisher bound to this session. Read more
Source§

fn create_subscription( &mut self, topic: &TopicInfo<'_>, qos: QoSProfile, ) -> Result<CffiSubscription, TransportError>

Create a subscriber bound to this session. Read more
Source§

fn create_service( &mut self, service: &ServiceInfo<'_>, qos: QoSProfile, ) -> Result<CffiService, TransportError>

Create a service server bound to this session. Replies are matched to requests by the sequence number returned from ServiceTrait::take_request. Read more
Source§

fn create_client( &mut self, service: &ServiceInfo<'_>, qos: QoSProfile, ) -> Result<CffiClient, TransportError>

Create a service client bound to this session. Read more
Source§

fn close(&mut self) -> Result<(), TransportError>

Close the session, releasing transport resources. All entity handles created from this session must already be dropped.
Source§

fn drive_io(&mut self, timeout_ms: i32) -> Result<(), TransportError>

Drive transport I/O (poll network, dispatch callbacks). Read more
Source§

fn next_deadline_ms(&self) -> Option<u32>

Phase 110.0 — backend’s next internal-event deadline in milliseconds from now (lease keepalive, heartbeat, reader ACK-NACK timeout, etc.). Read more
Source§

unsafe fn set_wake_callback( &mut self, cb: Option<unsafe extern "C" fn(ctx: *mut c_void)>, ctx: *mut c_void, )

Phase 124.B.1 — install (or clear, when cb.is_none()) the executor wake callback. The runtime calls this once per session after open with cb pointing at a runtime-owned function and ctx pointing at the executor’s wake state. The backend stores (cb, ctx) in its per-session state and calls cb(ctx) whenever its transport notification path fires (datagram arrival, condvar wake, etc.) — the runtime cb does flag-write + condvar-signal atomically, so a spin_once blocked on the wake condvar resumes immediately instead of waiting for the next poll iteration. Read more
Source§

fn supports_wake_callback(&self) -> bool

Phase 130.4 — does this backend actually honour set_wake_callback? Read more
Source§

fn get_service_names_and_types( &mut self, visit: &mut dyn FnMut(&str, &[&str]) -> bool, ) -> Result<(), TransportError>

phase-381 W3 — every service, with its types. As Self::get_topic_names_and_types, over servers and clients.
Source§

fn count_publishers( &mut self, topic_name: &str, ) -> Result<usize, TransportError>

phase-381 W3 — how many publishers this session can see on topic_name. Read more
Source§

fn count_subscribers( &mut self, topic_name: &str, ) -> Result<usize, TransportError>

phase-381 W3 — how many subscribers this session can see on topic_name. See Self::count_publishers for the caveats.
Source§

fn ping_session(&mut self, timeout_ms: i32) -> Result<(), TransportError>

Phase 124.F.1 — session-level connectivity probe. Read more
Source§

const SERIALIZATION_FORMAT: &'static str = _

RFC-0088 — the serialization format this backend speaks, as ROS 2’s rmw_get_serialization_format() reports it (“One middleware can only have one encoding”). Read more
Source§

const SERIALIZATION_FORMAT_ID: SerializationFormatId = nros_serdes::format::SerializationFormatId::Cdr

Image-local discriminant for Self::SERIALIZATION_FORMAT. Never persisted, never compared across images — see nros_serdes::format.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.