open_protocol/messages/
communication.rs

1use open_protocol_codec_proc_macro::{OpenProtocolDecode, OpenProtocolEncode, OpenProtocolMessage};
2use crate::enums::error::ErrorCode;
3
4#[derive(Debug, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode)]
5pub enum KeepAlive {
6    #[open_protocol_value(number = 0)]
7    Use,
8    #[open_protocol_value(number = 1)]
9    Ignore,
10}
11
12#[derive(
13    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
14)]
15#[open_protocol_message(MID = 0001, revision = 7)]
16pub struct MID0001rev7 {
17    #[open_protocol_field(number = 1, length = 1)]
18    pub keep_alive: Option<KeepAlive>,
19}
20
21#[derive(
22    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
23)]
24#[open_protocol_message(MID = 0002, revision = 1)]
25pub struct MID0002rev1 {
26    #[open_protocol_field(number = 1, length = 4)]
27    pub cell_id: u16,
28    #[open_protocol_field(number = 2, length = 2)]
29    pub channel_id: u8,
30    #[open_protocol_field(number = 3, length = 25)]
31    pub controller_name: String,
32}
33
34#[derive(
35    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
36)]
37#[open_protocol_message(MID = 0002, revision = 2)]
38pub struct MID0002rev2 {
39    #[open_protocol_field(number = 1, length = 4)]
40    pub cell_id: u16,
41    #[open_protocol_field(number = 2, length = 2)]
42    pub channel_id: u8,
43    #[open_protocol_field(number = 3, length = 25)]
44    pub controller_name: String,
45    #[open_protocol_field(number = 4, length = 3)]
46    pub supplier_code: String,
47}
48
49#[derive(
50    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
51)]
52#[open_protocol_message(MID = 0002, revision = 3)]
53pub struct MID0002rev3 {
54    #[open_protocol_field(number = 1, length = 4)]
55    pub cell_id: u16,
56    #[open_protocol_field(number = 2, length = 2)]
57    pub channel_id: u8,
58    #[open_protocol_field(number = 3, length = 25)]
59    pub controller_name: String,
60    #[open_protocol_field(number = 4, length = 3)]
61    pub supplier_code: String,
62    #[open_protocol_field(number = 5, length = 19)]
63    pub open_protocol_version: String,
64    #[open_protocol_field(number = 6, length = 19)]
65    pub controller_software_version: String,
66    #[open_protocol_field(number = 7, length = 19)]
67    pub tool_software_version: String,
68}
69
70#[derive(
71    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
72)]
73#[open_protocol_message(MID = 0002, revision = 4)]
74pub struct MID0002rev4 {
75    #[open_protocol_field(number = 1, length = 4)]
76    pub cell_id: u16,
77    #[open_protocol_field(number = 2, length = 2)]
78    pub channel_id: u8,
79    #[open_protocol_field(number = 3, length = 25)]
80    pub controller_name: String,
81    #[open_protocol_field(number = 4, length = 3)]
82    pub supplier_code: String,
83    #[open_protocol_field(number = 5, length = 19)]
84    pub open_protocol_version: String,
85    #[open_protocol_field(number = 6, length = 19)]
86    pub controller_software_version: String,
87    #[open_protocol_field(number = 7, length = 19)]
88    pub tool_software_version: String,
89    #[open_protocol_field(number = 8, length = 24)]
90    pub rbu_type: String,
91    #[open_protocol_field(number = 9, length = 10)]
92    pub controller_serial_number: String,
93}
94
95#[derive(
96    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
97)]
98#[open_protocol_message(MID = 0002, revision = 5)]
99pub struct MID0002rev5 {
100    #[open_protocol_field(number = 1, length = 4)]
101    pub cell_id: u16,
102    #[open_protocol_field(number = 2, length = 2)]
103    pub channel_id: u8,
104    #[open_protocol_field(number = 3, length = 25)]
105    pub controller_name: String,
106    #[open_protocol_field(number = 4, length = 3)]
107    pub supplier_code: String,
108    #[open_protocol_field(number = 5, length = 19)]
109    pub open_protocol_version: String,
110    #[open_protocol_field(number = 6, length = 19)]
111    pub controller_software_version: String,
112    #[open_protocol_field(number = 7, length = 19)]
113    pub tool_software_version: String,
114    #[open_protocol_field(number = 8, length = 24)]
115    pub rbu_type: String,
116    #[open_protocol_field(number = 9, length = 10)]
117    pub controller_serial_number: String,
118    #[open_protocol_field(number = 10, length = 3)]
119    pub system_type: u16,
120    #[open_protocol_field(number = 11, length = 3)]
121    pub system_subtype: u16,
122}
123
124#[derive(
125    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
126)]
127#[open_protocol_message(MID = 0002, revision = 6)]
128pub struct MID0002rev6 {
129    #[open_protocol_field(number = 1, length = 4)]
130    pub cell_id: u16,
131    #[open_protocol_field(number = 2, length = 2)]
132    pub channel_id: u8,
133    #[open_protocol_field(number = 3, length = 25)]
134    pub controller_name: String,
135    #[open_protocol_field(number = 4, length = 3)]
136    pub supplier_code: String,
137    #[open_protocol_field(number = 5, length = 19)]
138    pub open_protocol_version: String,
139    #[open_protocol_field(number = 6, length = 19)]
140    pub controller_software_version: String,
141    #[open_protocol_field(number = 7, length = 19)]
142    pub tool_software_version: String,
143    #[open_protocol_field(number = 8, length = 24)]
144    pub rbu_type: String,
145    #[open_protocol_field(number = 9, length = 10)]
146    pub controller_serial_number: String,
147    #[open_protocol_field(number = 10, length = 3)]
148    pub system_type: u16,
149    #[open_protocol_field(number = 11, length = 3)]
150    pub system_subtype: u16,
151    #[open_protocol_field(number = 12, length = 1)]
152    pub sequence_number_supported: bool,
153    #[open_protocol_field(number = 13, length = 1)]
154    pub linking_handling_supported: bool,
155    #[open_protocol_field(number = 14, length = 10)]
156    pub station_or_cell_id: u32,
157    #[open_protocol_field(number = 15, length = 25)]
158    pub station_or_cell_name: String,
159    #[open_protocol_field(number = 16, length = 1)]
160    pub client_id: u8,
161}
162
163#[derive(
164    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
165)]
166#[open_protocol_message(MID = 0002, revision = 7)]
167pub struct MID0002rev7 {
168    #[open_protocol_field(number = 1, length = 4)]
169    pub cell_id: u16,
170    #[open_protocol_field(number = 2, length = 2)]
171    pub channel_id: u8,
172    #[open_protocol_field(number = 3, length = 25)]
173    pub controller_name: String,
174    #[open_protocol_field(number = 4, length = 3)]
175    pub supplier_code: String,
176    #[open_protocol_field(number = 5, length = 19)]
177    pub open_protocol_version: String,
178    #[open_protocol_field(number = 6, length = 19)]
179    pub controller_software_version: String,
180    #[open_protocol_field(number = 7, length = 19)]
181    pub tool_software_version: String,
182    #[open_protocol_field(number = 8, length = 24)]
183    pub rbu_type: String,
184    #[open_protocol_field(number = 9, length = 10)]
185    pub controller_serial_number: String,
186    #[open_protocol_field(number = 10, length = 3)]
187    pub system_type: u16,
188    #[open_protocol_field(number = 11, length = 3)]
189    pub system_subtype: u16,
190    #[open_protocol_field(number = 12, length = 1)]
191    pub sequence_number_supported: bool,
192    #[open_protocol_field(number = 13, length = 1)]
193    pub linking_handling_supported: bool,
194    #[open_protocol_field(number = 14, length = 10)]
195    pub station_or_cell_id: u32,
196    #[open_protocol_field(number = 15, length = 25)]
197    pub station_or_cell_name: String,
198    #[open_protocol_field(number = 16, length = 1)]
199    pub client_id: u8,
200    #[open_protocol_field(number = 17, length = 1)]
201    pub keep_alive: Option<KeepAlive>,
202}
203
204/// # 5.2.3 MID 0003 Application Communication stop
205/// This message disables the communication. The controller will stop to respond to any commands
206/// except for MID 0001 Communication start after receiving this command.
207#[derive(
208    Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage,
209)]
210#[open_protocol_message(MID = 0003, revision = 1)]
211pub struct MID0003rev1 {}
212
213/// # 5.2.4 MID 0004 Application Communication negative acknowledge
214/// This message is used by the controller when a request, command or subscription for any reason
215/// has not been performed. The data field contains the message ID of the message request that
216/// failed as well as an error code.
217#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
218#[open_protocol_message(MID = 0004, revision = 1)]
219pub struct MID0004rev1 {
220    #[open_protocol_field(length = 4)]
221    pub mid: u16,
222    #[open_protocol_field(length = 2)]
223    pub error_code: ErrorCode,
224}
225
226/// # 5.2.4 MID 0004 Application Communication negative acknowledge
227/// This message is used by the controller when a request, command or subscription for any reason
228/// has not been performed. The data field contains the message ID of the message request that
229/// failed as well as an error code.
230#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
231#[open_protocol_message(MID = 0004, revision = 2)]
232pub struct MID0004rev2 {
233    #[open_protocol_field(length = 4)]
234    pub mid: u16,
235    #[open_protocol_field(length = 3)]
236    pub error_code: ErrorCode,
237}
238
239/// # 5.2.5 MID 0005 Application Communication positive acknowledge
240/// This message is used by the controller to confirm that the latest command, request or
241/// subscription sent by the integrator was accepted. The data field contains the MID of the
242/// request accepted if the special MIDs for request or subscription are used.
243#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
244#[open_protocol_message(MID = 0005, revision = 1)]
245pub struct MID0005rev1 {
246    #[open_protocol_field(length = 4)]
247    pub mid: u16,
248}
249
250/// # 5.2.6 MID 0006 Application data message request
251/// Do a request for data. This message is used for ALL request handling.
252/// When used it substitutes the use of all MID special request messages.
253#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
254#[open_protocol_message(MID = 0006, revision = 1)]
255pub struct MID0006rev1 {
256    #[open_protocol_field(length = 4)]
257    requested_mid: u16,
258    #[open_protocol_field(length = 3)]
259    wanted_revision: u16,
260    #[open_protocol_field(length = 2)]
261    extra_data_length: u8,
262    #[open_protocol_field(list, amount = "extra_data_length", length = 1)]
263    extra_data: Vec<u8>,
264}
265
266/// # 5.2.7 MID 0008 Application data message subscription
267/// Start a subscription of data.
268/// This message is used for ALL subscription handling.
269/// When used it substitutes the use of all MID special subscription messages.
270#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
271#[open_protocol_message(MID = 8, revision = 1)]
272pub struct MID0008rev1 {
273    /// The MID ID to be subscribed for. Can be used for ALL subscription handling.
274    #[open_protocol_field(length = 4)]
275    pub subscription_mid: u16,
276
277    /// The revision of the MID to subscribe for.
278    #[open_protocol_field(length = 3)]
279    pub wanted_revision: u16,
280
281    /// The length of the extra data field.
282    #[open_protocol_field(length = 2)]
283    pub extra_data_length: u16,
284
285    /// The extra data field (variable length).
286    #[open_protocol_field(list, amount = "extra_data_length", length = 1)]
287    pub extra_data: Vec<u8>,
288}
289
290/// # 5.2.8 MID 0009 Application Data Message unsubscribe.
291/// Unsubscribe from a previously subscribed MID.
292/// This message is used for ALL unsubscriptions.
293#[derive(Debug, Default, Eq, PartialEq, OpenProtocolEncode, OpenProtocolDecode, OpenProtocolMessage)]
294#[open_protocol_message(MID = 9, revision = 1)]
295pub struct MID0009rev1 {
296    /// The MID ID to be unsubscribed for.
297    #[open_protocol_field(length = 4)]
298    pub unsubscription_mid: u16,
299
300    /// The revision of the MIDs extra data that is subscribed for.
301    #[open_protocol_field(length = 3)]
302    pub extra_data_revision: u16,
303
304    /// The length of the extra data field.
305    #[open_protocol_field(length = 2)]
306    pub extra_data_length: u16,
307
308    /// The extra data field (variable length).
309    #[open_protocol_field(list, amount = "extra_data_length", length = 1)]
310    pub extra_data: Vec<u8>,
311}
312
313#[cfg(test)]
314mod tests {
315    use super::*;
316    use open_protocol_codec::{decode, encode};
317
318    #[test]
319    fn encode_mid0001rev7_with_keep_alive() {
320        let message = MID0001rev7 {
321            keep_alive: Some(KeepAlive::Use),
322        };
323
324        let output = encode::encode(&message).unwrap();
325
326        assert_eq!(output, "010".to_string());
327    }
328
329    #[test]
330    fn encode_mid0001rev7_empty() {
331        let message = MID0001rev7 { keep_alive: None };
332
333        let output = encode::encode(&message).unwrap();
334
335        assert_eq!(output, "".to_string());
336    }
337
338    #[test]
339    fn parse_mid0002_rev1() {
340        let message = "010001020103Airbag1                  ";
341
342        let parsed = decode::decode::<MID0002rev1>(message.as_bytes());
343
344        assert_eq!(
345            parsed,
346            Ok(MID0002rev1 {
347                cell_id: 1,
348                channel_id: 1,
349                controller_name: "Airbag1".into()
350            })
351        )
352    }
353
354    #[test]
355    fn write_mid0002_rev1() {
356        let message = MID0002rev1 {
357            cell_id: 1,
358            channel_id: 1,
359            controller_name: "Airbag1".into(),
360        };
361
362        let encoded = encode::encode(&message);
363
364        assert_eq!(
365            encoded,
366            Ok("010001020103Airbag1                  ".to_string())
367        );
368    }
369}