Browse Source

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

Mathias Gottschlag 5 years ago
parent
commit
ce0896f5c0
2 changed files with 35 additions and 23 deletions
  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 View File

161
 
161
 
162
         // Decode the packet.
162
         // Decode the packet.
163
         let packet = match Packet::decrypt_and_decode(key, payload) {
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
                 return Ok(());
169
                 return Ok(());
167
             }
170
             }
168
-            Some(p) => p,
171
+            Ok(p) => p,
169
         };
172
         };
170
         // TODO: For all packets except for salt requests, check whether the
173
         // TODO: For all packets except for salt requests, check whether the
171
         // salt was incremented to prevent replay attacks.
174
         // salt was incremented to prevent replay attacks.

+ 29
- 20
common/rust-protocol/src/lib.rs View File

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

Loading…
Cancel
Save