Bladeren bron

rust-protocol: Let decode functions return errors for easier debugging.

Mathias Gottschlag 5 jaren geleden
bovenliggende
commit
ce0896f5c0
2 gewijzigde bestanden met toevoegingen van 35 en 23 verwijderingen
  1. 6
    3
      base-station/software/src/radio.rs
  2. 29
    20
      common/rust-protocol/src/lib.rs

+ 6
- 3
base-station/software/src/radio.rs Bestand weergeven

@@ -161,11 +161,14 @@ impl<'a> Radio<'a> {
161 161
 
162 162
         // Decode the packet.
163 163
         let packet = match Packet::decrypt_and_decode(key, payload) {
164
-            None => {
165
-                info!("invalid packet from device {:02x}", device_id);
164
+            Err(e) => {
165
+                info!(
166
+                    "invalid packet from device {:02x}, error {:?}",
167
+                    device_id, e
168
+                );
166 169
                 return Ok(());
167 170
             }
168
-            Some(p) => p,
171
+            Ok(p) => p,
169 172
         };
170 173
         // TODO: For all packets except for salt requests, check whether the
171 174
         // salt was incremented to prevent replay attacks.

+ 29
- 20
common/rust-protocol/src/lib.rs Bestand weergeven

@@ -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
+}

Laden…
Annuleren
Opslaan