|
|
@@ -17,12 +17,12 @@ pub enum Packet {
|
|
17
|
17
|
}
|
|
18
|
18
|
|
|
19
|
19
|
impl Packet {
|
|
20
|
|
- pub fn decrypt_and_decode(key: &[u8], data: &mut [u8]) -> Option<Packet> {
|
|
|
20
|
+ pub fn decrypt_and_decode(key: &[u8], data: &mut [u8]) -> Result<Packet, Error> {
|
|
21
|
21
|
decrypt_cbc(key, data);
|
|
22
|
22
|
let checksummed = &data[8..];
|
|
23
|
23
|
let remainder = State::<KERMIT>::calculate(&checksummed);
|
|
24
|
24
|
if remainder != 0 {
|
|
25
|
|
- return None;
|
|
|
25
|
+ return Err(Error::CRC);
|
|
26
|
26
|
}
|
|
27
|
27
|
Self::decode(&checksummed[..22])
|
|
28
|
28
|
}
|
|
|
@@ -38,21 +38,21 @@ impl Packet {
|
|
38
|
38
|
true
|
|
39
|
39
|
}
|
|
40
|
40
|
|
|
41
|
|
- fn decode(data: &[u8]) -> Option<Packet> {
|
|
|
41
|
+ fn decode(data: &[u8]) -> Result<Packet, Error> {
|
|
42
|
42
|
let type_ = data[0] & 0x1f;
|
|
43
|
43
|
// count can be at most 7, so we do not need any checks when indexing 8-element arrays
|
|
44
|
44
|
// below.
|
|
45
|
45
|
let count = data[0] >> 5;
|
|
46
|
46
|
match type_ {
|
|
47
|
|
- 0 => Some(Self::GetSalt),
|
|
48
|
|
- 1 => Some(Self::Salt({
|
|
|
47
|
+ 0 => Ok(Self::GetSalt),
|
|
|
48
|
+ 1 => Ok(Self::Salt({
|
|
49
|
49
|
// The lowest 8 bit of the salt are the device ID and are filled in by the caller.
|
|
50
|
50
|
u64::from_le_bytes(data[1..9].try_into().unwrap()) << 8
|
|
51
|
51
|
})),
|
|
52
|
|
- 2 => Some(Self::Report(Report::decode(count, &data[1..])?)),
|
|
53
|
|
- 3 => Some(Self::GetValues(GetValues::decode(count, &data[1..])?)),
|
|
54
|
|
- 4 => Some(Self::Values(Values::decode(count, &data[1..])?)),
|
|
55
|
|
- _ => None,
|
|
|
52
|
+ 2 => Ok(Self::Report(Report::decode(count, &data[1..])?)),
|
|
|
53
|
+ 3 => Ok(Self::GetValues(GetValues::decode(count, &data[1..])?)),
|
|
|
54
|
+ 4 => Ok(Self::Values(Values::decode(count, &data[1..])?)),
|
|
|
55
|
+ _ => Err(Error::InvalidPacketType),
|
|
56
|
56
|
}
|
|
57
|
57
|
}
|
|
58
|
58
|
|
|
|
@@ -90,7 +90,7 @@ pub struct Report {
|
|
90
|
90
|
}
|
|
91
|
91
|
|
|
92
|
92
|
impl Report {
|
|
93
|
|
- fn decode(count: u8, mut data: &[u8]) -> Option<Report> {
|
|
|
93
|
+ fn decode(count: u8, mut data: &[u8]) -> Result<Report, Error> {
|
|
94
|
94
|
let mut report = Self {
|
|
95
|
95
|
count,
|
|
96
|
96
|
values: [Value::Invalid; 8],
|
|
|
@@ -98,7 +98,7 @@ impl Report {
|
|
98
|
98
|
for i in 0..count {
|
|
99
|
99
|
report.values[i as usize] = Value::decode(&mut data)?;
|
|
100
|
100
|
}
|
|
101
|
|
- Some(report)
|
|
|
101
|
+ Ok(report)
|
|
102
|
102
|
}
|
|
103
|
103
|
|
|
104
|
104
|
fn encode(&self, mut data: &mut [u8]) -> bool {
|
|
|
@@ -124,9 +124,9 @@ pub struct GetValues {
|
|
124
|
124
|
}
|
|
125
|
125
|
|
|
126
|
126
|
impl GetValues {
|
|
127
|
|
- fn decode(_count: u8, _data: &[u8]) -> Option<GetValues> {
|
|
|
127
|
+ fn decode(_count: u8, _data: &[u8]) -> Result<GetValues, Error> {
|
|
128
|
128
|
// TODO
|
|
129
|
|
- None
|
|
|
129
|
+ Err(Error::InvalidPacketType)
|
|
130
|
130
|
}
|
|
131
|
131
|
|
|
132
|
132
|
fn encode(&self, mut _data: &[u8]) -> bool {
|
|
|
@@ -143,9 +143,9 @@ pub struct Values {
|
|
143
|
143
|
}
|
|
144
|
144
|
|
|
145
|
145
|
impl Values {
|
|
146
|
|
- fn decode(_count: u8, _data: &[u8]) -> Option<Values> {
|
|
|
146
|
+ fn decode(_count: u8, _data: &[u8]) -> Result<Values, Error> {
|
|
147
|
147
|
// TODO
|
|
148
|
|
- None
|
|
|
148
|
+ Err(Error::InvalidPacketType)
|
|
149
|
149
|
}
|
|
150
|
150
|
|
|
151
|
151
|
fn encode(&self, mut _data: &[u8]) -> bool {
|
|
|
@@ -173,27 +173,27 @@ pub enum Value {
|
|
173
|
173
|
}
|
|
174
|
174
|
|
|
175
|
175
|
impl Value {
|
|
176
|
|
- fn decode(data: &mut &[u8]) -> Option<Value> {
|
|
|
176
|
+ fn decode(data: &mut &[u8]) -> Result<Value, Error> {
|
|
177
|
177
|
let type_ = data[0];
|
|
178
|
178
|
let length = match type_ {
|
|
179
|
179
|
0 => 9,
|
|
180
|
180
|
1 => 3,
|
|
181
|
181
|
2 => 5,
|
|
182
|
182
|
3 => 3,
|
|
183
|
|
- _ => return None,
|
|
|
183
|
+ _ => return Err(Error::InvalidValueType),
|
|
184
|
184
|
};
|
|
185
|
185
|
if data.len() < length {
|
|
186
|
|
- return None;
|
|
|
186
|
+ return Err(Error::TooShort);
|
|
187
|
187
|
}
|
|
188
|
188
|
let result = match type_ {
|
|
189
|
189
|
0 => Self::Time(u64::from_le_bytes(data[1..9].try_into().unwrap())),
|
|
190
|
190
|
1 => Self::Temperature(i16::from_le_bytes(data[1..3].try_into().unwrap())),
|
|
191
|
191
|
2 => Self::Pressure(u32::from_le_bytes(data[1..5].try_into().unwrap())),
|
|
192
|
192
|
3 => Self::Humidity(u16::from_le_bytes(data[1..3].try_into().unwrap())),
|
|
193
|
|
- _ => return None,
|
|
|
193
|
+ _ => return Err(Error::InvalidValueType),
|
|
194
|
194
|
};
|
|
195
|
195
|
*data = &data[length..];
|
|
196
|
|
- Some(result)
|
|
|
196
|
+ Ok(result)
|
|
197
|
197
|
}
|
|
198
|
198
|
|
|
199
|
199
|
fn encode(&self, data: &mut [u8]) -> bool {
|
|
|
@@ -263,3 +263,12 @@ fn decrypt_cbc(key: &[u8], data: &mut [u8]) {
|
|
263
|
263
|
}
|
|
264
|
264
|
}
|
|
265
|
265
|
}
|
|
|
266
|
+
|
|
|
267
|
+#[derive(Debug, Copy, Clone)]
|
|
|
268
|
+pub enum Error {
|
|
|
269
|
+ CRC,
|
|
|
270
|
+ InvalidPacketType,
|
|
|
271
|
+ InvalidValueType,
|
|
|
272
|
+ InvalidLocation,
|
|
|
273
|
+ TooShort,
|
|
|
274
|
+}
|