@@ -28,10 +28,15 @@ use log::trace;
28
28
use serde:: ser:: { Serialize , SerializeStruct , Serializer } ;
29
29
30
30
use std:: {
31
- fmt:: { self , Formatter } ,
31
+ fmt:: { self , Display , Formatter , Write } ,
32
32
str,
33
33
} ;
34
34
35
+ use crate :: {
36
+ nested_parser:: ParseRestResolver , GeneralParseLogError , LogMessage , ParseLogSeverity ,
37
+ ResolveParseHint ,
38
+ } ;
39
+
35
40
const DLT_COLUMN_SENTINAL : char = '\u{0004}' ;
36
41
const DLT_ARGUMENT_SENTINAL : char = '\u{0005}' ;
37
42
const DLT_NEWLINE_SENTINAL_SLICE : & [ u8 ] = & [ 0x6 ] ;
@@ -281,6 +286,17 @@ impl<'a> Serialize for FormattableMessage<'a> {
281
286
None => state. serialize_field ( "payload" , "[Unknown CtrlCommand]" ) ?,
282
287
}
283
288
}
289
+ PayloadContent :: NetworkTrace ( slices) => {
290
+ state. serialize_field ( "app-id" , & ext_header_app_id) ?;
291
+ state. serialize_field ( "context-id" , & ext_header_context_id) ?;
292
+ state. serialize_field ( "message-type" , & ext_header_msg_type) ?;
293
+ let arg_string = slices
294
+ . iter ( )
295
+ . map ( |slice| format ! ( "{:02X?}" , slice) )
296
+ . collect :: < Vec < String > > ( )
297
+ . join ( "|" ) ;
298
+ state. serialize_field ( "payload" , & arg_string) ?;
299
+ }
284
300
}
285
301
state. end ( )
286
302
}
@@ -386,12 +402,25 @@ impl<'a> FormattableMessage<'a> {
386
402
payload_string,
387
403
) )
388
404
}
405
+ PayloadContent :: NetworkTrace ( slices) => {
406
+ let payload_string = slices
407
+ . iter ( )
408
+ . map ( |slice| format ! ( "{:02X?}" , slice) )
409
+ . collect :: < Vec < String > > ( )
410
+ . join ( "|" ) ;
411
+ Ok ( PrintableMessage :: new (
412
+ ext_h_app_id,
413
+ eh_ctx_id,
414
+ ext_h_msg_type,
415
+ payload_string,
416
+ ) )
417
+ }
389
418
}
390
419
}
391
420
392
421
fn write_app_id_context_id_and_message_type (
393
422
& self ,
394
- f : & mut fmt:: Formatter ,
423
+ f : & mut impl std :: fmt:: Write ,
395
424
) -> Result < ( ) , fmt:: Error > {
396
425
match self . message . extended_header . as_ref ( ) {
397
426
Some ( ext) => {
@@ -419,7 +448,7 @@ impl<'a> FormattableMessage<'a> {
419
448
& self ,
420
449
id : u32 ,
421
450
data : & [ u8 ] ,
422
- f : & mut fmt:: Formatter ,
451
+ f : & mut impl std :: fmt:: Write ,
423
452
) -> fmt:: Result {
424
453
trace ! ( "format_nonverbose_data" ) ;
425
454
let mut fibex_info_added = false ;
@@ -511,7 +540,16 @@ impl<'a> FormattableMessage<'a> {
511
540
}
512
541
}
513
542
514
- impl < ' a > fmt:: Display for FormattableMessage < ' a > {
543
+ impl LogMessage for FormattableMessage < ' _ > {
544
+ type ParseError = GeneralParseLogError ;
545
+
546
+ fn to_writer < W : std:: io:: Write > ( & self , writer : & mut W ) -> Result < usize , std:: io:: Error > {
547
+ let bytes = self . message . as_bytes ( ) ;
548
+ let len = bytes. len ( ) ;
549
+ writer. write_all ( & bytes) ?;
550
+ Ok ( len)
551
+ }
552
+
515
553
/// will format dlt Message with those fields:
516
554
/// ********* storage-header ********
517
555
/// date-time
@@ -528,43 +566,101 @@ impl<'a> fmt::Display for FormattableMessage<'a> {
528
566
/// context-id
529
567
///
530
568
/// payload
531
- fn fmt ( & self , f : & mut Formatter ) -> Result < ( ) , fmt:: Error > {
569
+ fn try_resolve (
570
+ & self ,
571
+ resolver : Option < & mut ParseRestResolver > ,
572
+ ) -> Result < impl Display , Self :: ParseError > {
573
+ let mut msg = String :: new ( ) ;
574
+ // Taken from Documentation: string formatting is considered an infallible operation.
575
+ // Thus we can ignore `fmt::Error` errors.
576
+ // Link from Clippy: 'https://rust-lang.github.io/rust-clippy/master/index.html#/format_push_string'
577
+ // TODO: Consider another way of concatenating the string after prototyping.
532
578
if let Some ( h) = & self . message . storage_header {
533
579
let tz = self . options . map ( |o| o. tz ) ;
534
580
match tz {
535
581
Some ( Some ( tz) ) => {
536
- write_tz_string ( f, & h. timestamp , & tz) ?;
537
- write ! ( f, "{DLT_COLUMN_SENTINAL}{}" , h. ecu_id) ?;
582
+ let _ = write_tz_string ( & mut msg, & h. timestamp , & tz) ;
583
+ let _ = write ! ( msg, "{DLT_COLUMN_SENTINAL}{}" , h. ecu_id) ;
584
+ }
585
+ _ => {
586
+ let _ = write ! ( msg, "{}" , DltStorageHeader ( h) ) ;
538
587
}
539
- _ => write ! ( f, "{}" , DltStorageHeader ( h) ) ?,
540
588
} ;
541
589
}
542
590
let header = DltStandardHeader ( & self . message . header ) ;
543
- write ! ( f , "{DLT_COLUMN_SENTINAL}" , ) ? ;
544
- write ! ( f , "{header}" ) ? ;
545
- write ! ( f , "{DLT_COLUMN_SENTINAL}" , ) ? ;
591
+ write ! ( msg , "{DLT_COLUMN_SENTINAL}" , ) . unwrap ( ) ;
592
+ write ! ( msg , "{header}" ) . unwrap ( ) ;
593
+ write ! ( msg , "{DLT_COLUMN_SENTINAL}" , ) . unwrap ( ) ;
546
594
547
595
match & self . message . payload {
548
596
PayloadContent :: Verbose ( arguments) => {
549
- self . write_app_id_context_id_and_message_type ( f) ?;
550
- arguments
551
- . iter ( )
552
- . try_for_each ( |arg| write ! ( f, "{}{}" , DLT_ARGUMENT_SENTINAL , DltArgument ( arg) ) )
597
+ let _ = self . write_app_id_context_id_and_message_type ( & mut msg) ;
598
+ arguments. iter ( ) . for_each ( |arg| {
599
+ let _ = write ! ( msg, "{}{}" , DLT_ARGUMENT_SENTINAL , DltArgument ( arg) ) ;
600
+ } ) ;
601
+ }
602
+ PayloadContent :: NonVerbose ( id, data) => {
603
+ let _ = self . format_nonverbose_data ( * id, data, & mut msg) ;
553
604
}
554
- PayloadContent :: NonVerbose ( id, data) => self . format_nonverbose_data ( * id, data, f) ,
555
605
PayloadContent :: ControlMsg ( ctrl_id, _data) => {
556
- self . write_app_id_context_id_and_message_type ( f ) ? ;
606
+ let _ = self . write_app_id_context_id_and_message_type ( & mut msg ) ;
557
607
match service_id_lookup ( ctrl_id. value ( ) ) {
558
- Some ( ( name, _desc) ) => write ! ( f, "[{name}]" ) ,
559
- None => write ! ( f, "[Unknown CtrlCommand]" ) ,
608
+ Some ( ( name, _desc) ) => {
609
+ let _ = write ! ( msg, "[{name}]" ) ;
610
+ }
611
+ None => {
612
+ let _ = write ! ( msg, "[Unknown CtrlCommand]" ) ;
613
+ }
560
614
}
561
615
}
616
+ PayloadContent :: NetworkTrace ( slices) => {
617
+ let _ = self . write_app_id_context_id_and_message_type ( & mut msg) ;
618
+ let is_someip = self
619
+ . message
620
+ . extended_header
621
+ . as_ref ( )
622
+ . is_some_and ( |ext_header| {
623
+ matches ! (
624
+ ext_header. message_type,
625
+ MessageType :: NetworkTrace ( NetworkTraceType :: Ipc )
626
+ | MessageType :: NetworkTrace ( NetworkTraceType :: Someip )
627
+ )
628
+ } ) ;
629
+
630
+ if is_someip {
631
+ if let Some ( resolver) = resolver {
632
+ if let Some ( slice) = slices. get ( 1 ) {
633
+ match resolver. try_resolve ( slice, ResolveParseHint :: SomeIP ) {
634
+ Some ( Ok ( resolved) ) => {
635
+ let _ = write ! ( msg, "{resolved}" ) ;
636
+ return Ok ( msg) ;
637
+ }
638
+ Some ( Err ( _) ) | None => {
639
+ //TODO: Ignore nested Error while prototyping
640
+ }
641
+ }
642
+ }
643
+ }
644
+ }
645
+
646
+ slices. iter ( ) . for_each ( |slice| {
647
+ let _ = write ! ( msg, "{}{:02X?}" , DLT_ARGUMENT_SENTINAL , slice) ;
648
+ } ) ;
649
+
650
+ return Err ( GeneralParseLogError :: new (
651
+ msg,
652
+ "Error while resolving Network trace payload" . into ( ) ,
653
+ ParseLogSeverity :: Error ,
654
+ ) ) ;
655
+ }
562
656
}
657
+
658
+ Ok ( msg)
563
659
}
564
660
}
565
661
566
662
fn write_tz_string (
567
- f : & mut Formatter ,
663
+ f : & mut impl std :: fmt :: Write ,
568
664
time_stamp : & DltTimeStamp ,
569
665
tz : & Tz ,
570
666
) -> Result < ( ) , fmt:: Error > {
0 commit comments