1use core::fmt::{self, Display};
2
3#[derive(Debug, PartialEq, Eq, Clone, Copy)]
5pub struct MessageId {
6 pub service_id: u16,
7 pub method_id: u16,
8}
9
10impl MessageId {
11 pub fn from_u32(value: u32) -> MessageId {
20 MessageId {
21 service_id: (value >> 16) as u16,
22 method_id: (value & 0xFFFF) as u16,
23 }
24 }
25
26 pub fn to_u32(&self) -> u32 {
32 ((self.service_id as u32) << 16) | (self.method_id as u32)
33 }
34}
35
36impl Display for MessageId {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 write!(f, "{:04X}.{:04X}", self.service_id, self.method_id)
39 }
40}
41
42#[derive(Debug, PartialEq, Eq, Clone, Copy)]
44pub struct ClientId {
45 pub client_id_prefix: u8,
46 pub client_id: u8,
47}
48
49#[allow(dead_code)]
50impl ClientId {
51 pub fn from_u16(value: u16) -> ClientId {
60 ClientId {
61 client_id_prefix: ((value >> 8) & 0xFF) as u8,
62 client_id: (value & 0xFF) as u8,
63 }
64 }
65
66 pub fn to_u16(&self) -> u16 {
72 ((self.client_id_prefix as u16) << 8) | (self.client_id as u16)
73 }
74}
75
76impl Display for ClientId {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 write!(f, "{:02X}.{:02X}", self.client_id_prefix, self.client_id)
79 }
80}
81
82#[derive(Debug, PartialEq, Eq, Clone, Copy)]
84pub struct RequestId {
85 pub client_id: ClientId,
86 pub session_id: u16,
87}
88
89#[allow(dead_code)]
90impl RequestId {
91 pub fn from_u32(value: u32) -> RequestId {
100 RequestId {
101 client_id: ClientId::from_u16((value >> 16) as u16),
102 session_id: (value & 0xFFFF) as u16,
103 }
104 }
105
106 pub fn to_u32(&self) -> u32 {
112 ((self.client_id.to_u16() as u32) << 16) | (self.session_id as u32)
113 }
114}
115
116impl Display for RequestId {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 write!(f, "{}.{:04X}", self.client_id, self.session_id)
119 }
120}
121
122#[derive(PartialEq, Eq, Clone, Copy, Debug)]
128#[allow(non_camel_case_types)]
129pub enum ReturnCode {
130 E_OK,
132 E_NOT_OK,
134 E_UNKNOWN_SERVICE,
136 E_UNKNOWN_METHOD,
138 E_NOT_READY,
140 E_NOT_REACHABLE,
142 E_TIMEOUT,
144 E_WRONG_PROTOCOL_VERSION,
146 E_WRONG_INTERFACE_VERSION,
148 E_MALFORMED_MESSAGE,
150 E_WRONG_MESSAGE_TYPE,
152 E_E2E_REPEATED,
154 E_E2E_WRONG_SEQUENCE,
156 E_E2E,
158 E_E2E_NOT_AVAILABLE,
160 E_E2E_NO_NEW_DATA,
162 ReservedSomeIP(u8),
164 ReservedServiceMethod(u8),
166}
167
168impl ReturnCode {
169 pub fn from_u8(value: u8) -> Option<Self> {
173 if value > 0x5E {
174 return None;
175 }
176
177 Some(match value {
178 0x00 => ReturnCode::E_OK,
179 0x01 => ReturnCode::E_NOT_OK,
180 0x02 => ReturnCode::E_UNKNOWN_SERVICE,
181 0x03 => ReturnCode::E_UNKNOWN_METHOD,
182 0x04 => ReturnCode::E_NOT_READY,
183 0x05 => ReturnCode::E_NOT_REACHABLE,
184 0x06 => ReturnCode::E_TIMEOUT,
185 0x07 => ReturnCode::E_WRONG_PROTOCOL_VERSION,
186 0x08 => ReturnCode::E_WRONG_INTERFACE_VERSION,
187 0x09 => ReturnCode::E_MALFORMED_MESSAGE,
188 0x0A => ReturnCode::E_WRONG_MESSAGE_TYPE,
189 0x0B => ReturnCode::E_E2E_REPEATED,
190 0x0C => ReturnCode::E_E2E_WRONG_SEQUENCE,
191 0x0D => ReturnCode::E_E2E,
192 0x0E => ReturnCode::E_E2E_NOT_AVAILABLE,
193 0x0F => ReturnCode::E_E2E_NO_NEW_DATA,
194 0x10..=0x1F => ReturnCode::ReservedSomeIP(value),
195 0x20..=0x5E => ReturnCode::ReservedServiceMethod(value),
196 _ => unreachable!("value validated to be <= 0x5E"),
197 })
198 }
199
200 pub fn as_u8(&self) -> u8 {
202 match self {
203 ReturnCode::E_OK => 0x00,
204 ReturnCode::E_NOT_OK => 0x01,
205 ReturnCode::E_UNKNOWN_SERVICE => 0x02,
206 ReturnCode::E_UNKNOWN_METHOD => 0x03,
207 ReturnCode::E_NOT_READY => 0x04,
208 ReturnCode::E_NOT_REACHABLE => 0x05,
209 ReturnCode::E_TIMEOUT => 0x06,
210 ReturnCode::E_WRONG_PROTOCOL_VERSION => 0x07,
211 ReturnCode::E_WRONG_INTERFACE_VERSION => 0x08,
212 ReturnCode::E_MALFORMED_MESSAGE => 0x09,
213 ReturnCode::E_WRONG_MESSAGE_TYPE => 0x0A,
214 ReturnCode::E_E2E_REPEATED => 0x0B,
215 ReturnCode::E_E2E_WRONG_SEQUENCE => 0x0C,
216 ReturnCode::E_E2E => 0x0D,
217 ReturnCode::E_E2E_NOT_AVAILABLE => 0x0E,
218 ReturnCode::E_E2E_NO_NEW_DATA => 0x0F,
219 ReturnCode::ReservedSomeIP(v) => *v,
220 ReturnCode::ReservedServiceMethod(v) => *v,
221 }
222 }
223
224 pub const fn is_ok(&self) -> bool {
226 matches!(self, ReturnCode::E_OK)
227 }
228
229 pub const fn is_reserved_someip(&self) -> bool {
231 matches!(self, ReturnCode::ReservedSomeIP(_))
232 }
233
234 pub const fn is_reserved_service_method(&self) -> bool {
236 matches!(self, ReturnCode::ReservedServiceMethod(_))
237 }
238}
239
240impl From<ReturnCode> for u8 {
242 fn from(code: ReturnCode) -> Self {
243 code.as_u8()
244 }
245}
246
247impl Display for ReturnCode {
248 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
249 match self {
250 ReturnCode::E_OK => write!(f, "E_OK"),
251 ReturnCode::E_NOT_OK => write!(f, "E_NOT_OK"),
252 ReturnCode::E_UNKNOWN_SERVICE => write!(f, "E_UNKNOWN_SERVICE"),
253 ReturnCode::E_UNKNOWN_METHOD => write!(f, "E_UNKNOWN_METHOD"),
254 ReturnCode::E_NOT_READY => write!(f, "E_NOT_READY"),
255 ReturnCode::E_NOT_REACHABLE => write!(f, "E_NOT_REACHABLE"),
256 ReturnCode::E_TIMEOUT => write!(f, "E_TIMEOUT"),
257 ReturnCode::E_WRONG_PROTOCOL_VERSION => write!(f, "E_WRONG_PROTOCOL_VERSION"),
258 ReturnCode::E_WRONG_INTERFACE_VERSION => write!(f, "E_WRONG_INTERFACE_VERSION"),
259 ReturnCode::E_MALFORMED_MESSAGE => write!(f, "E_MALFORMED_MESSAGE"),
260 ReturnCode::E_WRONG_MESSAGE_TYPE => write!(f, "E_WRONG_MESSAGE_TYPE"),
261 ReturnCode::E_E2E_REPEATED => write!(f, "E_E2E_REPEATED"),
262 ReturnCode::E_E2E_WRONG_SEQUENCE => write!(f, "E_E2E_WRONG_SEQUENCE"),
263 ReturnCode::E_E2E => write!(f, "E_E2E"),
264 ReturnCode::E_E2E_NOT_AVAILABLE => write!(f, "E_E2E_NOT_AVAILABLE"),
265 ReturnCode::E_E2E_NO_NEW_DATA => write!(f, "E_E2E_NO_NEW_DATA"),
266 ReturnCode::ReservedSomeIP(v) => write!(f, "Reserved SOME/IP Error (0x{:02X})", v),
267 ReturnCode::ReservedServiceMethod(v) => {
268 write!(f, "Reserved Service/Method Error (0x{:02X})", v)
269 }
270 }
271 }
272}
273
274#[derive(Debug, PartialEq, Eq, Clone, Copy)]
279pub enum MessageType {
280 Request,
282 RequestNoReturn,
284 Notification,
286 Response,
288 Error,
290 TPRequest,
292 TPRequestNoReturn,
294 TPNotification,
296 TPResponse,
298 TPError,
300}
301
302impl MessageType {
303 pub fn from_u8(value: u8) -> Option<Self> {
307 match value {
308 0x00 => Some(MessageType::Request),
309 0x01 => Some(MessageType::RequestNoReturn),
310 0x02 => Some(MessageType::Notification),
311 0x03 => Some(MessageType::Response),
312 0x04 => Some(MessageType::Error),
313 0x20 => Some(MessageType::TPRequest),
314 0x21 => Some(MessageType::TPRequestNoReturn),
315 0x22 => Some(MessageType::TPNotification),
316 0xA0 => Some(MessageType::TPResponse),
317 0xA1 => Some(MessageType::TPError),
318 _ => None,
319 }
320 }
321
322 pub fn as_u8(&self) -> u8 {
324 match self {
325 MessageType::Request => 0x00,
326 MessageType::RequestNoReturn => 0x01,
327 MessageType::Notification => 0x02,
328 MessageType::Response => 0x03,
329 MessageType::Error => 0x04,
330 MessageType::TPRequest => 0x20,
331 MessageType::TPRequestNoReturn => 0x21,
332 MessageType::TPNotification => 0x22,
333 MessageType::TPResponse => 0xA0,
334 MessageType::TPError => 0xA1,
335 }
336 }
337
338 pub const fn is_request(&self) -> bool {
340 matches!(self, MessageType::Request | MessageType::TPRequest)
341 }
342
343 pub const fn is_request_no_return(&self) -> bool {
345 matches!(
346 self,
347 MessageType::RequestNoReturn | MessageType::TPRequestNoReturn
348 )
349 }
350
351 pub const fn is_notification(&self) -> bool {
353 matches!(
354 self,
355 MessageType::Notification | MessageType::TPNotification
356 )
357 }
358
359 pub const fn is_response(&self) -> bool {
361 matches!(self, MessageType::Response | MessageType::TPResponse)
362 }
363
364 pub const fn is_error(&self) -> bool {
366 matches!(self, MessageType::Error | MessageType::TPError)
367 }
368
369 pub const fn is_tp(&self) -> bool {
371 matches!(
372 self,
373 MessageType::TPRequest
374 | MessageType::TPRequestNoReturn
375 | MessageType::TPNotification
376 | MessageType::TPResponse
377 | MessageType::TPError
378 )
379 }
380}
381
382impl From<MessageType> for u8 {
384 fn from(mt: MessageType) -> Self {
385 mt.as_u8()
386 }
387}
388
389impl Display for MessageType {
390 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391 match self {
392 MessageType::Request => write!(f, "Request"),
393 MessageType::RequestNoReturn => write!(f, "Request No Return"),
394 MessageType::Notification => write!(f, "Notification"),
395 MessageType::Response => write!(f, "Response"),
396 MessageType::Error => write!(f, "Error"),
397 MessageType::TPRequest => write!(f, "TP Request"),
398 MessageType::TPRequestNoReturn => write!(f, "TP Request No Return"),
399 MessageType::TPNotification => write!(f, "TP Notification"),
400 MessageType::TPResponse => write!(f, "TP Response"),
401 MessageType::TPError => write!(f, "TP Error"),
402 }
403 }
404}