1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! # Simple `DoIP`
//!
//! An implementation of Diagnostics over IP (`DoIP`), the vehicle-diagnostics transport
//! specified in [ISO 13400-2](https://www.iso.org/standard/74785.html).
//!
//! ## Design
//!
//! The protocol core is `no_std` and zero-copy: [`messages::Message`] borrows directly
//! from the receive buffer and never allocates. Wire primitives come from
//! [`automotive_wire_codec`], re-exported as [`wire`] so consumers do not need their own
//! dependency on it.
//!
//! Capability is layered by Cargo feature, each building on the previous:
//!
//! | Feature | Adds |
//! |---|---|
//! | *(none)* | `no_std` borrowed messages, [`try_frame`] framing, encode/decode |
//! | `alloc` | Owned mirrors (`messages::OwnedMessage`) that outlive the receive buffer |
//! | `std` | `std`-backed I/O and error traits |
//! | `codec` | `message_codec::MessageCodec`, a `tokio-util` `Encoder`/`Decoder` |
//! | `client` | The async `client::Client` |
//! | `server` | The async `server::Server` |
//!
//! `default = []`, so an embedded target gets the `no_std` core with no allocator and no
//! runtime.
//!
//! ## Where to start
//!
//! - **Bare metal / sans-io:** [`try_frame`] delimits a frame from a byte buffer without
//! owning any I/O resource; [`messages::Payload::decode`] then interprets the body.
//! See `examples/bare_metal_codec.rs`.
//! - **Bare-metal entity (server):** [`bare_metal_entity::Entity`] is a complete sans-io
//! ISO 13400-2 entity — vehicle announcement, routing activation, diagnostic-message
//! dispatch — driven through platform callbacks, for `no_std` targets with a single
//! diagnostic TCP socket.
//! - **Async client:** `client::Client` handles connection, routing activation, and
//! acknowledgements (requires the `client` feature). See `examples/simple_client.rs`.
//! - **Async server:** implement `server::ServerConnectionHandler` and hand it to
//! `server::Server` (requires the `server` feature). See `examples/echo_server.rs`.
extern crate alloc;
extern crate std;
pub use LogicalAddress;
pub use ;
pub use Error;
use Duration;
/// Default TCP port for `DoIP`
/// This is the port used for unencrypted connections
/// Used for:
/// * Vehicle information services
/// * Control commands
///
pub const TCP_PORT: u16 = 13400;
/// Default UDP port for `DoIP`
/// This is the port used for discovery
pub const UDP_DISCOVERY_PORT: u16 = 13400;
/// TCP port for `DoIP` over TLS, per ISO 13400-2. Not currently used by this
/// crate: connections are established in the clear via [`TCP_PORT`]; there is no
/// TLS support yet.
pub const TCP_TLS_PORT: u16 = 3496;
/// An example logical address constant of uncertain provenance.
///
/// Despite its name, this value is used exactly once in this repository — by
/// `examples/simple_client.rs`, which assigns it to `server_logical_address`,
/// i.e. the **ECU** side rather than the tester side. No test references it.
///
/// This value is **not** mandated by ISO 13400-2 — a tester's logical address is
/// assigned per-deployment from the range
/// [`LogicalAddress::MIN_CLIENT_ADDRESS`]..=[`LogicalAddress::MAX_CLIENT_ADDRESS`]
/// (`0x0E00`-`0x0FFF`), and `0xE400` falls outside that range, so it is
/// inconsistent with the tester role its name implies. Callers should supply
/// their own deployment-specific addresses rather than relying on this constant.
pub const TESTER_LOGICAL_ADDRESS: LogicalAddress = LogicalAddress;
// DoIP timing and communication parameters
/// Initial inactivity timeout in seconds for TCP connections directly after a `TCP_DATA` socket is established. Timeout is 2 seconds.
///
/// Must complete routing activation within this time otherwise the socket is closed by the `DoIP` entity
pub const TCP_TIMEOUT_INITIAL_INACTIVITY: Duration = from_secs;
/// General inactivity timeout for TCP connections. Timeout is 300 seconds (5 minutes).
///
/// If no data is sent or received for this duration, the connection is closed by the `DoIP` entity
pub const TCP_TIMEOUT_GENERAL_INACTIVITY: Duration = from_secs;
/// Alive check for the maximum amount of time an entity waits for an alive check response after having
/// made an alive check request. Timeout is 5 seconds.
pub const TCP_TIMEOUT_ALIVE_CHECK: Duration = from_secs;
/// Time between receipt of the last byte of a `DoIP` Diagnostic Message and transmission of the ACK or NACK.
///
/// This is a performance requirement on the **entity emitting the ACK**, not a
/// deadline for a tester waiting on one. Do not use it to time out a send:
/// it allows nothing for network transit or for an entity that ACKs after
/// running its handler, and an entity that is merely slow is not an entity
/// that failed. [`TIMEOUT_DIAGNOSTIC_MESSAGE_RESPONSE`] is the parameter that
/// governs when a message may be considered lost.
pub const TIMEOUT_DIAGNOSTIC_MESSAGE_INITIAL: Duration = from_millis;
/// After the timeout has elapsed, the request or response is considered to be lost and the request may be repeated
///
/// Ref: `A_DoIP_Diagnostic_Message`
pub const TIMEOUT_DIAGNOSTIC_MESSAGE_RESPONSE: Duration = from_secs;