Parcourir la source

Update packet handling protocol

The packets are not yet encrypted
Bernd Gottschlag il y a 5 ans
Parent
révision
ae3b470844

+ 14
- 0
base-station/software/Cargo.lock Voir le fichier

@@ -24,6 +24,7 @@ dependencies = [
24 24
 name = "base-station"
25 25
 version = "0.1.0"
26 26
 dependencies = [
27
+ "crc16",
27 28
  "embedded-hal",
28 29
  "embedded-nrf24l01",
29 30
  "env_logger",
@@ -31,6 +32,7 @@ dependencies = [
31 32
  "log",
32 33
  "mqtt-protocol",
33 34
  "thiserror",
35
+ "xxtea-nostd",
34 36
 ]
35 37
 
36 38
 [[package]]
@@ -72,6 +74,12 @@ version = "0.1.10"
72 74
 source = "registry+https://github.com/rust-lang/crates.io-index"
73 75
 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
74 76
 
77
+[[package]]
78
+name = "crc16"
79
+version = "0.4.0"
80
+source = "registry+https://github.com/rust-lang/crates.io-index"
81
+checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff"
82
+
75 83
 [[package]]
76 84
 name = "embedded-hal"
77 85
 version = "0.2.3"
@@ -424,3 +432,9 @@ name = "winapi-x86_64-pc-windows-gnu"
424 432
 version = "0.4.0"
425 433
 source = "registry+https://github.com/rust-lang/crates.io-index"
426 434
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
435
+
436
+[[package]]
437
+name = "xxtea-nostd"
438
+version = "0.1.0"
439
+source = "registry+https://github.com/rust-lang/crates.io-index"
440
+checksum = "6dadadfbf2be7aa1d3b83607115d95f37a9e1d2b91b1978b718df545ad434b9b"

+ 2
- 0
base-station/software/Cargo.toml Voir le fichier

@@ -14,3 +14,5 @@ mqtt-protocol = "0.8"
14 14
 env_logger = "0.7"
15 15
 log = "0.4"
16 16
 thiserror = "1.0"
17
+crc16 = "0.4.0"
18
+xxtea-nostd = "0.1.0"

+ 102
- 14
base-station/software/src/radio.rs Voir le fichier

@@ -4,11 +4,13 @@ use std::thread;
4 4
 use std::thread::sleep;
5 5
 use std::time::{Duration, Instant};
6 6
 
7
+use crc16::{State, KERMIT};
7 8
 use embedded_nrf24l01::{Configuration, CrcMode, DataRate, NRF24L01};
8 9
 use linux_embedded_hal::spidev::{SpiModeFlags, Spidev, SpidevOptions};
9 10
 use linux_embedded_hal::sysfs_gpio::Direction;
10 11
 use linux_embedded_hal::Pin;
11 12
 use log::{error, info};
13
+use xxtea_nostd::{decrypt, encrypt};
12 14
 
13 15
 use crate::spi::EmbeddedHalSpidev;
14 16
 use crate::Error;
@@ -93,44 +95,130 @@ fn radio_thread(updates: &mpsc::Sender<SensorUpdate>) -> Result<(), Error> {
93 95
         if let Some(pipe) = nrf24.can_read().unwrap() {
94 96
             let payload = nrf24.read().unwrap();
95 97
             info!(
96
-                "packet received on pipe {}: {:?}, {}",
98
+                "packet received on pipe {}: {:x?}, {}",
97 99
                 pipe,
98 100
                 payload.as_ref(),
99 101
                 payload.len()
100 102
             );
101
-            if payload.len() != 13 {
103
+            if payload.len() != 32 {
102 104
                 continue;
103 105
             }
104 106
 
105 107
             let sensor_id = payload.as_ref()[0];
108
+            let remainder_of_salt = payload.as_ref()[1..7].to_vec();
109
+
110
+            // Calculate the CRC
111
+            let crc_calculation_buffer = payload.as_ref()[8..30].to_vec();
112
+            let calculated_crc = State::<KERMIT>::calculate(&crc_calculation_buffer);
113
+            info!("calculated crc: 0x{:x}", calculated_crc);
114
+            let crc = u16::from_le_bytes(payload.as_ref()[30..32].try_into().unwrap());
115
+
116
+            if crc != calculated_crc {
117
+                info!("malformed packet received: crc mismatch!");
118
+                info!(
119
+                    "Calculated crc: 0x{:x}, received crc: 0x{:x}",
120
+                    calculated_crc, crc
121
+                );
122
+                continue;
123
+            }
106 124
 
107
-            let pressure = u32::from_le_bytes(payload.as_ref()[1..5].try_into().unwrap());
125
+            let packet_identifier = payload.as_ref()[8];
126
+            let packet_payload = &payload.as_ref()[9..29];
127
+            info!("sensor id: 0x{:x}", sensor_id);
128
+            info!("crc: 0x{:x}", crc);
129
+
130
+            let packet_type = packet_identifier & 0x1F;
131
+            let element_count = (packet_identifier & 0xE0) >> 5;
132
+            info!("packet_type: 0x{:x}", packet_type);
133
+            info!("element_count: 0x{:x}", element_count);
134
+
135
+            let mut temperature = 0;
136
+            let mut pressure = 0;
137
+            let mut humidity = 0;
138
+
139
+            if packet_type == 1 {
140
+                let mut i = 0;
141
+                let mut buffer_position = 0;
142
+                info!("report packet received");
143
+                info!("packet_payload: {:x?}", packet_payload.as_ref());
144
+                while i < element_count {
145
+                    let value_type = packet_payload[buffer_position];
146
+
147
+                    buffer_position += 1; // Set the position to the value
148
+
149
+                    if value_type == 0 {
150
+                        info!("time value not yet supported");
151
+                        buffer_position += 8;
152
+                    } else if value_type == 1 {
153
+                        temperature = i16::from_le_bytes(
154
+                            packet_payload[buffer_position..buffer_position + 2]
155
+                                .try_into()
156
+                                .unwrap(),
157
+                        );
158
+                        info!(
159
+                            "temp: {:x?}, {:x}",
160
+                            packet_payload[buffer_position..buffer_position + 2].to_vec(),
161
+                            temperature
162
+                        );
163
+                        buffer_position += 2;
164
+                    } else if value_type == 2 {
165
+                        pressure = u32::from_le_bytes(
166
+                            packet_payload[buffer_position..buffer_position + 4]
167
+                                .try_into()
168
+                                .unwrap(),
169
+                        );
170
+                        info!(
171
+                            "pressure: {:x?}, {:x}",
172
+                            packet_payload[buffer_position..buffer_position + 4].to_vec(),
173
+                            pressure
174
+                        );
175
+                        buffer_position += 4;
176
+                    } else if value_type == 3 {
177
+                        humidity = u16::from_le_bytes(
178
+                            packet_payload[buffer_position..buffer_position + 2]
179
+                                .try_into()
180
+                                .unwrap(),
181
+                        );
182
+                        info!(
183
+                            "humidity: {:x?}, {:x}",
184
+                            packet_payload[buffer_position..buffer_position + 2].to_vec(),
185
+                            humidity
186
+                        );
187
+                        buffer_position += 2;
188
+                    } else {
189
+                        info!("unknown value type");
190
+                    }
191
+
192
+                    i += 1;
193
+                }
194
+            } else {
195
+                info!("unknown packet type");
196
+                continue;
197
+            }
108 198
 
199
+            /* Check the values for validity */
109 200
             if pressure < 50000 || pressure > 150000 {
110 201
                 info!("pressure outside of range: {}", pressure);
111 202
                 continue;
112 203
             }
113 204
 
114
-            let temperature = i32::from_le_bytes(payload.as_ref()[5..9].try_into().unwrap());
115
-
116
-            if temperature < -50 * 100 || temperature > 100 * 100 {
205
+            if temperature < -50 * 10 || temperature > 100 * 10 {
117 206
                 info!("temperature outside of range: {}", temperature);
118 207
                 continue;
119 208
             }
120 209
 
121
-            let humidity = u32::from_le_bytes(payload.as_ref()[9..13].try_into().unwrap());
122
-            if humidity > 100 * 1024 {
210
+            if humidity > 1000 {
123 211
                 info!("humidity outside of range: {}", humidity);
124 212
                 continue;
125 213
             }
126 214
 
127 215
             let pressure = pressure as f32 / 100.0;
128
-            let temperature = temperature as f32 / 100.0;
129
-            let humidity = humidity as f32 / 1024.0;
130
-            info!("sensor id: 0x{:x}", sensor_id);
131
-            info!("pressure: {}", pressure);
132
-            info!("temperature: {}", temperature);
133
-            info!("humidity: {}", humidity);
216
+            let temperature = temperature as f32 / 10.0;
217
+            let humidity = humidity as f32 / 102.4;
218
+            info!("pressure: {} HPa", pressure);
219
+            info!("temperature: {} °C", temperature);
220
+            info!("humidity: {}%", humidity);
221
+
134 222
             /*
135 223
             updates
136 224
                 .send(SensorUpdate {

Loading…
Annuler
Enregistrer