resol_vbus/
recording_encoder.rs1use byteorder::{ByteOrder, LittleEndian};
5use chrono::{DateTime, TimeZone, Utc};
6
7use crate::{data::Data, header::Header};
8
9pub fn length_from_data(data: &Data) -> usize {
11 match *data {
12 Data::Packet(ref packet) => 26 + packet.frame_count as usize * 4,
13 Data::Datagram(_) => 26 + 6,
14 Data::Telegram(ref tgram) => 26 + tgram.frame_count() as usize * 7,
15 }
16}
17
18pub fn bytes_from_timestamp(timestamp: DateTime<Utc>, buf: &mut [u8]) {
20 let timestamp_s = timestamp.timestamp();
21 let timestamp_ms = timestamp.timestamp_subsec_millis();
22 let timestamp = timestamp_s * 1000 + i64::from(timestamp_ms);
23
24 LittleEndian::write_i64(&mut buf[0..8], timestamp);
25}
26
27pub fn bytes_from_record(typ: u8, length: u16, timestamp: DateTime<Utc>, buf: &mut [u8]) {
29 buf[0] = 0xA5;
30 buf[1] = typ;
31 LittleEndian::write_u16(&mut buf[2..4], length);
32 LittleEndian::write_u16(&mut buf[4..6], length);
33 bytes_from_timestamp(timestamp, &mut buf[6..14]);
34}
35
36pub fn bytes_from_channel(channel: u8, buf: &mut [u8]) {
38 bytes_from_record(0x77, 16, Utc.timestamp(0, 0), buf);
39 buf[14] = channel;
40 buf[15] = 0;
41}
42
43pub fn bytes_from_data(data: &Data, buf: &mut [u8]) {
45 let length = length_from_data(data);
46
47 {
48 let header: &Header = data.as_ref();
49 bytes_from_record(0x66, length as u16, header.timestamp, buf);
50 LittleEndian::write_u16(&mut buf[14..16], header.destination_address);
51 LittleEndian::write_u16(&mut buf[16..18], header.source_address);
52 buf[18] = header.protocol_version;
53 buf[19] = 0;
54 }
55
56 match *data {
57 Data::Packet(ref packet) => {
58 let frame_data_length = packet.frame_count as usize * 4;
59
60 LittleEndian::write_u16(&mut buf[20..22], packet.command);
61 LittleEndian::write_u16(&mut buf[22..24], frame_data_length as u16);
62 buf[24] = 0;
63 buf[25] = 0;
64 buf[26..(26 + frame_data_length)]
65 .copy_from_slice(&packet.frame_data[0..frame_data_length]);
66 }
67 Data::Datagram(ref dgram) => {
68 LittleEndian::write_u16(&mut buf[20..22], dgram.command);
69 buf[22] = 6;
70 buf[23] = 0;
71 buf[24] = 0;
72 buf[25] = 0;
73 LittleEndian::write_i16(&mut buf[26..28], dgram.param16);
74 LittleEndian::write_i32(&mut buf[28..32], dgram.param32);
75 }
76 Data::Telegram(ref tgram) => {
77 let frame_data_length = tgram.frame_count() as usize * 7;
78
79 buf[20] = tgram.command;
80 buf[21] = 0;
81 LittleEndian::write_u16(&mut buf[22..24], frame_data_length as u16);
82 buf[24] = 0;
83 buf[25] = 0;
84 buf[26..(26 + frame_data_length)]
85 .copy_from_slice(&tgram.frame_data[0..frame_data_length]);
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 use chrono::TimeZone;
95
96 use crate::{
97 recording_decoder::data_from_checked_bytes,
98 test_data::{RECORDING_1, RECORDING_3},
99 test_utils::to_hex_string,
100 };
101
102 #[test]
103 fn test_length_from_data() {
104 let channel = 0x11;
105
106 let data1 = data_from_checked_bytes(channel, &RECORDING_1[100..]);
107
108 assert_eq!(134, length_from_data(&data1));
109
110 let data2 = data_from_checked_bytes(channel, &RECORDING_3[0..]);
111
112 assert_eq!(32, length_from_data(&data2));
113
114 }
116
117 #[test]
118 fn test_bytes_from_timestamp() {
119 let timestamp = Utc.timestamp(1485688933, 0);
120
121 let mut buf = [0u8; 8];
122
123 bytes_from_timestamp(timestamp, &mut buf);
124 assert_eq!("880af6e959010000", to_hex_string(&buf));
125 }
126
127 #[test]
128 fn test_bytes_from_record() {
129 let timestamp = Utc.timestamp(1485688933, 0);
130
131 let mut buf = [0u8; 14];
132
133 bytes_from_record(0x66, 134, timestamp, &mut buf);
134 assert_eq!("a56686008600880af6e959010000", to_hex_string(&buf));
135 }
136
137 #[test]
138 fn test_bytes_from_channel() {
139 let mut buf = [0u8; 16];
140
141 bytes_from_channel(0x11, &mut buf);
142 assert_eq!("a5771000100000000000000000001100", to_hex_string(&buf));
143 }
144
145 #[test]
146 fn test_bytes_from_data() {
147 let channel = 0x11;
148
149 let mut buf = [0u8; 1024];
150
151 let data1 = data_from_checked_bytes(channel, &RECORDING_1[100..]);
152
153 bytes_from_data(&data1, &mut buf);
154 assert_eq!(&RECORDING_1[100..234], &buf[0..134]);
155
156 let data2 = data_from_checked_bytes(channel, &RECORDING_3[0..]);
157
158 bytes_from_data(&data2, &mut buf);
159 assert_eq!(&RECORDING_3[0..32], &buf[0..32]);
160
161 }
163}