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
137
138
139
140
141
//! # Connection Module
//!
//! Provides the [`Connector`] trait and its default implementation [`ConnectorSocket`].
//!
//! [`Connector`] is the extension point for callers who need to control how the TCP
//! connection is established — a non-standard port, custom socket options, or a
//! pre-existing stream. [`ConnectorSocket`] connects to [`crate::TCP_PORT`] and refuses
//! any other port, so tests and non-standard deployments substitute their own.
//!
//! # Examples
//!
//! ## Default implementation
//!
//! ```no_run
//! use simple_doip::client::{Client, ClientOptions, RoutingActivationOptions};
//! use simple_doip::connection::ConnectorSocket;
//! use simple_doip::messages::{ActivationTypeCode, ProtocolVersion};
//! use simple_doip::LogicalAddress;
//! use std::net::{IpAddr, SocketAddr};
//!
//! # async fn example() -> Result<(), simple_doip::Error> {
//! let options = ClientOptions {
//! server_address: SocketAddr::new("127.0.0.1".parse().unwrap(), simple_doip::TCP_PORT),
//! server_logical_address: LogicalAddress(0x0001),
//! server_physical_address: LogicalAddress(0x0001),
//! client_address: IpAddr::from([0, 0, 0, 0]),
//! client_logical_address: LogicalAddress(0x0E01),
//! protocol_version: ProtocolVersion::V2012,
//! routing_activation_options: Some(RoutingActivationOptions {
//! activation_type: ActivationTypeCode::Default,
//! oem_specific: None,
//! }),
//! diagnostic_message_timeout: simple_doip::TIMEOUT_DIAGNOSTIC_MESSAGE_RESPONSE,
//! };
//! // The turbofish is required even though `Client<Conn>` defaults to `ConnectorSocket`:
//! // a type parameter's default is not used for inference on an associated-function call,
//! // so omitting it fails with E0283 "type annotations needed".
//! let client = Client::<ConnectorSocket>::connect(options).await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Custom implementation
//!
//! ```no_run
//! use simple_doip::connection::Connector;
//! use std::net::SocketAddr;
//! use std::time::Duration;
//! use tokio::net::{TcpSocket, tcp::{OwnedReadHalf, OwnedWriteHalf}};
//!
//! pub struct MyConnector;
//!
//! #[async_trait::async_trait]
//! impl Connector for MyConnector {
//! async fn establish_connection(
//! gateway_address: SocketAddr,
//! ) -> Result<(OwnedReadHalf, OwnedWriteHalf), simple_doip::Error> {
//! // IPv4 only, for brevity. `ConnectorSocket` below picks `new_v4`/`new_v6`
//! // from `gateway_address`; do the same if you need to support both.
//! let tcp_socket = TcpSocket::new_v4()?;
//! tcp_socket.set_reuseaddr(true)?;
//! tcp_socket.set_nodelay(true)?;
//! let tcp_stream = tokio::time::timeout(
//! Duration::from_millis(5100),
//! tcp_socket.connect(gateway_address),
//! )
//! .await??;
//! Ok(tcp_stream.into_split())
//! }
//! }
//! ```
use ;
use ;
use ;
/// Connector trait for establishing a connection to the `DoIP` node
/// Send and receive buffer size requested on the diagnostic TCP socket.
///
/// Fixed rather than configurable: `Connector` is the seam for a caller that
/// needs different socket options, so a `ConnectorSocket` knob would duplicate
/// it. Implement [`Connector`] to size these yourself.
const BUFFER_SIZE: u32 = 1024 * 64;
/// ISO 13400-2:2012 Connection to the gateway node via port 13400
///
/// This socket is used to connect to the server directly.
;