Skip to main content

ara_com/
transport.rs

1use crate::error::AraComError;
2use crate::types::*;
3use async_trait::async_trait;
4use bytes::Bytes;
5
6/// SOME/IP message header carrying routing metadata.
7///
8/// Every message exchanged over a [`Transport`] is paired with a header that
9/// identifies the target service, method, and instance. The transport layer
10/// uses this information to route the message and correlate request/response
11/// pairs via `session_id`.
12#[derive(Debug, Clone)]
13pub struct MessageHeader {
14    /// Target service identifier.
15    pub service_id: ServiceId,
16    /// Target method or event identifier.
17    pub method_id: MethodId,
18    /// Target service instance.
19    pub instance_id: InstanceId,
20    /// Session identifier for request/response correlation.
21    /// Transports typically assign this automatically; set to `0` in
22    /// outgoing calls and let the transport fill it in.
23    pub session_id: u16,
24    /// Discriminates request, response, notification, and error frames.
25    pub message_type: MessageType,
26    /// SOME/IP return code (meaningful in responses and errors).
27    pub return_code: ReturnCode,
28}
29
30/// SOME/IP message type discriminator (PRS_SOMEIP_00055).
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
32pub enum MessageType {
33    /// Client-to-server request expecting a [`Response`](MessageType::Response).
34    Request,
35    /// Client-to-server fire-and-forget (no response expected).
36    RequestNoReturn,
37    /// Server-to-client event notification (unsolicited).
38    Notification,
39    /// Server-to-client response to a [`Request`](MessageType::Request).
40    Response,
41    /// Server-to-client error response.
42    Error,
43}
44
45/// SOME/IP return code (PRS_SOMEIP_00058).
46///
47/// Carried in response and error messages to indicate success or the reason
48/// for failure.
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50#[repr(u8)]
51pub enum ReturnCode {
52    /// No error.
53    Ok = 0x00,
54    /// Unspecified error.
55    NotOk = 0x01,
56    /// The requested service is not known.
57    UnknownService = 0x02,
58    /// The requested method/event is not known.
59    UnknownMethod = 0x03,
60    /// The service is registered but not yet ready.
61    NotReady = 0x04,
62    /// The service instance is not reachable (network-level).
63    NotReachable = 0x05,
64    /// The request timed out on the server side.
65    Timeout = 0x06,
66    /// Protocol version mismatch.
67    WrongProtocolVersion = 0x07,
68    /// Interface version mismatch.
69    WrongInterfaceVersion = 0x08,
70    /// The message payload could not be parsed.
71    MalformedMessage = 0x09,
72    /// The message type is not valid in this context.
73    WrongMessageType = 0x0A,
74}
75
76/// Serialization trait for AUTOSAR-compatible wire format encoding.
77///
78/// All primitive types, `String`, and `Vec<T>` implement this trait using
79/// big-endian byte order and SOME/IP length-prefix conventions.
80/// Generated struct types receive an implementation from `cargo-arxml`.
81pub trait AraSerialize: Send + Sync {
82    /// Append the wire-format bytes of `self` to `buf`.
83    fn ara_serialize(&self, buf: &mut Vec<u8>) -> Result<(), AraComError>;
84    /// Return the exact number of bytes that [`ara_serialize`](AraSerialize::ara_serialize)
85    /// will append.
86    fn serialized_size(&self) -> usize;
87}
88
89/// Deserialization trait for AUTOSAR-compatible wire format decoding.
90///
91/// Counterpart to [`AraSerialize`]. Implementations consume bytes from the
92/// front of `buf` and return the decoded value.
93pub trait AraDeserialize: Sized + Send + Sync {
94    /// Decode a value from the beginning of `buf`.
95    fn ara_deserialize(buf: &[u8]) -> Result<Self, AraComError>;
96}
97
98/// Async transport backend trait.
99///
100/// This is the primary extension point of `ara-com`. Transport backends
101/// (such as `ara-com-someip`) implement this trait to provide the actual
102/// network I/O. Generated proxy and skeleton code interacts with the
103/// transport exclusively through this interface.
104///
105/// # Instance binding invariant
106///
107/// A transport enforces **one instance per service per transport**: once a
108/// service ID is bound to an instance (via [`offer_service`](Transport::offer_service),
109/// [`find_service`](Transport::find_service), or
110/// [`subscribe_event_group`](Transport::subscribe_event_group)), attempting
111/// to bind a *different* instance for the same service on the same transport
112/// must return an error.
113#[async_trait]
114pub trait Transport: Send + Sync + 'static {
115    /// Send a request and wait for a response
116    async fn send_request(
117        &self,
118        header: MessageHeader,
119        payload: Bytes,
120    ) -> Result<(MessageHeader, Bytes), AraComError>;
121
122    /// Send a fire-and-forget message
123    async fn send_fire_and_forget(
124        &self,
125        header: MessageHeader,
126        payload: Bytes,
127    ) -> Result<(), AraComError>;
128
129    /// Send a notification/event
130    async fn send_notification(
131        &self,
132        header: MessageHeader,
133        payload: Bytes,
134    ) -> Result<(), AraComError>;
135
136    /// Offer a service instance (skeleton side)
137    async fn offer_service(
138        &self,
139        service_id: ServiceId,
140        instance_id: InstanceId,
141        major_version: MajorVersion,
142        minor_version: MinorVersion,
143    ) -> Result<(), AraComError>;
144
145    /// Stop offering a service
146    async fn stop_offer_service(
147        &self,
148        service_id: ServiceId,
149        instance_id: InstanceId,
150    ) -> Result<(), AraComError>;
151
152    /// Find a service instance (proxy side)
153    async fn find_service(
154        &self,
155        service_id: ServiceId,
156        instance_id: InstanceId,
157        major_version: MajorVersion,
158        minor_version: MinorVersion,
159    ) -> Result<ServiceInstanceId, AraComError>;
160
161    /// Register a handler for incoming requests (skeleton side)
162    async fn register_request_handler(
163        &self,
164        service_id: ServiceId,
165        instance_id: InstanceId,
166        handler: Box<
167            dyn Fn(
168                    MessageHeader,
169                    Bytes,
170                )
171                    -> futures_core::future::BoxFuture<'static, Result<Bytes, AraComError>>
172                + Send
173                + Sync,
174        >,
175    ) -> Result<(), AraComError>;
176
177    /// Subscribe to an event group
178    async fn subscribe_event_group(
179        &self,
180        service_id: ServiceId,
181        instance_id: InstanceId,
182        event_group_id: EventGroupId,
183    ) -> Result<(), AraComError>;
184
185    /// Unsubscribe from an event group
186    async fn unsubscribe_event_group(
187        &self,
188        service_id: ServiceId,
189        instance_id: InstanceId,
190        event_group_id: EventGroupId,
191    ) -> Result<(), AraComError>;
192}