@@ -8,71 +8,78 @@ use defmt_decoder::{Frame, Table};
88
99use crate :: cli:: monitor:: parser:: InputParser ;
1010
11+ #[ derive( Debug , PartialEq ) ]
1112enum FrameKind < ' a > {
12- Defmt ( Frame < ' a > ) ,
13+ Defmt ( & ' a [ u8 ] ) ,
1314 Raw ( & ' a [ u8 ] ) ,
1415}
1516
1617struct FrameDelimiter {
1718 buffer : Vec < u8 > ,
18- table : Option < Table > ,
1919 in_frame : bool ,
2020}
2121
2222// Framing info added by esp-println
2323const FRAME_START : & [ u8 ] = & [ 0xFF , 0x00 ] ;
2424const FRAME_END : & [ u8 ] = & [ 0x00 ] ;
2525
26- fn search ( haystack : & [ u8 ] , look_for_end : bool ) -> Option < ( & [ u8 ] , usize ) > {
27- let needle = if look_for_end { FRAME_END } else { FRAME_START } ;
28- let start = if look_for_end {
29- // skip leading zeros
30- haystack. iter ( ) . position ( |& b| b != 0 ) ?
31- } else {
32- 0
33- } ;
34-
35- let end = haystack[ start..]
36- . windows ( needle. len ( ) )
37- . position ( |window| window == needle) ?;
38-
39- Some ( ( & haystack[ start..] [ ..end] , start + end + needle. len ( ) ) )
40- }
41-
4226impl FrameDelimiter {
43- pub fn feed ( & mut self , buffer : & [ u8 ] , mut process : impl FnMut ( FrameKind < ' _ > ) ) {
44- let Some ( table) = self . table . as_mut ( ) else {
45- process ( FrameKind :: Raw ( buffer) ) ;
46- return ;
27+ fn new ( ) -> Self {
28+ Self {
29+ buffer : Vec :: new ( ) ,
30+ in_frame : false ,
31+ }
32+ }
33+
34+ fn search ( haystack : & [ u8 ] , look_for_end : bool ) -> Option < ( & [ u8 ] , usize ) > {
35+ let needle = if look_for_end { FRAME_END } else { FRAME_START } ;
36+ let start = if look_for_end {
37+ // skip leading zeros
38+ haystack. iter ( ) . position ( |& b| b != 0 ) ?
39+ } else {
40+ 0
4741 } ;
4842
49- let mut decoder = table. new_stream_decoder ( ) ;
43+ let end = haystack[ start..]
44+ . windows ( needle. len ( ) )
45+ . position ( |window| window == needle) ?;
46+
47+ Some ( ( & haystack[ start..] [ ..end] , start + end + needle. len ( ) ) )
48+ }
5049
50+ pub fn feed ( & mut self , buffer : & [ u8 ] , mut process : impl FnMut ( FrameKind < ' _ > ) ) {
5151 self . buffer . extend_from_slice ( buffer) ;
5252
53- while let Some ( ( frame, consumed) ) = search ( & self . buffer , self . in_frame ) {
54- if !self . in_frame {
53+ while let Some ( ( frame, consumed) ) = Self :: search ( & self . buffer , self . in_frame ) {
54+ if self . in_frame {
55+ process ( FrameKind :: Defmt ( frame) ) ;
56+ } else if !frame. is_empty ( ) {
5557 process ( FrameKind :: Raw ( frame) ) ;
56- self . in_frame = true ;
58+ }
59+ self . in_frame = !self . in_frame ;
60+
61+ self . buffer . drain ( ..consumed) ;
62+ }
63+
64+ if !self . in_frame {
65+ // If we have a 0xFF byte at the end, we should assume it's the start of a new frame.
66+ let consume = if self . buffer . ends_with ( & [ 0xFF ] ) {
67+ & self . buffer [ ..self . buffer . len ( ) - 1 ]
5768 } else {
58- decoder. received ( frame) ;
59- // small reliance on rzcobs internals: we need to feed the terminating zero
60- decoder. received ( FRAME_END ) ;
61- if let Ok ( frame) = decoder. decode ( ) {
62- process ( FrameKind :: Defmt ( frame) ) ;
63- } else {
64- log:: warn!( "Failed to decode defmt frame" ) ;
65- }
66- self . in_frame = false ;
69+ self . buffer . as_slice ( )
6770 } ;
6871
69- self . buffer . drain ( ..consumed) ;
72+ if !consume. is_empty ( ) {
73+ process ( FrameKind :: Raw ( consume) ) ;
74+ self . buffer . drain ( ..consume. len ( ) ) ;
75+ }
7076 }
7177 }
7278}
7379
7480pub struct EspDefmt {
7581 delimiter : FrameDelimiter ,
82+ table : Option < Table > ,
7683}
7784
7885impl EspDefmt {
@@ -94,48 +101,187 @@ impl EspDefmt {
94101
95102 pub fn new ( elf : Option < & [ u8 ] > ) -> Self {
96103 Self {
97- delimiter : FrameDelimiter {
98- buffer : Vec :: new ( ) ,
99- table : Self :: load_table ( elf) ,
100- in_frame : false ,
101- } ,
104+ delimiter : FrameDelimiter :: new ( ) ,
105+ table : Self :: load_table ( elf) ,
102106 }
103107 }
108+
109+ fn handle_raw ( bytes : & [ u8 ] , out : & mut impl Write ) {
110+ out. write_all ( bytes) . unwrap ( ) ;
111+ }
112+
113+ fn handle_defmt ( frame : Frame < ' _ > , out : & mut impl Write ) {
114+ match frame. level ( ) {
115+ Some ( level) => {
116+ let color = match level {
117+ defmt_parser:: Level :: Trace => Color :: Cyan ,
118+ defmt_parser:: Level :: Debug => Color :: Blue ,
119+ defmt_parser:: Level :: Info => Color :: Green ,
120+ defmt_parser:: Level :: Warn => Color :: Yellow ,
121+ defmt_parser:: Level :: Error => Color :: Red ,
122+ } ;
123+
124+ // Print the level before each line.
125+ let level = level. as_str ( ) . to_uppercase ( ) ;
126+ for line in frame. display_message ( ) . to_string ( ) . lines ( ) {
127+ out. queue ( PrintStyledContent (
128+ format ! ( "[{level}] - {line}\r \n " ) . with ( color) ,
129+ ) )
130+ . unwrap ( ) ;
131+ }
132+ }
133+ None => {
134+ out. queue ( Print ( frame. display_message ( ) . to_string ( ) ) )
135+ . unwrap ( ) ;
136+ out. queue ( Print ( "\r \n " ) ) . unwrap ( ) ;
137+ }
138+ }
139+
140+ out. flush ( ) . unwrap ( ) ;
141+ }
104142}
105143
106144impl InputParser for EspDefmt {
107145 fn feed ( & mut self , bytes : & [ u8 ] , out : & mut impl Write ) {
146+ let Some ( table) = self . table . as_mut ( ) else {
147+ Self :: handle_raw ( bytes, out) ;
148+ return ;
149+ } ;
150+
151+ let mut decoder = table. new_stream_decoder ( ) ;
152+
108153 self . delimiter . feed ( bytes, |frame| match frame {
109154 FrameKind :: Defmt ( frame) => {
110- match frame. level ( ) {
111- Some ( level) => {
112- let color = match level {
113- defmt_parser:: Level :: Trace => Color :: Cyan ,
114- defmt_parser:: Level :: Debug => Color :: Blue ,
115- defmt_parser:: Level :: Info => Color :: Green ,
116- defmt_parser:: Level :: Warn => Color :: Yellow ,
117- defmt_parser:: Level :: Error => Color :: Red ,
118- } ;
119-
120- // Print the level before each line.
121- let level = level. as_str ( ) . to_uppercase ( ) ;
122- for line in frame. display_message ( ) . to_string ( ) . lines ( ) {
123- out. queue ( PrintStyledContent (
124- format ! ( "[{level}] - {line}\r \n " ) . with ( color) ,
125- ) )
126- . unwrap ( ) ;
127- }
128- }
129- None => {
130- out. queue ( Print ( frame. display_message ( ) . to_string ( ) ) )
131- . unwrap ( ) ;
132- out. queue ( Print ( "\r \n " ) ) . unwrap ( ) ;
133- }
134- } ;
155+ decoder. received ( frame) ;
156+ // small reliance on rzcobs internals: we need to feed the terminating zero
157+ decoder. received ( FRAME_END ) ;
158+
159+ if let Ok ( frame) = decoder. decode ( ) {
160+ Self :: handle_defmt ( frame, out) ;
161+ } else {
162+ log:: warn!( "Failed to decode defmt frame" ) ;
163+ }
164+ }
165+ FrameKind :: Raw ( bytes) => Self :: handle_raw ( bytes, out) ,
166+ } ) ;
167+ }
168+ }
169+
170+ #[ cfg( test) ]
171+ mod test {
172+ use super :: * ;
173+
174+ #[ test]
175+ fn framing_prints_raw_data_by_default ( ) {
176+ let mut parser = FrameDelimiter :: new ( ) ;
177+
178+ let mut asserted = 0 ;
179+ parser. feed ( b"hello" , |frame| {
180+ assert_eq ! ( frame, FrameKind :: Raw ( b"hello" ) ) ;
181+ asserted += 1 ;
182+ } ) ;
183+ assert_eq ! ( asserted, 1 ) ;
184+ }
185+
186+ #[ test]
187+ fn start_byte_on_end_is_not_part_of_the_raw_sequence ( ) {
188+ let mut parser = FrameDelimiter :: new ( ) ;
189+
190+ let mut asserted = 0 ;
191+ parser. feed ( b"hello\xFF " , |frame| {
192+ assert_eq ! ( frame, FrameKind :: Raw ( b"hello" ) ) ;
193+ asserted += 1 ;
194+ } ) ;
195+ assert_eq ! ( asserted, 1 ) ;
196+ }
197+
198+ #[ test]
199+ fn frame_start_on_end_is_not_part_of_the_raw_sequence ( ) {
200+ let mut parser = FrameDelimiter :: new ( ) ;
201+
202+ let mut asserted = 0 ;
203+ parser. feed ( b"hello\xFF \x00 " , |frame| {
204+ assert_eq ! ( frame, FrameKind :: Raw ( b"hello" ) ) ;
205+ asserted += 1 ;
206+ } ) ;
207+ assert_eq ! ( asserted, 1 ) ;
208+ }
209+
210+ #[ test]
211+ fn process_data_after_frame ( ) {
212+ let mut parser = FrameDelimiter :: new ( ) ;
135213
136- out. flush ( ) . unwrap ( ) ;
214+ let mut asserted = 0 ;
215+ parser. feed ( b"\xFF \x00 frame data\x00 hello" , |frame| {
216+ match asserted {
217+ 0 => assert_eq ! ( frame, FrameKind :: Defmt ( b"frame data" ) ) ,
218+ 1 => assert_eq ! ( frame, FrameKind :: Raw ( b"hello" ) ) ,
219+ _ => panic ! ( "Too many frames" ) ,
137220 }
138- FrameKind :: Raw ( bytes) => out. write_all ( bytes) . unwrap ( ) ,
221+ asserted += 1 ;
222+ } ) ;
223+ assert_eq ! ( asserted, 2 ) ;
224+ }
225+
226+ #[ test]
227+ fn can_concatenate_partial_defmt_frames ( ) {
228+ let mut parser = FrameDelimiter :: new ( ) ;
229+
230+ let mut asserted = 0 ;
231+ parser. feed ( b"\xFF \x00 frame" , |_| {
232+ panic ! ( "Should not have a frame yet" ) ;
233+ } ) ;
234+ parser. feed ( b" data\x00 \xFF " , |frame| {
235+ assert_eq ! ( frame, FrameKind :: Defmt ( b"frame data" ) ) ;
236+ asserted += 1 ;
237+ } ) ;
238+ parser. feed ( b"\x00 second frame" , |_| {
239+ panic ! ( "Should not have a frame yet" ) ;
139240 } ) ;
241+ parser. feed ( b"\x00 last part" , |frame| {
242+ match asserted {
243+ 1 => assert_eq ! ( frame, FrameKind :: Defmt ( b"second frame" ) ) ,
244+ 2 => assert_eq ! ( frame, FrameKind :: Raw ( b"last part" ) ) ,
245+ _ => panic ! ( "Too many frames" ) ,
246+ }
247+ asserted += 1 ;
248+ } ) ;
249+ assert_eq ! ( asserted, 3 ) ;
250+ }
251+
252+ #[ test]
253+ fn defmt_frames_back_to_back ( ) {
254+ let mut parser = FrameDelimiter :: new ( ) ;
255+
256+ let mut asserted = 0 ;
257+ parser. feed ( b"\xFF \x00 frame data1\x00 \xFF \x00 frame data2\x00 " , |frame| {
258+ match asserted {
259+ 0 => assert_eq ! ( frame, FrameKind :: Defmt ( b"frame data1" ) ) ,
260+ 1 => assert_eq ! ( frame, FrameKind :: Defmt ( b"frame data2" ) ) ,
261+ _ => panic ! ( "Too many frames" ) ,
262+ }
263+ asserted += 1 ;
264+ } ) ;
265+ assert_eq ! ( asserted, 2 ) ;
266+ }
267+
268+ #[ test]
269+ fn output_includes_ff_and_0_bytes ( ) {
270+ let mut parser = FrameDelimiter :: new ( ) ;
271+
272+ let mut asserted = 0 ;
273+ parser. feed (
274+ b"some message\xFF with parts of\0 a defmt \0 \xFF frame delimiter" ,
275+ |frame| {
276+ assert_eq ! (
277+ frame,
278+ FrameKind :: Raw (
279+ b"some message\xFF with parts of\0 a defmt \0 \xFF frame delimiter"
280+ )
281+ ) ;
282+ asserted += 1 ;
283+ } ,
284+ ) ;
285+ assert_eq ! ( asserted, 1 ) ;
140286 }
141287}
0 commit comments