1
1
use prelude:: v1:: * ;
2
+ use crc_any:: CRCu8 ;
3
+
2
4
3
5
/// Packet parsing error
4
6
#[ derive( Copy , Clone , Debug , PartialEq ) ]
@@ -38,7 +40,7 @@ impl MspPacketDirection {
38
40
#[ derive( Debug , Clone , PartialEq ) ]
39
41
/// A decoded MSP packet, with a command code, direction and payload
40
42
pub struct MspPacket < ' a > {
41
- pub cmd : u8 ,
43
+ pub cmd : u16 ,
42
44
pub direction : MspPacketDirection ,
43
45
pub data : Cow < ' a , [ u8 ] >
44
46
}
@@ -48,33 +50,47 @@ enum MspParserState {
48
50
Header1 ,
49
51
Header2 ,
50
52
Direction ,
53
+ FlagV2 ,
51
54
DataLength ,
55
+ DataLengthV2 ,
52
56
Command ,
57
+ CommandV2 ,
53
58
Data ,
54
- Crc
59
+ DataV2 ,
60
+ Crc ,
61
+ }
62
+
63
+ #[ derive( Copy , Clone , PartialEq , Debug ) ]
64
+ enum MSPVersion {
65
+ V1 ,
66
+ V2 ,
55
67
}
56
68
57
69
#[ derive( Debug ) ]
58
70
/// Parser that can find packets from a raw byte stream
59
71
pub struct MspParser {
60
72
state : MspParserState ,
73
+ packet_version : MSPVersion ,
61
74
packet_direction : MspPacketDirection ,
62
- packet_cmd : u8 ,
63
- packet_data_length_remaining : usize ,
75
+ packet_cmd : u16 ,
76
+ packet_data_length_remaining : u16 ,
64
77
packet_data : Vec < u8 > ,
65
- packet_crc : u8
78
+ packet_crc : u8 ,
79
+ packet_crc_v2 : CRCu8 ,
66
80
}
67
81
68
82
impl MspParser {
69
83
/// Create a new parser
70
84
pub fn new ( ) -> MspParser {
71
- MspParser {
85
+ Self {
72
86
state : MspParserState :: Header1 ,
87
+ packet_version : MSPVersion :: V1 ,
73
88
packet_direction : MspPacketDirection :: ToFlightController ,
74
89
packet_data_length_remaining : 0 ,
75
90
packet_cmd : 0 ,
76
91
packet_data : Vec :: new ( ) ,
77
- packet_crc : 0
92
+ packet_crc : 0 ,
93
+ packet_crc_v2 : CRCu8 :: crc8dvb_s2 ( ) ,
78
94
}
79
95
}
80
96
@@ -96,11 +112,16 @@ impl MspParser {
96
112
} ,
97
113
98
114
MspParserState :: Header2 => {
99
- if input == ( 'M' as u8 ) {
100
- self . state = MspParserState :: Direction ;
101
- } else {
102
- self . reset ( ) ;
103
- }
115
+ self . packet_version = match input as char {
116
+ 'M' => MSPVersion :: V1 ,
117
+ 'X' => MSPVersion :: V2 ,
118
+ _=> {
119
+ self . reset ( ) ;
120
+ return Ok ( None ) ;
121
+ } ,
122
+ } ;
123
+
124
+ self . state = MspParserState :: Direction ;
104
125
} ,
105
126
106
127
MspParserState :: Direction => {
@@ -114,20 +135,70 @@ impl MspParser {
114
135
}
115
136
}
116
137
117
- self . state = MspParserState :: DataLength ;
138
+ self . state = match self . packet_version {
139
+ MSPVersion :: V1 => MspParserState :: DataLength ,
140
+ MSPVersion :: V2 => MspParserState :: FlagV2 ,
141
+ } ;
118
142
} ,
119
143
120
- MspParserState :: DataLength => {
144
+ MspParserState :: FlagV2 => {
145
+ // uint8, flag, usage to be defined (set to zero)
146
+ self . state = MspParserState :: CommandV2 ;
147
+ self . packet_data = Vec :: with_capacity ( 2 ) ;
148
+ self . packet_crc_v2 . digest ( & [ input] ) ;
149
+ } ,
150
+
151
+ MspParserState :: CommandV2 => {
152
+ self . packet_data . push ( input) ;
153
+
154
+ if self . packet_data . len ( ) == 2 {
155
+ let mut s = [ 0 ; 2 ] ;
156
+ s. copy_from_slice ( & self . packet_data ) ;
157
+ self . packet_cmd = u16:: from_le_bytes ( s) ;
158
+
159
+ self . packet_crc_v2 . digest ( & self . packet_data ) ;
160
+ self . packet_data . clear ( ) ;
161
+ self . state = MspParserState :: DataLengthV2 ;
162
+ }
163
+ } ,
164
+
165
+ MspParserState :: DataLengthV2 => {
166
+ self . packet_data . push ( input) ;
167
+
168
+ if self . packet_data . len ( ) == 2 {
169
+ let mut s = [ 0 ; 2 ] ;
170
+ s. copy_from_slice ( & self . packet_data ) ;
171
+ self . packet_data_length_remaining = u16:: from_le_bytes ( s) ;
172
+ self . packet_crc_v2 . digest ( & self . packet_data ) ;
173
+ self . packet_data = Vec :: with_capacity ( self . packet_data_length_remaining as usize ) ;
174
+
175
+ self . state = MspParserState :: DataV2 ;
176
+ }
177
+ } ,
178
+
179
+ MspParserState :: DataV2 => {
180
+ self . packet_data . push ( input) ;
181
+ self . packet_data_length_remaining -= 1 ;
182
+
183
+ if self . packet_data_length_remaining == 0 {
184
+ self . state = MspParserState :: Crc ;
185
+
186
+
187
+ self . packet_crc_v2 . digest ( & self . packet_data ) ;
188
+ self . packet_crc = self . packet_crc_v2 . get_crc ( ) ;
189
+ }
190
+ } ,
121
191
122
- self . packet_data_length_remaining = input as usize ;
192
+ MspParserState :: DataLength => {
193
+ self . packet_data_length_remaining = input as u16 ;
123
194
self . state = MspParserState :: Command ;
124
195
self . packet_crc ^= input;
125
196
self . packet_data = Vec :: with_capacity ( input as usize ) ;
126
197
} ,
127
198
128
199
MspParserState :: Command => {
129
200
130
- self . packet_cmd = input;
201
+ self . packet_cmd = input as u16 ;
131
202
132
203
if self . packet_data_length_remaining == 0 {
133
204
self . state = MspParserState :: Crc ;
@@ -153,7 +224,6 @@ impl MspParser {
153
224
} ,
154
225
155
226
MspParserState :: Crc => {
156
-
157
227
let packet_crc = self . packet_crc ;
158
228
if input != packet_crc {
159
229
self . reset ( ) ;
@@ -186,6 +256,7 @@ impl MspParser {
186
256
self . packet_cmd = 0 ;
187
257
self . packet_data . clear ( ) ;
188
258
self . packet_crc = 0 ;
259
+ self . packet_crc_v2 . reset ( ) ;
189
260
}
190
261
}
191
262
@@ -195,6 +266,11 @@ impl<'a> MspPacket<'a> {
195
266
6 + self . data . len ( )
196
267
}
197
268
269
+ /// Number of bytes that this packet requires to be packed
270
+ pub fn packet_size_bytes_v2 ( & self ) -> usize {
271
+ 9 + self . data . len ( )
272
+ }
273
+
198
274
/// Serialize to network bytes
199
275
pub fn serialize ( & self , output : & mut [ u8 ] ) -> Result < ( ) , MspPacketParseError > {
200
276
let l = output. len ( ) ;
@@ -207,7 +283,7 @@ impl<'a> MspPacket<'a> {
207
283
output[ 1 ] = 'M' as u8 ;
208
284
output[ 2 ] = self . direction . to_byte ( ) ;
209
285
output[ 3 ] = self . data . len ( ) as u8 ;
210
- output[ 4 ] = self . cmd ;
286
+ output[ 4 ] = self . cmd as u8 ;
211
287
212
288
213
289
output[ 5 ..l - 1 ] . copy_from_slice ( & self . data ) ;
@@ -220,6 +296,30 @@ impl<'a> MspPacket<'a> {
220
296
221
297
Ok ( ( ) )
222
298
}
299
+
300
+ /// Serialize to network bytes
301
+ pub fn serialize_v2 ( & self , output : & mut [ u8 ] ) -> Result < ( ) , MspPacketParseError > {
302
+ let l = output. len ( ) ;
303
+
304
+ if l != self . packet_size_bytes_v2 ( ) {
305
+ return Err ( MspPacketParseError :: OutputBufferSizeMismatch ) ;
306
+ }
307
+
308
+ output[ 0 ] = '$' as u8 ;
309
+ output[ 1 ] = 'X' as u8 ;
310
+ output[ 2 ] = self . direction . to_byte ( ) ;
311
+ output[ 3 ] = 0 ;
312
+ output[ 4 ..6 ] . copy_from_slice ( & self . cmd . to_le_bytes ( ) ) ;
313
+ output[ 6 ..8 ] . copy_from_slice ( & ( self . data . len ( ) as u16 ) . to_le_bytes ( ) ) ;
314
+
315
+ output[ 8 ..l - 1 ] . copy_from_slice ( & self . data ) ;
316
+
317
+ let mut crc = CRCu8 :: crc8dvb_s2 ( ) ;
318
+ crc. digest ( & output[ 3 ..l - 1 ] ) ;
319
+ output[ l - 1 ] = crc. get_crc ( ) ;
320
+
321
+ Ok ( ( ) )
322
+ }
223
323
}
224
324
225
325
@@ -301,4 +401,4 @@ fn test_roundtrip() {
301
401
} ;
302
402
roundtrip ( & packet) ;
303
403
}
304
- }
404
+ }
0 commit comments