public static string CreateEncoderReportString(EncoderCommunication data) { StringBuilder res = new StringBuilder( string.Format("Encoder communication session. Packets: {0}, period: {1}." + Environment.NewLine + Environment.NewLine, data.Packets.Length, data.Period)); foreach (var item in data.Packets) { if (item == null) { continue; } //if (FilterOutput) if (DetectNonsense(item)) continue; res.AppendLine("///////////////////////////////////// Packet ///////////////////////////////////"); if (item.Command != null) { if (item.Command.ParsedFields.All(x => x.Length == 0)) { res.AppendLine(EncoderCommandDatabase.BroadcastPacketReport); continue; } } res.AppendLine("Raw: " + string.Join(" ", item.ParsedData.Select(x => ArrayToString(x ?? new byte[0])))); res.AppendFormat(EncoderPacketFormat, DisableTimestamp ? -1 : item.Timestamp, item.FCSError ? "ERROR" : "OK", ArrayToString(item.ParsedData[(int)EncoderPacket.Fields.FCS]), ArrayToString(item.ComputedFCS)); res.AppendLine(item.DatabaseReport); //res.AppendLine(); } //ReportProgress("Report created..."); return(res.ToString()); }
public static int Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; if (args.Length < 1) { Console.WriteLine(@"Not enough arguments. Usage: MechatrolinkParser.exe <Exported text file path> <Line/time limit> <Frequency, Hz> [<Options>] Limit and frequency are optional only if <Options> is omitted, defaults: 20000 and 4000000. Use limit = 0 to disable the limit. Options: [-e] = packet body endianess swap (default is 'big-endian'), usually not needed [-s] = silent (switch off progress reports/warnings) [-x] = full exception info (defaults to distinct exception output) [-stm] = transcode the file into LogicSnifferSTM format [-f] = filter output (exclude nonsensical commands, e.g. with Control field equal to neither 01h nor 03h) [-b] = bulk (folder) processing, <file path> argument field becomes <""directory path|search string"">, other argument fields are not changed [-p] = parallel computation in bulk mode [-k] = keep console windows open (Console.ReadKey()) [-i] = invert raw data (to correct receiver polarity) [-pq:X] = set request preamble length to X (defaults to 16) [-ps:X] = set response preamble length to X (defaults to 16) [-n] = encoder mode (sets suitable preamble lengths, enables inversion, changes database and reporter engine - for CC-Link/Mechatrolink encoder communications) [-c:X] = set Kingst LA channel index (i.e. CSV column index) to X (defaults to 1) [-o:X] = start parsing from time offset X (w.r. to 0), units are x10nS [-imax:X] = max request-response delay (defaults to 1000x10nS) [-imin:X] = min request-response delay (defaults to 50x10nS) [-t] = use time limit instead of line limit [-dt] = disable timestamp output (useful for output file comparison during analysis) Returns: OK = 0, CommandLineError = 1, ParserError = 2, TranscoderError = 3, EmptyDataset = 4, BulkProcessingFailed = 5, OutOfMemory = 6 "); Console.ReadLine(); return((int)ExitCodes.CommandLineError); } //DataReporter.ReportProgress("Parsing command line..."); int limit = 20000; int freq = 4000000; int column = 1; int startOffset = int.MinValue; bool swap = false; bool transcode = false; bool invert = false; bool encoder = false; try { args[0] = args[0].Trim('"'); if (args.Length > 1) { limit = int.Parse(args[1]); if (limit == 0) { limit = int.MaxValue; } if (args.Length > 2) { freq = int.Parse(args[2]); } } DataReporter.FilterOutput = args.Contains("-f"); //DataReporter, BulkProcessing and ErrorListener setup goes first DataReporter.EnableProgressOutput = !args.Contains("-s"); DataReporter.DisableTimestamp = args.Contains("-dt"); BulkProcessing.UseParallelComputation = args.Contains("-p"); ErrorListener.PrintOnlyDistinctExceptions = !args.Contains("-x"); if (args.Contains("-b")) //Possible bulk processing goes second { return(BulkMain(args, limit, freq)); } LogicAnalyzerData.UseTimeLimit = args.Contains("-t"); invert = args.Contains("-i"); //And local vars are the last swap = args.Contains("-e"); transcode = args.Contains("-stm"); if (args.Contains("-n")) //Mode switches override on/off switches { //invert = true; encoder = true; HDLCManchesterDecoder.RequestPreambleLength = 15; HDLCManchesterDecoder.ResponsePreambleLength = 4; } //Switches with arguments override mode switches ArgumentHelper("-pq:", args, (int i) => { HDLCManchesterDecoder.RequestPreambleLength = i; }); ArgumentHelper("-ps:", args, (int i) => { HDLCManchesterDecoder.ResponsePreambleLength = i; }); ArgumentHelper("-c:", args, (int i) => { column = i; }); ArgumentHelper("-imin:", args, (int i) => { HDLCManchesterDecoder.MinRequestResponseDelay = i; }); ArgumentHelper("-imax:", args, (int i) => { HDLCManchesterDecoder.MaxRequestResponseDelay = i; }); ArgumentHelper("-o:", args, (int i) => { startOffset = i; }); } catch (Exception e) { Console.WriteLine("Unable to parse command line:"); Console.WriteLine(e.ToString()); return(ReturnHelper(ExitCodes.CommandLineError, args)); } DataReporter.ReportProgress(string.Format("{3} limit: {0}, frequency: {1}, endianess swap: {2}.", limit, freq, swap, LogicAnalyzerData.UseTimeLimit ? "Time" : "Line")); DataReporter.ReportProgress("Loading data..."); LogicAnalyzerData data; try { if (LogicAnalyzerData.DetectFormat(args[0]) == LogicAnalyzerData.Format.LogicSnifferSTM) { data = LogicAnalyzerData.CreateFromLogicSnifferSTM(args[0], limit); } else { data = LogicAnalyzerData.CreateFromKingst(args[0], column, limit); } if (data.Count == 0) { Console.WriteLine("Given current time constraints, the dataset empty!"); return(ReturnHelper(ExitCodes.EmptyDataset, args)); } if (invert) { data = data.Invert(); } data = data.SkipUntil(startOffset); GC.Collect(); DataReporter.ReportProgress("Parsing data..."); if (encoder) { var parsed = EncoderCommunication.Parse(data, freq, swap); DoneReportErrors(); Console.WriteLine(DataReporter.CreateEncoderReportString(parsed)); } else { var parsed = MechatrolinkCommunication.Parse(data, freq, swap); DoneReportErrors(); Console.WriteLine(DataReporter.CreateMechatrolinkReportString(parsed)); } } catch (OutOfMemoryException) { return(ReturnHelper(ExitCodes.OutOfMemory, args)); } catch (Exception e) { Console.WriteLine("Unable to parse the data:"); Console.WriteLine(e.ToString()); return(ReturnHelper(ExitCodes.ParserError, args)); } if (transcode) { try { MakeBackupCopy(args[0]); LogicAnalyzerData.WriteToLogicSnifferSTM(data, args[0]); } catch (Exception e) { Console.WriteLine("Unable to transcode the file:"); Console.WriteLine(e.ToString()); return(ReturnHelper(ExitCodes.TranscoderError, args)); } } return(ReturnHelper(0, args)); }