Doip server initial code #4
Conversation
|
Is this code supposed to build? When I ran cargo check and cargo build, I encountered some errors. IMO, code should build successfully. |
a11f029 to
c674ff3
Compare
build is successful is now. |
src/doip/diagnostic_message.rs
Outdated
| pub fn parse(payload: &[u8]) -> Result<Self, Error> { | ||
| let header: [u8; 4] = | ||
| payload | ||
| .get(..4) |
There was a problem hiding this comment.
magic number? other places I could see used const
Not just here, please check below ones
There was a problem hiding this comment.
Fixed all magic numbers across the codebase (named constants , protocol versions, and message sizes). Will push in the next commit.
|
fix minor formatting inconsistencies |
arvindr19
left a comment
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
same defined in errors.rs
why so?
There was a problem hiding this comment.
Fixed , re-exported now
| // Response codes per ISO 13400-2:2019 Table 25 | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| #[repr(u8)] | ||
| pub enum ResponseCode { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
@VinaykumarRS1995 please briefly comment in case you resolved it
src/doip/header_parser.rs
Outdated
| 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)"), |
There was a problem hiding this comment.
lib should never panic, return Result instead
There was a problem hiding this comment.
Fixed, retruns Result now.
darkwisebear
left a comment
There was a problem hiding this comment.
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
thiserroreverywhere. - Introduce a trait for message types and use everywhere
- Deduplicate common parsing code
src/doip/alive_check.rs
Outdated
| use bytes::{BufMut, Bytes, BytesMut}; | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub enum Error { |
There was a problem hiding this comment.
This crate references thiserror. You could use it to declare this error in a more convenient way.
src/doip/vehicle_id.rs
Outdated
| use bytes::{BufMut, Bytes, BytesMut}; | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub enum Error { |
There was a problem hiding this comment.
A similar definition exists in alive_check.rs. Imo we should have a common definition of an error type for the entire module.
There was a problem hiding this comment.
moved to mod.rs and shared across
|
|
||
| // Vehicle Identification Request (0x0001) - no payload | ||
| #[derive(Debug, Clone, PartialEq, Eq, Default)] | ||
| pub struct Request; |
There was a problem hiding this comment.
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.
src/doip/vehicle_id.rs
Outdated
| 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(), | ||
| })?; |
There was a problem hiding this comment.
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.
src/doip/header_parser.rs
Outdated
|
|
||
| impl PayloadType { | ||
| #[must_use] | ||
| pub fn from_u16(value: u16) -> Option<Self> { |
There was a problem hiding this comment.
Why not impl TryFrom<u16> for PayloadType? This is more canonical than such a custom function.
src/server/config.rs
Outdated
| let bind = server | ||
| .bind_address | ||
| .as_deref() | ||
| .unwrap_or(DEFAULT_BIND_ADDRESS); |
There was a problem hiding this comment.
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 }".
There was a problem hiding this comment.
Yes , it is updated now
src/doip/alive_check.rs
Outdated
| @@ -0,0 +1,144 @@ | |||
| /* | |||
| * Copyright (c) 2025 The Contributors to Eclipse OpenSOVD (see CONTRIBUTORS) | |||
There was a problem hiding this comment.
year should be 2026, please check all the license headers
81e9ff5 to
9fa0c6e
Compare
|
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. |
lh-sag
left a comment
There was a problem hiding this comment.
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.
Cargo.toml
Outdated
| [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"] } |
There was a problem hiding this comment.
Always use default-features = false and explicitly add feature as needed. This reduced sbom and binary size often significantly.
src/uds/mod.rs
Outdated
| // #[cfg(any(test, feature = "test-handlers"))] | ||
| // pub mod dummy_handler; |
src/server/config.rs
Outdated
| 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"); |
There was a problem hiding this comment.
Optional: I would rather return a proper error type than a string.
Cargo.toml
Outdated
| dashmap = "6.0" | ||
| parking_lot = "0.12" |
There was a problem hiding this comment.
Can you please double check that all crates are used/referenced in your code?
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. |
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. |
@lh-sag personally, I would be reluctant with using creates where there is only exactly one maintainer and no updates in the github repo since quite some time. This is risk in my eyes. What's your opinion on this situation? |
The consideration for integrating DoIP crates is tracked in #9 - will revisit once they are officially part of the OpenSOVD project. Not blocking this PR. |
src/doip/alive_check.rs
Outdated
| } | ||
|
|
||
| impl DoipParseable for Response { | ||
| fn parse(payload: &[u8]) -> std::result::Result<Self, DoipError> { |
There was a problem hiding this comment.
| fn parse(payload: &[u8]) -> std::result::Result<Self, DoipError> { | |
| fn parse(payload: &[u8]) -> crate::DoipResult<Self> { |
There was a problem hiding this comment.
This repeats in other files, please also fix there.
There was a problem hiding this comment.
Done. Added pub use error::DoipResult in lib.rs and updated all signatures across the codebase — no raw Result<_, DoipError> left anywhere outside error.rs.
src/doip/diagnostic_message.rs
Outdated
| // Diagnostic message positive ack codes per ISO 13400-2:2019 Table 27 | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| #[repr(u8)] | ||
| pub enum AckCode { |
There was a problem hiding this comment.
Why would this need to be exposed? Isn't that simply signalling "no error", which would be encoded as Ok(...)?
There was a problem hiding this comment.
AckCode::Acknowledged was just encoding "no error" as a type — removed it. Replaced with AckResult::Positive (no code needed) and AckResult::Negative(NackCode) for the failure case.
src/doip/diagnostic_message.rs
Outdated
| pub struct PositiveAck { | ||
| source_address: u16, | ||
| target_address: u16, | ||
| ack_code: AckCode, |
There was a problem hiding this comment.
That seems redundant. The pure existence of the instance indicates success.
There was a problem hiding this comment.
Merged PositiveAck and NegativeAck into a single DiagnosticAck with result: AckResult (Positive | Negative(NackCode)).
src/doip/diagnostic_message.rs
Outdated
| /// # Wire Format | ||
| /// Payload: SA(2) + TA(2) + nack_code(1) + optional previous_diag_data | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct NegativeAck { |
There was a problem hiding this comment.
This looks exactly like PositiveAck. I have the feeling that it makes sense to merge both structs, and also the code, into one entity that simply represents what was received, no matter whether it was negative or positive.
There was a problem hiding this comment.
Merged PositiveAck and NegativeAck into a single DiagnosticAck with result: AckResult (Positive | Negative(NackCode)).
c8ccfbf to
0c12dc0
Compare
doip-server/src/doip/alive_check.rs
Outdated
| Some(0) | ||
| } | ||
|
|
||
| fn write_to(&self, _buf: &mut BytesMut) {} |
There was a problem hiding this comment.
maybe add todo! ("...") or unimplemented!("...") so if this method then it will through error.
There was a problem hiding this comment.
Done. Added comment: // Intentionally empty — Alive Check Request has zero-length payload per ISO 13400-2.
| } | ||
|
|
||
| impl Response { | ||
| pub const LEN: usize = 2; |
There was a problem hiding this comment.
Added /// doc comments to all constants explaining wire-format size.
| /// Override this to enable pre-allocated buffers in [`to_bytes`], avoiding | ||
| /// incremental `BytesMut` reallocations for large messages. | ||
| fn serialized_len(&self) -> Option<usize> { | ||
| None |
There was a problem hiding this comment.
Returning None in the default implementation doesn’t seem correct to me. If a user calls this method on a type that doesn’t override it, they still get a valid Option, which may be misleading.
There was a problem hiding this comment.
Done, Changes are pushed
doip-server/src/doip/mod.rs
Outdated
| .and_then(|s| s.try_into().ok()) | ||
| .ok_or_else(|| { | ||
| let e = too_short(payload, N); | ||
| warn!("{} parse failed: {}", context, e); |
There was a problem hiding this comment.
Done. Changed all parse-failure sites to error!. warn! kept only for recoverable NACK paths.
doip-server/src/doip/mod.rs
Outdated
| }) | ||
| } | ||
|
|
||
| // Re-export core types and constants for convenient access. |
There was a problem hiding this comment.
Consider keeping the header at the start of the file. If it’s user-facing, re-exporting it via lib.rs could be a good option.
There was a problem hiding this comment.
Done. Moved all pub use re-exports to top mod.rs
doip-server/src/server/session.rs
Outdated
| pub struct SessionManager { | ||
| sessions: RwLock<HashMap<u64, Session>>, | ||
| addr_to_session: RwLock<HashMap<SocketAddr, u64>>, | ||
| next_id: RwLock<u64>, |
There was a problem hiding this comment.
Do we really need RwLock for next_id ?
|
In general I would like to see structured logs instead of strings. This is done in CDA and Core. Can you please apply this to your logs? With structured logging (simplified for demonstration purpose): |
doip-server/src/server/session.rs
Outdated
| sessions: RwLock<HashMap<u64, Session>>, | ||
| addr_to_session: RwLock<HashMap<SocketAddr, u64>>, | ||
| next_id: RwLock<u64>, |
There was a problem hiding this comment.
Do you need such fine granular locking? Instead you could have an inner session manager and have a single rwlock.
Lock contention might be longer but you have atomicity.
I did not looked further into detail but please consider this if it is applicable.
There was a problem hiding this comment.
Done. Consolidated to single RwLock for atomic map consistency + AtomicU64 for lock-free ID allocation.
doip-server/src/error.rs
Outdated
| pub use crate::doip::routing_activation::ResponseCode as RoutingActivationCode; | ||
|
|
||
| /// Result type alias for `DoIP` operations | ||
| pub type DoipResult<T> = std::result::Result<T, DoipError>; |
There was a problem hiding this comment.
Usually the alias is Result and this is how it is named across the opensovd code base. Please also check the with the diag lib guys about the naming.
There was a problem hiding this comment.
Renamed to pub type Result.
src/doip/hearder_parser.rs
Outdated
| pub enum ParseError { | ||
| InvalidHeader(String), | ||
| Io(io::Error), | ||
| } | ||
|
|
||
| impl std::fmt::Display for ParseError { | ||
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
| match self { | ||
| Self::InvalidHeader(msg) => write!(f, "Invalid header: {}", msg), | ||
| Self::Io(e) => write!(f, "IO error: {}", e), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl std::error::Error for ParseError {} | ||
|
|
||
| impl From<io::Error> for ParseError { | ||
| fn from(e: io::Error) -> Self { | ||
| Self::Io(e) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
You already use thiserror, please use it here as well if it is applicable.
There was a problem hiding this comment.
Done — ParseError removed, all errors unified under DoipError with #[derive(thiserror::Error)].
- Renamed hearder_parser.rs to header_parser.rs (typo fix) - Added unit tests for header parsing - Updated MAX_DOIP_MESSAGE_SIZE to 4MB
- 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
- 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
Replace std::result::Result<_, DoipError> with crate::DoipResult across all files; add pub use error::DoipResult in lib.rs - remove redundant AckCode enum - remove redundant ack_code field from PositiveAck - merge PositiveAck + NegativeAck into DiagnosticAck with AckResult enum (Positive | Negative(NackCode))
3ce6bcb to
3e77b11
Compare
doip-server/src/lib.rs
Outdated
| /// UDS service layer – bridges DoIP transport to ISO 14229-1 request/response handling. | ||
| pub mod uds; | ||
| pub use error::DoipError; | ||
| pub use error::Result; |
There was a problem hiding this comment.
@VinaykumarRS1995 how would this Result type get used on user side now? will there still be a prefix? and how would it look like?
There was a problem hiding this comment.
Yes,the crate name acts as the natural prefix. Re-exported via pub use error::Result in lib.rs, it's accessible as:
// fully qualified
fn parse() -> doip_server::Result
// or with import
use doip_server::Result;
fn connect() -> Result { ... }
At least sharing the definition for DoIP across client (CDA) and server (this project) would be good. Afair the definition crate will now me forked to this organisation and will then be maintained by use. |
Yes, that's what we agreed on with the CDS folks :) |
3e77b11 to
e9e6b36
Compare
- structured tracing logging; error! for parse failures - rename DoipResult → Result - single RwLock<SessionManagerInner> + AtomicU64 - merge DiagnosticAck + AckResult; remove AckCode - doc comments on all public API items
e9e6b36 to
d2f96e9
Compare
deny.toml
Outdated
| allow = ["Apache-2.0", "MIT"] | ||
| # Unicode-3.0 is required by `unicode-ident` (transitive dep of serde/thiserror) | ||
| # and is an OSI-approved license covering Unicode data tables. | ||
| allow = ["Apache-2.0", "MIT", "Unicode-3.0"] |
There was a problem hiding this comment.
I intentionally limited it to Apache and MIT licenses, as we were not certain which licenses the proxy should be permitted to use. As @stmuench suggested limited to 2 licenses.
There was a problem hiding this comment.
Agreed, @stmuench is reviewing the approved license list — handled as a scoped exception for unicode-ident only for now.
Cargo.toml
Outdated
| pedantic = { level = "warn", priority = -1 } | ||
| ## exclude some too pedantic lints for now | ||
| similar_names = "allow" | ||
| module_name_repetitions = "allow" |
| workspace = true | ||
|
|
||
| # Lints are aligned with shared-lints.toml from: | ||
| # https://github.com/eclipse-opensovd/cicd-workflows/tree/main/shared-lints |
There was a problem hiding this comment.
This is the workspace Cargo.toml, so this information shouldn’t be removed. I’d suggest keeping these changes in the package-level Cargo.toml instead. I also noticed that the comments below were removed, please keep them intact.
There was a problem hiding this comment.
Restored — lint header comment and all per-lint explanatory comments are kept intact.
| @@ -1,3 +1,6 @@ | |||
| # SPDX-License-Identifier: Apache-2.0 | |||
| # SPDX-FileCopyrightText: 2026 The Contributors to Eclipse OpenSOVD (see CONTRIBUTORS) | |||
| @@ -0,0 +1,46 @@ | |||
| # SPDX-License-Identifier: Apache-2.0 | |||
There was a problem hiding this comment.
Regarding the Cargo.toml hierarchy: define shared crate metadata in the workspace-level Cargo.toml (workspace.package) and inherit it in the package-level Cargo.toml. Please refer to the CDA multi-crate structure, as we’ll eventually have the same hierarchy.
There was a problem hiding this comment.
Yes. Updated and Pushed
| /// * `source` - Source address (tester or ECU) | ||
| /// * `target` - Target address (tester or ECU) | ||
| /// * `data` - UDS payload data | ||
| pub fn new(source: u16, target: u16, data: Bytes) -> Self { |
There was a problem hiding this comment.
| pub fn new(source: u16, target: u16, data: Bytes) -> Self { | |
| pub fn new(source: u16, target: u16, data: Bytes) -> Result<Self> { | |
| if data.is_empty() { | |
| return Err(DoipError::EmptyUserData); | |
| } | |
| Ok(Self { source_address: source, target_address: target, user_data: data }) | |
| } |
Isn't it better to handle empty data?
There was a problem hiding this comment.
Updated.
Message::new will return crate::Result and return Err(DoipError::EmptyUserData) when data.is_empty().
lh-sag
left a comment
There was a problem hiding this comment.
@VinaykumarRS1995 thansk for addressing the reviews. LGTM.
|
|
||
| impl DoipParseable for Request { | ||
| fn parse(_payload: &[u8]) -> crate::Result<Self> { | ||
| Ok(Self) |
There was a problem hiding this comment.
minor issue to consider in a follow-up PR: should we return an error here in case the payload would not be empty as expected?
There was a problem hiding this comment.
Agreed, noted as a follow-up PR
| dst.extend_from_slice(&item.payload); | ||
| Ok(()) | ||
| } | ||
| } |
There was a problem hiding this comment.
why no unit tests for this file?
There was a problem hiding this comment.
Fixed. Unit tests added.
| } | ||
|
|
||
| /// Get the source address | ||
| pub fn source_address(&self) -> u16 { |
There was a problem hiding this comment.
down below, you used #[must_use]. why not here as well?
doip-server/src/doip/header.rs
Outdated
| /// | ||
| /// Returns `None` if valid, or the `GenericNackCode` describing the first violation. | ||
| pub fn validate(&self) -> Option<GenericNackCode> { | ||
| debug!( |
There was a problem hiding this comment.
do we really want to debug EVERY incoming doip header? that would flood the logs I fear
| error!(context, error = %e, "parse failed"); | ||
| e | ||
| }) | ||
| } |
There was a problem hiding this comment.
why no unit tests for this file?
There was a problem hiding this comment.
ixed. Unit tests added.
| PayloadType::GenericNack, | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
from these few unit tests, I could already spot that we are not covering 95% of the LOCs here. but that might be something for a follow-up PR
There was a problem hiding this comment.
Agreed, noted as a follow-up PR
doip-server/src/error.rs
Outdated
| #[cfg(test)] | ||
| /// UDS Negative Response Codes (ISO 14229-1:2020) | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| #[repr(u8)] | ||
| enum UdsNrc { | ||
| GeneralReject = 0x10, | ||
| ServiceNotSupported = 0x11, | ||
| SubFunctionNotSupported = 0x12, | ||
| IncorrectMessageLength = 0x13, | ||
| BusyRepeatRequest = 0x21, | ||
| ConditionsNotCorrect = 0x22, | ||
| RequestSequenceError = 0x24, | ||
| RequestOutOfRange = 0x31, | ||
| SecurityAccessDenied = 0x33, | ||
| InvalidKey = 0x35, | ||
| ExceededNumberOfAttempts = 0x36, | ||
| RequiredTimeDelayNotExpired = 0x37, | ||
| ResponsePending = 0x78, | ||
| ServiceNotSupportedInActiveSession = 0x7F, | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| impl UdsNrc { | ||
| #[must_use] | ||
| const fn as_u8(self) -> u8 { | ||
| self as u8 | ||
| } | ||
| } |
There was a problem hiding this comment.
why moving this into the tests mod below?
There was a problem hiding this comment.
Fixed — moved inside mod tests.
| uses: actions/checkout@v4 | ||
| - name: Format and Clippy - Nightly toolchain pinned | ||
| uses: eclipse-opensovd/cicd-workflows/rust-lint-and-format-action@41c531349e9d7e7852455c35682cd200519fb81b | ||
| uses: eclipse-opensovd/cicd-workflows/rust-lint-and-format-action@fef5cc7b2d4c4c6593b105402fbf4edd54db7d5a |
There was a problem hiding this comment.
please explain why these adjustments are required for this PR
There was a problem hiding this comment.
These files exist in the repo from upstream main. Only the SHA on the "Nightly latest" step was bumped to track current cicd-workflows main — the "Nightly pinned" step was missed and will be updated to match.
There was a problem hiding this comment.
suggestion: revert the changes from this file and if needed create a separate PR to update CICD workflow.
| // Diagnostic message negative ack codes per ISO 13400-2:2019 Table 28 | ||
| #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
| #[repr(u8)] | ||
| pub enum NackCode { |
There was a problem hiding this comment.
@VinaykumarRS1995 please briefly comment in case you resolved it
|
|
||
| let mut buf = BytesMut::new(); | ||
| codec.encode(original.clone(), &mut buf).unwrap(); | ||
| let decoded = codec.decode(&mut buf).unwrap().unwrap(); |
There was a problem hiding this comment.
to be checked as a follow-up PR: it's kind of weird that we have to perform unwrap().unwrap(). this smells like inappropriate combination of API types. or is this there a reasonable explanation why that should be required?
| pub struct RequestWithEid { | ||
| eid: [u8; 6], | ||
| } | ||
|
|
||
| impl RequestWithEid { | ||
| /// Fixed wire-format length of a Vehicle Identification Request with EID | ||
| /// payload (6-byte EID filter). | ||
| pub const LEN: usize = 6; | ||
|
|
||
| /// Create a new Vehicle Identification Request filtered by the given 6-byte EID. | ||
| #[must_use] | ||
| pub fn new(eid: [u8; 6]) -> Self { | ||
| Self { eid } | ||
| } | ||
|
|
||
| /// The EID filter value | ||
| #[must_use] | ||
| pub fn eid(&self) -> &[u8; 6] { | ||
| &self.eid | ||
| } | ||
| } | ||
|
|
||
| /// Vehicle Identification Request filtered by VIN (payload type `0x0003`). | ||
| /// | ||
| /// Only the `DoIP` entity with a matching 17-byte VIN should respond. | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct RequestWithVin { | ||
| vin: [u8; 17], | ||
| } | ||
|
|
||
| impl RequestWithVin { | ||
| /// Fixed wire-format length of a Vehicle Identification Request with VIN payload (17-byte VIN). | ||
| pub const LEN: usize = 17; | ||
|
|
||
| /// Create a new Vehicle Identification Request filtered by the given 17-byte VIN. | ||
| #[must_use] | ||
| pub fn new(vin: [u8; 17]) -> Self { | ||
| Self { vin } | ||
| } | ||
|
|
||
| /// The VIN filter value as bytes | ||
| #[must_use] | ||
| pub fn vin(&self) -> &[u8; 17] { | ||
| &self.vin | ||
| } | ||
|
|
||
| /// The VIN filter value as a UTF-8 string (lossy – non-UTF-8 bytes replaced with `�`). | ||
| #[must_use] | ||
| pub fn vin_string(&self) -> String { | ||
| String::from_utf8_lossy(&self.vin).to_string() | ||
| } | ||
| } |
There was a problem hiding this comment.
you are still using literal values here, such as 6 and 17. why can't we instead use the constants that you defined above. I mean, that's what these should be used for, shouldn't they?
|
|
||
| impl DoipParseable for Request { | ||
| fn parse(_payload: &[u8]) -> crate::Result<Self> { | ||
| Ok(Self) |
There was a problem hiding this comment.
what if _payload is not empty as expected? shouldn't this result in an error?
|
|
||
| /// Thread-safe registry of active `DoIP` sessions. | ||
| /// | ||
| /// The mutable session state is held in a single [`RwLock`]-protected `Inner` |
There was a problem hiding this comment.
| /// The mutable session state is held in a single [`RwLock`]-protected `Inner` | |
| /// The mutable session state is held in this single [`RwLock`]-protected `Inner` |
|
|
||
| use bytes::Bytes; | ||
|
|
||
| /// UDS Service IDs (ISO 14229-1:2020) |
There was a problem hiding this comment.
could you add a more precise reference, i.e. section or table id, here?
|
|
||
|
|
There was a problem hiding this comment.
could you omit these two newly added newlines here?
| uses: actions/checkout@v4 | ||
| - name: Format and Clippy - Nightly toolchain pinned | ||
| uses: eclipse-opensovd/cicd-workflows/rust-lint-and-format-action@41c531349e9d7e7852455c35682cd200519fb81b | ||
| uses: eclipse-opensovd/cicd-workflows/rust-lint-and-format-action@fef5cc7b2d4c4c6593b105402fbf4edd54db7d5a |
There was a problem hiding this comment.
suggestion: revert the changes from this file and if needed create a separate PR to update CICD workflow.
| steps: | ||
| - name: Run checks | ||
| uses: eclipse-opensovd/cicd-workflows/pre-commit-action@41c531349e9d7e7852455c35682cd200519fb81b | ||
| uses: eclipse-opensovd/cicd-workflows/pre-commit-action@fef5cc7b2d4c4c6593b105402fbf4edd54db7d5a |
| impl RequestWithEid { | ||
| /// Fixed wire-format length of a Vehicle Identification Request with EID | ||
| /// payload (6-byte EID filter). | ||
| pub const LEN: usize = 6; |
There was a problem hiding this comment.
LEN is very generic, please make it meaningful and use it in below functions,
Same comment is valid for VIN related code snippet
| /// VIN(17) + LogicalAddr(2) + EID(6) + GID(6) + FurtherAction(1) + optional SyncStatus(1) | ||
| #[derive(Debug, Clone, PartialEq, Eq)] | ||
| pub struct Response { | ||
| vin: [u8; 17], |
There was a problem hiding this comment.
vin, eid , gid etc lengths defined as const at line 23 not used
Summary
Checklist