1- using System ;
2- using System . Collections . Generic ;
3- using System . Diagnostics ;
1+ using System . Diagnostics ;
42using System . Globalization ;
53using System . IO ;
6- using System . Linq ;
74using System . Text ;
85using System . Text . RegularExpressions ;
9- using System . Threading . Tasks ;
106using System . Windows ;
117using static NMEA2000Analyzer . MainWindow ;
128
@@ -22,13 +18,20 @@ public enum FileFormat
2218 CanDump1 ,
2319 CanDump2 ,
2420 YDWG ,
21+ YDBinary ,
2522 PCANView
2623 }
2724
2825 public static FileFormat DetectFileFormat ( string filePath )
2926 {
3027 try
3128 {
29+ if ( IsBinaryYDFormat ( filePath ) )
30+ {
31+ Debug . WriteLine ( "Binary CAN format detected" ) ;
32+ return FileFormat . YDBinary ;
33+ }
34+
3235 var lines = File . ReadLines ( filePath ) . Take ( 10 ) . ToList ( ) ; // Read the first few lines
3336
3437 foreach ( var line in lines )
@@ -407,5 +410,110 @@ public static List<Nmea2000Record> LoadPCANView(string filePath)
407410 return records ;
408411 }
409412
413+ private static bool IsBinaryYDFormat ( string filePath )
414+ {
415+ try
416+ {
417+ using ( var fs = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) )
418+ using ( var reader = new BinaryReader ( fs ) )
419+ {
420+ if ( fs . Length < 16 ) return false ; // File must be at least one record (16 bytes) long
421+
422+ byte [ ] firstRecord = reader . ReadBytes ( 16 ) ;
423+
424+ if ( firstRecord . Length < 16 ) return false ;
425+
426+ // Check if position 4-7 (Message Identifier) is 0xFFFFFFFF (Service Record)
427+ uint messageId = BitConverter . ToUInt32 ( firstRecord , 4 ) ;
428+ if ( messageId != 0xFFFFFFFF )
429+ return false ;
430+
431+ // Check if data field (position 8-15) contains "YDVR v05"
432+ string dataString = Encoding . ASCII . GetString ( firstRecord , 8 , 8 ) . TrimEnd ( '\0 ' ) ;
433+ return dataString . StartsWith ( "YDVR v05" ) ;
434+ }
435+ }
436+ catch
437+ {
438+ return false ;
439+ }
440+ }
441+
442+ public static List < Nmea2000Record > LoadYDBinary ( string filePath )
443+ {
444+ var records = new List < Nmea2000Record > ( ) ;
445+
446+ try
447+ {
448+ using ( var fs = new FileStream ( filePath , FileMode . Open , FileAccess . Read ) )
449+ using ( var reader = new BinaryReader ( fs ) )
450+ {
451+ while ( reader . BaseStream . Position < reader . BaseStream . Length )
452+ {
453+ byte [ ] recordBytes = reader . ReadBytes ( 16 ) ;
454+ if ( recordBytes . Length < 16 ) break ; // Ensure full record read
455+
456+ // Extract fields from the binary record
457+ ushort header = BitConverter . ToUInt16 ( recordBytes , 0 ) ;
458+ ushort timeInMs = BitConverter . ToUInt16 ( recordBytes , 2 ) ;
459+ uint messageId = BitConverter . ToUInt32 ( recordBytes , 4 ) ;
460+ byte [ ] data = recordBytes . Skip ( 8 ) . Take ( 8 ) . ToArray ( ) ;
461+
462+ // Decode header fields
463+ bool is11BitId = ( header & 0x8000 ) != 0 ;
464+ bool isTx = ( header & 0x4000 ) != 0 ;
465+ int dataLength = ( ( header >> 12 ) & 0x07 ) + 1 ; // Values 0-7 map to 1-8 bytes
466+ int interfaceId = ( header & 0x0800 ) != 0 ? 1 : 0 ;
467+ int timestampMinutes = header & 0x03FF ; // 10-bit timestamp in minutes
468+
469+ // Convert timestamp
470+ string timestamp = $ "{ timestampMinutes : D4} :{ timeInMs : D5} "; // Example format: "0345:01234"
471+
472+ // Extract PGN, Source, Destination
473+ uint pgn ;
474+ int source , destination , priority ;
475+
476+ if ( is11BitId )
477+ {
478+ // 11-bit identifier case (usually not PGN-based)
479+ pgn = messageId & 0x07FF ;
480+ source = - 1 ;
481+ destination = - 1 ;
482+ priority = - 1 ;
483+ }
484+ else
485+ {
486+ // 29-bit identifier
487+ priority = ( int ) ( ( messageId >> 26 ) & 0x07 ) ;
488+ pgn = ( messageId >> 8 ) & 0x1FFFF ; // Extract PGN (middle 18 bits)
489+ destination = ( int ) ( ( messageId >> 8 ) & 0xFF ) ;
490+ source = ( int ) ( messageId & 0xFF ) ;
491+ }
492+
493+ // Format data bytes as a space-separated hex string
494+ string dataHex = string . Join ( " " , data . Take ( dataLength ) . Select ( b => $ "0x{ b : X2} ") ) ;
495+
496+ // Create the record
497+ var record = new Nmea2000Record
498+ {
499+ Timestamp = timestamp ,
500+ Priority = priority . ToString ( ) ,
501+ PGN = pgn . ToString ( ) ,
502+ Source = source . ToString ( ) ,
503+ Destination = destination . ToString ( ) ,
504+ Data = dataHex
505+ } ;
506+
507+ records . Add ( record ) ;
508+ }
509+ }
510+ }
511+ catch ( Exception ex )
512+ {
513+ MessageBox . Show ( $ "Failed to load binary CAN file: { ex . Message } ", "Error" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
514+ }
515+
516+ return records ;
517+ }
410518 }
411519}
0 commit comments