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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
//! DoIP protocol encoding and decoding library
//!
//! This crate provides all the Diagnostic over IP messages, with their
//! associated :
//! - encoding into a writer
//! - decoding from a reader
//!
//! For reference on the protocol, see ISO-14229-1.
//!
//! A DoIP message is composed of a header and a payload, ie. [`DoIpHeader`] and [`Payload`].
//!
//! The payload is the meaningfull part of the message, and is one of the
//! [`message`] module structs.
//!
//! A typical reception sequence using the library would be :
//! - call [`read_header()`].
//! - call [`read_payload()`] on the correct type.
//! - see documentation of [`read_message()`].
//!
//! A typical emission sequence using the library would be :
//! - build a message struct which implements [`Payload`].
//! - send it with [`write_message()`].
//! - see documentation of [`write_message()`].
use ;
pub use DoIpError;
pub use ;
pub use ;
/// A DoIP logical address, both for a tester or a tested entity
pub type LogicalAddress = u16;
/// A Vehicle Identifier Number
pub type Vin = ;
/// Reads a DoIP header and attemps to read a DoIp payload
///
/// This function is only usable if it is known beforehand which message is
/// coming next, in which case it returns that DoIp payload. If used with the
/// wrong payload type, it will return a PayloadLengthTooShort error, and stops
/// reading after the header.
///
/// A sounder use would be :
/// ```
/// use doip_rw::{read_header, read_payload, PayloadType, Payload, message::AliveCheckRequest, };
/// use std::io::Cursor;
///
/// // let mut tcp = TcpStream::connect("127.0.0.1:13400").unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00]);
/// let header = read_header(&mut tcp).unwrap();
/// match header.payload_type {
/// PayloadType::AliveCheckRequest => {
/// let acr : AliveCheckRequest = read_payload(&mut tcp, header.payload_length as usize).unwrap();
/// },
/// _ => {},
/// }
/// ```
/// Writes a DoIP header and its DoIp payload
///
/// This function calculates the DoIp Header from the payload, and then sends them
/// both in the writer.
/// This is the main and probably the _only_ function which should be used to send
/// DoIP messages.
///
/// Example:
/// ```
/// use doip_rw::{write_message, message::RoutingActivationRequest, message::ActivationType};
/// use std::net::TcpStream;
///
/// // let mut tcp = TcpStream::connect("127.0.0.1:13400").unwrap();
/// let mut tcp = vec![];
/// let routing_activation = RoutingActivationRequest {
/// source_address: 0x00ed,
/// activation_type: ActivationType::Default,
/// reserved: [0; 4],
/// reserved_oem: Some([0; 4]),
/// };
/// write_message(&routing_activation, &mut tcp).unwrap();
/// ```
/// Length of a DoIp message in bytes
///
/// The length is the fixed number of bytes of the DoIp header, added to the
/// number of bytes of the provided payload.
/// Read a DoIp header
///
/// Read a full DoIp header, ie. the 8 bytes of a DoIp header.
/// This is the first part of a DoIp message normal read flow.
///
/// Example:
/// ```
/// use std::io::Cursor;
/// use doip_rw::read_header;
///
/// // let mut tcp = TcpStream::connect("127.0.0.1:13400").unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00]);
/// let hdr = read_header(&mut tcp).unwrap();
/// ```
/// Read a specific DoIp payload, specifying the exact payload through Payload type
///
/// This function should normally be called after `read_header`, depending on the
/// `payload_type`.
///
/// Example: if the header payload_type == RoutingActivationResponse :
/// ```
/// use std::io::Cursor;
/// use doip_rw::{read_header, read_payload, message::AliveCheckResponse};
///
/// // let mut tcp = TcpStream::connect("127.0.0.1:13400").unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x04, 0x54]);
/// let hdr = read_header(&mut tcp).unwrap();
/// let response : AliveCheckResponse = read_payload(&mut tcp, hdr.payload_length as usize).unwrap();
/// ```
/// Read a specific DoIp payload into an existing payload
///
/// This function is `read_payload` without a memory allocation. The difference
/// is that this function reuses the payload's buffer, and if there is an
/// internal buffer, such as in DiagnosticMessage::user_data, the internal
/// buffer is resized.
///
/// Example:
/// ```
/// use std::io::Cursor;
/// use doip_rw::{read_header, read_payload, read_replace_payload, message::AliveCheckResponse};
///
/// // let mut tcp = TcpStream::connect("127.0.0.1:13400").unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x04, 0x54]);
/// let hdr = read_header(&mut tcp).unwrap();
/// let mut response : AliveCheckResponse = read_payload(&mut tcp, hdr.payload_length as usize).unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x04, 0x54]);
/// read_replace_payload(&mut response, &mut tcp, hdr.payload_length as usize).unwrap();
/// ```
/// Read a specific DoIp message into an existing message
///
/// This function is `read_message` without a memory allocation. The difference
/// is that this function reuses the message's buffer, and if there is an
/// internal buffer, such as in DiagnosticMessage::user_data, the internal
/// buffer is resized.
///
/// Example:
/// ```
/// use std::io::Cursor;
/// use doip_rw::{read_header, read_payload, read_replace_message, message::AliveCheckResponse};
///
/// // let mut tcp = TcpStream::connect("127.0.0.1:13400").unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x04, 0x54]);
/// let hdr = read_header(&mut tcp).unwrap();
/// let mut response : AliveCheckResponse = read_payload(&mut tcp, hdr.payload_length as usize).unwrap();
/// let mut tcp = Cursor::new([0x02, 0xfd, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x04, 0x54]);
/// read_replace_message(&mut response, &mut tcp).unwrap();
/// ```
/// Module containing all the *messages* handled by the API.
///
/// The [`read_message()`], [`read_payload()`], [`write_message()`] all rely on
/// the messages in this module, which represent all the possible DoIP messages.