25
25
26
26
use crate :: {
27
27
id:: { FdFlags , IdFlags } ,
28
- CanAnyFrame , CanDataFrame , CanFdFrame , CanFrame , ConstructionError ,
28
+ CanAnyFrame , CanDataFrame , CanFdFrame , CanFrame , CanRemoteFrame , ConstructionError ,
29
29
} ;
30
30
use embedded_can:: StandardId ;
31
31
use hex:: FromHex ;
@@ -43,15 +43,15 @@ use std::{
43
43
/// A CAN log reader.
44
44
pub struct Reader < R > {
45
45
rdr : R ,
46
- line_buf : Vec < u8 > ,
46
+ line_buf : String ,
47
47
}
48
48
49
49
impl < R : io:: Read > Reader < R > {
50
50
/// Creates an I/O buffered reader from a CAN log reader.
51
51
pub fn from_reader ( rdr : R ) ->Reader < BufReader < R > > {
52
52
Reader {
53
53
rdr : BufReader :: new ( rdr) ,
54
- line_buf : Vec :: new ( ) ,
54
+ line_buf : String :: new ( ) ,
55
55
}
56
56
}
57
57
}
@@ -112,7 +112,9 @@ impl From<ConstructionError> for ParseError {
112
112
lazy_static ! {
113
113
// Matches a candump line
114
114
static refRE_DUMP : Regex =Regex :: new(
115
- r"\s*\((?P<t_num>[0-9]+)\.(?P<t_mant>[0-9]*)\)\s+(?P<iface>\w+)\s+(?P<can_id>[0-9A-Fa-f]+)(((?P<fd_sep>\#\#)(?P<fd_flags>[0-9A-Fa-f]))|(?P<sep>\#))(?P<data>[0-9A-Fa-f\s]*)"
115
+ // r"\s*\((?P<t_num>[0-9]+)\.(?P<t_mant>[0-9]*)\)\s+(?P<iface>\w+)\s+(?P<can_id>[0-9A-Fa-f]+)(((?P<fd_sep>\#\#)(?P<fd_flags>[0-9A-Fa-f]))|(?P<sep>\#))(?P<data>[0-9A-Fa-f\s]*)"
116
+ // r"\s*\((?P<t_num>[0-9]+)\.(?P<t_mant>[0-9]*)\)\s+(?P<iface>\w+)\s+(?P<can_id>[0-9A-Fa-f]+)(((?P<fd_sep>\#\#)(?P<fd_flags>[0-9A-Fa-f]))|(\#(?P<data>[0-9A-Fa-f]*))|(\#R(?P<rlen>[0-9]*)))"
117
+ r"\s*\((?P<t_num>[0-9]+)\.(?P<t_mant>[0-9]*)\)\s+(?P<iface>\w+)\s+(?P<can_id>[0-9A-Fa-f]+)\#(((?<remote>R)(?<rlen>[0-9]*))|(((?<fd_sep>\#)(?<fd_flags>[0-9A-Fa-f]))?(?<data>[0-9A-Fa-f]*)))"
116
118
) . unwrap( ) ;
117
119
}
118
120
@@ -125,17 +127,14 @@ impl<R: BufRead> Reader<R> {
125
127
/// Advance state, returning next record.
126
128
pub fn next_record ( & mut self ) ->Result < Option < CanDumpRecord > , ParseError > {
127
129
self . line_buf . clear ( ) ;
128
- let bytes_read =self . rdr . read_until ( b'\n' , & mut self . line_buf ) ?;
130
+ let nbytes =self . rdr . read_line ( & mut self . line_buf ) ?;
129
131
130
- if bytes_read ==0 {
132
+ if nbytes ==0 {
131
133
return Ok ( None ) ;
132
134
}
133
135
134
- let line = str:: from_utf8 ( & self . line_buf [ ..bytes_read] )
135
- . map_err ( |_|ParseError :: InvalidCanFrame ) ?;
136
-
137
136
let caps =RE_DUMP
138
- . captures ( line )
137
+ . captures ( & self . line_buf )
139
138
. ok_or ( ParseError :: UnexpectedEndOfLine ) ?;
140
139
141
140
let t_num: u64 = caps
@@ -156,8 +155,6 @@ impl<R: BufRead> Reader<R> {
156
155
//.map(String::from)
157
156
. ok_or ( ParseError :: InvalidDeviceName ) ?;
158
157
159
- let is_fd_frame = caps. name ( "fd_sep" ) . is_some ( ) ;
160
-
161
158
let mut can_id: canid_t = caps
162
159
. name ( "can_id" )
163
160
. and_then ( |m| canid_t:: from_str_radix ( m. as_str ( ) , 16 ) . ok ( ) )
@@ -166,15 +163,18 @@ impl<R: BufRead> Reader<R> {
166
163
let can_data = caps
167
164
. name ( "data" )
168
165
. map ( |m| m. as_str ( ) . trim ( ) )
169
- . ok_or ( ParseError :: InvalidCanFrame ) ?;
166
+ //.ok_or(ParseError::InvalidCanFrame)?;
167
+ . unwrap_or_default ( ) ;
168
+
169
+ let is_remote_frame = caps. name ( "remote" ) . is_some ( ) ;
170
+ let is_fd_frame = caps. name ( "fd_sep" ) . is_some ( ) ;
170
171
171
172
let mut id_flags =IdFlags :: empty ( ) ;
172
- id_flags. set ( IdFlags :: RTR , "R" == can_data ) ;
173
+ id_flags. set ( IdFlags :: RTR , is_remote_frame ) ;
173
174
id_flags. set ( IdFlags :: EFF , can_id >=StandardId :: MAX . as_raw ( ) as canid_t ) ;
174
- // TODO: How are error frames saved?
175
175
can_id |= id_flags. bits ( ) ;
176
176
177
- let data =match id_flags . contains ( IdFlags :: RTR ) {
177
+ let data =match is_remote_frame {
178
178
true =>vec ! [ ] ,
179
179
false =>Vec :: from_hex ( can_data) . map_err ( |_|ParseError :: InvalidCanFrame ) ?,
180
180
} ;
@@ -185,8 +185,15 @@ impl<R: BufRead> Reader<R> {
185
185
. and_then ( |m| u8:: from_str_radix ( m. as_str ( ) , 16 ) . ok ( ) )
186
186
. map ( FdFlags :: from_bits_truncate)
187
187
. ok_or ( ParseError :: InvalidCanFrame ) ?;
188
-
189
188
CanFdFrame :: init ( can_id, & data, fd_flags) . map ( CanAnyFrame :: Fd )
189
+ } else if is_remote_frame{
190
+ let rlen = caps
191
+ . name ( "rlen" )
192
+ . and_then ( |m| m. as_str ( ) . parse :: < usize > ( ) . ok ( ) )
193
+ . unwrap_or_default ( ) ;
194
+ CanRemoteFrame :: init ( can_id, rlen)
195
+ . map ( CanFrame :: Remote )
196
+ . map ( CanAnyFrame :: from)
190
197
} else {
191
198
CanDataFrame :: init ( can_id, & data)
192
199
. map ( CanFrame :: Data )
@@ -264,7 +271,7 @@ mod test {
264
271
#[ test]
265
272
fn test_extended_example ( ) {
266
273
let input: & [ u8 ] =b"(1469439874.299591) can1 080080#\n \
267
- (1469439874.299654) can1 053701#7F ";
274
+ (1469439874.299654) can1 053701#00112233 ";
268
275
269
276
let mut reader =Reader :: from_reader ( input) ;
270
277
@@ -278,6 +285,7 @@ mod test {
278
285
assert_eq ! ( frame. is_remote_frame( ) , false ) ;
279
286
assert_eq ! ( frame. is_error_frame( ) , false ) ;
280
287
assert_eq ! ( frame. is_extended( ) , true ) ;
288
+ assert_eq ! ( frame. data( ) . len( ) , 0 ) ;
281
289
assert_eq ! ( frame. data( ) , & [ ] ) ;
282
290
} else {
283
291
panic ! ( "Expected Normal frame, got FD" ) ;
@@ -292,14 +300,57 @@ mod test {
292
300
assert_eq ! ( frame. is_remote_frame( ) , false ) ;
293
301
assert_eq ! ( frame. is_error_frame( ) , false ) ;
294
302
assert_eq ! ( frame. is_extended( ) , true ) ;
295
- assert_eq ! ( frame. data( ) , & [ 0x7F ] ) ;
303
+ assert_eq ! ( frame. data( ) . len( ) , 4 ) ;
304
+ assert_eq ! ( frame. data( ) , & [ 0x00 , 0x11 , 0x22 , 0x33 ] ) ;
296
305
} else {
297
306
panic ! ( "Expected Normal frame, got FD" ) ;
298
307
}
299
308
300
309
assert ! ( reader. next_record( ) . unwrap( ) . is_none( ) ) ;
301
310
}
302
311
312
+ #[ test]
313
+ fn test_remote ( ) {
314
+ let input: & [ u8 ] =b"(1469439874.299591) can0 080080#R\n \
315
+ (1469439874.299654) can0 053701#R4";
316
+
317
+ let mut reader =Reader :: from_reader ( input) ;
318
+
319
+ let rec1 = reader. next_record ( ) . unwrap ( ) . unwrap ( ) ;
320
+
321
+ assert_eq ! ( rec1. t_us, 1469439874299591 ) ;
322
+ assert_eq ! ( rec1. device, "can0" ) ;
323
+
324
+ if let CanAnyFrame :: Remote ( frame) = rec1. frame {
325
+ assert_eq ! ( frame. raw_id( ) , 0x080080 ) ;
326
+ assert ! ( !frame. is_data_frame( ) ) ;
327
+ assert ! ( frame. is_remote_frame( ) ) ;
328
+ assert ! ( !frame. is_error_frame( ) ) ;
329
+ assert ! ( frame. is_extended( ) ) ;
330
+ assert_eq ! ( frame. len( ) , 0 ) ;
331
+ assert_eq ! ( frame. data( ) , & [ ] ) ;
332
+ } else {
333
+ panic ! ( "Expected Remote frame" ) ;
334
+ }
335
+
336
+ let rec2 = reader. next_record ( ) . unwrap ( ) . unwrap ( ) ;
337
+ assert_eq ! ( rec2. t_us, 1469439874299654 ) ;
338
+ assert_eq ! ( rec2. device, "can0" ) ;
339
+
340
+ if let CanAnyFrame :: Remote ( frame) = rec2. frame {
341
+ assert_eq ! ( frame. raw_id( ) , 0x053701 ) ;
342
+ assert ! ( !frame. is_data_frame( ) ) ;
343
+ assert ! ( frame. is_remote_frame( ) ) ;
344
+ assert ! ( !frame. is_error_frame( ) ) ;
345
+ assert ! ( frame. is_extended( ) ) ;
346
+ assert_eq ! ( frame. len( ) , 4 ) ;
347
+ } else {
348
+ panic ! ( "Expected Remote frame" ) ;
349
+ }
350
+
351
+ assert ! ( reader. next_record( ) . unwrap( ) . is_none( ) ) ;
352
+ }
353
+
303
354
// Issue #74
304
355
#[ test]
305
356
fn test_extended_id_fd ( ) {