Skip to content

Doip server initial code #4

Open
VinaykumarRS1995 wants to merge 7 commits intoeclipse-opensovd:mainfrom
VinaykumarRS1995:doip-server-initial
Open

Doip server initial code #4
VinaykumarRS1995 wants to merge 7 commits intoeclipse-opensovd:mainfrom
VinaykumarRS1995:doip-server-initial

Conversation

@VinaykumarRS1995
Copy link

Summary

Checklist

  • I have tested my changes locally
  • I have added or updated documentation
  • I have linked related issues or discussions
  • I have added or updated tests

@arvindr19
Copy link
Contributor

Is this code supposed to build? When I ran cargo check and cargo build, I encountered some errors. IMO, code should build successfully.

@VinaykumarRS1995 VinaykumarRS1995 force-pushed the doip-server-initial branch 2 times, most recently from a11f029 to c674ff3 Compare February 26, 2026 09:40
@VinaykumarRS1995
Copy link
Author

Is this code supposed to build? When I ran cargo check and cargo build, I encountered some errors. IMO, code should build successfully.

build is successful is now.

pub fn parse(payload: &[u8]) -> Result<Self, Error> {
let header: [u8; 4] =
payload
.get(..4)
Copy link
Contributor

@arvindr19 arvindr19 Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magic number? other places I could see used const
Not just here, please check below ones

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed all magic numbers across the codebase (named constants , protocol versions, and message sizes). Will push in the next commit.

@arvindr19
Copy link
Contributor

fix minor formatting inconsistencies
toml = "0.9.11+spec-1.1.0" causing warning, why not toml = "0.9" instead?

Copy link
Contributor

@arvindr19 arvindr19 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only header_parser.rs has any tracing at all. Every other file has no tracing.

/// when the `DoIP` entity cannot process a received message due to header-level issues.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum GenericNackCode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same defined in errors.rs
why so?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed , re-exported now

// Response codes per ISO 13400-2:2019 Table 25
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum ResponseCode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicates in error.rs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed , re-exported now.

// Diagnostic message negative ack codes per ISO 13400-2:2019 Table 28
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum NackCode {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

duplicates in error.rs

inverse_version: DEFAULT_PROTOCOL_VERSION_INV,
payload_type: payload_type as u16,
payload_length: u32::try_from(payload.len())
.expect("DoIP payload exceeds u32::MAX (protocol limit is 4MB)"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lib should never panic, return Result instead

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, retruns Result now.

Copy link

@darkwisebear darkwisebear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't go into details yet, but from what I see there are some general things that need cleanup before I will do that:

  • Consolidate error types and use thiserror everywhere.
  • Introduce a trait for message types and use everywhere
  • Deduplicate common parsing code

use bytes::{BufMut, Bytes, BytesMut};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This crate references thiserror. You could use it to declare this error in a more convenient way.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

use bytes::{BufMut, Bytes, BytesMut};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar definition exists in alive_check.rs. Imo we should have a common definition of an error type for the entire module.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to mod.rs and shared across


// Vehicle Identification Request (0x0001) - no payload
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Request;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shape of this module is very similar to that of alive_check.rs. I think there should be a trait for message types so that there is an impl Request for VehicleIdRequest or the like.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trait defined

Comment on lines +68 to +74
let eid: [u8; 6] = payload
.get(..Self::LEN)
.and_then(|s| s.try_into().ok())
.ok_or(Error::PayloadTooShort {
expected: Self::LEN,
actual: payload.len(),
})?;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such code could be factored out, as there is similar code also in alive_check.rs. I think there should be a submodule messages with common definitions and then types for each message.


impl PayloadType {
#[must_use]
pub fn from_u16(value: u16) -> Option<Self> {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not impl TryFrom<u16> for PayloadType? This is more canonical than such a custom function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, updated.

let bind = server
.bind_address
.as_deref()
.unwrap_or(DEFAULT_BIND_ADDRESS);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

serde allows for specifying defaults inside the type definition. This would save you a lot of code that of the scheme "if value { copy } else { use default }".

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes , it is updated now

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2025 The Contributors to Eclipse OpenSOVD (see CONTRIBUTORS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

year should be 2026, please check all the license headers

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated where needed

- Consolidate errors into DoipError; add TryFrom<u8> on all enums
- Strongly type activation_type field (ActivationType, not u8)
- Add DoipParseable / DoipSerializable traits + DoipPayload dispatch enum
- Override serialized_len() on all impls; fix array size magic numbers
- Make ParseError pub(crate); add serde(default), tracing
@arvindr19
Copy link
Contributor

Please run cargo fmt --check; it currently fails. Once the CI workflow PR is merged, this PR will need to be reworked, so it’s better to fix it beforehand.

@VinaykumarRS1995 VinaykumarRS1995 marked this pull request as ready for review March 2, 2026 09:23
@lh-sag lh-sag requested review from a team and removed request for darkwisebear March 4, 2026 06:32
Copy link

@lh-sag lh-sag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just had a brief look at the PR.

@VinaykumarRS1995 did you had a chance to evaluate any of these crates to ease development?

Adding @alexmohr and @theswiftfox to share their experience with some of the crates above.

Cargo.toml Outdated
Comment on lines +6 to +30
[dependencies]
# Async runtime
tokio = { version = "1.35", features = ["full"] }
tokio-util = { version = "0.7", features = ["codec"] }

# Serialization
serde = { version = "1.0", features = ["derive"] }
toml = "0.9"

# Logging
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }

# Error handling
thiserror = "2.0"
anyhow = "1.0"

# Data structures
bytes = "1.0"
dashmap = "6.0"
parking_lot = "0.12"

# Utilities
uuid = { version = "1.6", features = ["v4"] }
clap = { version = "4.4", features = ["derive"] }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always use default-features = false and explicitly add feature as needed. This reduced sbom and binary size often significantly.

src/uds/mod.rs Outdated
Comment on lines +18 to +19
// #[cfg(any(test, feature = "test-handlers"))]
// pub mod dummy_handler;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove commented out code.

fn parse_vin(s: &str) -> anyhow::Result<[u8; 17]> {
let bytes = s.as_bytes();
if bytes.len() != 17 {
anyhow::bail!("VIN must be exactly 17 characters");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: I would rather return a proper error type than a string.

Cargo.toml Outdated
Comment on lines +25 to +26
dashmap = "6.0"
parking_lot = "0.12"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please double check that all crates are used/referenced in your code?

@alexmohr
Copy link

alexmohr commented Mar 4, 2026

Just had a brief look at the PR.

@VinaykumarRS1995 did you had a chance to evaluate any of these crates to ease development?

* https://github.com/samp-reston/doip-definitions

* https://github.com/samp-reston/doip-codec

* https://github.com/samp-reston/doip-sockets

* https://github.com/samp-reston/doip-server

Adding @alexmohr and @theswiftfox to share their experience with some of the crates above.

We're only using codec and definitions in the CDA as we had some issues with sockets. But using codecs and definitions would already prevent re-implemeting some things here. The sockets connections can be re-used from CDA. Currently both doip libraries we use are forked by @theswiftfox. I believe it would be a good idea to use her fork as a base to officially provide an eclipse fork we use in all of our projects.

- Split header_parser.rs into header.rs + codec.rs
- Merge ParseError into DoipError (single error type)
- Add parse_fixed_slice helper, remove duplicated parse patterns
- Add DoipParseable / DoipSerializable traits
- Make struct fields private, add public getters
- Set default-features = false on all dependencies
- Trim tokio features to io-util only
- Remove dead test-handlers feature from Cargo.toml
@floroks
Copy link

floroks commented Mar 5, 2026

I believe it would be a good idea to use her fork as a base to officially provide an eclipse fork we use in all of our projects.

As we've also run into some issues with the original code, I think we need should fork them into the eclipse-opensovd repo, so we can adapt them quickly to our needs. I'll put it on the agenda for the next architecture board.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants