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
|
pub mod types;
use crate::layer2;
use crate::model;
pub struct DecodedField {
pub v: Option<types::Value>,
pub name: String,
pub field: model::PacketField,
}
pub fn decode_fields(p: &layer2::Packet, fields: &[model::PacketField]) -> Vec<DecodedField> {
fields
.iter()
.map(|f| {
let r = |decoder: &dyn Fn(&[u8]) -> Option<types::Value>,
offset: &u8,
name: &String| DecodedField {
v: decoder(
p.payload_decoded()
.get((*offset as usize)..)
.unwrap_or(&[0; 0]),
),
name: name.clone(),
field: f.clone(),
};
match f {
model::PacketField::Byte { offset, name } => r(&types::byte, offset, name),
model::PacketField::Data1b { offset, name } => r(&types::data1b, offset, name),
model::PacketField::Data1c { offset, name } => r(&types::data1c, offset, name),
model::PacketField::Data2b { offset, name } => r(&types::data2b, offset, name),
model::PacketField::Data2c { offset, name } => r(&types::data2c, offset, name),
model::PacketField::ByteEnum {
offset,
name,
options,
} => r(&(move |data| types::byteenum(data, options)), offset, name),
model::PacketField::Bcd { offset, name } => r(&types::bcd, offset, name),
model::PacketField::Bit { offset, name } => r(&types::bit, offset, name),
model::PacketField::Word { offset, name } => r(&types::word, offset, name),
model::PacketField::String {
offset,
name,
length,
} => r(
&(move |data| types::string(data, *length as usize)),
offset,
name,
),
}
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
static EBUS_XML: &[u8] = include_bytes!("../../../ebus-xml/ebus.xml");
fn tostring(values: Vec<DecodedField>) -> String {
values
.iter()
.map(|df| {
df.name.clone()
+ "="
+ &df
.v
.as_ref()
.map(|v2| v2.convert())
.unwrap_or(String::from("<None>"))
})
.collect::<Vec<String>>()
.join(",")
}
#[test]
fn test1() {
let conf = model::read_config(EBUS_XML).unwrap();
let data = [
0xf1, 0xfe, 0x5, 0x3, 0x08, 0x01, 0x01, 0x10, 0xff, 0x4e, 0xff, 0x35, 0x0b, 0x92, 0x00,
0xaa,
];
let l2p = layer2::parse(&data[..]).unwrap();
let pack = conf.packets.get(l2p.primary, l2p.secondary).unwrap();
let values = decode_fields(&l2p, pack.fields.fields.as_ref().unwrap());
assert_eq!("stellgradKesselleistung=<None>,kesselTemperatur=39,ruecklaufTemperatur=<None>,boilerTemperatur=53,aussenTemperatur=11", tostring(values));
}
#[test]
fn test() {
let conf = model::read_config(EBUS_XML).unwrap();
let data: Vec<u8> = vec![
170, // Syn
170, // Syn
003, // Source
241, // Destination
008, // primaryCommand
000, // secondaryCommand
008, // payloadLength
128, // p1
040, // p2
230, // p3
002, // p4
000, // p5
002, // p6
000, // p7
010, // p8
128, // CRC
000, // ACK
170, // SYN
170,
];
let res = layer2::parse(&data).unwrap();
assert_eq!(
res.payload_decoded(),
vec![128, 040, 230, 002, 000, 002, 000, 010]
);
let pack = conf.packets.get(res.primary, res.secondary).unwrap();
let values = decode_fields(&res, pack.fields.fields.as_ref().unwrap());
assert_eq!(
"TK_soll=40.5,TA_ist=2.8984375,L_zwang=0,Status=false,TB_soll=10",
tostring(values)
);
}
}
|