Skip to main content

UdsClient

Struct UdsClient 

Source
pub struct UdsClient<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> { /* private fields */ }
Expand description

Stateful UDS tester client state machine.

Sends raw UDS request frames and emits ClientEvents as responses arrive. The client tracks only what is necessary for the protocol exchange - P2 and P2* timeouts on pending requests. Session state, security state, and retry logic are entirely the caller’s responsibility.

N - maximum number of concurrent pending requests. Defaults to 1. UDS is strictly sequential in most implementations - use UdsClient<1> unless you have a specific need for pipelining.

Implementations§

Source§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_EVENTS, PERIODIC_DIDS, MAX_DATA>

Source

pub fn new(config: ClientConfig, address: NodeAddress) -> Self

Source

pub fn address(&self) -> &NodeAddress

Source

pub fn handle( &mut self, _src: &NodeAddress, data: &[u8], now: Instant, ) -> Result<(), ClientError>

Delivers an inbound frame to the client.

Classifies the frame before attempting any pending request match:

  1. Empty frame - ignored
  2. 0x7F - negative response - matched by requested SID at byte 1
  3. First byte is a subscribed periodic DID - PeriodicData event
  4. First byte has bit 6 set - positive response - matched by request SID
  5. Anything else - Unsolicited event

Periodic classification must precede positive response classification because a periodic DID low byte could theoretically have bit 6 set. Explicit subscription registry takes priority.

Source

pub fn tick(&mut self, now: Instant) -> Result<(), ClientError>

Advances internal timers - expires timed-out pending requests.

Source

pub fn drain_outbox( &mut self, out: &mut Vec<(NodeAddress, Vec<u8, SIM_MAX_FRAME>), SIM_MAX_OUTBOX>, ) -> usize

Drains pending outbound frames into out.

Source

pub fn request(&mut self, data: &[u8], now: Instant) -> Result<(), ClientError>

Enqueues a raw UDS request for transmission.

data must begin with the SID byte followed by any parameters. The client tracks this as a pending request and starts the P2 timer.

Returns ClientError::QueueFull if N concurrent requests are already pending.

Source

pub fn subscribe_periodic(&mut self, did_low_byte: u8)

Registers the low byte of a periodic DID identifier as subscribed.

Inbound frames whose first byte matches a subscribed DID low byte are classified as PeriodicData events rather than Unsolicited.

The low byte corresponds to the periodic_data_identifier field in ReadDataByPeriodicIdentifierResponseData. For a DID of 0xF201 the low byte is 0x01.

Silently does nothing if already subscribed or the registry is full.

Source

pub fn unsubscribe_periodic(&mut self, did_low_byte: u8)

Removes a periodic DID subscription.

After calling this, frames with this DID low byte will be classified as Unsolicited rather than PeriodicData.

Source

pub fn is_periodic_subscribed(&self, did_low_byte: u8) -> bool

Returns true if the given DID low byte is currently subscribed.

Source

pub fn drain_events( &mut self, ) -> impl Iterator<Item = ClientEvent<MAX_DATA>> + '_

Drains all accumulated events, returning an iterator.

Events are consumed - calling drain_events twice returns events on the first call and nothing on the second.

Source

pub fn has_events(&self) -> bool

Returns true if any events are pending.

Source

pub fn pending_count(&self) -> usize

Returns the number of currently pending requests.

Trait Implementations§

Source§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> Debug for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> SimNode<SIM_MAX_FRAME, SIM_MAX_OUTBOX> for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_EVENTS, PERIODIC_DIDS, MAX_DATA>

Maximum UDS frame payload bytes = matches ace-server for bus compatibility. Maximum outbox depth.

Source§

type Error = ClientError

Source§

fn address(&self) -> &NodeAddress

Returns this node’s address on the simulation bus.
Source§

fn handle( &mut self, src: &NodeAddress, data: &[u8], now: Instant, ) -> Result<(), Self::Error>

Delivers an inbound message to the node.
Source§

fn tick(&mut self, now: Instant) -> Result<(), Self::Error>

Advances the node’s internal state to the given time. Read more
Source§

fn drain_outbox( &mut self, out: &mut Vec<(NodeAddress, Vec<u8, SIM_MAX_FRAME>), SIM_MAX_OUTBOX>, ) -> usize

Drains all pending outbound messages from the node’s outbox. Read more

Auto Trait Implementations§

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> Freeze for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> RefUnwindSafe for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> Send for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> Sync for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> Unpin for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> UnsafeUnpin for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

§

impl<const PENDING: usize, const SIM_MAX_FRAME: usize, const SIM_MAX_OUTBOX: usize, const MAX_TARGET_EVENTS: usize, const PERIODIC_DIDS: usize, const MAX_DATA: usize> UnwindSafe for UdsClient<PENDING, SIM_MAX_FRAME, SIM_MAX_OUTBOX, MAX_TARGET_EVENTS, PERIODIC_DIDS, MAX_DATA>

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.