From 1667d911f8aea38cca286106b3803ea2c40add2e Mon Sep 17 00:00:00 2001 From: docbender Date: Mon, 14 Feb 2022 09:23:44 +0100 Subject: [PATCH 01/18] .NET6 conversion --- .gitignore | 3 + SerialMonitor.sln | 11 +- SerialMonitor/Cinout.cs | 4 +- SerialMonitor/Program.cs | 2005 +++++++++++----------- SerialMonitor/Properties/AssemblyInfo.cs | 36 - SerialMonitor/SerialMonitor.csproj | 71 +- 6 files changed, 1027 insertions(+), 1103 deletions(-) delete mode 100644 SerialMonitor/Properties/AssemblyInfo.cs diff --git a/.gitignore b/.gitignore index 58d158b..989a8de 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ /SerialMonitor.suo /SerialMonitor/bin/Release /SerialMonitor/obj/Release +.vs +bin +obj diff --git a/SerialMonitor.sln b/SerialMonitor.sln index 2deb249..7d324a3 100644 --- a/SerialMonitor.sln +++ b/SerialMonitor.sln @@ -1,7 +1,9 @@  -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerialMonitor", "SerialMonitor\SerialMonitor.csproj", "{019A06E0-C535-488C-AACF-E2A0E1A26861}" +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32112.339 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerialMonitor", "SerialMonitor\SerialMonitor.csproj", "{019A06E0-C535-488C-AACF-E2A0E1A26861}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,4 +19,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0EB2695A-E2CB-4290-9B63-F93C61AA527E} + EndGlobalSection EndGlobal diff --git a/SerialMonitor/Cinout.cs b/SerialMonitor/Cinout.cs index 9ce88eb..9de2da4 100644 --- a/SerialMonitor/Cinout.cs +++ b/SerialMonitor/Cinout.cs @@ -10,9 +10,9 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Text; using System.Threading; -using System.Windows.Forms; namespace SerialMonitor { @@ -90,7 +90,7 @@ protected static void borders() Console.WriteLine("Window is too small!!!!"); return; } - string name = " " + Application.ProductName + " v." + Application.ProductVersion.Substring(0, Application.ProductVersion.Length - 2) + " "; + string name = $" SerialMonitor v.{Assembly.GetExecutingAssembly().GetName().Version.ToString(3)} "; Console.WriteLine("+" + new string('-', Console.WindowWidth - 2) + "+"); if(Console.WindowWidth > name.Length) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index f7fcff1..ed4441c 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -16,246 +16,245 @@ using System.IO; using System.Text.RegularExpressions; using System.Diagnostics; -using System.Windows.Forms; namespace SerialMonitor { - class Program - { - static ArgumentCollection arguments = new ArgumentCollection(new string[] { "baudrate", "parity", "databits", "stopbits", + class Program + { + static ArgumentCollection arguments = new ArgumentCollection(new string[] { "baudrate", "parity", "databits", "stopbits", "repeatfile", "logfile", "logincomingonly", "showascii", "notime", "gaptolerance", "continuousmode", "nogui" }); - static string version = Application.ProductVersion.Substring(0, Application.ProductVersion.Length-2); - static long lastTimeReceved = 0; - static bool repeaterEnabled = false; - static bool repeaterUseHex = false; - static bool showAscii = false; - static Dictionary repeaterMap; - static bool logfile = false; - static bool logincomingonly = false; - static string logFilename = ""; - static bool noTime = false; - static int gapTolerance = 0; - static bool gapToleranceEnable = false; - static bool continuousMode = false; - /// - /// Flag for stop printing communication data. Log into file will continue. - /// - static bool pausePrint = false; - /// - /// Flag for pause / resume connection - /// - static bool pauseConnection = false; + static string version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(3); + static long lastTimeReceved = 0; + static bool repeaterEnabled = false; + static bool repeaterUseHex = false; + static bool showAscii = false; + static Dictionary repeaterMap; + static bool logfile = false; + static bool logincomingonly = false; + static string logFilename = ""; + static bool noTime = false; + static int gapTolerance = 0; + static bool gapToleranceEnable = false; + static bool continuousMode = false; + /// + /// Flag for stop printing communication data. Log into file will continue. + /// + static bool pausePrint = false; + /// + /// Flag for pause / resume connection + /// + static bool pauseConnection = false; + + + /// + /// Main loop + /// + /// + static void Main(string[] args) + { + string portName = IsRunningOnMono() ? "/dev/ttyS1" : "COM1"; + + if (args.Length > 0) + { + if (args[0].Equals("-?") || args[0].Equals("-help") || args[0].Equals("--help") || args[0].Equals("?") || args[0].Equals("/?")) + { + consoleWriteLineNoTrace("SerialMonitor v." + version); + printHelp(); + Console.WriteLine("\nPress [Enter] to exit"); + Console.ReadLine(); + return; + } + else + portName = args[0]; + } + else + { + string[] savedArgs = Config.LoadStarters(); + if (savedArgs != null) + { + portName = savedArgs[0]; + args = savedArgs; + } + } - /// - /// Main loop - /// - /// - static void Main(string[] args) - { - string portName = IsRunningOnMono() ? "/dev/ttyS1" : "COM1"; + arguments.Parse(args); + + continuousMode = arguments.GetArgument("continuousmode").Enabled || arguments.GetArgument("nogui").Enabled; ; + + if (!continuousMode) + Cinout.Init(); + else + consoleWriteLineNoTrace("SerialMonitor v." + version); + + showAscii = arguments.GetArgument("showascii").Enabled; + noTime = arguments.GetArgument("notime").Enabled; + + int baudrate = 9600; + Parity parity = Parity.None; + int dataBits = 8; + StopBits stopBits = StopBits.One; - if(args.Length > 0) - { - if(args[0].Equals("-?") || args[0].Equals("-help") || args[0].Equals("--help") || args[0].Equals("?") || args[0].Equals("/?")) + Argument arg = arguments.GetArgument("baudrate"); + if (arg.Enabled) + int.TryParse(arg.Parameter, out baudrate); + + arg = arguments.GetArgument("parity"); + if (arg.Enabled) { - consoleWriteLineNoTrace("SerialMonitor v." + version); - printHelp(); - Console.WriteLine("\nPress [Enter] to exit"); - Console.ReadLine(); - return; + if (arg.Parameter.ToLower().Equals("odd")) + parity = Parity.Odd; + else if (arg.Parameter.ToLower().Equals("even")) + parity = Parity.Even; + else if (arg.Parameter.ToLower().Equals("mark")) + parity = Parity.Mark; + else if (arg.Parameter.ToLower().Equals("space")) + parity = Parity.Space; } - else - portName = args[0]; - } - else - { - string[] savedArgs = Config.LoadStarters(); - if(savedArgs!=null) + arg = arguments.GetArgument("databits"); + if (arg.Enabled) + int.TryParse(arg.Parameter, out dataBits); + + arg = arguments.GetArgument("stopbits"); + if (arg.Enabled) { - portName = savedArgs[0]; - args = savedArgs; + if (arg.Parameter.ToLower().Equals("1")) + stopBits = StopBits.One; + else if (arg.Parameter.ToLower().Equals("1.5")) + stopBits = StopBits.OnePointFive; + else if (arg.Parameter.ToLower().Equals("2")) + stopBits = StopBits.Two; + else if (arg.Parameter.ToLower().Equals("0")) + stopBits = StopBits.None; } - } - - arguments.Parse(args); - - continuousMode = arguments.GetArgument("continuousmode").Enabled || arguments.GetArgument("nogui").Enabled; ; - - if(!continuousMode) - Cinout.Init(); - else - consoleWriteLineNoTrace("SerialMonitor v." + version); - - showAscii = arguments.GetArgument("showascii").Enabled; - noTime = arguments.GetArgument("notime").Enabled; - - int baudrate = 9600; - Parity parity = Parity.None; - int dataBits = 8; - StopBits stopBits = StopBits.One; - - Argument arg = arguments.GetArgument("baudrate"); - if(arg.Enabled) - int.TryParse(arg.Parameter, out baudrate); - - arg = arguments.GetArgument("parity"); - if(arg.Enabled) - { - if(arg.Parameter.ToLower().Equals("odd")) - parity = Parity.Odd; - else if(arg.Parameter.ToLower().Equals("even")) - parity = Parity.Even; - else if(arg.Parameter.ToLower().Equals("mark")) - parity = Parity.Mark; - else if(arg.Parameter.ToLower().Equals("space")) - parity = Parity.Space; - } - - arg = arguments.GetArgument("databits"); - if(arg.Enabled) - int.TryParse(arg.Parameter, out dataBits); - - arg = arguments.GetArgument("stopbits"); - if(arg.Enabled) - { - if(arg.Parameter.ToLower().Equals("1")) - stopBits = StopBits.One; - else if(arg.Parameter.ToLower().Equals("1.5")) - stopBits = StopBits.OnePointFive; - else if(arg.Parameter.ToLower().Equals("2")) - stopBits = StopBits.Two; - else if(arg.Parameter.ToLower().Equals("0")) - stopBits = StopBits.None; - } - - SerialPort port = new SerialPort(portName, baudrate, parity, dataBits, stopBits); + + SerialPort port = new SerialPort(portName, baudrate, parity, dataBits, stopBits); #if __MonoCS__ #else - port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); - port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived); - port.PinChanged += new SerialPinChangedEventHandler(port_PinChanged); + port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); + port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived); + port.PinChanged += new SerialPinChangedEventHandler(port_PinChanged); #endif - //log option - arg = arguments.GetArgument("logfile"); - if(arg.Enabled) - { - if(arg.Parameter.Length == 0) + //log option + arg = arguments.GetArgument("logfile"); + if (arg.Enabled) { - logFilename = "log_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") +".txt"; - consoleWriteLine("Warning: Log file name not specified. Used " + logFilename); + if (arg.Parameter.Length == 0) + { + logFilename = "log_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".txt"; + consoleWriteLine("Warning: Log file name not specified. Used " + logFilename); + } + else + logFilename = arg.Parameter; + + logfile = true; } - else - logFilename = arg.Parameter; - - logfile = true; - } - arg = arguments.GetArgument("logincomingonly"); - if(arg.Enabled) - { - if(!logfile) + arg = arguments.GetArgument("logincomingonly"); + if (arg.Enabled) { - logfile = true; - logFilename = "log_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") +".txt"; - consoleWriteLine("Warning: Parameter logfile not specified. Log enabled to the file: " + logFilename); - logfile = true; + if (!logfile) + { + logfile = true; + logFilename = "log_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".txt"; + consoleWriteLine("Warning: Parameter logfile not specified. Log enabled to the file: " + logFilename); + logfile = true; + } + logincomingonly = true; } - logincomingonly = true; - } - //gap argument - arg = arguments.GetArgument("gaptolerance"); - if(arg.Enabled) - { - int.TryParse(arg.Parameter, out gapTolerance); + //gap argument + arg = arguments.GetArgument("gaptolerance"); + if (arg.Enabled) + { + int.TryParse(arg.Parameter, out gapTolerance); - if(gapTolerance == 0) - consoleWriteLine("Warning: Parameter gaptolerance has invalid argument. Gap tolerance must be greater than zero."); - else - gapToleranceEnable = true; - } + if (gapTolerance == 0) + consoleWriteLine("Warning: Parameter gaptolerance has invalid argument. Gap tolerance must be greater than zero."); + else + gapToleranceEnable = true; + } - if(logfile) - { - //check path - string path = System.IO.Path.GetDirectoryName(logFilename); - if(path.Length == 0) - logFilename = System.IO.Directory.GetCurrentDirectory() + "\\" + logFilename; - else + if (logfile) { - if(!System.IO.Directory.Exists(path)) - System.IO.Directory.CreateDirectory(path); + //check path + string path = System.IO.Path.GetDirectoryName(logFilename); + if (path.Length == 0) + logFilename = System.IO.Directory.GetCurrentDirectory() + "\\" + logFilename; + else + { + if (!System.IO.Directory.Exists(path)) + System.IO.Directory.CreateDirectory(path); + } + + if (!isFileNameValid(logFilename)) + { + consoleWriteLine("\nPress [Enter] to exit"); + Console.ReadLine(); + + return; + } + + //assign file to listener + if (Trace.Listeners["Default"] is DefaultTraceListener) + ((DefaultTraceListener)Trace.Listeners["Default"]).LogFileName = logFilename; } - if(!isFileNameValid(logFilename)) + if (args.Length > 0) { - consoleWriteLine("\nPress [Enter] to exit"); - Console.ReadLine(); - - return; + if (Config.SaveStarters(args)) + consoleWriteLine("Program parameters have been saved. Will be used next time you start program."); + else + consoleWriteLine("Warning: Program parameters cannot be saved."); } - //assign file to listener - if(Trace.Listeners["Default"] is DefaultTraceListener) - ((DefaultTraceListener)Trace.Listeners["Default"]).LogFileName = logFilename; - } - - if(args.Length > 0) - { - if(Config.SaveStarters(args)) - consoleWriteLine("Program parameters have been saved. Will be used next time you start program."); - else - consoleWriteLine("Warning: Program parameters cannot be saved."); - } - - Argument repeatfile = arguments.GetArgument("repeatfile"); - if(repeatfile.Enabled) - { - if(!isFileNameValid(repeatfile.Parameter)) + Argument repeatfile = arguments.GetArgument("repeatfile"); + if (repeatfile.Enabled) { - consoleWriteLine("\nPress [Enter] to exit"); - Console.ReadLine(); - - return; + if (!isFileNameValid(repeatfile.Parameter)) + { + consoleWriteLine("\nPress [Enter] to exit"); + Console.ReadLine(); + + return; + } + PrepareRepeatFile(repeatfile.Parameter); } - PrepareRepeatFile(repeatfile.Parameter); - } - consoleWriteLine("Opening port {0}: baudrate={1}b/s, parity={2}, databits={3}, stopbits={4}", port.PortName, port.BaudRate.ToString(), port.Parity.ToString(), port.DataBits.ToString(), port.StopBits.ToString()); + consoleWriteLine("Opening port {0}: baudrate={1}b/s, parity={2}, databits={3}, stopbits={4}", port.PortName, port.BaudRate.ToString(), port.Parity.ToString(), port.DataBits.ToString(), port.StopBits.ToString()); - writePortStatus(port); + writePortStatus(port); - portConnectInfinite(port); + portConnectInfinite(port); - if(port.IsOpen) - { - consoleWriteLine("Port {0} opened", portName); - writePortStatus(port); - writePinStatus(port); - } - else - return; + if (port.IsOpen) + { + consoleWriteLine("Port {0} opened", portName); + writePortStatus(port); + writePinStatus(port); + } + else + return; #if __MonoCS__ SerialPinChange _pinsStatesNow = 0; SerialPinChange _pinsStatesOld = 0; #endif - bool exit = false; + bool exit = false; - string[] history = Config.LoadHistory(); + string[] history = Config.LoadHistory(); - if(history != null && history.Length > 0) - { - Cinout.CommandHistory = new List(history); - history = null; - } + if (history != null && history.Length > 0) + { + Cinout.CommandHistory = new List(history); + history = null; + } - while(!exit) - { + while (!exit) + { #if __MonoCS__ if(port.BytesToRead > 0) port_DataReceived(port, null); @@ -276,500 +275,500 @@ static void Main(string[] args) Thread.Sleep(100); } #else - Thread.Sleep(100); + Thread.Sleep(100); #endif - CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); - if(cmd == CommandEnum.EXIT) - { - Exit(); - port.Close(); - exit = true; - } + CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); + if (cmd == CommandEnum.EXIT) + { + Exit(); + port.Close(); + exit = true; + } + + switch (cmd) + { + case CommandEnum.PAUSE: + pausePrint = !pausePrint; + if (pausePrint) + consoleWriteLine("Print paused"); + else + consoleWriteLine("Print resumed"); + + if (!continuousMode) + Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); + break; + case CommandEnum.CONNECT: + connectCommand(port); + if (!continuousMode) + Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); + break; + case CommandEnum.HELP: + printHelp(); + break; + case CommandEnum.SEND: + if (continuousMode) + consoleWriteLineNoTrace("Type message to send: "); + else + Cinout.StartSendDataType(); - switch(cmd) - { - case CommandEnum.PAUSE: - pausePrint = !pausePrint; - if(pausePrint) - consoleWriteLine("Print paused"); - else - consoleWriteLine("Print resumed"); - - if(!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - case CommandEnum.CONNECT: - connectCommand(port); - if(!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - case CommandEnum.HELP: - printHelp(); - break; - case CommandEnum.SEND: - if(continuousMode) - consoleWriteLineNoTrace("Type message to send: "); - else - Cinout.StartSendDataType(); - - string line = Cinout.ConsoleReadLine(!continuousMode); - - if(!continuousMode) - Cinout.EndSendDataType(); - - if(line != null) - { - if(userDataSend(port, line)) - consoleWriteLine("Sent: {0}", line); - } - break; - case CommandEnum.SEND_FILE: - if(continuousMode) - consoleWriteLineNoTrace("Type file to send: "); - else - Cinout.StartSendFile(); - - string filepath = Cinout.ConsoleReadLine(!continuousMode); - - if(!continuousMode) - Cinout.EndSendFile(); - - if(filepath != null) - { - if(userDataSendFile(port, filepath)) - consoleWriteLine("Sent file: {0}", filepath); - } - break; - case CommandEnum.RTS: - port.RtsEnable = !port.RtsEnable; - writePinStatus(port); - break; - case CommandEnum.DTR: - port.DtrEnable = !port.DtrEnable; - writePinStatus(port); - break; - case CommandEnum.FORMAT: - showAscii = !showAscii; - - if(!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - } + string line = Cinout.ConsoleReadLine(!continuousMode); - if(!pauseConnection && !port.IsOpen) - { - consoleWriteLine(" Port disconnected...."); - portConnectInfinite(port); - } - } - } + if (!continuousMode) + Cinout.EndSendDataType(); - /// - /// Send tada typed by user - /// - /// - /// - /// - private static bool userDataSend(SerialPort port, string line) - { - if(line.Length == 0) - { - consoleWriteError("Nothing to sent."); - return false; - } - - bool hex = false; - byte[] data; - - if(line.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase)) - hex = true; + if (line != null) + { + if (userDataSend(port, line)) + consoleWriteLine("Sent: {0}", line); + } + break; + case CommandEnum.SEND_FILE: + if (continuousMode) + consoleWriteLineNoTrace("Type file to send: "); + else + Cinout.StartSendFile(); - if(hex) - { - string prepared = line.Replace("0x", ""); + string filepath = Cinout.ConsoleReadLine(!continuousMode); - Regex reg = new Regex("^([0-9A-Fa-f]{1,2}\\s*)+$"); + if (!continuousMode) + Cinout.EndSendFile(); - if(!reg.IsMatch(prepared)) - { - consoleWriteError("Message is not well formated. Data will be not sent."); - return false; + if (filepath != null) + { + if (userDataSendFile(port, filepath)) + consoleWriteLine("Sent file: {0}", filepath); + } + break; + case CommandEnum.RTS: + port.RtsEnable = !port.RtsEnable; + writePinStatus(port); + break; + case CommandEnum.DTR: + port.DtrEnable = !port.DtrEnable; + writePinStatus(port); + break; + case CommandEnum.FORMAT: + showAscii = !showAscii; + + if (!continuousMode) + Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); + break; + } + + if (!pauseConnection && !port.IsOpen) + { + consoleWriteLine(" Port disconnected...."); + portConnectInfinite(port); + } } - - string[] parts = prepared.Split(' '); - string[] partsReady = new string[parts.Length]; - int recordsLength = 0, bytesLength = 0; - - foreach(string s in parts) + } + + /// + /// Send tada typed by user + /// + /// + /// + /// + private static bool userDataSend(SerialPort port, string line) + { + if (line.Length == 0) { - if(s.Length > 0) - { - int bytes = s.Length / 2; - - if((s.Length % 2) == 1) - { - partsReady[recordsLength++] = "0" + s; - - bytesLength += bytes + 1; - } - else - { - partsReady[recordsLength++] = s; - - bytesLength += bytes; - } - } + consoleWriteError("Nothing to sent."); + return false; } - data = new byte[bytesLength]; + bool hex = false; + byte[] data; - bytesLength = 0; + if (line.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase)) + hex = true; - for(int i = 0;i < recordsLength;i++) + if (hex) { - for(int j = 0;j < partsReady[i].Length;j=j+2) - { - data[bytesLength++] = Convert.ToByte(partsReady[i].Substring(j, 2), 16); - } - } - } - else - { - data = ASCIIEncoding.ASCII.GetBytes(line); - } + string prepared = line.Replace("0x", ""); + Regex reg = new Regex("^([0-9A-Fa-f]{1,2}\\s*)+$"); - if(data != null) - { - try - { - port.Write(data, 0, data.Length); - } - catch(Exception ex) - { - consoleWriteError(ex.ToString()); + if (!reg.IsMatch(prepared)) + { + consoleWriteError("Message is not well formated. Data will be not sent."); + return false; + } - return false; - } - } + string[] parts = prepared.Split(' '); + string[] partsReady = new string[parts.Length]; + int recordsLength = 0, bytesLength = 0; - return true; - } + foreach (string s in parts) + { + if (s.Length > 0) + { + int bytes = s.Length / 2; - /// - /// - /// - /// - /// - /// - private static bool userDataSendFile(SerialPort port, string filePath) - { - if(filePath.Length == 0) - { - consoleWriteError("Nothing to sent."); - return false; - } + if ((s.Length % 2) == 1) + { + partsReady[recordsLength++] = "0" + s; - consoleWriteError("Not implemented"); - //TODO: file send - return false; - } + bytesLength += bytes + 1; + } + else + { + partsReady[recordsLength++] = s; - /// - /// Print serial port status - /// - /// - private static void writePortStatus(SerialPort port) - { - if(!continuousMode) - Cinout.WritePortStatus(port.PortName, port.IsOpen, port.BaudRate); - } + bytesLength += bytes; + } + } + } - /// - /// Print serial port pin statuses - /// - /// - private static void writePinStatus(SerialPort port) - { - if(!continuousMode) - { - Cinout.WritePinStatus(port.RtsEnable ? 1 : 0, port.CtsHolding ? 1 : 0, port.DtrEnable ? 1 : 0, port.DsrHolding ? 1 : 0, port.CDHolding ? 1 : 0, port.BreakState ? 1 : 0); - } - } + data = new byte[bytesLength]; - /// - /// Connecting to port in infinite loop - /// - /// - private static void portConnectInfinite(SerialPort port) - { - do - { - if(!portConnect(port)) - { - string waitText = "Waiting 5s to reconnect..."; - consoleWrite(waitText); + bytesLength = 0; - for(int i=0;i<5;i++) - { - for(int j=0;j<4;j++) - { - Thread.Sleep(250); + for (int i = 0; i < recordsLength; i++) + { + for (int j = 0; j < partsReady[i].Length; j = j + 2) + { + data[bytesLength++] = Convert.ToByte(partsReady[i].Substring(j, 2), 16); + } + } + } + else + { + data = ASCIIEncoding.ASCII.GetBytes(line); + } - consoleWrite(j==0 ? "/" : j==1 ? "-" : j==2 ? "\\" : "|"); - consoleCursorLeft(-1); - } - consoleWrite("."); - } + if (data != null) + { + try + { + port.Write(data, 0, data.Length); + } + catch (Exception ex) + { + consoleWriteError(ex.ToString()); + + return false; + } + } - consoleCursorLeftReset(); - consoleWrite(new string(' ', waitText.Length + 5)); - consoleCursorLeftReset(); + return true; + } + + /// + /// + /// + /// + /// + /// + private static bool userDataSendFile(SerialPort port, string filePath) + { + if (filePath.Length == 0) + { + consoleWriteError("Nothing to sent."); + return false; } - CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); - if(cmd == CommandEnum.EXIT) + consoleWriteError("Not implemented"); + //TODO: file send + return false; + } + + /// + /// Print serial port status + /// + /// + private static void writePortStatus(SerialPort port) + { + if (!continuousMode) + Cinout.WritePortStatus(port.PortName, port.IsOpen, port.BaudRate); + } + + /// + /// Print serial port pin statuses + /// + /// + private static void writePinStatus(SerialPort port) + { + if (!continuousMode) { - port.Close(); - break; + Cinout.WritePinStatus(port.RtsEnable ? 1 : 0, port.CtsHolding ? 1 : 0, port.DtrEnable ? 1 : 0, port.DsrHolding ? 1 : 0, port.CDHolding ? 1 : 0, port.BreakState ? 1 : 0); } + } + + /// + /// Connecting to port in infinite loop + /// + /// + private static void portConnectInfinite(SerialPort port) + { + do + { + if (!portConnect(port)) + { + string waitText = "Waiting 5s to reconnect..."; + consoleWrite(waitText); + + for (int i = 0; i < 5; i++) + { + for (int j = 0; j < 4; j++) + { + Thread.Sleep(250); - } - while(!port.IsOpen); - } + consoleWrite(j == 0 ? "/" : j == 1 ? "-" : j == 2 ? "\\" : "|"); + consoleCursorLeft(-1); + } - /// - /// Connecting to port - /// - /// - /// - private static bool portConnect(SerialPort port) - { - try - { - port.Open(); - } - catch(System.IO.IOException ex) - { - consoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); - consoleWriteLine(" Available ports: " + string.Join(",", SerialPort.GetPortNames())); + consoleWrite("."); + } - return false; - } - catch(Exception ex) - { - consoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); + consoleCursorLeftReset(); + consoleWrite(new string(' ', waitText.Length + 5)); + consoleCursorLeftReset(); + } - return false; - } + CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); + if (cmd == CommandEnum.EXIT) + { + port.Close(); + break; + } - return true; - } + } + while (!port.IsOpen); + } + + /// + /// Connecting to port + /// + /// + /// + private static bool portConnect(SerialPort port) + { + try + { + port.Open(); + } + catch (System.IO.IOException ex) + { + consoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); + consoleWriteLine(" Available ports: " + string.Join(",", SerialPort.GetPortNames())); - /// - /// Close port - /// - /// - /// - private static void portClose(SerialPort port) - { - if(port.IsOpen) - port.Close(); - } + return false; + } + catch (Exception ex) + { + consoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); - /// - /// Provide connect (pause/resume) command - /// - private static void connectCommand(SerialPort port) - { - pauseConnection = !pauseConnection; + return false; + } - if(pauseConnection) - { - consoleWriteLine(" Connection paused. Port closed."); - port.Close(); + return true; + } + + /// + /// Close port + /// + /// + /// + private static void portClose(SerialPort port) + { + if (port.IsOpen) + port.Close(); + } + + /// + /// Provide connect (pause/resume) command + /// + private static void connectCommand(SerialPort port) + { + pauseConnection = !pauseConnection; + + if (pauseConnection) + { + consoleWriteLine(" Connection paused. Port closed."); + port.Close(); - writePortStatus(port); - } - else - { - consoleWriteLine(" Resuming connection..."); + writePortStatus(port); + } + else + { + consoleWriteLine(" Resuming connection..."); - portConnectInfinite(port); + portConnectInfinite(port); - if(port.IsOpen) - { - consoleWriteLine(" Connection resumed"); + if (port.IsOpen) + { + consoleWriteLine(" Connection resumed"); - writePortStatus(port); + writePortStatus(port); - writePinStatus(port); + writePinStatus(port); + } } - } - } - - /// - /// Validating file name(path) - /// - /// - /// - private static bool isFileNameValid(string filePath) - { - foreach(char c in System.IO.Path.GetInvalidPathChars()) - { - if(filePath.Contains(c.ToString())) + } + + /// + /// Validating file name(path) + /// + /// + /// + private static bool isFileNameValid(string filePath) + { + foreach (char c in System.IO.Path.GetInvalidPathChars()) { - consoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); + if (filePath.Contains(c.ToString())) + { + consoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); - return false; + return false; + } } - } - foreach(char c in System.IO.Path.GetInvalidFileNameChars()) - { - if(System.IO.Path.GetFileName(filePath).Contains(c.ToString())) + foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { - consoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); + if (System.IO.Path.GetFileName(filePath).Contains(c.ToString())) + { + consoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); - return false; + return false; + } } - } - return true; - } - - /// - /// Procedure to read data from repeat file - /// - /// - private static void PrepareRepeatFile(string fileName) - { - if(!File.Exists(fileName)) - consoleWriteError("File {0} was not found", fileName); - else - { - try + return true; + } + + /// + /// Procedure to read data from repeat file + /// + /// + private static void PrepareRepeatFile(string fileName) + { + if (!File.Exists(fileName)) + consoleWriteError("File {0} was not found", fileName); + else { - string[] lines = File.ReadAllLines(fileName); + try + { + string[] lines = File.ReadAllLines(fileName); - if(lines.Length == 0) - consoleWriteError("Zero lines in file {0}", fileName); + if (lines.Length == 0) + consoleWriteError("Zero lines in file {0}", fileName); - consoleWriteLine("File {0} opened and {1} lines has been read", fileName, lines.Length); + consoleWriteLine("File {0} opened and {1} lines has been read", fileName, lines.Length); - repeaterMap = new Dictionary(); + repeaterMap = new Dictionary(); - //check format file - string startLine = lines[0]; - bool hex; - int linesWithData = 0; - string ask = ""; + //check format file + string startLine = lines[0]; + bool hex; + int linesWithData = 0; + string ask = ""; - Regex reg = new Regex("^(0x[0-9A-Fa-f]{1,2}\\s*)+$"); + Regex reg = new Regex("^(0x[0-9A-Fa-f]{1,2}\\s*)+$"); - if(reg.IsMatch(startLine)) - { - hex = true; - consoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); + if (reg.IsMatch(startLine)) + { + hex = true; + consoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); - Regex regWhite = new Regex("\\s+"); + Regex regWhite = new Regex("\\s+"); - //check whole file - for(int i = 0;i < lines.Length;i++) - { - if(lines[i].Trim().Length > 0) - { - if(reg.IsMatch(lines[i])) - { - if(++linesWithData % 2 == 1) - ask = regWhite.Replace(lines[i].Replace("0x", ""), ""); - else - repeaterMap.Add(ask, regWhite.Replace(lines[i].Replace("0x", ""), "")); - } - else + //check whole file + for (int i = 0; i < lines.Length; i++) { - repeaterMap = null; - throw new RepeatFileException("Line {0} not coresponds to hex format.", i); + if (lines[i].Trim().Length > 0) + { + if (reg.IsMatch(lines[i])) + { + if (++linesWithData % 2 == 1) + ask = regWhite.Replace(lines[i].Replace("0x", ""), ""); + else + repeaterMap.Add(ask, regWhite.Replace(lines[i].Replace("0x", ""), "")); + } + else + { + repeaterMap = null; + throw new RepeatFileException("Line {0} not coresponds to hex format.", i); + } + } } - } - } - repeaterUseHex = true; - } - else - { - reg = new Regex("^([0-9A-Fa-f])+$"); + repeaterUseHex = true; + } + else + { + reg = new Regex("^([0-9A-Fa-f])+$"); - if(reg.IsMatch(startLine)) - { - hex = true; - consoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); - - //check whole file - for(int i = 0;i < lines.Length;i++) - { - if(lines[i].Trim().Length > 0) + if (reg.IsMatch(startLine)) { - if(lines[i].Length % 2 == 1) - { - repeaterMap = null; - throw new RepeatFileException("Line {0} has odd number of characters.", i); - } - - if(reg.IsMatch(lines[i])) - { - if(++linesWithData % 2 == 1) - ask = lines[i]; - else - repeaterMap.Add(ask, lines[i]); - } - else - { - repeaterMap = null; - throw new RepeatFileException("Line {0} not coresponds to hex format.", i); - } + hex = true; + consoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); + + //check whole file + for (int i = 0; i < lines.Length; i++) + { + if (lines[i].Trim().Length > 0) + { + if (lines[i].Length % 2 == 1) + { + repeaterMap = null; + throw new RepeatFileException("Line {0} has odd number of characters.", i); + } + + if (reg.IsMatch(lines[i])) + { + if (++linesWithData % 2 == 1) + ask = lines[i]; + else + repeaterMap.Add(ask, lines[i]); + } + else + { + repeaterMap = null; + throw new RepeatFileException("Line {0} not coresponds to hex format.", i); + } + } + } + + repeaterUseHex = true; } - } - - repeaterUseHex = true; - } - else - { - hex = false; - consoleWriteLine("First line not corresponds hex format. File will be read and packets compared as ASCII."); - - //check whole file - for(int i = 0;i < lines.Length;i++) - { - if(lines[i].Trim().Length > 0) + else { - if(++linesWithData % 2 == 1) - ask = lines[i]; - else - repeaterMap.Add(ask, lines[i]); + hex = false; + consoleWriteLine("First line not corresponds hex format. File will be read and packets compared as ASCII."); + + //check whole file + for (int i = 0; i < lines.Length; i++) + { + if (lines[i].Trim().Length > 0) + { + if (++linesWithData % 2 == 1) + ask = lines[i]; + else + repeaterMap.Add(ask, lines[i]); + } + } } - } - } - } + } - if(linesWithData % 2 == 1) - consoleWriteError("Odd number of lines in file {0} with code. One line ask, one line answer.", fileName); + if (linesWithData % 2 == 1) + consoleWriteError("Odd number of lines in file {0} with code. One line ask, one line answer.", fileName); - repeaterEnabled = true; + repeaterEnabled = true; - consoleWriteLine("{0} pairs ask/answer ready", repeaterMap.Count); - } - catch(Exception ex) - { - consoleWriteError("Cannot read file {0}", fileName); - consoleWriteError(ex.ToString()); + consoleWriteLine("{0} pairs ask/answer ready", repeaterMap.Count); + } + catch (Exception ex) + { + consoleWriteError("Cannot read file {0}", fileName); + consoleWriteError(ex.ToString()); + } } - } - } + } -#if __MonoCS__ +#if __MonoCS__ /// /// Event on serial port "pin was changed" /// @@ -778,431 +777,431 @@ private static void PrepareRepeatFile(string fileName) static void port_PinChanged(object sender, SerialPinChange pinsStatesChange) { #else - /// - /// Event on serial port "pin was changed" - /// - /// - /// - static void port_PinChanged(object sender, SerialPinChangedEventArgs e) - { - SerialPinChange pinsStatesChange = e.EventType; + /// + /// Event on serial port "pin was changed" + /// + /// + /// + static void port_PinChanged(object sender, SerialPinChangedEventArgs e) + { + SerialPinChange pinsStatesChange = e.EventType; #endif - SerialPort port = ((SerialPort)sender); - - if(continuousMode) - { - Console.ForegroundColor = ConsoleColor.Cyan; + SerialPort port = ((SerialPort)sender); - //TODO: change enumerator SerialPinChange printing??? - consoleWriteLine("Pin {0} changed", pinsStatesChange.ToString()); - - writePinState("RTS", port.RtsEnable); - writePinState("CTS", port.CtsHolding); - writePinState("DTR", port.DtrEnable); - writePinState("DSR", port.DsrHolding); - writePinState("CD", port.CDHolding); - writePinState("Break", port.BreakState); - - consoleWrite("\n"); - - Console.ResetColor(); - } - else - Cinout.WritePinStatus(port.RtsEnable ? 1 : 0, port.CtsHolding ? 1 : 0, port.DtrEnable ? 1 : 0, port.DsrHolding ? 1 : 0, port.CDHolding ? 1 : 0, port.BreakState ? 1 : 0); - } + if (continuousMode) + { + Console.ForegroundColor = ConsoleColor.Cyan; - /// - /// Print serialport pin state - /// - /// - /// - static void writePinState(string name, bool state) - { - Console.ForegroundColor = state ? ConsoleColor.Green : ConsoleColor.White; + //TODO: change enumerator SerialPinChange printing??? + consoleWriteLine("Pin {0} changed", pinsStatesChange.ToString()); - consoleWrite("{0}({1}) ", name, state ? "1" : "0"); - } + writePinState("RTS", port.RtsEnable); + writePinState("CTS", port.CtsHolding); + writePinState("DTR", port.DtrEnable); + writePinState("DSR", port.DsrHolding); + writePinState("CD", port.CDHolding); + writePinState("Break", port.BreakState); - /// - /// Serial port OnError event - /// - /// - /// - static void port_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) - { - consoleWriteError(e.EventType.ToString()); - } + consoleWrite("\n"); - /// - /// Serial port event when new data arrived - /// - /// - /// - static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) - { - SerialPort port = ((SerialPort)sender); - byte[] incoming; - - try - { - incoming = new byte[port.BytesToRead]; - - port.Read(incoming, 0, incoming.Length); - } - catch(Exception ex) - { - consoleWriteError(ex.ToString()); - return; - } - - TimeSpan time = DateTime.Now.TimeOfDay; - bool applyGapTolerance = false; - - //print time since last receive only if not disabled - if(lastTimeReceved > 0) - { - double sinceLastReceive = ((double)(time.Ticks - lastTimeReceved) / 10000); - applyGapTolerance = (gapToleranceEnable && sinceLastReceive <= gapTolerance); - - if(!noTime && (!gapToleranceEnable || !applyGapTolerance)) - consoleWriteCommunication(ConsoleColor.Magenta, "\n+" + sinceLastReceive.ToString("F3") + " ms"); - } - - //Write to output - string line = ""; - - if(showAscii) - { - if(noTime || applyGapTolerance) - line = ASCIIEncoding.ASCII.GetString(incoming); - else - line = time.ToString() + " " + ASCIIEncoding.ASCII.GetString(incoming); - } - else - { - if(noTime || applyGapTolerance) - line = string.Join(" ", Array.ConvertAll(incoming, x => "0x" + x.ToString("X2"))); + Console.ResetColor(); + } else - line = time.ToString() + " " + string.Join(" ", Array.ConvertAll(incoming, x => "0x" + x.ToString("X2"))); - } - - if(applyGapTolerance) - consoleWriteCommunication(ConsoleColor.Yellow, line); - else - { - consoleWriteCommunication(ConsoleColor.Yellow, "\n"); - consoleWriteCommunication(ConsoleColor.Yellow, line); - } - - - lastTimeReceved = time.Ticks; + Cinout.WritePinStatus(port.RtsEnable ? 1 : 0, port.CtsHolding ? 1 : 0, port.DtrEnable ? 1 : 0, port.DsrHolding ? 1 : 0, port.CDHolding ? 1 : 0, port.BreakState ? 1 : 0); + } + + /// + /// Print serialport pin state + /// + /// + /// + static void writePinState(string name, bool state) + { + Console.ForegroundColor = state ? ConsoleColor.Green : ConsoleColor.White; + + consoleWrite("{0}({1}) ", name, state ? "1" : "0"); + } + + /// + /// Serial port OnError event + /// + /// + /// + static void port_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) + { + consoleWriteError(e.EventType.ToString()); + } + + /// + /// Serial port event when new data arrived + /// + /// + /// + static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) + { + SerialPort port = ((SerialPort)sender); + byte[] incoming; - if(repeaterEnabled) - { - byte[] data = data2Send(incoming); + try + { + incoming = new byte[port.BytesToRead]; - if(data != null) + port.Read(incoming, 0, incoming.Length); + } + catch (Exception ex) { - try - { - port.Write(data, 0, data.Length); - } - catch(Exception ex) - { - consoleWriteError(ex.ToString()); - } + consoleWriteError(ex.ToString()); + return; } - } - } - /// - /// prepare data as answer - /// - /// - /// - static byte[] data2Send(byte[] incoming) - { - if(repeaterUseHex) - { - string ask = string.Join("", Array.ConvertAll(incoming, x => x.ToString("X2"))); + TimeSpan time = DateTime.Now.TimeOfDay; + bool applyGapTolerance = false; - if(repeaterMap.ContainsKey(ask)) + //print time since last receive only if not disabled + if (lastTimeReceved > 0) { - string answer = repeaterMap[ask]; - byte[] data = new byte[answer.Length / 2]; + double sinceLastReceive = ((double)(time.Ticks - lastTimeReceved) / 10000); + applyGapTolerance = (gapToleranceEnable && sinceLastReceive <= gapTolerance); - for(int i = 0;i < data.Length;i++) - { - data[i] = Convert.ToByte(answer.Substring(2 * i, 2), 16); - } + if (!noTime && (!gapToleranceEnable || !applyGapTolerance)) + consoleWriteCommunication(ConsoleColor.Magenta, "\n+" + sinceLastReceive.ToString("F3") + " ms"); + } - if(noTime) - consoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => "0x" + x.ToString("X2")))); - else - consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => "0x" + x.ToString("X2")))); + //Write to output + string line = ""; - return data; + if (showAscii) + { + if (noTime || applyGapTolerance) + line = ASCIIEncoding.ASCII.GetString(incoming); + else + line = time.ToString() + " " + ASCIIEncoding.ASCII.GetString(incoming); } else { - consoleWriteLine("Repeater: Unknown ask"); + if (noTime || applyGapTolerance) + line = string.Join(" ", Array.ConvertAll(incoming, x => "0x" + x.ToString("X2"))); + else + line = time.ToString() + " " + string.Join(" ", Array.ConvertAll(incoming, x => "0x" + x.ToString("X2"))); } - } - else - { - string ask = ASCIIEncoding.ASCII.GetString(incoming); - if(repeaterMap.ContainsKey(ask)) + if (applyGapTolerance) + consoleWriteCommunication(ConsoleColor.Yellow, line); + else { - string answer = repeaterMap[ask]; + consoleWriteCommunication(ConsoleColor.Yellow, "\n"); + consoleWriteCommunication(ConsoleColor.Yellow, line); + } - if(noTime) - consoleWriteCommunication(ConsoleColor.Green, "\n" + answer); - else - consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + answer); - return ASCIIEncoding.ASCII.GetBytes(answer); + lastTimeReceved = time.Ticks; + + if (repeaterEnabled) + { + byte[] data = data2Send(incoming); + + if (data != null) + { + try + { + port.Write(data, 0, data.Length); + } + catch (Exception ex) + { + consoleWriteError(ex.ToString()); + } + } + } + } + + /// + /// prepare data as answer + /// + /// + /// + static byte[] data2Send(byte[] incoming) + { + if (repeaterUseHex) + { + string ask = string.Join("", Array.ConvertAll(incoming, x => x.ToString("X2"))); + + if (repeaterMap.ContainsKey(ask)) + { + string answer = repeaterMap[ask]; + byte[] data = new byte[answer.Length / 2]; + + for (int i = 0; i < data.Length; i++) + { + data[i] = Convert.ToByte(answer.Substring(2 * i, 2), 16); + } + + if (noTime) + consoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => "0x" + x.ToString("X2")))); + else + consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => "0x" + x.ToString("X2")))); + + return data; + } + else + { + consoleWriteLine("Repeater: Unknown ask"); + } } else { - consoleWriteLine("Repeater: Unknown ask"); + string ask = ASCIIEncoding.ASCII.GetString(incoming); + + if (repeaterMap.ContainsKey(ask)) + { + string answer = repeaterMap[ask]; + + if (noTime) + consoleWriteCommunication(ConsoleColor.Green, "\n" + answer); + else + consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + answer); + + return ASCIIEncoding.ASCII.GetBytes(answer); + } + else + { + consoleWriteLine("Repeater: Unknown ask"); + } } - } - - return null; - } - - /// - /// Print error - /// - /// - /// - private static void consoleWriteError(string text, params object[] arg) - { - consoleWriteLine(ConsoleColor.Red, text, arg); - } - - /// - /// Print - /// - /// - /// - private static void consoleWrite(string message, params object[] parameters) - { - if(!continuousMode) - Cinout.Write(message, parameters); - else - Console.Write(message, parameters); - - if(logfile && !logincomingonly) - Trace.Write(string.Format(message, parameters)); - } - - /// - /// Print single line - /// - /// - /// - private static void consoleWriteLine(string message, params object[] parameters) - { - if(!continuousMode) - Cinout.WriteLine(message, parameters); - else - { - if(Console.CursorLeft > 0) - Console.WriteLine(""); - Console.WriteLine(message, parameters); - } - - if(logfile && !logincomingonly) - Trace.WriteLine(string.Format(message, parameters)); - } - - /// - /// Print single line - /// - /// - /// - /// - private static void consoleWriteLine(ConsoleColor color, string message, params object[] parameters) - { - if(!continuousMode) - Cinout.WriteLine(color, message, parameters); - else - { - Console.ForegroundColor = color; - Console.WriteLine(message, parameters); - Console.ResetColor(); - } - - if(logfile && !logincomingonly) - Trace.WriteLine(string.Format(message, parameters)); - } - - /// - /// Print single line without trace log - /// - /// - /// - private static void consoleWriteLineNoTrace(string message, params object[] parameters) - { - if(!continuousMode) - Cinout.WriteLine(message, parameters); - else - Console.WriteLine(message, parameters); - } - - /// - /// Print single line without trace log - /// - /// - /// - /// - private static void consoleWriteLineNoTrace(ConsoleColor color, string message, params object[] parameters) - { - if(!continuousMode) - Cinout.WriteLine(color, message, parameters); - else - { - Console.ForegroundColor = color; - Console.WriteLine(message, parameters); - Console.ResetColor(); - } - } - /// - /// Print line that is involved in communication - /// - /// - /// - private static void consoleWriteCommunication(ConsoleColor color, string message, params object[] parameters) - { - if(!pausePrint) - { - if(!continuousMode) - Cinout.Write(color, message, parameters); + return null; + } + + /// + /// Print error + /// + /// + /// + private static void consoleWriteError(string text, params object[] arg) + { + consoleWriteLine(ConsoleColor.Red, text, arg); + } + + /// + /// Print + /// + /// + /// + private static void consoleWrite(string message, params object[] parameters) + { + if (!continuousMode) + Cinout.Write(message, parameters); + else + Console.Write(message, parameters); + + if (logfile && !logincomingonly) + Trace.Write(string.Format(message, parameters)); + } + + /// + /// Print single line + /// + /// + /// + private static void consoleWriteLine(string message, params object[] parameters) + { + if (!continuousMode) + Cinout.WriteLine(message, parameters); else { - Console.ForegroundColor = color; - consoleWrite(message, parameters); - Console.ResetColor(); + if (Console.CursorLeft > 0) + Console.WriteLine(""); + Console.WriteLine(message, parameters); } - } - - if(logfile) - Trace.Write(string.Format(message, parameters)); - } - - ///// - ///// Print line that is involved in communication - ///// - ///// - ///// - //private static void consoleWriteLineCommunication(string message, params object[] parameters) - //{ - // if(!pausePrint) - // { - // if(!continuousMode) - // Cinout.WriteLine(message, parameters); - // else - // consoleWriteLine(message, parameters); - // } - - // if(logfile) - // Trace.WriteLine(string.Format(message, parameters)); - //} - /// - /// Move console cursor in current line - /// - /// - private static void consoleCursorLeft(int moveBy) - { - if(continuousMode) - Console.CursorLeft += moveBy; - else - Cinout.CursorLeft(moveBy); - } - - /// - /// Set cursor to left border - /// - private static void consoleCursorLeftReset() - { - if(continuousMode) - Console.CursorLeft = 0; - else - Cinout.CursorLeftReset(); - } - - /// - /// Print help - /// - private static void printHelp() - { - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("Usage: serialmonitor PortName [ parameter]"); - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("Switches:"); - consoleWriteLineNoTrace("-baudrate {{baud rate}}: set port baud rate. Default 9600kbps."); - consoleWriteLineNoTrace("-parity {{used parity}}: set used port parity. Default none. Available parameters odd, even, mark and space."); - consoleWriteLineNoTrace("-databits {{used databits}}: set data bits count. Default 8 data bits."); - consoleWriteLineNoTrace("-stopbits {{used stopbits}}: set stop bits count. Default 1 stop bit. Available parameters 0, 1, 1.5 and 2."); - consoleWriteLineNoTrace("-repeatfile {{file name}}: enable repeat mode with protocol specified in file"); - consoleWriteLineNoTrace("-logfile {{file name}}: set file name for log into that file"); - consoleWriteLineNoTrace("-logincomingonly: log into file would be only incoming data"); - consoleWriteLineNoTrace("-showascii: communication would be show in ASCII format (otherwise HEX is used)"); - consoleWriteLineNoTrace("-notime: time information about incoming data would not be printed"); - consoleWriteLineNoTrace("-gaptolerance {{time gap in ms}}: messages received within specified time gap will be printed together"); - consoleWriteLineNoTrace("-continuousmode or -nogui: start program in normal console mode (scrolling list). Not with primitive text GUI"); - - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("Example: serialmonitor COM1"); - consoleWriteLineNoTrace(" serialmonitor COM1 -baudrate 57600 -parity odd -databits 7 -stopbits 1.5"); - consoleWriteLineNoTrace(" serialmonitor COM83 -baudrate 19200 -repeatfile protocol.txt"); - - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("In program commands:"); - consoleWriteLineNoTrace("F1: print help"); - consoleWriteLineNoTrace("F2: pause/resume print on screen"); - consoleWriteLineNoTrace("F3: toggle between data print format (HEX / ASCII)"); - consoleWriteLineNoTrace("F4: pause/resume connection to serial port"); - consoleWriteLineNoTrace("F5: send specified data (in HEX format if data start with 0x otherwise ASCII is send)"); - consoleWriteLineNoTrace("F6: send specified file)"); - - consoleWriteLineNoTrace("F10 or ^C: program exit"); - consoleWriteLineNoTrace("F11: toggle RST pin"); - consoleWriteLineNoTrace("F12: toggle DTR pin"); - - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("In program color schema:"); - consoleWriteLineNoTrace(ConsoleColor.Cyan, "Control pin status changed"); - consoleWriteLineNoTrace(ConsoleColor.Green, "Control pin ON"); - consoleWriteLineNoTrace(ConsoleColor.White, "Control pin OFF"); - consoleWriteLineNoTrace(ConsoleColor.Magenta, "Time between received data"); - consoleWriteLineNoTrace(ConsoleColor.Yellow, "Received data"); - consoleWriteLineNoTrace(ConsoleColor.Green, "Sended data"); - consoleWriteLineNoTrace(ConsoleColor.Red, "Error"); - - Console.ResetColor(); - } + if (logfile && !logincomingonly) + Trace.WriteLine(string.Format(message, parameters)); + } + + /// + /// Print single line + /// + /// + /// + /// + private static void consoleWriteLine(ConsoleColor color, string message, params object[] parameters) + { + if (!continuousMode) + Cinout.WriteLine(color, message, parameters); + else + { + Console.ForegroundColor = color; + Console.WriteLine(message, parameters); + Console.ResetColor(); + } - /// - /// Check Mono runtime - /// - /// - public static bool IsRunningOnMono() - { - return Type.GetType("Mono.Runtime") != null; - } + if (logfile && !logincomingonly) + Trace.WriteLine(string.Format(message, parameters)); + } + + /// + /// Print single line without trace log + /// + /// + /// + private static void consoleWriteLineNoTrace(string message, params object[] parameters) + { + if (!continuousMode) + Cinout.WriteLine(message, parameters); + else + Console.WriteLine(message, parameters); + } + + /// + /// Print single line without trace log + /// + /// + /// + /// + private static void consoleWriteLineNoTrace(ConsoleColor color, string message, params object[] parameters) + { + if (!continuousMode) + Cinout.WriteLine(color, message, parameters); + else + { + Console.ForegroundColor = color; + Console.WriteLine(message, parameters); + Console.ResetColor(); + } + } + + /// + /// Print line that is involved in communication + /// + /// + /// + private static void consoleWriteCommunication(ConsoleColor color, string message, params object[] parameters) + { + if (!pausePrint) + { + if (!continuousMode) + Cinout.Write(color, message, parameters); + else + { + Console.ForegroundColor = color; + consoleWrite(message, parameters); + Console.ResetColor(); + } + } - /// - /// Call exit actions - /// - private static void Exit() - { - Config.SaveHistory(Cinout.CommandHistory.ToArray()); - } + if (logfile) + Trace.Write(string.Format(message, parameters)); + } + + ///// + ///// Print line that is involved in communication + ///// + ///// + ///// + //private static void consoleWriteLineCommunication(string message, params object[] parameters) + //{ + // if(!pausePrint) + // { + // if(!continuousMode) + // Cinout.WriteLine(message, parameters); + // else + // consoleWriteLine(message, parameters); + // } + + // if(logfile) + // Trace.WriteLine(string.Format(message, parameters)); + //} + + /// + /// Move console cursor in current line + /// + /// + private static void consoleCursorLeft(int moveBy) + { + if (continuousMode) + Console.CursorLeft += moveBy; + else + Cinout.CursorLeft(moveBy); + } + + /// + /// Set cursor to left border + /// + private static void consoleCursorLeftReset() + { + if (continuousMode) + Console.CursorLeft = 0; + else + Cinout.CursorLeftReset(); + } + + /// + /// Print help + /// + private static void printHelp() + { + consoleWriteLineNoTrace(""); + consoleWriteLineNoTrace("Usage: serialmonitor PortName [ parameter]"); + consoleWriteLineNoTrace(""); + consoleWriteLineNoTrace("Switches:"); + consoleWriteLineNoTrace("-baudrate {{baud rate}}: set port baud rate. Default 9600kbps."); + consoleWriteLineNoTrace("-parity {{used parity}}: set used port parity. Default none. Available parameters odd, even, mark and space."); + consoleWriteLineNoTrace("-databits {{used databits}}: set data bits count. Default 8 data bits."); + consoleWriteLineNoTrace("-stopbits {{used stopbits}}: set stop bits count. Default 1 stop bit. Available parameters 0, 1, 1.5 and 2."); + consoleWriteLineNoTrace("-repeatfile {{file name}}: enable repeat mode with protocol specified in file"); + consoleWriteLineNoTrace("-logfile {{file name}}: set file name for log into that file"); + consoleWriteLineNoTrace("-logincomingonly: log into file would be only incoming data"); + consoleWriteLineNoTrace("-showascii: communication would be show in ASCII format (otherwise HEX is used)"); + consoleWriteLineNoTrace("-notime: time information about incoming data would not be printed"); + consoleWriteLineNoTrace("-gaptolerance {{time gap in ms}}: messages received within specified time gap will be printed together"); + consoleWriteLineNoTrace("-continuousmode or -nogui: start program in normal console mode (scrolling list). Not with primitive text GUI"); + + consoleWriteLineNoTrace(""); + consoleWriteLineNoTrace("Example: serialmonitor COM1"); + consoleWriteLineNoTrace(" serialmonitor COM1 -baudrate 57600 -parity odd -databits 7 -stopbits 1.5"); + consoleWriteLineNoTrace(" serialmonitor COM83 -baudrate 19200 -repeatfile protocol.txt"); + + consoleWriteLineNoTrace(""); + consoleWriteLineNoTrace("In program commands:"); + consoleWriteLineNoTrace("F1: print help"); + consoleWriteLineNoTrace("F2: pause/resume print on screen"); + consoleWriteLineNoTrace("F3: toggle between data print format (HEX / ASCII)"); + consoleWriteLineNoTrace("F4: pause/resume connection to serial port"); + consoleWriteLineNoTrace("F5: send specified data (in HEX format if data start with 0x otherwise ASCII is send)"); + consoleWriteLineNoTrace("F6: send specified file)"); + + consoleWriteLineNoTrace("F10 or ^C: program exit"); + consoleWriteLineNoTrace("F11: toggle RST pin"); + consoleWriteLineNoTrace("F12: toggle DTR pin"); + + consoleWriteLineNoTrace(""); + consoleWriteLineNoTrace("In program color schema:"); + consoleWriteLineNoTrace(ConsoleColor.Cyan, "Control pin status changed"); + consoleWriteLineNoTrace(ConsoleColor.Green, "Control pin ON"); + consoleWriteLineNoTrace(ConsoleColor.White, "Control pin OFF"); + consoleWriteLineNoTrace(ConsoleColor.Magenta, "Time between received data"); + consoleWriteLineNoTrace(ConsoleColor.Yellow, "Received data"); + consoleWriteLineNoTrace(ConsoleColor.Green, "Sended data"); + consoleWriteLineNoTrace(ConsoleColor.Red, "Error"); - } + Console.ResetColor(); + } + + /// + /// Check Mono runtime + /// + /// + public static bool IsRunningOnMono() + { + return Type.GetType("Mono.Runtime") != null; + } + + /// + /// Call exit actions + /// + private static void Exit() + { + Config.SaveHistory(Cinout.CommandHistory.ToArray()); + } + + } } diff --git a/SerialMonitor/Properties/AssemblyInfo.cs b/SerialMonitor/Properties/AssemblyInfo.cs deleted file mode 100644 index 5bc6561..0000000 --- a/SerialMonitor/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("SerialMonitor")] -[assembly: AssemblyDescription("serial port monitor")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Vita Tucek")] -[assembly: AssemblyProduct("SerialMonitor")] -[assembly: AssemblyCopyright("Copyright © Vita Tucek 2015")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("b3446b41-adfa-474a-b390-524094504058")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.3.0.0")] -[assembly: AssemblyFileVersion("1.3.0.0")] diff --git a/SerialMonitor/SerialMonitor.csproj b/SerialMonitor/SerialMonitor.csproj index 390ab32..cb0489c 100644 --- a/SerialMonitor/SerialMonitor.csproj +++ b/SerialMonitor/SerialMonitor.csproj @@ -1,64 +1,17 @@ - - + + - Release - AnyCPU - 9.0.30729 - 2.0 - {019A06E0-C535-488C-AACF-E2A0E1A26861} Exe - Properties - SerialMonitor - SerialMonitor - v2.0 - 512 - SerialMonitor.Program - - + net6.0 + enable + enable + 2.0.0.0 + 2.0.0.0 + 2.0.0.0.myversion - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - + - + - - - \ No newline at end of file + + From c85c4dfbc40194065e24c204c6ff5bd5eeef1fc5 Mon Sep 17 00:00:00 2001 From: docbender Date: Sun, 20 Feb 2022 23:09:41 +0100 Subject: [PATCH 02/18] Migrate to Terminal.Gui --- SerialMonitor/Cinout.cs | 592 ----------------------------- SerialMonitor/CommandEnum.cs | 23 -- SerialMonitor/Program.cs | 482 +++++++++++------------ SerialMonitor/RingBuffer.cs | 265 +++++++++++++ SerialMonitor/SerialMonitor.csproj | 4 + SerialMonitor/UI.cs | 244 ++++++++++++ 6 files changed, 735 insertions(+), 875 deletions(-) delete mode 100644 SerialMonitor/Cinout.cs delete mode 100644 SerialMonitor/CommandEnum.cs create mode 100644 SerialMonitor/RingBuffer.cs create mode 100644 SerialMonitor/UI.cs diff --git a/SerialMonitor/Cinout.cs b/SerialMonitor/Cinout.cs deleted file mode 100644 index 9de2da4..0000000 --- a/SerialMonitor/Cinout.cs +++ /dev/null @@ -1,592 +0,0 @@ -//--------------------------------------------------------------------------- -// -// Name: Cinout.cs -// Author: Vita Tucek -// Created: 11.3.2015 -// License: MIT -// Description: Console GUI -// -//--------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; -using System.Threading; - -namespace SerialMonitor -{ - class Cinout - { - class Line - { - public string Text; - public ConsoleColor Color; - - public Line(string text, ConsoleColor color) - { - Text = text; - Color = color; - } - } - - static List Messages; - static object lockobj; - static int originalheight = 0, originalwidth = 0; - static bool Service = false; - static ConsoleColor DefaultFore = ConsoleColor.Gray; - - static int rts, cts, dtr, dsr, cd, brk; - static string port; - static bool isOpen; - static int baudrate; - static bool showAscii = false, pausePrint = false, pauseConnection = false; - - static bool sendType = false; - static bool sendFile = false; - - public static List CommandHistory = new List(); - static StringBuilder inBuffer = new StringBuilder(); - static string sendLineMessage; - - public static void Init() - { - Console.CursorVisible = false; - - DefaultFore = Console.ForegroundColor; - - Messages = new List(); - Messages.Add(new Line("", DefaultFore)); - lockobj = new object(); - - WritePortStatus("", false, 0); - WritePinStatus(-1, -1, -1, -1, -1, -1); - } - - public static void Render() - { - Console.Clear(); - - borders(); - writePortStatus(); - writePinStatus(); - printMessages(); - writeMenuBar(); - - if(sendType || sendFile) - printSendLine(); - } - - protected static void borders() - { - if(Service) - return; - - Console.ResetColor(); - Console.SetCursorPosition(0, 0); - - if(Console.WindowWidth < 20) - { - Console.WriteLine("Window is too small!!!!"); - return; - } - string name = $" SerialMonitor v.{Assembly.GetExecutingAssembly().GetName().Version.ToString(3)} "; - - Console.WriteLine("+" + new string('-', Console.WindowWidth - 2) + "+"); - if(Console.WindowWidth > name.Length) - { - Console.SetCursorPosition(Console.WindowWidth/2 - name.Length/2, 0); - Console.Write(name); - } - - Console.SetCursorPosition(0, 1); - Console.Write("|" + new string(' ', Console.WindowWidth - 2) + "|"); - Console.SetCursorPosition(0, 2); - Console.Write("|" + new string(' ', Console.WindowWidth - 2) + "|"); - Console.WriteLine("+" + new string('-', Console.WindowWidth - 2) + "+"); - - originalheight = Console.WindowHeight; - originalwidth = Console.WindowWidth; - } - - public static void WritePortStatus(string port, bool isOpen, int baudrate) - { - Cinout.port = port; - Cinout.isOpen = isOpen; - Cinout.baudrate = baudrate; - - Render(); - } - - protected static void writePortStatus() - { - Console.ResetColor(); - Console.SetCursorPosition(2, 1); - Console.Write("Port: " + port + " "); - if(isOpen) - { - Console.ForegroundColor = ConsoleColor.Green; - Console.Write("Opened"); - } - else - { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.Write("Closed"); - } - - Console.ResetColor(); - - Console.Write(" Speed: {0}b/s", baudrate); - } - - public static void WritePinStatus(int rts, int cts, int dtr, int dsr, int cd, int brk) - { - Cinout.rts = rts; - Cinout.cts = cts; - Cinout.dtr = dtr; - Cinout.dsr = dsr; - Cinout.cd = cd; - Cinout.brk = brk; - - Render(); - } - - protected static void writePinStatus() - { - Console.ResetColor(); - Console.SetCursorPosition(2, 2); - Console.Write("Pins: "); - - printPin("RTS", rts, ConsoleColor.Green); - printPin("CTS", cts, ConsoleColor.Green); - printPin("DTR", dtr, ConsoleColor.Green); - printPin("DSR", dsr, ConsoleColor.Green); - printPin("CD", cd, ConsoleColor.Green); - printPin("BREAK", brk, ConsoleColor.Red); - } - - protected static void printPin(string pin, int state, ConsoleColor activeColor) - { - Console.Write(" {0}", pin); - - if(state == 1) - Console.ForegroundColor = activeColor; - - Console.Write(" ({0})", (state < 0 || state > 1) ? "?" : state.ToString()); - - Console.ResetColor(); - } - - protected static void writeMenuBar() - { - Console.SetCursorPosition(0, Console.WindowHeight-1); - - if(sendType || sendFile) - { - Console.ResetColor(); - Console.Write("Enter"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write(" Send "); - Console.ResetColor(); - Console.Write("Esc"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write(" Return "); - } - else - { - Console.ResetColor(); - Console.Write("F1"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write("Help "); - Console.ResetColor(); - Console.Write("F2"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; if(!pausePrint) Console.Write("NoPrint "); else Console.Write("Print "); - Console.ResetColor(); - Console.Write("F3"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; if(showAscii) Console.Write("Hex "); else Console.Write("Ascii "); - Console.ResetColor(); - Console.Write("F4"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; if(!pauseConnection) Console.Write("Close "); else Console.Write("Resume "); - Console.ResetColor(); - Console.Write("F5"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write("Send "); - Console.ResetColor(); - Console.Write("F6"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write("SendFile "); - Console.ResetColor(); - Console.Write("F10"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write("Exit "); - Console.ResetColor(); - Console.Write("F11"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write("RTS "); - Console.ResetColor(); - Console.Write("F12"); Console.BackgroundColor = ConsoleColor.Cyan; Console.ForegroundColor = ConsoleColor.Black; Console.Write("DTR "); - } - - Console.ResetColor(); - } - - public static void WriteMenuBar(bool showAscii, bool pausePrint, bool pauseConnection) - { - Cinout.showAscii = showAscii; - Cinout.pausePrint = pausePrint; - Cinout.pauseConnection = pauseConnection; - - Render(); - } - - public static void WriteLine(string Message, object[] parameters) - { - WriteLine(DefaultFore, Message, parameters); - } - - public static void WriteLine(ConsoleColor activeColor, string Message, object[] parameters) - { - if(Service) - return; - - Write(activeColor, true, Message, parameters); - Write(activeColor, false, "\n", parameters); - } - - public static void Write(string Message, object[] parameters) - { - Write(DefaultFore, false, Message, parameters); - } - - public static void Write(ConsoleColor activeColor, string Message, object[] parameters) - { - Write(activeColor, false, Message, parameters); - } - - public static void Write(ConsoleColor activeColor, bool onNewLine, string Message, object[] parameters) - { - if(Service) - return; - - lock(lockobj) - { - string msg = string.Format(Message, parameters); - if(msg.Contains("\n")) - { - string[] lines = msg.Split('\n'); - - for(int i = 0;i < lines.Length;i++) - { - string l = lines[i]; - - if(i==0 && onNewLine && (Messages[Messages.Count - 1].Text.Length > 0)) - { - if(l.Length <= Console.WindowWidth) - Messages.Add(new Line(l, activeColor)); - else - splitAndPrintLongLines(activeColor, l); - } - else - { - if(l.Length + Messages[Messages.Count - 1].Text.Length <= Console.WindowWidth) - { - Messages[Messages.Count - 1].Text += l; - if(l.Length > 0) - Messages[Messages.Count - 1].Color = activeColor; - } - else - { - int currentLeft = Console.WindowWidth - Messages[Messages.Count - 1].Text.Length; - - Messages[Messages.Count - 1].Text += l.Substring(0, currentLeft); - - if(l.Length > 0) - Messages[Messages.Count - 1].Color = activeColor; - - splitAndPrintLongLines(activeColor, l.Substring(currentLeft)); - } - } - - if(i < lines.Length - 1) - Messages.Add(new Line("", activeColor)); - } - } - else - { - if(onNewLine && (Messages[Messages.Count - 1].Text.Length > 0)) - { - if(msg.Length <= Console.WindowWidth) - Messages.Add(new Line(msg, activeColor)); - else - splitAndPrintLongLines(activeColor, msg); - } - else - { - if(msg.Length + Messages[Messages.Count - 1].Text.Length <= Console.WindowWidth) - { - Messages[Messages.Count - 1].Text += msg; - if(msg.Length > 0) - Messages[Messages.Count - 1].Color = activeColor; - } - else - { - int currentLeft = Console.WindowWidth - Messages[Messages.Count - 1].Text.Length; - - Messages[Messages.Count - 1].Text += msg.Substring(0, currentLeft); - - if(msg.Length > 0) - Messages[Messages.Count - 1].Color = activeColor; - - splitAndPrintLongLines(activeColor, msg.Substring(currentLeft)); - } - } - } - - Render(); - } - } - - protected static void printMessages() - { - int rows = Console.WindowHeight - 4 - 1 - 1; - - if(rows <= 0) - return; - - if(Messages.Count > rows) - Messages.RemoveRange(0, Messages.Count - rows); - - for(int i = 0;i < Messages.Count;i++) - { - Console.SetCursorPosition(0, 4 + i); - - Console.ForegroundColor = Messages[i].Color; - if(Console.WindowWidth >= Messages[i].Text.Length) - Console.Write(Messages[i].Text + new string(' ', Console.WindowWidth - Messages[i].Text.Length)); - else - Console.Write(Messages[i].Text); - } - } - - protected static void splitAndPrintLongLines(ConsoleColor activeColor, string msg) - { - string line = msg; - while(line.Length > 0) - { - if(line.Length > Console.WindowWidth) - { - Messages.Add(new Line(line.Substring(0, Console.WindowWidth), activeColor)); - - line = line.Substring(Console.WindowWidth); - } - else - { - Messages.Add(new Line(line, activeColor)); - break; - } - } - } - - public static void CursorLeft(int moveBy) - { - if(moveBy > 0) - { - Messages[Messages.Count - 1].Text += new string(' ', moveBy); - } - else if(moveBy < 0) - { - if(Messages[Messages.Count - 1].Text.Length + moveBy >= 0) - { - Messages[Messages.Count - 1].Text = Messages[Messages.Count - 1].Text.Substring(0, Messages[Messages.Count - 1].Text.Length + moveBy); - } - } - } - - public static void CursorLeftReset() - { - Messages[Messages.Count - 1].Text = ""; - } - - #region send file - - public static void StartSendFile() - { - sendFile = true; - inBuffer = new StringBuilder(); - sendLineMessage = "File to send: "; - printSendLine(); - - Console.CursorVisible = true; - - Render(); - } - - public static void EndSendFile() - { - sendFile = false; - Console.CursorVisible = false; - - Render(); - } - - #endregion - - #region send data type - - public static void StartSendDataType() - { - sendType = true; - inBuffer = new StringBuilder(); - sendLineMessage = "Message to send: "; - - Console.CursorVisible = true; - - Render(); - } - - public static void EndSendDataType() - { - sendType = false; - Console.CursorVisible = false; - - Render(); - } - #endregion - - protected static void printSendLine() - { - Console.SetCursorPosition(0, Console.WindowHeight-2); - Console.Write(new string(' ', Console.WindowWidth)); - Console.SetCursorPosition(0, Console.WindowHeight-2); - - string begin = sendLineMessage; - Console.Write(begin); - - if(begin.Length + inBuffer.Length < Console.WindowWidth) - { - Console.Write(inBuffer.ToString()); - Console.SetCursorPosition(begin.Length + inBuffer.Length, Console.WindowHeight-2); - } - else - { - Console.Write(inBuffer.ToString().Substring(begin.Length + inBuffer.Length-Console.WindowWidth+1)); - Console.SetCursorPosition(Console.WindowWidth-1, Console.WindowHeight-2); - } - } - - protected static void putSendDataChar(char c) - { - inBuffer.Append(c); - - printSendLine(); - } - - protected static void removeSendDataChar() - { - inBuffer.Remove(inBuffer.Length-1, 1); - - printSendLine(); - } - - protected static void putSendDataLine(string s) - { - if(inBuffer.Length > 0) - inBuffer.Remove(0, inBuffer.Length); - - inBuffer.Append(s); - - printSendLine(); - } - - /// - /// Command key decoder - /// - /// - public static CommandEnum ConsoleReadCommand(bool hideCursor) - { - if(Console.KeyAvailable) - { - ConsoleKeyInfo k = Console.ReadKey(hideCursor); - - //command keys - if(k.Key == ConsoleKey.F1) - return CommandEnum.HELP; - else if(k.Key == ConsoleKey.F2) - return CommandEnum.PAUSE; - else if(k.Key == ConsoleKey.F3) - return CommandEnum.FORMAT; - else if(k.Key == ConsoleKey.F4) - return CommandEnum.CONNECT; - else if(k.Key == ConsoleKey.F5) - return CommandEnum.SEND; - else if(k.Key == ConsoleKey.F6) - return CommandEnum.SEND_FILE; - else if(k.Key == ConsoleKey.F10) - return CommandEnum.EXIT; - else if(k.Key == ConsoleKey.F11) - return CommandEnum.RTS; - else if(k.Key == ConsoleKey.F12) - return CommandEnum.DTR; - else if(k.KeyChar != 0) - putSendDataChar(k.KeyChar); - } - - return CommandEnum.NONE; - } - - /// - /// Read typed char to console - /// - /// - public static string ConsoleReadLine(bool hideCursor) - { - ConsoleKeyInfo k = Console.ReadKey(hideCursor); - int historyPosition = CommandHistory.Count; - - while(k.Key != ConsoleKey.Enter && k.Key != ConsoleKey.Escape) - { - if(k.Key == ConsoleKey.Backspace) - { - if(inBuffer.Length > 0) - { - removeSendDataChar(); - } - } - else if(k.Key == ConsoleKey.UpArrow) - { - if(historyPosition-1 >= 0) - { - string hist = CommandHistory[--historyPosition]; - - Console.CursorLeft = 0; - Console.Write(new string(' ', Console.WindowWidth-1)); - Console.CursorLeft = 0; - Console.Write(hist); - - putSendDataLine(hist); - } - } - else if(k.Key == ConsoleKey.DownArrow) - { - if(historyPosition+1 < CommandHistory.Count) - { - string hist = CommandHistory[++historyPosition]; - - Console.CursorLeft = 0; - Console.Write(new string(' ', Console.WindowWidth-1)); - Console.CursorLeft = 0; - Console.Write(hist); - - putSendDataLine(hist); - } - } - else if(k.Key == ConsoleKey.LeftArrow || k.Key == ConsoleKey.RightArrow) - { - - } - else if(k.KeyChar != 0) - { - putSendDataChar(k.KeyChar); - } - - k = Console.ReadKey(hideCursor); - } - - if(k.Key == ConsoleKey.Enter) - { - string line = inBuffer.ToString(); - inBuffer.Remove(0, inBuffer.Length); - - if(CommandHistory.Count == 0 || !CommandHistory[CommandHistory.Count-1].Equals(line)) - CommandHistory.Add(line); - - return line; - } - - return null; - } - } -} diff --git a/SerialMonitor/CommandEnum.cs b/SerialMonitor/CommandEnum.cs deleted file mode 100644 index 3cbe5eb..0000000 --- a/SerialMonitor/CommandEnum.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace SerialMonitor -{ - /// - /// Command enumerator - /// - enum CommandEnum - { - NONE, - EXIT, - PAUSE, - HELP, - SEND, - SEND_FILE, - CONNECT, - RTS, - DTR, - FORMAT - }; -} diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index ed4441c..5f176d6 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -8,14 +8,10 @@ // //--------------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Text; +using System.Diagnostics; using System.IO.Ports; -using System.Threading; -using System.IO; +using System.Text; using System.Text.RegularExpressions; -using System.Diagnostics; namespace SerialMonitor { @@ -52,7 +48,8 @@ class Program /// static void Main(string[] args) { - string portName = IsRunningOnMono() ? "/dev/ttyS1" : "COM1"; + DateTime lastTry = DateTime.MinValue; + string portName = System.OperatingSystem.IsWindows() ? "COM3" : "/dev/ttyS1"; if (args.Length > 0) { @@ -83,9 +80,9 @@ static void Main(string[] args) continuousMode = arguments.GetArgument("continuousmode").Enabled || arguments.GetArgument("nogui").Enabled; ; if (!continuousMode) - Cinout.Init(); + UI.Init(); else - consoleWriteLineNoTrace("SerialMonitor v." + version); + consoleWriteLineNoTrace($"SerialMonitor v.{version}"); showAscii = arguments.GetArgument("showascii").Enabled; noTime = arguments.GetArgument("notime").Enabled; @@ -130,13 +127,9 @@ static void Main(string[] args) } SerialPort port = new SerialPort(portName, baudrate, parity, dataBits, stopBits); - -#if __MonoCS__ -#else port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived); port.PinChanged += new SerialPinChangedEventHandler(port_PinChanged); -#endif //log option arg = arguments.GetArgument("logfile"); @@ -182,12 +175,19 @@ static void Main(string[] args) { //check path string path = System.IO.Path.GetDirectoryName(logFilename); - if (path.Length == 0) + if (path?.Length == 0) logFilename = System.IO.Directory.GetCurrentDirectory() + "\\" + logFilename; else { if (!System.IO.Directory.Exists(path)) - System.IO.Directory.CreateDirectory(path); + try + { + System.IO.Directory.CreateDirectory(path); + } + catch (Exception ex) + { + consoleWriteLine($"Warning: Cannot create directory {path}"); + } } if (!isFileNameValid(logFilename)) @@ -226,142 +226,166 @@ static void Main(string[] args) consoleWriteLine("Opening port {0}: baudrate={1}b/s, parity={2}, databits={3}, stopbits={4}", port.PortName, port.BaudRate.ToString(), port.Parity.ToString(), port.DataBits.ToString(), port.StopBits.ToString()); - writePortStatus(port); - - portConnectInfinite(port); - - if (port.IsOpen) - { - consoleWriteLine("Port {0} opened", portName); - writePortStatus(port); - writePinStatus(port); - } - else - return; - -#if __MonoCS__ - SerialPinChange _pinsStatesNow = 0; - SerialPinChange _pinsStatesOld = 0; -#endif bool exit = false; string[] history = Config.LoadHistory(); if (history != null && history.Length > 0) { - Cinout.CommandHistory = new List(history); history = null; } - while (!exit) - { -#if __MonoCS__ - if(port.BytesToRead > 0) - port_DataReceived(port, null); - else + if (continuousMode) { - _pinsStatesNow = (SerialPinChange)(Convert.ToInt32(port.CtsHolding) * ((int)SerialPinChange.CtsChanged) - | Convert.ToInt32(port.CDHolding) * ((int)SerialPinChange.CDChanged) - | Convert.ToInt32(port.DsrHolding) * ((int)SerialPinChange.DsrChanged) - | Convert.ToInt32(port.BreakState) * ((int)SerialPinChange.Break)); - - if(_pinsStatesNow != _pinsStatesOld) - { - SerialPinChange _pinsStatesChange = _pinsStatesNow ^ _pinsStatesOld; - - port_PinChanged(port, _pinsStatesChange); - _pinsStatesOld = _pinsStatesNow; - } - Thread.Sleep(100); - } -#else - Thread.Sleep(100); -#endif - CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); - if (cmd == CommandEnum.EXIT) + while (!exit) { - Exit(); - port.Close(); - exit = true; + Thread.Sleep(100); + if (!pauseConnection && !port.IsOpen) + { + consoleWriteLine(" Port disconnected...."); + portConnectInfinite(port); + } } - - switch (cmd) + } + else + { + UI.ActionHelp = () => { printHelp(); }; + UI.ActionPrint = (print) => { pausePrint = !print; }; + UI.ActionPrintAsHex = (hex) => { showAscii = !hex; }; + UI.ActionOpenClose = (close) => { pauseConnection = close; }; + UI.ActionSend = (data) => { userDataSend(port,data); }; + UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; + UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); }; + + UI.SetPortStatus(port); + UI.Run((loop) => { - case CommandEnum.PAUSE: - pausePrint = !pausePrint; - if (pausePrint) - consoleWriteLine("Print paused"); - else - consoleWriteLine("Print resumed"); - - if (!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - case CommandEnum.CONNECT: - connectCommand(port); - if (!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - case CommandEnum.HELP: - printHelp(); - break; - case CommandEnum.SEND: - if (continuousMode) - consoleWriteLineNoTrace("Type message to send: "); - else - Cinout.StartSendDataType(); - - string line = Cinout.ConsoleReadLine(!continuousMode); - - if (!continuousMode) - Cinout.EndSendDataType(); - - if (line != null) + if (!port.IsOpen) + { + if (lastTry.AddSeconds(5) <= DateTime.Now) { - if (userDataSend(port, line)) - consoleWriteLine("Sent: {0}", line); + lastTry = DateTime.Now; + if (portConnect(port)) + { + UI.SetPortStatus(port); + UI.SetPinStatus(port); + } } - break; - case CommandEnum.SEND_FILE: - if (continuousMode) - consoleWriteLineNoTrace("Type file to send: "); - else - Cinout.StartSendFile(); + } + return true; + }); + } + } - string filepath = Cinout.ConsoleReadLine(!continuousMode); + /* + return; + #if __MonoCS__ + if(port.BytesToRead > 0) + port_DataReceived(port, null); + else + { + _pinsStatesNow = (SerialPinChange)(Convert.ToInt32(port.CtsHolding) * ((int)SerialPinChange.CtsChanged) + | Convert.ToInt32(port.CDHolding) * ((int)SerialPinChange.CDChanged) + | Convert.ToInt32(port.DsrHolding) * ((int)SerialPinChange.DsrChanged) + | Convert.ToInt32(port.BreakState) * ((int)SerialPinChange.Break)); + + if(_pinsStatesNow != _pinsStatesOld) + { + SerialPinChange _pinsStatesChange = _pinsStatesNow ^ _pinsStatesOld; + + port_PinChanged(port, _pinsStatesChange); + _pinsStatesOld = _pinsStatesNow; + } + Thread.Sleep(100); + } + #else + Thread.Sleep(100); + #endif + CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); + if (cmd == CommandEnum.EXIT) + { + Exit(); + port.Close(); + exit = true; + } - if (!continuousMode) - Cinout.EndSendFile(); + switch (cmd) + { + case CommandEnum.PAUSE: + pausePrint = !pausePrint; + if (pausePrint) + consoleWriteLine("Print paused"); + else + consoleWriteLine("Print resumed"); + + if (!continuousMode) + Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); + break; + case CommandEnum.CONNECT: + connectCommand(port); + if (!continuousMode) + Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); + break; + case CommandEnum.HELP: + printHelp(); + break; + case CommandEnum.SEND: + if (continuousMode) + consoleWriteLineNoTrace("Type message to send: "); + else + Cinout.StartSendDataType(); + + string line = Cinout.ConsoleReadLine(!continuousMode); + + if (!continuousMode) + Cinout.EndSendDataType(); + + if (line != null) + { + if (userDataSend(port, line)) + consoleWriteLine("Sent: {0}", line); + } + break; + case CommandEnum.SEND_FILE: + if (continuousMode) + consoleWriteLineNoTrace("Type file to send: "); + else + Cinout.StartSendFile(); - if (filepath != null) - { - if (userDataSendFile(port, filepath)) - consoleWriteLine("Sent file: {0}", filepath); - } - break; - case CommandEnum.RTS: - port.RtsEnable = !port.RtsEnable; - writePinStatus(port); - break; - case CommandEnum.DTR: - port.DtrEnable = !port.DtrEnable; - writePinStatus(port); - break; - case CommandEnum.FORMAT: - showAscii = !showAscii; - - if (!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - } + string filepath = Cinout.ConsoleReadLine(!continuousMode); - if (!pauseConnection && !port.IsOpen) - { - consoleWriteLine(" Port disconnected...."); - portConnectInfinite(port); - } - } - } + if (!continuousMode) + Cinout.EndSendFile(); + + if (filepath != null) + { + if (userDataSendFile(port, filepath)) + consoleWriteLine("Sent file: {0}", filepath); + } + break; + case CommandEnum.RTS: + port.RtsEnable = !port.RtsEnable; + writePinStatus(port); + break; + case CommandEnum.DTR: + port.DtrEnable = !port.DtrEnable; + writePinStatus(port); + break; + case CommandEnum.FORMAT: + showAscii = !showAscii; + + if (!continuousMode) + Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); + break; + } + + if (!pauseConnection && !port.IsOpen) + { + consoleWriteLine(" Port disconnected...."); + portConnectInfinite(port); + } + } + */ /// /// Send tada typed by user @@ -474,28 +498,6 @@ private static bool userDataSendFile(SerialPort port, string filePath) return false; } - /// - /// Print serial port status - /// - /// - private static void writePortStatus(SerialPort port) - { - if (!continuousMode) - Cinout.WritePortStatus(port.PortName, port.IsOpen, port.BaudRate); - } - - /// - /// Print serial port pin statuses - /// - /// - private static void writePinStatus(SerialPort port) - { - if (!continuousMode) - { - Cinout.WritePinStatus(port.RtsEnable ? 1 : 0, port.CtsHolding ? 1 : 0, port.DtrEnable ? 1 : 0, port.DsrHolding ? 1 : 0, port.CDHolding ? 1 : 0, port.BreakState ? 1 : 0); - } - } - /// /// Connecting to port in infinite loop /// @@ -527,13 +529,15 @@ private static void portConnectInfinite(SerialPort port) consoleCursorLeftReset(); } - CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); + // TODO: + /* + CommandEnum cmd = UI.ConsoleReadCommand(!continuousMode); if (cmd == CommandEnum.EXIT) { port.Close(); break; } - + */ } while (!port.IsOpen); } @@ -549,9 +553,9 @@ private static bool portConnect(SerialPort port) { port.Open(); } - catch (System.IO.IOException ex) + catch (IOException ex) { - consoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); + consoleWriteError("Cannot open " + port.PortName + ". " + ex.Message); consoleWriteLine(" Available ports: " + string.Join(",", SerialPort.GetPortNames())); return false; @@ -576,38 +580,37 @@ private static void portClose(SerialPort port) if (port.IsOpen) port.Close(); } + /* + /// + /// Provide connect (pause/resume) command + /// + private static void connectCommand(SerialPort port) + { + pauseConnection = !pauseConnection; - /// - /// Provide connect (pause/resume) command - /// - private static void connectCommand(SerialPort port) - { - pauseConnection = !pauseConnection; - - if (pauseConnection) - { - consoleWriteLine(" Connection paused. Port closed."); - port.Close(); - - writePortStatus(port); - } - else - { - consoleWriteLine(" Resuming connection..."); + if (pauseConnection) + { + consoleWriteLine(" Connection paused. Port closed."); + port.Close(); - portConnectInfinite(port); + UI.SetPortStatus(port); + } + else + { + consoleWriteLine(" Resuming connection..."); - if (port.IsOpen) - { - consoleWriteLine(" Connection resumed"); + portConnectInfinite(port); - writePortStatus(port); + if (port.IsOpen) + { + consoleWriteLine(" Connection resumed"); - writePinStatus(port); + UI.SetPortStatus(port); + UI.SetPinStatus(port); + } + } } - } - } - + */ /// /// Validating file name(path) /// @@ -767,16 +770,6 @@ private static void PrepareRepeatFile(string fileName) } } - -#if __MonoCS__ - /// - /// Event on serial port "pin was changed" - /// - /// - /// - static void port_PinChanged(object sender, SerialPinChange pinsStatesChange) - { -#else /// /// Event on serial port "pin was changed" /// @@ -784,42 +777,10 @@ static void port_PinChanged(object sender, SerialPinChange pinsStatesChange) /// static void port_PinChanged(object sender, SerialPinChangedEventArgs e) { - SerialPinChange pinsStatesChange = e.EventType; -#endif - SerialPort port = ((SerialPort)sender); - if (continuousMode) - { - Console.ForegroundColor = ConsoleColor.Cyan; - - //TODO: change enumerator SerialPinChange printing??? - consoleWriteLine("Pin {0} changed", pinsStatesChange.ToString()); - - writePinState("RTS", port.RtsEnable); - writePinState("CTS", port.CtsHolding); - writePinState("DTR", port.DtrEnable); - writePinState("DSR", port.DsrHolding); - writePinState("CD", port.CDHolding); - writePinState("Break", port.BreakState); - - consoleWrite("\n"); - - Console.ResetColor(); - } - else - Cinout.WritePinStatus(port.RtsEnable ? 1 : 0, port.CtsHolding ? 1 : 0, port.DtrEnable ? 1 : 0, port.DsrHolding ? 1 : 0, port.CDHolding ? 1 : 0, port.BreakState ? 1 : 0); - } - - /// - /// Print serialport pin state - /// - /// - /// - static void writePinState(string name, bool state) - { - Console.ForegroundColor = state ? ConsoleColor.Green : ConsoleColor.White; + return; - consoleWrite("{0}({1}) ", name, state ? "1" : "0"); + UI.SetPinStatus((SerialPort)sender); } /// @@ -989,7 +950,7 @@ private static void consoleWriteError(string text, params object[] arg) private static void consoleWrite(string message, params object[] parameters) { if (!continuousMode) - Cinout.Write(message, parameters); + UI.Write(message, parameters); else Console.Write(message, parameters); @@ -1005,7 +966,9 @@ private static void consoleWrite(string message, params object[] parameters) private static void consoleWriteLine(string message, params object[] parameters) { if (!continuousMode) - Cinout.WriteLine(message, parameters); + { + UI.WriteLine(message, parameters); + } else { if (Console.CursorLeft > 0) @@ -1026,7 +989,9 @@ private static void consoleWriteLine(string message, params object[] parameters) private static void consoleWriteLine(ConsoleColor color, string message, params object[] parameters) { if (!continuousMode) - Cinout.WriteLine(color, message, parameters); + { + UI.WriteLine(message, parameters, color); + } else { Console.ForegroundColor = color; @@ -1046,7 +1011,7 @@ private static void consoleWriteLine(ConsoleColor color, string message, params private static void consoleWriteLineNoTrace(string message, params object[] parameters) { if (!continuousMode) - Cinout.WriteLine(message, parameters); + UI.WriteLine(message, parameters); else Console.WriteLine(message, parameters); } @@ -1060,7 +1025,9 @@ private static void consoleWriteLineNoTrace(string message, params object[] para private static void consoleWriteLineNoTrace(ConsoleColor color, string message, params object[] parameters) { if (!continuousMode) - Cinout.WriteLine(color, message, parameters); + { + UI.WriteLine(message, parameters, color); + } else { Console.ForegroundColor = color; @@ -1079,7 +1046,9 @@ private static void consoleWriteCommunication(ConsoleColor color, string message if (!pausePrint) { if (!continuousMode) - Cinout.Write(color, message, parameters); + { + UI.Write(message, parameters, color); + } else { Console.ForegroundColor = color; @@ -1119,8 +1088,8 @@ private static void consoleCursorLeft(int moveBy) { if (continuousMode) Console.CursorLeft += moveBy; - else - Cinout.CursorLeft(moveBy); + //else + // Cinout.CursorLeft(moveBy); } /// @@ -1130,8 +1099,8 @@ private static void consoleCursorLeftReset() { if (continuousMode) Console.CursorLeft = 0; - else - Cinout.CursorLeftReset(); + //else + // Cinout.CursorLeftReset(); } /// @@ -1170,29 +1139,23 @@ private static void printHelp() consoleWriteLineNoTrace("F6: send specified file)"); consoleWriteLineNoTrace("F10 or ^C: program exit"); - consoleWriteLineNoTrace("F11: toggle RST pin"); + consoleWriteLineNoTrace("F11: toggle RTS pin"); consoleWriteLineNoTrace("F12: toggle DTR pin"); - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("In program color schema:"); - consoleWriteLineNoTrace(ConsoleColor.Cyan, "Control pin status changed"); - consoleWriteLineNoTrace(ConsoleColor.Green, "Control pin ON"); - consoleWriteLineNoTrace(ConsoleColor.White, "Control pin OFF"); - consoleWriteLineNoTrace(ConsoleColor.Magenta, "Time between received data"); - consoleWriteLineNoTrace(ConsoleColor.Yellow, "Received data"); - consoleWriteLineNoTrace(ConsoleColor.Green, "Sended data"); - consoleWriteLineNoTrace(ConsoleColor.Red, "Error"); - - Console.ResetColor(); - } + if (continuousMode) + { + consoleWriteLineNoTrace(""); + consoleWriteLineNoTrace("In program color schema:"); + consoleWriteLineNoTrace(ConsoleColor.Cyan, "Control pin status changed"); + consoleWriteLineNoTrace(ConsoleColor.Green, "Control pin ON"); + consoleWriteLineNoTrace(ConsoleColor.White, "Control pin OFF"); + consoleWriteLineNoTrace(ConsoleColor.Magenta, "Time between received data"); + consoleWriteLineNoTrace(ConsoleColor.Yellow, "Received data"); + consoleWriteLineNoTrace(ConsoleColor.Green, "Sended data"); + consoleWriteLineNoTrace(ConsoleColor.Red, "Error"); - /// - /// Check Mono runtime - /// - /// - public static bool IsRunningOnMono() - { - return Type.GetType("Mono.Runtime") != null; + Console.ResetColor(); + } } /// @@ -1200,8 +1163,7 @@ public static bool IsRunningOnMono() /// private static void Exit() { - Config.SaveHistory(Cinout.CommandHistory.ToArray()); + Config.SaveHistory(UI.CommandHistory.ToArray()); } - } } diff --git a/SerialMonitor/RingBuffer.cs b/SerialMonitor/RingBuffer.cs new file mode 100644 index 0000000..2abf906 --- /dev/null +++ b/SerialMonitor/RingBuffer.cs @@ -0,0 +1,265 @@ +using System.Collections; + +namespace SerialMonitor +{ + public class RingBuffer : IEnumerable,IList + { + private readonly T[] data; + + private int start = 0; + private int end = 0; + private int count = 0; + + public RingBuffer(int capacity) + { + data = new T[capacity]; + } + + public int Capacity + { + get + { + return data.Length; + } + } + + public int Count + { + get + { + return count; + } + } + + public bool IsEmpty + { + get + { + return Count == 0; + } + } + + public T Last + { + get + { + if (IsEmpty) + return default; + + return data[(end != 0 ? end : Capacity) - 1]; + } + set + { + if (IsEmpty) + return; + + data[(end != 0 ? end : Capacity) - 1] = value; + } + } + + public bool IsReadOnly => true; + + public bool IsFixedSize => false; + + public bool IsSynchronized => false; + + public object SyncRoot => null; + + object? IList.this[int index] { get => this[index]; set => this[index]= (T?)value; } + + public T this[int index] + { + get + { + if (IsEmpty || index >= count) + throw new ArgumentOutOfRangeException(); + return data[InternalIndex(index)]; + } + set + { + if (IsEmpty || index >= count) + throw new ArgumentOutOfRangeException(); + data[InternalIndex(index)] = value; + } + } + + public void Add(T item) + { + data[end] = item; + if (++end == Capacity) + end = 0; + + if (count==Capacity) + start = end; + else + ++count; + } + + public void Clear() + { + start = 0; + end = 0; + count = 0; + } + + public T[] ToArray() + { + T[] newArray = new T[Count]; + var segments = ToArraySegments(); + segments[0].CopyTo(newArray); + segments[1].CopyTo(newArray, segments[0].Count); + return newArray; + } + + /// + /// Get the contents of the buffer as 2 ArraySegments. + /// Respects the logical contents of the buffer, where + /// each segment and items in each segment are ordered + /// according to insertion. + /// + /// Fast: does not copy the array elements. + /// Useful for methods like Send(IList<ArraySegment<Byte>>). + /// + /// Segments may be empty. + /// + /// An IList with 2 segments corresponding to the buffer content. + public IList> ToArraySegments() + { + return new[] { ArrayOne(), ArrayTwo() }; + } + + #region IEnumerable implementation + /// + /// Returns an enumerator that iterates through this buffer. + /// + /// An enumerator that can be used to iterate this collection. + public IEnumerator GetEnumerator() + { + var segments = ToArraySegments(); + foreach (ArraySegment segment in segments) + { + for (int i = 0; i < segment.Count; i++) + { + yield return segment.Array[segment.Offset + i]; + } + } + } + #endregion + #region IEnumerable implementation + IEnumerator IEnumerable.GetEnumerator() + { + return (IEnumerator)GetEnumerator(); + } + #endregion + + private int InternalIndex(int index) + { + return start + (index < (Capacity - start) ? index : index - Capacity); + } + + private int OuterIndex(int internalIndex) + { + return internalIndex - (internalIndex < start ? (Capacity-start) : start); + } + + // doing ArrayOne and ArrayTwo methods returning ArraySegment as seen here: + // http://www.boost.org/doc/libs/1_37_0/libs/circular_buffer/doc/circular_buffer.html#classboost_1_1circular__buffer_1957cccdcb0c4ef7d80a34a990065818d + // http://www.boost.org/doc/libs/1_37_0/libs/circular_buffer/doc/circular_buffer.html#classboost_1_1circular__buffer_1f5081a54afbc2dfc1a7fb20329df7d5b + // should help a lot with the code. + + #region Array items easy access. + // The array is composed by at most two non-contiguous segments, + // the next two methods allow easy access to those. + + private ArraySegment ArrayOne() + { + if (IsEmpty) + { + return new ArraySegment(Array.Empty()); + } + else if (start < end) + { + return new ArraySegment(data, start, end - start); + } + else + { + return new ArraySegment(data, start, data.Length - start); + } + } + + private ArraySegment ArrayTwo() + { + if (IsEmpty) + { + return new ArraySegment(Array.Empty()); + } + else if (start < end) + { + return new ArraySegment(data, end, 0); + } + else + { + return new ArraySegment(data, 0, end); + } + } + + public int IndexOf(T item) + { + for(int i=0;i2.0.0.0.myversion + + + + diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs new file mode 100644 index 0000000..01fb89a --- /dev/null +++ b/SerialMonitor/UI.cs @@ -0,0 +1,244 @@ +using System.IO.Ports; +using Terminal.Gui; + +namespace SerialMonitor +{ + internal class UI + { + static readonly RingBuffer lines = new RingBuffer(500); + // port label + static readonly Label portLabel = new Label() { Text = "Port: ", X = 1, Y = 0 }; + static readonly Label pinsLabel = new Label() { Text = "Pins: ", X = 1, Y = 1 }; + static readonly Label portName = new Label() { Text = "???", X = 8, Y = 0 }; + static readonly Label portStatus = new Label() { Text = "Closed", X = Pos.Right(portName) + 2, Y = 0 }; + static readonly Label portSpeed = new Label() { Text = $"Speed: 0b/s", X = Pos.Right(portStatus) + 2, Y = 0 }; + static readonly Label pinRTS = new Label() { Text = "RTS(?)", X = 8, Y = 1 }; + static readonly Label pinCTS = new Label() { Text = "CTS(?)", X = Pos.Right(pinRTS) + 2, Y = 1 }; + static readonly Label pinDTR = new Label() { Text = "DTR(?)", X = Pos.Right(pinCTS) + 2, Y = 1 }; + static readonly Label pinDSR = new Label() { Text = "DSR(?)", X = Pos.Right(pinDTR) + 2, Y = 1 }; + static readonly Label pinCD = new Label() { Text = "CD(?)", X = Pos.Right(pinDSR) + 2, Y = 1 }; + static readonly Label pinBreak = new Label() { Text = "Break(?)", X = Pos.Right(pinCD) + 2, Y = 1 }; + + static readonly Label timeLabel = new Label() { Text = "", X = 50, Y = 0 }; + static readonly Label debugLabel = new Label() { Text = "", X = 40, Y = 0 }; + // properties + public static bool PrintToLogView { get; set; } = true; + public static bool PrintAsHexToLogView { get; set; } = true; + public static bool RequestPortClose { get; set; } = false; + public static List CommandHistory { get; } = new List(); + + // menu + static readonly Label menu = new Label() { X = 0, Y = 0 }; + public static Action? ActionHelp; + public static Action? ActionPrint; + public static Action? ActionPrintAsHex; + public static Action? ActionOpenClose; + public static Action? ActionSend; + public static Action? ActionRts; + public static Action? ActionDtr; + + // data view + static readonly ListView logView = new ListView() + { + X = 0, + Y = 0, + Width = Dim.Fill(), + Height = Dim.Fill() + }; + + public static void Init() + { + Application.Init(); + // main window + var win = new Window() + { + X = 0, + Y = 0, + Width = Dim.Fill(), + Height = Dim.Fill() - 1, +#pragma warning disable CS8602 // Dereference of a possibly null reference. + Title = $"SerialMonitor v.{System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(3)}" +#pragma warning restore CS8602 // Dereference of a possibly null reference. + }; + + // hotkeys + Application.QuitKey = Key.F10; + win.KeyUp += (e) => + { + processHotKey(e.KeyEvent); + }; + // set colorscheme + win.ColorScheme = Colors.TopLevel; + // top frame + var frameStatus = new FrameView() + { + X = 0, + Y = 0, + Width = Dim.Fill(), + Height = 4 + }; + + frameStatus.Add(portLabel, pinsLabel, portName, portStatus, portSpeed, + pinRTS, pinCTS, pinDTR, pinDSR, pinCD, pinBreak, debugLabel, timeLabel); + + timeLabel.X = Pos.Right(frameStatus) - 10; + // data frame + var frameData = new FrameView() + { + X = 0, + Y = 4, + Width = Dim.Fill(), + Height = Dim.Fill() - 1, + Text = "text" + }; + + // compose + frameData.Add(logView); + win.Add(frameStatus, frameData); + Application.Top.Add(win); + // scrollbar for textview + var _scrollBar = new ScrollBarView(logView, true); + _scrollBar.ChangedPosition += () => + { + /*logView.CursorPosition = new Point(logView.CursorPosition.X, _scrollBar.Position); + if (textView.CursorPosition.Y != _scrollBar.Position) + { + _scrollBar.Position = logView.CursorPosition.Y; + } + logView.SetNeedsDisplay();*/ + }; + + logView.DrawContent += (e) => + { + _scrollBar.Size = lines.Count - 1; + _scrollBar.Position = logView.SelectedItem; + _scrollBar.Refresh(); + }; + // add shortcut menu + Application.Top.Add(menu); + menu.Y = Pos.Bottom(Application.Top) - 1; + SetBottomMenuText(); + // bind log data + logView.SetSource(lines); + } + + private static void processHotKey(KeyEvent keyEvent) + { + if (keyEvent.Key == Key.F1) + { + ActionHelp?.Invoke(); + } + else if (keyEvent.Key == Key.F2) + { + PrintToLogView = !PrintToLogView; + ActionPrint?.Invoke(PrintToLogView); + SetBottomMenuText(); + } + else if (keyEvent.Key == Key.F3) + { + PrintAsHexToLogView = !PrintAsHexToLogView; + ActionPrintAsHex?.Invoke(PrintAsHexToLogView); + SetBottomMenuText(); + } + else if (keyEvent.Key == Key.F4) + { + RequestPortClose = !RequestPortClose; + ActionOpenClose?.Invoke(RequestPortClose); + SetBottomMenuText(); + } + else if (keyEvent.Key == Key.F5) + { + // TODO: Send string - dialog needed + ActionSend?.Invoke("NotImplemented"); + } + else if (keyEvent.Key == Key.F6) + { + // TODO: Send file - file selection needed + ActionSend?.Invoke("NotImplemented"); + } + else if (keyEvent.Key == Key.F11) + { + ActionRts?.Invoke(); + } + else if (keyEvent.Key == Key.F12) + { + ActionDtr?.Invoke(); + } + } + + private static void SetBottomMenuText() + { + menu.Text = $" F1 Help | F2 {(!PrintToLogView ? "Print " : "No Print")} | F3 {(!PrintAsHexToLogView ? "Hex " : "Text")} | F4 {(!RequestPortClose ? "Close" : "Open ")} | F5 Send | F6 SendFile | F10 Exit | F11 RTS | F12 DTR"; + } + + public static void Run(Func action) + { + Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(100), action); + Application.MainLoop.AddTimeout(TimeSpan.FromMilliseconds(1000), (loop) => { timeLabel.Text = DateTime.Now.ToLongTimeString(); return true; }); + Application.Run(); + } + + internal static void SetPortStatus(SerialPort port) + { + portName.Text = port.PortName; + portStatus.Text = port.IsOpen ? "Opened" : "Closed"; + portSpeed.Text = $"{port.BaudRate}b/s"; + } + + internal static void SetPinStatus(SerialPort port) + { + pinRTS.Text = $"RTS({(port.RtsEnable ? 1 : "0")})"; + pinCTS.Text = $"CTS({(port.CtsHolding ? 1 : "0")})"; + pinDTR.Text = $"DTR({(port.DtrEnable ? 1 : "0")})"; + pinDSR.Text = $"DSR({(port.DsrHolding ? 1 : "0")})"; + pinCD.Text = $"CD({(port.CDHolding ? 1 : "0")})"; + pinBreak.Text = $"Break({(port.BreakState ? 1 : "0")})"; + } + + internal static void WriteLine(string message, ConsoleColor color = ConsoleColor.White) + { + lines.Add(message); + if (!logView.IsInitialized) + return; + + if (logView.SelectedItem >= lines.Count-2) + logView.MoveDown(); + + debugLabel.Text = $"xx/{lines.Count}"; + } + + internal static void WriteLine(string message, object[] parameters, ConsoleColor color = ConsoleColor.White) + { + WriteLine(string.Format(message, parameters), color); + } + + internal static void Write(string message, ConsoleColor color = ConsoleColor.White) + { + if (lines.IsEmpty) + lines.Add(message); + else + lines.Last += message; + } + + internal static void Write(string message, object[] parameters, ConsoleColor color = ConsoleColor.White) + { + var msg = string.Format(message, parameters); + + if (msg.Contains("\r\n") || msg.Contains('\n')) + { + var msgLines = message.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None); + for (int i = 0; i < msgLines.Length; i++) + { + if (i == 0) + Write(msgLines[i], color); + else + WriteLine(msgLines[i], color); + } + } + else + { + Write(msg, color); + } + } + } +} From feadd5151dc432a101e123625b9b583a9a36cbef Mon Sep 17 00:00:00 2001 From: docbender Date: Mon, 21 Feb 2022 18:16:43 +0100 Subject: [PATCH 03/18] Prevent splitting received data --- SerialMonitor/Program.cs | 44 ++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 5f176d6..6a1742f 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -40,6 +40,10 @@ class Program /// Flag for pause / resume connection /// static bool pauseConnection = false; + /// + /// Incoming data buffer + /// + static byte[] incoming = new byte[32]; /// @@ -799,15 +803,24 @@ static void port_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) /// /// static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) - { + { SerialPort port = ((SerialPort)sender); - byte[] incoming; + int byteCount; + int cycle = 0; try { - incoming = new byte[port.BytesToRead]; - - port.Read(incoming, 0, incoming.Length); + do + { + byteCount = port.BytesToRead; + Thread.Sleep(2); + cycle++; + } while (byteCount < port.BytesToRead); + + if (incoming.Length < byteCount) + incoming = new byte[byteCount]; + + port.Read(incoming, 0, byteCount); } catch (Exception ex) { @@ -834,16 +847,16 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) if (showAscii) { if (noTime || applyGapTolerance) - line = ASCIIEncoding.ASCII.GetString(incoming); + line = ASCIIEncoding.ASCII.GetString(incoming,0,byteCount); else - line = time.ToString() + " " + ASCIIEncoding.ASCII.GetString(incoming); + line = time.ToString() + " " + Encoding.ASCII.GetString(incoming, 0, byteCount); } else { if (noTime || applyGapTolerance) - line = string.Join(" ", Array.ConvertAll(incoming, x => "0x" + x.ToString("X2"))); + line = string.Join(" ", incoming.Take(byteCount).Select(x=> $"0x{x:X2}")); else - line = time.ToString() + " " + string.Join(" ", Array.ConvertAll(incoming, x => "0x" + x.ToString("X2"))); + line = time.ToString() + " " + string.Join(" ", incoming.Take(byteCount).Select(x => $"0x{x:X2}")); } if (applyGapTolerance) @@ -859,7 +872,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) if (repeaterEnabled) { - byte[] data = data2Send(incoming); + byte[] data = data2Send(incoming, byteCount); if (data != null) { @@ -879,12 +892,13 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) /// prepare data as answer /// /// + /// /// - static byte[] data2Send(byte[] incoming) + static byte[] data2Send(byte[] incoming, int byteCount) { if (repeaterUseHex) { - string ask = string.Join("", Array.ConvertAll(incoming, x => x.ToString("X2"))); + string ask = string.Join("", incoming.Take(byteCount).Select(x => x.ToString("X2"))); if (repeaterMap.ContainsKey(ask)) { @@ -897,9 +911,9 @@ static byte[] data2Send(byte[] incoming) } if (noTime) - consoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => "0x" + x.ToString("X2")))); + consoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => $"0x{x:X2}"))); else - consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => "0x" + x.ToString("X2")))); + consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => $"0x{x:X2}"))); return data; } @@ -910,7 +924,7 @@ static byte[] data2Send(byte[] incoming) } else { - string ask = ASCIIEncoding.ASCII.GetString(incoming); + string ask = ASCIIEncoding.ASCII.GetString(incoming,0,byteCount); if (repeaterMap.ContainsKey(ask)) { From 97d6f72deb7698287059b322fd92e40390679979 Mon Sep 17 00:00:00 2001 From: docbender Date: Mon, 21 Feb 2022 19:53:17 +0100 Subject: [PATCH 04/18] Small fixes --- SerialMonitor/Program.cs | 282 +++++++++++++++++++-------------------- SerialMonitor/UI.cs | 4 +- 2 files changed, 141 insertions(+), 145 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 6a1742f..92444d4 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -17,14 +17,14 @@ namespace SerialMonitor { class Program { - static ArgumentCollection arguments = new ArgumentCollection(new string[] { "baudrate", "parity", "databits", "stopbits", + static readonly ArgumentCollection arguments = new ArgumentCollection(new string[] { "baudrate", "parity", "databits", "stopbits", "repeatfile", "logfile", "logincomingonly", "showascii", "notime", "gaptolerance", "continuousmode", "nogui" }); - static string version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version.ToString(3); + static readonly string version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version?.ToString(3); static long lastTimeReceved = 0; static bool repeaterEnabled = false; static bool repeaterUseHex = false; static bool showAscii = false; - static Dictionary repeaterMap; + static readonly Dictionary repeaterMap = new Dictionary(); static bool logfile = false; static bool logincomingonly = false; static string logFilename = ""; @@ -59,8 +59,8 @@ static void Main(string[] args) { if (args[0].Equals("-?") || args[0].Equals("-help") || args[0].Equals("--help") || args[0].Equals("?") || args[0].Equals("/?")) { - consoleWriteLineNoTrace("SerialMonitor v." + version); - printHelp(); + ConsoleWriteLineNoTrace($"SerialMonitor v.{version}"); + PrintHelp(); Console.WriteLine("\nPress [Enter] to exit"); Console.ReadLine(); return; @@ -86,7 +86,7 @@ static void Main(string[] args) if (!continuousMode) UI.Init(); else - consoleWriteLineNoTrace($"SerialMonitor v.{version}"); + ConsoleWriteLineNoTrace($"SerialMonitor v.{version}"); showAscii = arguments.GetArgument("showascii").Enabled; noTime = arguments.GetArgument("notime").Enabled; @@ -142,7 +142,7 @@ static void Main(string[] args) if (arg.Parameter.Length == 0) { logFilename = "log_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".txt"; - consoleWriteLine("Warning: Log file name not specified. Used " + logFilename); + ConsoleWriteLine("Warning: Log file name not specified. Used " + logFilename); } else logFilename = arg.Parameter; @@ -156,7 +156,7 @@ static void Main(string[] args) { logfile = true; logFilename = "log_" + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss") + ".txt"; - consoleWriteLine("Warning: Parameter logfile not specified. Log enabled to the file: " + logFilename); + ConsoleWriteLine("Warning: Parameter logfile not specified. Log enabled to the file: " + logFilename); logfile = true; } logincomingonly = true; @@ -166,10 +166,10 @@ static void Main(string[] args) arg = arguments.GetArgument("gaptolerance"); if (arg.Enabled) { - int.TryParse(arg.Parameter, out gapTolerance); + _ = int.TryParse(arg.Parameter, out gapTolerance); if (gapTolerance == 0) - consoleWriteLine("Warning: Parameter gaptolerance has invalid argument. Gap tolerance must be greater than zero."); + ConsoleWriteLine("Warning: Parameter gaptolerance has invalid argument. Gap tolerance must be greater than zero."); else gapToleranceEnable = true; } @@ -178,10 +178,8 @@ static void Main(string[] args) if (logfile) { //check path - string path = System.IO.Path.GetDirectoryName(logFilename); - if (path?.Length == 0) - logFilename = System.IO.Directory.GetCurrentDirectory() + "\\" + logFilename; - else + string? path = System.IO.Path.GetDirectoryName(logFilename); + if (path?.Length > 0) { if (!System.IO.Directory.Exists(path)) try @@ -190,37 +188,41 @@ static void Main(string[] args) } catch (Exception ex) { - consoleWriteLine($"Warning: Cannot create directory {path}"); + ConsoleWriteLine($"Warning: Cannot create directory {path}. {ex.Message}"); } } + else + { + logFilename = System.IO.Directory.GetCurrentDirectory() + "\\" + logFilename; + } - if (!isFileNameValid(logFilename)) + if (!IsFileNameValid(logFilename)) { - consoleWriteLine("\nPress [Enter] to exit"); + ConsoleWriteLine("\nPress [Enter] to exit"); Console.ReadLine(); return; } //assign file to listener - if (Trace.Listeners["Default"] is DefaultTraceListener) - ((DefaultTraceListener)Trace.Listeners["Default"]).LogFileName = logFilename; + if (Trace.Listeners["Default"] is DefaultTraceListener listener) + listener.LogFileName = logFilename; } if (args.Length > 0) { if (Config.SaveStarters(args)) - consoleWriteLine("Program parameters have been saved. Will be used next time you start program."); + ConsoleWriteLine("Program parameters have been saved. Will be used next time you start program."); else - consoleWriteLine("Warning: Program parameters cannot be saved."); + ConsoleWriteLine("Warning: Program parameters cannot be saved."); } Argument repeatfile = arguments.GetArgument("repeatfile"); if (repeatfile.Enabled) { - if (!isFileNameValid(repeatfile.Parameter)) + if (!IsFileNameValid(repeatfile.Parameter)) { - consoleWriteLine("\nPress [Enter] to exit"); + ConsoleWriteLine("\nPress [Enter] to exit"); Console.ReadLine(); return; @@ -228,7 +230,7 @@ static void Main(string[] args) PrepareRepeatFile(repeatfile.Parameter); } - consoleWriteLine("Opening port {0}: baudrate={1}b/s, parity={2}, databits={3}, stopbits={4}", port.PortName, port.BaudRate.ToString(), port.Parity.ToString(), port.DataBits.ToString(), port.StopBits.ToString()); + ConsoleWriteLine("Opening port {0}: baudrate={1}b/s, parity={2}, databits={3}, stopbits={4}", port.PortName, port.BaudRate.ToString(), port.Parity.ToString(), port.DataBits.ToString(), port.StopBits.ToString()); bool exit = false; @@ -246,18 +248,18 @@ static void Main(string[] args) Thread.Sleep(100); if (!pauseConnection && !port.IsOpen) { - consoleWriteLine(" Port disconnected...."); - portConnectInfinite(port); + ConsoleWriteLine(" Port disconnected...."); + PortConnectInfinite(port); } } } else { - UI.ActionHelp = () => { printHelp(); }; + UI.ActionHelp = () => { PrintHelp(); }; UI.ActionPrint = (print) => { pausePrint = !print; }; UI.ActionPrintAsHex = (hex) => { showAscii = !hex; }; UI.ActionOpenClose = (close) => { pauseConnection = close; }; - UI.ActionSend = (data) => { userDataSend(port,data); }; + UI.ActionSend = (data) => { UserDataSend(port,data); }; UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); }; @@ -269,7 +271,7 @@ static void Main(string[] args) if (lastTry.AddSeconds(5) <= DateTime.Now) { lastTry = DateTime.Now; - if (portConnect(port)) + if (PortConnect(port)) { UI.SetPortStatus(port); UI.SetPinStatus(port); @@ -397,11 +399,11 @@ static void Main(string[] args) /// /// /// - private static bool userDataSend(SerialPort port, string line) + private static bool UserDataSend(SerialPort port, string line) { if (line.Length == 0) { - consoleWriteError("Nothing to sent."); + ConsoleWriteError("Nothing to sent."); return false; } @@ -419,7 +421,7 @@ private static bool userDataSend(SerialPort port, string line) if (!reg.IsMatch(prepared)) { - consoleWriteError("Message is not well formated. Data will be not sent."); + ConsoleWriteError("Message is not well formated. Data will be not sent."); return false; } @@ -474,7 +476,7 @@ private static bool userDataSend(SerialPort port, string line) } catch (Exception ex) { - consoleWriteError(ex.ToString()); + ConsoleWriteError(ex.ToString()); return false; } @@ -489,15 +491,15 @@ private static bool userDataSend(SerialPort port, string line) /// /// /// - private static bool userDataSendFile(SerialPort port, string filePath) + private static bool UserDataSendFile(SerialPort port, string filePath) { if (filePath.Length == 0) { - consoleWriteError("Nothing to sent."); + ConsoleWriteError("Nothing to sent."); return false; } - consoleWriteError("Not implemented"); + ConsoleWriteError("Not implemented"); //TODO: file send return false; } @@ -506,14 +508,14 @@ private static bool userDataSendFile(SerialPort port, string filePath) /// Connecting to port in infinite loop /// /// - private static void portConnectInfinite(SerialPort port) + private static void PortConnectInfinite(SerialPort port) { do { - if (!portConnect(port)) + if (!PortConnect(port)) { string waitText = "Waiting 5s to reconnect..."; - consoleWrite(waitText); + ConsoleWrite(waitText); for (int i = 0; i < 5; i++) { @@ -521,16 +523,16 @@ private static void portConnectInfinite(SerialPort port) { Thread.Sleep(250); - consoleWrite(j == 0 ? "/" : j == 1 ? "-" : j == 2 ? "\\" : "|"); - consoleCursorLeft(-1); + ConsoleWrite(j == 0 ? "/" : j == 1 ? "-" : j == 2 ? "\\" : "|"); + ConsoleCursorLeft(-1); } - consoleWrite("."); + ConsoleWrite("."); } - consoleCursorLeftReset(); - consoleWrite(new string(' ', waitText.Length + 5)); - consoleCursorLeftReset(); + ConsoleCursorLeftReset(); + ConsoleWrite(new string(' ', waitText.Length + 5)); + ConsoleCursorLeftReset(); } // TODO: @@ -551,7 +553,7 @@ private static void portConnectInfinite(SerialPort port) /// /// /// - private static bool portConnect(SerialPort port) + private static bool PortConnect(SerialPort port) { try { @@ -559,14 +561,14 @@ private static bool portConnect(SerialPort port) } catch (IOException ex) { - consoleWriteError("Cannot open " + port.PortName + ". " + ex.Message); - consoleWriteLine(" Available ports: " + string.Join(",", SerialPort.GetPortNames())); + ConsoleWriteError("Cannot open " + port.PortName + ". " + ex.Message); + ConsoleWriteLine(" Available ports: " + string.Join(",", SerialPort.GetPortNames())); return false; } catch (Exception ex) { - consoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); + ConsoleWriteError("Cannot open port " + port.PortName + ". " + ex.Message); return false; } @@ -579,7 +581,7 @@ private static bool portConnect(SerialPort port) /// /// /// - private static void portClose(SerialPort port) + private static void PortClose(SerialPort port) { if (port.IsOpen) port.Close(); @@ -620,13 +622,13 @@ private static void connectCommand(SerialPort port) /// /// /// - private static bool isFileNameValid(string filePath) + private static bool IsFileNameValid(string filePath) { foreach (char c in System.IO.Path.GetInvalidPathChars()) { if (filePath.Contains(c.ToString())) { - consoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); + ConsoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); return false; } @@ -636,7 +638,7 @@ private static bool isFileNameValid(string filePath) { if (System.IO.Path.GetFileName(filePath).Contains(c.ToString())) { - consoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); + ConsoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); return false; } @@ -652,7 +654,7 @@ private static bool isFileNameValid(string filePath) private static void PrepareRepeatFile(string fileName) { if (!File.Exists(fileName)) - consoleWriteError("File {0} was not found", fileName); + ConsoleWriteError("File {0} was not found", fileName); else { try @@ -660,24 +662,22 @@ private static void PrepareRepeatFile(string fileName) string[] lines = File.ReadAllLines(fileName); if (lines.Length == 0) - consoleWriteError("Zero lines in file {0}", fileName); + ConsoleWriteError("Zero lines in file {0}", fileName); - consoleWriteLine("File {0} opened and {1} lines has been read", fileName, lines.Length); + ConsoleWriteLine("File {0} opened and {1} lines has been read", fileName, lines.Length); - repeaterMap = new Dictionary(); + repeaterMap.Clear(); //check format file string startLine = lines[0]; - bool hex; int linesWithData = 0; string ask = ""; Regex reg = new Regex("^(0x[0-9A-Fa-f]{1,2}\\s*)+$"); - + // match hex string if (reg.IsMatch(startLine)) { - hex = true; - consoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); + ConsoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); Regex regWhite = new Regex("\\s+"); @@ -695,7 +695,6 @@ private static void PrepareRepeatFile(string fileName) } else { - repeaterMap = null; throw new RepeatFileException("Line {0} not coresponds to hex format.", i); } } @@ -706,11 +705,10 @@ private static void PrepareRepeatFile(string fileName) else { reg = new Regex("^([0-9A-Fa-f])+$"); - + // match hex string if (reg.IsMatch(startLine)) - { - hex = true; - consoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); + { + ConsoleWriteLine("First line corresponds hex format. File will be read and packets compared as HEX."); //check whole file for (int i = 0; i < lines.Length; i++) @@ -719,7 +717,6 @@ private static void PrepareRepeatFile(string fileName) { if (lines[i].Length % 2 == 1) { - repeaterMap = null; throw new RepeatFileException("Line {0} has odd number of characters.", i); } @@ -732,7 +729,6 @@ private static void PrepareRepeatFile(string fileName) } else { - repeaterMap = null; throw new RepeatFileException("Line {0} not coresponds to hex format.", i); } } @@ -742,8 +738,8 @@ private static void PrepareRepeatFile(string fileName) } else { - hex = false; - consoleWriteLine("First line not corresponds hex format. File will be read and packets compared as ASCII."); + // non hex string + ConsoleWriteLine("First line not corresponds hex format. File will be read and packets compared as ASCII."); //check whole file for (int i = 0; i < lines.Length; i++) @@ -760,16 +756,16 @@ private static void PrepareRepeatFile(string fileName) } if (linesWithData % 2 == 1) - consoleWriteError("Odd number of lines in file {0} with code. One line ask, one line answer.", fileName); + ConsoleWriteError("Odd number of lines in file {0} with code. One line ask, one line answer.", fileName); repeaterEnabled = true; - consoleWriteLine("{0} pairs ask/answer ready", repeaterMap.Count); + ConsoleWriteLine("{0} pairs ask/answer ready", repeaterMap.Count); } catch (Exception ex) { - consoleWriteError("Cannot read file {0}", fileName); - consoleWriteError(ex.ToString()); + ConsoleWriteError("Cannot read file {0}", fileName); + ConsoleWriteError(ex.ToString()); } } } @@ -794,7 +790,7 @@ static void port_PinChanged(object sender, SerialPinChangedEventArgs e) /// static void port_ErrorReceived(object sender, SerialErrorReceivedEventArgs e) { - consoleWriteError(e.EventType.ToString()); + ConsoleWriteError(e.EventType.ToString()); } /// @@ -824,7 +820,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) } catch (Exception ex) { - consoleWriteError(ex.ToString()); + ConsoleWriteError(ex.ToString()); return; } @@ -838,7 +834,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) applyGapTolerance = (gapToleranceEnable && sinceLastReceive <= gapTolerance); if (!noTime && (!gapToleranceEnable || !applyGapTolerance)) - consoleWriteCommunication(ConsoleColor.Magenta, "\n+" + sinceLastReceive.ToString("F3") + " ms"); + ConsoleWriteCommunication(ConsoleColor.Magenta, "\n+" + sinceLastReceive.ToString("F3") + " ms"); } //Write to output @@ -860,11 +856,11 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) } if (applyGapTolerance) - consoleWriteCommunication(ConsoleColor.Yellow, line); + ConsoleWriteCommunication(ConsoleColor.Yellow, line); else { - consoleWriteCommunication(ConsoleColor.Yellow, "\n"); - consoleWriteCommunication(ConsoleColor.Yellow, line); + ConsoleWriteCommunication(ConsoleColor.Yellow, "\n"); + ConsoleWriteCommunication(ConsoleColor.Yellow, line); } @@ -872,7 +868,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) if (repeaterEnabled) { - byte[] data = data2Send(incoming, byteCount); + byte[]? data = Data2Send(incoming, byteCount); if (data != null) { @@ -882,7 +878,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) } catch (Exception ex) { - consoleWriteError(ex.ToString()); + ConsoleWriteError(ex.ToString()); } } } @@ -894,7 +890,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) /// /// /// - static byte[] data2Send(byte[] incoming, int byteCount) + static byte[]? Data2Send(byte[] incoming, int byteCount) { if (repeaterUseHex) { @@ -911,15 +907,15 @@ static byte[] data2Send(byte[] incoming, int byteCount) } if (noTime) - consoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => $"0x{x:X2}"))); + ConsoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => $"0x{x:X2}"))); else - consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => $"0x{x:X2}"))); + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => $"0x{x:X2}"))); return data; } else { - consoleWriteLine("Repeater: Unknown ask"); + ConsoleWriteLine("Repeater: Unknown ask"); } } else @@ -931,15 +927,15 @@ static byte[] data2Send(byte[] incoming, int byteCount) string answer = repeaterMap[ask]; if (noTime) - consoleWriteCommunication(ConsoleColor.Green, "\n" + answer); + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + answer); else - consoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + answer); + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + answer); return ASCIIEncoding.ASCII.GetBytes(answer); } else { - consoleWriteLine("Repeater: Unknown ask"); + ConsoleWriteLine("Repeater: Unknown ask"); } } @@ -951,9 +947,9 @@ static byte[] data2Send(byte[] incoming, int byteCount) /// /// /// - private static void consoleWriteError(string text, params object[] arg) + private static void ConsoleWriteError(string text, params object[] arg) { - consoleWriteLine(ConsoleColor.Red, text, arg); + ConsoleWriteLine(ConsoleColor.Red, text, arg); } /// @@ -961,7 +957,7 @@ private static void consoleWriteError(string text, params object[] arg) /// /// /// - private static void consoleWrite(string message, params object[] parameters) + private static void ConsoleWrite(string message, params object[] parameters) { if (!continuousMode) UI.Write(message, parameters); @@ -977,7 +973,7 @@ private static void consoleWrite(string message, params object[] parameters) /// /// /// - private static void consoleWriteLine(string message, params object[] parameters) + private static void ConsoleWriteLine(string message, params object[] parameters) { if (!continuousMode) { @@ -1000,7 +996,7 @@ private static void consoleWriteLine(string message, params object[] parameters) /// /// /// - private static void consoleWriteLine(ConsoleColor color, string message, params object[] parameters) + private static void ConsoleWriteLine(ConsoleColor color, string message, params object[] parameters) { if (!continuousMode) { @@ -1022,7 +1018,7 @@ private static void consoleWriteLine(ConsoleColor color, string message, params /// /// /// - private static void consoleWriteLineNoTrace(string message, params object[] parameters) + private static void ConsoleWriteLineNoTrace(string message, params object[] parameters) { if (!continuousMode) UI.WriteLine(message, parameters); @@ -1036,7 +1032,7 @@ private static void consoleWriteLineNoTrace(string message, params object[] para /// /// /// - private static void consoleWriteLineNoTrace(ConsoleColor color, string message, params object[] parameters) + private static void ConsoleWriteLineNoTrace(ConsoleColor color, string message, params object[] parameters) { if (!continuousMode) { @@ -1055,7 +1051,7 @@ private static void consoleWriteLineNoTrace(ConsoleColor color, string message, /// /// /// - private static void consoleWriteCommunication(ConsoleColor color, string message, params object[] parameters) + private static void ConsoleWriteCommunication(ConsoleColor color, string message, params object[] parameters) { if (!pausePrint) { @@ -1066,7 +1062,7 @@ private static void consoleWriteCommunication(ConsoleColor color, string message else { Console.ForegroundColor = color; - consoleWrite(message, parameters); + ConsoleWrite(message, parameters); Console.ResetColor(); } } @@ -1098,7 +1094,7 @@ private static void consoleWriteCommunication(ConsoleColor color, string message /// Move console cursor in current line /// /// - private static void consoleCursorLeft(int moveBy) + private static void ConsoleCursorLeft(int moveBy) { if (continuousMode) Console.CursorLeft += moveBy; @@ -1109,7 +1105,7 @@ private static void consoleCursorLeft(int moveBy) /// /// Set cursor to left border /// - private static void consoleCursorLeftReset() + private static void ConsoleCursorLeftReset() { if (continuousMode) Console.CursorLeft = 0; @@ -1120,53 +1116,53 @@ private static void consoleCursorLeftReset() /// /// Print help /// - private static void printHelp() + private static void PrintHelp() { - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("Usage: serialmonitor PortName [ parameter]"); - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("Switches:"); - consoleWriteLineNoTrace("-baudrate {{baud rate}}: set port baud rate. Default 9600kbps."); - consoleWriteLineNoTrace("-parity {{used parity}}: set used port parity. Default none. Available parameters odd, even, mark and space."); - consoleWriteLineNoTrace("-databits {{used databits}}: set data bits count. Default 8 data bits."); - consoleWriteLineNoTrace("-stopbits {{used stopbits}}: set stop bits count. Default 1 stop bit. Available parameters 0, 1, 1.5 and 2."); - consoleWriteLineNoTrace("-repeatfile {{file name}}: enable repeat mode with protocol specified in file"); - consoleWriteLineNoTrace("-logfile {{file name}}: set file name for log into that file"); - consoleWriteLineNoTrace("-logincomingonly: log into file would be only incoming data"); - consoleWriteLineNoTrace("-showascii: communication would be show in ASCII format (otherwise HEX is used)"); - consoleWriteLineNoTrace("-notime: time information about incoming data would not be printed"); - consoleWriteLineNoTrace("-gaptolerance {{time gap in ms}}: messages received within specified time gap will be printed together"); - consoleWriteLineNoTrace("-continuousmode or -nogui: start program in normal console mode (scrolling list). Not with primitive text GUI"); - - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("Example: serialmonitor COM1"); - consoleWriteLineNoTrace(" serialmonitor COM1 -baudrate 57600 -parity odd -databits 7 -stopbits 1.5"); - consoleWriteLineNoTrace(" serialmonitor COM83 -baudrate 19200 -repeatfile protocol.txt"); - - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("In program commands:"); - consoleWriteLineNoTrace("F1: print help"); - consoleWriteLineNoTrace("F2: pause/resume print on screen"); - consoleWriteLineNoTrace("F3: toggle between data print format (HEX / ASCII)"); - consoleWriteLineNoTrace("F4: pause/resume connection to serial port"); - consoleWriteLineNoTrace("F5: send specified data (in HEX format if data start with 0x otherwise ASCII is send)"); - consoleWriteLineNoTrace("F6: send specified file)"); - - consoleWriteLineNoTrace("F10 or ^C: program exit"); - consoleWriteLineNoTrace("F11: toggle RTS pin"); - consoleWriteLineNoTrace("F12: toggle DTR pin"); + ConsoleWriteLineNoTrace(""); + ConsoleWriteLineNoTrace("Usage: serialmonitor PortName [ parameter]"); + ConsoleWriteLineNoTrace(""); + ConsoleWriteLineNoTrace("Switches:"); + ConsoleWriteLineNoTrace("-baudrate {{baud rate}}: set port baud rate. Default 9600kbps."); + ConsoleWriteLineNoTrace("-parity {{used parity}}: set used port parity. Default none. Available parameters odd, even, mark and space."); + ConsoleWriteLineNoTrace("-databits {{used databits}}: set data bits count. Default 8 data bits."); + ConsoleWriteLineNoTrace("-stopbits {{used stopbits}}: set stop bits count. Default 1 stop bit. Available parameters 0, 1, 1.5 and 2."); + ConsoleWriteLineNoTrace("-repeatfile {{file name}}: enable repeat mode with protocol specified in file"); + ConsoleWriteLineNoTrace("-logfile {{file name}}: set file name for log into that file"); + ConsoleWriteLineNoTrace("-logincomingonly: log into file would be only incoming data"); + ConsoleWriteLineNoTrace("-showascii: communication would be show in ASCII format (otherwise HEX is used)"); + ConsoleWriteLineNoTrace("-notime: time information about incoming data would not be printed"); + ConsoleWriteLineNoTrace("-gaptolerance {{time gap in ms}}: messages received within specified time gap will be printed together"); + ConsoleWriteLineNoTrace("-continuousmode or -nogui: start program in normal console mode (scrolling list). Not with primitive text GUI"); + + ConsoleWriteLineNoTrace(""); + ConsoleWriteLineNoTrace("Example: serialmonitor COM1"); + ConsoleWriteLineNoTrace(" serialmonitor COM1 -baudrate 57600 -parity odd -databits 7 -stopbits 1.5"); + ConsoleWriteLineNoTrace(" serialmonitor COM83 -baudrate 19200 -repeatfile protocol.txt"); + + ConsoleWriteLineNoTrace(""); + ConsoleWriteLineNoTrace("In program commands:"); + ConsoleWriteLineNoTrace("F1: print help"); + ConsoleWriteLineNoTrace("F2: pause/resume print on screen"); + ConsoleWriteLineNoTrace("F3: toggle between data print format (HEX / ASCII)"); + ConsoleWriteLineNoTrace("F4: pause/resume connection to serial port"); + ConsoleWriteLineNoTrace("F5: send specified data (in HEX format if data start with 0x otherwise ASCII is send)"); + ConsoleWriteLineNoTrace("F6: send specified file)"); + + ConsoleWriteLineNoTrace("F10 or ^C: program exit"); + ConsoleWriteLineNoTrace("F11: toggle RTS pin"); + ConsoleWriteLineNoTrace("F12: toggle DTR pin"); if (continuousMode) { - consoleWriteLineNoTrace(""); - consoleWriteLineNoTrace("In program color schema:"); - consoleWriteLineNoTrace(ConsoleColor.Cyan, "Control pin status changed"); - consoleWriteLineNoTrace(ConsoleColor.Green, "Control pin ON"); - consoleWriteLineNoTrace(ConsoleColor.White, "Control pin OFF"); - consoleWriteLineNoTrace(ConsoleColor.Magenta, "Time between received data"); - consoleWriteLineNoTrace(ConsoleColor.Yellow, "Received data"); - consoleWriteLineNoTrace(ConsoleColor.Green, "Sended data"); - consoleWriteLineNoTrace(ConsoleColor.Red, "Error"); + ConsoleWriteLineNoTrace(""); + ConsoleWriteLineNoTrace("In program color schema:"); + ConsoleWriteLineNoTrace(ConsoleColor.Cyan, "Control pin status changed"); + ConsoleWriteLineNoTrace(ConsoleColor.Green, "Control pin ON"); + ConsoleWriteLineNoTrace(ConsoleColor.White, "Control pin OFF"); + ConsoleWriteLineNoTrace(ConsoleColor.Magenta, "Time between received data"); + ConsoleWriteLineNoTrace(ConsoleColor.Yellow, "Received data"); + ConsoleWriteLineNoTrace(ConsoleColor.Green, "Sended data"); + ConsoleWriteLineNoTrace(ConsoleColor.Red, "Error"); Console.ResetColor(); } diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 01fb89a..58dcefc 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -65,7 +65,7 @@ public static void Init() Application.QuitKey = Key.F10; win.KeyUp += (e) => { - processHotKey(e.KeyEvent); + ProcessHotKey(e.KeyEvent); }; // set colorscheme win.ColorScheme = Colors.TopLevel; @@ -122,7 +122,7 @@ public static void Init() logView.SetSource(lines); } - private static void processHotKey(KeyEvent keyEvent) + private static void ProcessHotKey(KeyEvent keyEvent) { if (keyEvent.Key == Key.F1) { From d11e22b66c844a9a2c1d297402bf1b415edcfd36 Mon Sep 17 00:00:00 2001 From: docbender Date: Tue, 22 Feb 2022 17:43:51 +0100 Subject: [PATCH 05/18] Send messages and files --- SerialMonitor/Program.cs | 15 ++-- SerialMonitor/UI.cs | 152 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 154 insertions(+), 13 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 92444d4..0f286d1 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -260,6 +260,7 @@ static void Main(string[] args) UI.ActionPrintAsHex = (hex) => { showAscii = !hex; }; UI.ActionOpenClose = (close) => { pauseConnection = close; }; UI.ActionSend = (data) => { UserDataSend(port,data); }; + UI.ActionSendFile = (file) => { UserDataSendFile(port, file); }; UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); }; @@ -399,9 +400,9 @@ static void Main(string[] args) /// /// /// - private static bool UserDataSend(SerialPort port, string line) + private static bool UserDataSend(SerialPort port, string? line) { - if (line.Length == 0) + if (string.IsNullOrEmpty(line)) { ConsoleWriteError("Nothing to sent."); return false; @@ -416,7 +417,6 @@ private static bool UserDataSend(SerialPort port, string line) if (hex) { string prepared = line.Replace("0x", ""); - Regex reg = new Regex("^([0-9A-Fa-f]{1,2}\\s*)+$"); if (!reg.IsMatch(prepared)) @@ -473,6 +473,11 @@ private static bool UserDataSend(SerialPort port, string line) try { port.Write(data, 0, data.Length); + + if (noTime) + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + line); + else + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + line); } catch (Exception ex) { @@ -491,9 +496,9 @@ private static bool UserDataSend(SerialPort port, string line) /// /// /// - private static bool UserDataSendFile(SerialPort port, string filePath) + private static bool UserDataSendFile(SerialPort port, string? filePath) { - if (filePath.Length == 0) + if (string.IsNullOrEmpty(filePath)) { ConsoleWriteError("Nothing to sent."); return false; diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 58dcefc..7c0c7bd 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -26,6 +26,7 @@ internal class UI public static bool PrintAsHexToLogView { get; set; } = true; public static bool RequestPortClose { get; set; } = false; public static List CommandHistory { get; } = new List(); + public static List FileHistory { get; } = new(); // menu static readonly Label menu = new Label() { X = 0, Y = 0 }; @@ -33,7 +34,8 @@ internal class UI public static Action? ActionPrint; public static Action? ActionPrintAsHex; public static Action? ActionOpenClose; - public static Action? ActionSend; + public static Action? ActionSend; + public static Action? ActionSendFile; public static Action? ActionRts; public static Action? ActionDtr; @@ -77,7 +79,7 @@ public static void Init() Width = Dim.Fill(), Height = 4 }; - + frameStatus.Add(portLabel, pinsLabel, portName, portStatus, portSpeed, pinRTS, pinCTS, pinDTR, pinDSR, pinCD, pinBreak, debugLabel, timeLabel); @@ -147,14 +149,143 @@ private static void ProcessHotKey(KeyEvent keyEvent) SetBottomMenuText(); } else if (keyEvent.Key == Key.F5) - { - // TODO: Send string - dialog needed - ActionSend?.Invoke("NotImplemented"); + { + // dialog + bool sendpressed = false; + var send = new Button("Send"); + var cancel = new Button("Cancel"); + var dialog = new Dialog("Send message", 50, 6, send, cancel); + var textField = new TextField() + { + X = Pos.Center(), + Y = Pos.Center(), + Width = Dim.Fill() - 2 + }; + textField.KeyUp += (key) => + { + if (key.KeyEvent.Key == Key.Enter && !textField.Text.IsEmpty) + { + sendpressed = true; + Application.RequestStop(); + } + }; + dialog.Add(textField); + + send.Clicked += () => + { + if (textField.Text.IsEmpty) + { + MessageBox.Query("Warning", "Fill text line.", "OK"); + } + else + { + sendpressed = true; + Application.RequestStop(); + } + }; + cancel.Clicked += () => + { + Application.RequestStop(); + }; + textField.SetFocus(); + Application.Run(dialog); + + if (sendpressed) + ActionSend?.Invoke(textField.Text.ToString()); } else if (keyEvent.Key == Key.F6) { - // TODO: Send file - file selection needed - ActionSend?.Invoke("NotImplemented"); + // dialog + bool sendpressed = false; + var browse = new Button("Browse"); + var send = new Button("Send") { Enabled = FileHistory.Count > 0 }; + var cancel = new Button("Cancel"); + var remove = new Button("Remove") { Enabled = FileHistory.Count > 0 }; + var dialog = new Dialog("Send file", 50, 10, browse, send, remove, cancel); + + var fileList = new ListView() { X = 1, Y = 1, Height = Dim.Fill() - 2, Width = Dim.Fill() - 2 }; + fileList.SetSource(FileHistory); + fileList.ColorScheme = Colors.TopLevel; + dialog.Add(fileList); + + browse.Clicked += () => + { + bool okpressed = false; + var ok = new Button("Ok"); + var cancel = new Button("Cancel"); + var fileDlg = new Dialog("File to send...", 50, 6, ok, cancel); + var filePathField = new TextField() + { + X = Pos.Center(), + Y = Pos.Center(), + Width = Dim.Fill() - 2 + }; + filePathField.KeyUp += (key) => + { + if (key.KeyEvent.Key == Key.Enter && !filePathField.Text.IsEmpty) + { + if (File.Exists(filePathField.Text.ToString())) + { + okpressed = true; + Application.RequestStop(); + } + else + { + MessageBox.Query("Warning", "File does not exist.", "OK"); + } + } + }; + fileDlg.Add(filePathField); + + ok.Clicked += () => + { + if (File.Exists(filePathField.Text.ToString())) + { + okpressed = true; + Application.RequestStop(); + } + else + { + MessageBox.Query("Warning", "File does not exist.", "OK"); + } + }; + cancel.Clicked += () => + { + Application.RequestStop(); + }; + filePathField.SetFocus(); + Application.Run(fileDlg); + if (okpressed) + { + FileHistory.Add(filePathField.Text.ToString()); + remove.Enabled = send.Enabled = true; + } + }; + send.Clicked += () => + { + sendpressed = true; + Application.RequestStop(); + }; + remove.Clicked += () => + { + if (fileList.SelectedItem > -1 && FileHistory.Count > 0) + { + FileHistory.RemoveAt(fileList.SelectedItem); + fileList.SelectedItem = FileHistory.Count - 1; + + remove.Enabled = send.Enabled = FileHistory.Count > 0; + } + }; + cancel.Clicked += () => + { + Application.RequestStop(); + }; + + Application.Run(dialog); + + if (sendpressed) + // Send file data + ActionSendFile?.Invoke(FileHistory[fileList.SelectedItem]); } else if (keyEvent.Key == Key.F11) { @@ -164,6 +295,11 @@ private static void ProcessHotKey(KeyEvent keyEvent) { ActionDtr?.Invoke(); } + + //int calcDlgHeight() + //{ + // return 5 + (FileHistory.Count > 0 ? 2 : 0) + FileHistory.Count; + //} } private static void SetBottomMenuText() @@ -201,7 +337,7 @@ internal static void WriteLine(string message, ConsoleColor color = ConsoleColor if (!logView.IsInitialized) return; - if (logView.SelectedItem >= lines.Count-2) + if (logView.SelectedItem >= lines.Count - 2) logView.MoveDown(); debugLabel.Text = $"xx/{lines.Count}"; From be81d0c86b11b2aeb0a6dcddeddf4d24317c1163 Mon Sep 17 00:00:00 2001 From: docbender Date: Tue, 22 Feb 2022 18:33:42 +0100 Subject: [PATCH 06/18] Preserve config --- SerialMonitor/Config.cs | 396 +++++++++++++++++++++------------------ SerialMonitor/Program.cs | 18 +- 2 files changed, 225 insertions(+), 189 deletions(-) diff --git a/SerialMonitor/Config.cs b/SerialMonitor/Config.cs index 4963db7..d6e8088 100644 --- a/SerialMonitor/Config.cs +++ b/SerialMonitor/Config.cs @@ -16,215 +16,241 @@ namespace SerialMonitor { - class Config - { - const string CONFIG_FILE = "serialmonitor.cfg"; - const string START_ARGUMENTS = "StartArgs="; - const string START_ARGUMENTS_REGEX="(" + START_ARGUMENTS + ")([^\n]*)"; - const string HISTORY = "CommandHistory="; - const string HISTORY_REGEX="(" + HISTORY + ")([^\n]*)"; - -#if __MonoCS__ - static string filePath = Directory.GetCurrentDirectory() + "/" + CONFIG_FILE; -#else - static string filePath = Directory.GetCurrentDirectory() + "\\" + CONFIG_FILE; -#endif - - /// - /// Save started parameters - /// - /// - /// - public static bool SaveStarters(string[] args) - { - string cfgRecord = START_ARGUMENTS + String.Join(";", args); - - string cfg = ReadConfigFileAndPrepareSave(START_ARGUMENTS_REGEX, cfgRecord); - - if(cfg.Length == 0) - cfg = cfgRecord; - - return SaveConfigFile(cfg); - } - - /// - /// Save history - /// - /// - /// - public static bool SaveHistory(string[] args) - { - string cfgRecord = HISTORY + String.Join(";", args); - - string cfg = ReadConfigFileAndPrepareSave(HISTORY, cfgRecord); - - if(cfg.Length == 0) - cfg = cfgRecord; - - return SaveConfigFile(cfg); - } - - /// - /// Save configuration into file - /// - /// - /// - private static bool SaveConfigFile(string configuration) - { - try - { - using(FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write)) + class Config + { + const string CONFIG_FILE = "serialmonitor.cfg"; + const string START_ARGUMENTS = "StartArgs="; + const string START_ARGUMENTS_REGEX = "(" + START_ARGUMENTS + ")([^\n]*)"; + const string HISTORY = "CommandHistory="; + const string FILE_LIST = "FileList="; + const string HISTORY_REGEX = "(" + HISTORY + ")([^\n]*)"; + const string FILE_LIST_REGEX = "(" + FILE_LIST + ")([^\n]*)"; + + static readonly string filePath = Path.Combine(Directory.GetCurrentDirectory(),CONFIG_FILE); + + /// + /// Save started parameters + /// + /// + /// + public static bool SaveStarters(string[] args) + { + string cfgRecord = START_ARGUMENTS + String.Join(";", args); + + string cfg = ReadConfigFileAndPrepareSave(START_ARGUMENTS_REGEX, cfgRecord); + + if (string.IsNullOrEmpty(cfg)) + cfg = cfgRecord; + + return SaveConfigFile(cfg); + } + + /// + /// Save history + /// + /// + /// + public static bool SaveHistory(IEnumerable args) + { + string cfgRecord = HISTORY + String.Join(";", args); + + string cfg = ReadConfigFileAndPrepareSave(HISTORY, cfgRecord); + + if (string.IsNullOrEmpty(cfg)) + cfg = cfgRecord; + + return SaveConfigFile(cfg); + } + + /// + /// Save file list + /// + /// + /// + public static bool SaveFileList(IEnumerable args) + { + string cfgRecord = FILE_LIST + String.Join(";", args); + + string cfg = ReadConfigFileAndPrepareSave(FILE_LIST, cfgRecord); + + if (string.IsNullOrEmpty(cfg)) + cfg = cfgRecord; + + return SaveConfigFile(cfg); + } + + /// + /// Save configuration into file + /// + /// + /// + private static bool SaveConfigFile(string configuration) + { + try { - using(StreamWriter sw = new StreamWriter(fs, Encoding.UTF8)) - { - sw.Write(configuration); - sw.Flush(); - sw.Close(); - } - - fs.Close(); + using FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write); + using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8)) + { + sw.Write(configuration); + sw.Flush(); + sw.Close(); + } + + fs.Close(); } - } - catch(System.IO.IOException ex) - { - Console.WriteLine("Error (IOException) accessing config file. " + ex.ToString()); - return false; - } - catch(Exception ex) - { - Console.WriteLine("Error accessing config file. " + ex.ToString()); - return false; - } - - - return true; - } - - /// - /// Prepare configuration file - /// - /// - /// - /// - private static string ReadConfigFileAndPrepareSave(string itemName, string newConfigRecord) - { - string cfg = ""; - - if(File.Exists(filePath)) - { - try + catch (System.IO.IOException ex) { - using(FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - if(fs.Length > 0) - { - using(TextReader sr = new StreamReader(fs, Encoding.UTF8)) - { - cfg = sr.ReadToEnd(); - } - - Regex rg = new Regex(itemName); - if(rg.IsMatch(cfg)) - cfg = rg.Replace(cfg, newConfigRecord); - else - cfg += "\n" + newConfigRecord; - } - } + Console.WriteLine($"Error (IOException) accessing config file. {ex}"); + return false; } - catch(FileNotFoundException ex) + catch (Exception ex) { + Console.WriteLine($"Error accessing config file. {ex}"); + return false; } - catch(Exception ex) + + return true; + } + + /// + /// Prepare configuration file + /// + /// + /// + /// + private static string ReadConfigFileAndPrepareSave(string itemName, string newConfigRecord) + { + string cfg = ""; + + if (File.Exists(filePath)) { - Console.WriteLine("Error while open config file. " + ex.ToString()); + try + { + using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); + if (fs.Length > 0) + { + using (TextReader sr = new StreamReader(fs, Encoding.UTF8)) + { + cfg = sr.ReadToEnd(); + } + + Regex rg = new Regex(itemName); + if (rg.IsMatch(cfg)) + cfg = rg.Replace(cfg, newConfigRecord); + else + cfg += "\n" + newConfigRecord; + } + } + catch (FileNotFoundException ex) + { + } + catch (Exception ex) + { + Console.WriteLine($"Error while open config file. {ex}"); + } } - } - return cfg; - } - - /// - /// Load saved start configuration - /// - /// - public static string[] LoadStarters() - { - string[] configArgs = null; - - string cfg = ReadConfiguration(); - - if(cfg.Length > 0) - { - Regex rg = new Regex(START_ARGUMENTS_REGEX); - - MatchCollection mc = rg.Matches(cfg); - if(mc.Count > 0) + return cfg; + } + + /// + /// Load saved start configuration + /// + /// + public static string[]? LoadStarters() + { + string? cfg = ReadConfiguration(); + + if (!string.IsNullOrEmpty(cfg)) { - string cfgLine = mc[0].Groups[2].Value; + Regex rg = new Regex(START_ARGUMENTS_REGEX); + + MatchCollection mc = rg.Matches(cfg); + if (mc.Count > 0) + { + string cfgLine = mc[0].Groups[2].Value; - return cfgLine.Split(';'); + return cfgLine.Split(';'); + } } - } - return configArgs; - } + return null; + } + + /// + /// Load saved start configuration + /// + /// + public static string[]? LoadHistory() + { + string? cfg = ReadConfiguration(); + + if (!string.IsNullOrEmpty(cfg)) + { + Regex rg = new Regex(HISTORY_REGEX); + + MatchCollection mc = rg.Matches(cfg); + if (mc.Count > 0) + { + string cfgLine = mc[0].Groups[2].Value; - /// - /// Load saved start configuration - /// - /// - public static string[] LoadHistory() - { - string[] history = null; + return cfgLine.Split(';'); + } + } - string cfg = ReadConfiguration(); + return null; + } - if(cfg.Length > 0) - { - Regex rg = new Regex(HISTORY_REGEX); + /// + /// Load saved start configuration + /// + /// + public static string[]? LoadFileList() + { + string? cfg = ReadConfiguration(); - MatchCollection mc = rg.Matches(cfg); - if(mc.Count > 0) + if (!string.IsNullOrEmpty(cfg)) { - string cfgLine = mc[0].Groups[2].Value; + Regex rg = new Regex(FILE_LIST_REGEX); - return cfgLine.Split(';'); + MatchCollection mc = rg.Matches(cfg); + if (mc.Count > 0) + { + string cfgLine = mc[0].Groups[2].Value; + + return cfgLine.Split(';'); + } } - } - return history; - } + return null; + } - private static string ReadConfiguration() - { - string cfg = ""; + private static string? ReadConfiguration() + { + string cfg = ""; - if(File.Exists(filePath)) - { - try + if (File.Exists(filePath)) { - using(FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) - { - if(fs.Length > 0) - { - using(TextReader sr = new StreamReader(fs, Encoding.UTF8)) - { + try + { + using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); + if (fs.Length > 0) + { + using TextReader sr = new StreamReader(fs, Encoding.UTF8); cfg = sr.ReadToEnd(); - } - } - } - } - catch(FileNotFoundException ex) - { - return null; - } - catch(Exception ex) - { - Console.WriteLine("Error while open config file. " + ex.ToString()); - return null; + } + } + catch (FileNotFoundException ex) + { + return null; + } + catch (Exception ex) + { + Console.WriteLine($"Error while open config file. {ex}"); + return null; + } } - } - return cfg; - } - } + return cfg; + } + } } diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 0f286d1..6a64e54 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -70,7 +70,7 @@ static void Main(string[] args) } else { - string[] savedArgs = Config.LoadStarters(); + string[]? savedArgs = Config.LoadStarters(); if (savedArgs != null) { @@ -234,13 +234,22 @@ static void Main(string[] args) bool exit = false; - string[] history = Config.LoadHistory(); + string[]? history = Config.LoadHistory(); - if (history != null && history.Length > 0) + if (history?.Length > 0) { + UI.CommandHistory.AddRange(history); history = null; } + string[]? fileList = Config.LoadFileList(); + + if (fileList?.Length > 0) + { + UI.FileHistory.AddRange(fileList); + fileList = null; + } + if (continuousMode) { while (!exit) @@ -1178,7 +1187,8 @@ private static void PrintHelp() /// private static void Exit() { - Config.SaveHistory(UI.CommandHistory.ToArray()); + Config.SaveHistory(UI.CommandHistory); + Config.SaveFileList(UI.FileHistory); } } } From 690ce109a1ea7e445c5e5972e62823d6b24f5865 Mon Sep 17 00:00:00 2001 From: docbender Date: Sun, 27 Feb 2022 23:50:37 +0100 Subject: [PATCH 07/18] Configuration fix --- SerialMonitor/Config.cs | 19 ++++++++++++------- SerialMonitor/Program.cs | 3 +++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/SerialMonitor/Config.cs b/SerialMonitor/Config.cs index d6e8088..7631988 100644 --- a/SerialMonitor/Config.cs +++ b/SerialMonitor/Config.cs @@ -134,7 +134,7 @@ private static string ReadConfigFileAndPrepareSave(string itemName, string newCo cfg = sr.ReadToEnd(); } - Regex rg = new Regex(itemName); + Regex rg = new Regex($"{itemName}.*"); if (rg.IsMatch(cfg)) cfg = rg.Replace(cfg, newConfigRecord); else @@ -188,10 +188,12 @@ private static string ReadConfigFileAndPrepareSave(string itemName, string newCo { Regex rg = new Regex(HISTORY_REGEX); - MatchCollection mc = rg.Matches(cfg); - if (mc.Count > 0) + Match mc = rg.Match(cfg); + if (mc.Success) { - string cfgLine = mc[0].Groups[2].Value; + string cfgLine = mc.Groups[2].Value; + if (string.IsNullOrEmpty(cfgLine)) + return null; return cfgLine.Split(';'); } @@ -212,10 +214,13 @@ private static string ReadConfigFileAndPrepareSave(string itemName, string newCo { Regex rg = new Regex(FILE_LIST_REGEX); - MatchCollection mc = rg.Matches(cfg); - if (mc.Count > 0) + Match mc = rg.Match(cfg); + if (mc.Success) { - string cfgLine = mc[0].Groups[2].Value; + string cfgLine = mc.Groups[2].Value; + + if (string.IsNullOrEmpty(cfgLine)) + return null; return cfgLine.Split(';'); } diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 6a64e54..a67b870 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -250,6 +250,7 @@ static void Main(string[] args) fileList = null; } + if (continuousMode) { while (!exit) @@ -290,6 +291,8 @@ static void Main(string[] args) } return true; }); + + Exit(); } } From 85d8f72b59a872ffb2296012cfcf7eaf95699a1b Mon Sep 17 00:00:00 2001 From: docbender Date: Mon, 28 Feb 2022 17:25:14 +0100 Subject: [PATCH 08/18] Commandline --- SerialMonitor/Program.cs | 142 +++++++++------------------------------ SerialMonitor/UI.cs | 68 +++++++++++++++++-- 2 files changed, 94 insertions(+), 116 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index a67b870..0bb2b34 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -45,6 +45,8 @@ class Program /// static byte[] incoming = new byte[32]; + static readonly SerialPort port = new SerialPort(); + /// /// Main loop @@ -130,7 +132,11 @@ static void Main(string[] args) stopBits = StopBits.None; } - SerialPort port = new SerialPort(portName, baudrate, parity, dataBits, stopBits); + port.PortName = portName; + port.BaudRate = baudrate; + port.Parity = parity; + port.DataBits = dataBits; + port.StopBits = stopBits; port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived); port.PinChanged += new SerialPinChangedEventHandler(port_PinChanged); @@ -273,6 +279,7 @@ static void Main(string[] args) UI.ActionSendFile = (file) => { UserDataSendFile(port, file); }; UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); }; + UI.ActionCommand = (text) => { ProcessCommand(text); }; UI.SetPortStatus(port); UI.Run((loop) => @@ -296,115 +303,21 @@ static void Main(string[] args) } } - /* - return; - #if __MonoCS__ - if(port.BytesToRead > 0) - port_DataReceived(port, null); - else - { - _pinsStatesNow = (SerialPinChange)(Convert.ToInt32(port.CtsHolding) * ((int)SerialPinChange.CtsChanged) - | Convert.ToInt32(port.CDHolding) * ((int)SerialPinChange.CDChanged) - | Convert.ToInt32(port.DsrHolding) * ((int)SerialPinChange.DsrChanged) - | Convert.ToInt32(port.BreakState) * ((int)SerialPinChange.Break)); - - if(_pinsStatesNow != _pinsStatesOld) - { - SerialPinChange _pinsStatesChange = _pinsStatesNow ^ _pinsStatesOld; - - port_PinChanged(port, _pinsStatesChange); - _pinsStatesOld = _pinsStatesNow; - } - Thread.Sleep(100); - } - #else - Thread.Sleep(100); - #endif - CommandEnum cmd = Cinout.ConsoleReadCommand(!continuousMode); - if (cmd == CommandEnum.EXIT) - { - Exit(); - port.Close(); - exit = true; - } - - switch (cmd) - { - case CommandEnum.PAUSE: - pausePrint = !pausePrint; - if (pausePrint) - consoleWriteLine("Print paused"); - else - consoleWriteLine("Print resumed"); - - if (!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - case CommandEnum.CONNECT: - connectCommand(port); - if (!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - case CommandEnum.HELP: - printHelp(); - break; - case CommandEnum.SEND: - if (continuousMode) - consoleWriteLineNoTrace("Type message to send: "); - else - Cinout.StartSendDataType(); - - string line = Cinout.ConsoleReadLine(!continuousMode); - - if (!continuousMode) - Cinout.EndSendDataType(); - - if (line != null) - { - if (userDataSend(port, line)) - consoleWriteLine("Sent: {0}", line); - } - break; - case CommandEnum.SEND_FILE: - if (continuousMode) - consoleWriteLineNoTrace("Type file to send: "); - else - Cinout.StartSendFile(); - - string filepath = Cinout.ConsoleReadLine(!continuousMode); - - if (!continuousMode) - Cinout.EndSendFile(); - - if (filepath != null) - { - if (userDataSendFile(port, filepath)) - consoleWriteLine("Sent file: {0}", filepath); - } - break; - case CommandEnum.RTS: - port.RtsEnable = !port.RtsEnable; - writePinStatus(port); - break; - case CommandEnum.DTR: - port.DtrEnable = !port.DtrEnable; - writePinStatus(port); - break; - case CommandEnum.FORMAT: - showAscii = !showAscii; - - if (!continuousMode) - Cinout.WriteMenuBar(showAscii, pausePrint, pauseConnection); - break; - } - - if (!pauseConnection && !port.IsOpen) - { - consoleWriteLine(" Port disconnected...."); - portConnectInfinite(port); - } - } - */ + /// + /// Process command from command line + /// + /// + private static void ProcessCommand(string? text) + { + if (string.IsNullOrEmpty(text)) + return; + if (text.Equals("help")) + PrintHelp(); + else if (text.StartsWith("send ")) + UserDataSend(port, text.Substring(5)); + else + ConsoleWriteLineNoTrace($"Unknown command: {text}"); + } /// /// Send tada typed by user @@ -1157,7 +1070,7 @@ private static void PrintHelp() ConsoleWriteLineNoTrace(" serialmonitor COM83 -baudrate 19200 -repeatfile protocol.txt"); ConsoleWriteLineNoTrace(""); - ConsoleWriteLineNoTrace("In program commands:"); + ConsoleWriteLineNoTrace("Program shortcuts:"); ConsoleWriteLineNoTrace("F1: print help"); ConsoleWriteLineNoTrace("F2: pause/resume print on screen"); ConsoleWriteLineNoTrace("F3: toggle between data print format (HEX / ASCII)"); @@ -1165,10 +1078,15 @@ private static void PrintHelp() ConsoleWriteLineNoTrace("F5: send specified data (in HEX format if data start with 0x otherwise ASCII is send)"); ConsoleWriteLineNoTrace("F6: send specified file)"); - ConsoleWriteLineNoTrace("F10 or ^C: program exit"); + ConsoleWriteLineNoTrace("F10: program exit"); ConsoleWriteLineNoTrace("F11: toggle RTS pin"); ConsoleWriteLineNoTrace("F12: toggle DTR pin"); + ConsoleWriteLineNoTrace(""); + ConsoleWriteLineNoTrace("In program commands:"); + ConsoleWriteLineNoTrace("help: print help"); + ConsoleWriteLineNoTrace("send : send message"); + if (continuousMode) { ConsoleWriteLineNoTrace(""); diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 7c0c7bd..97d4c0e 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -38,6 +38,7 @@ internal class UI public static Action? ActionSendFile; public static Action? ActionRts; public static Action? ActionDtr; + public static Action? ActionCommand; // data view static readonly ListView logView = new ListView() @@ -67,7 +68,7 @@ public static void Init() Application.QuitKey = Key.F10; win.KeyUp += (e) => { - ProcessHotKey(e.KeyEvent); + e.Handled = ProcessHotKey(e.KeyEvent); }; // set colorscheme win.ColorScheme = Colors.TopLevel; @@ -93,10 +94,61 @@ public static void Init() Height = Dim.Fill() - 1, Text = "text" }; + // command textfield + var commandlabel = new Label(">") + { + X = 0, + Y = Pos.Bottom(frameData), + }; + commandlabel.ColorScheme = Colors.Dialog; + var commandline = new TextField() + { + X = 1, + Y = Pos.Bottom(frameData), + Width = Dim.Fill(), - // compose + }; + int commandId = -1; + commandline.KeyPress += (e) => + { + switch (e.KeyEvent.Key) + { + case Key.CursorUp: + e.Handled = true; + if (!CommandHistory.Any()) + return; + if (commandId == -1) + commandId = CommandHistory.Count - 1; + else if (commandId == 0) + return; + else + commandId--; + commandline.Text = CommandHistory[commandId]; + break; + case Key.CursorDown: + e.Handled = true; + if (!CommandHistory.Any()) + return; + if (commandId < 0 || commandId + 1 >= CommandHistory.Count) + return; + commandline.Text = CommandHistory[++commandId]; + break; + case Key.Enter: + e.Handled = true; + commandId = -1; + string? text = commandline.Text.ToString(); + if (string.IsNullOrEmpty(text)) + return; + commandline.Text = ""; + if (!CommandHistory.Any() || !CommandHistory.Last().Equals(text)) + CommandHistory.Add(text); + ActionCommand?.Invoke(text); + break; + } + }; + // compose frameData.Add(logView); - win.Add(frameStatus, frameData); + win.Add(frameStatus, frameData, commandlabel, commandline); Application.Top.Add(win); // scrollbar for textview var _scrollBar = new ScrollBarView(logView, true); @@ -116,15 +168,17 @@ public static void Init() _scrollBar.Position = logView.SelectedItem; _scrollBar.Refresh(); }; + // add shortcut menu Application.Top.Add(menu); menu.Y = Pos.Bottom(Application.Top) - 1; SetBottomMenuText(); // bind log data logView.SetSource(lines); + commandline.SetFocus(); } - private static void ProcessHotKey(KeyEvent keyEvent) + private static bool ProcessHotKey(KeyEvent keyEvent) { if (keyEvent.Key == Key.F1) { @@ -295,6 +349,12 @@ private static void ProcessHotKey(KeyEvent keyEvent) { ActionDtr?.Invoke(); } + else + { + return false; + } + + return true; //int calcDlgHeight() //{ From 406911e953905a226a3e837cb7d7ab38e108d95f Mon Sep 17 00:00:00 2001 From: docbender Date: Tue, 1 Mar 2022 23:39:43 +0100 Subject: [PATCH 09/18] Fix open/close shortcut --- SerialMonitor/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 0bb2b34..0a1685c 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -274,7 +274,7 @@ static void Main(string[] args) UI.ActionHelp = () => { PrintHelp(); }; UI.ActionPrint = (print) => { pausePrint = !print; }; UI.ActionPrintAsHex = (hex) => { showAscii = !hex; }; - UI.ActionOpenClose = (close) => { pauseConnection = close; }; + UI.ActionOpenClose = (close) => { pauseConnection = close; if (close) port.Close(); UI.SetPortStatus(port); }; UI.ActionSend = (data) => { UserDataSend(port,data); }; UI.ActionSendFile = (file) => { UserDataSendFile(port, file); }; UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; @@ -284,7 +284,7 @@ static void Main(string[] args) UI.SetPortStatus(port); UI.Run((loop) => { - if (!port.IsOpen) + if (!port.IsOpen && !pauseConnection) { if (lastTry.AddSeconds(5) <= DateTime.Now) { From c22d4511d0c800ecc32cb571034eeab4d15ec9b1 Mon Sep 17 00:00:00 2001 From: docbender Date: Fri, 4 Mar 2022 20:38:49 +0100 Subject: [PATCH 10/18] Setting --- SerialMonitor/Config.cs | 130 +++++++++++++++------------ SerialMonitor/Program.cs | 190 ++++++++++++++++++++------------------- SerialMonitor/Setting.cs | 26 ++++++ SerialMonitor/UI.cs | 84 +++++++++++++++-- 4 files changed, 270 insertions(+), 160 deletions(-) create mode 100644 SerialMonitor/Setting.cs diff --git a/SerialMonitor/Config.cs b/SerialMonitor/Config.cs index 7631988..e3f55ec 100644 --- a/SerialMonitor/Config.cs +++ b/SerialMonitor/Config.cs @@ -8,10 +8,7 @@ // //--------------------------------------------------------------------------- -using System; -using System.Collections.Generic; using System.Text; -using System.IO; using System.Text.RegularExpressions; namespace SerialMonitor @@ -19,14 +16,19 @@ namespace SerialMonitor class Config { const string CONFIG_FILE = "serialmonitor.cfg"; - const string START_ARGUMENTS = "StartArgs="; - const string START_ARGUMENTS_REGEX = "(" + START_ARGUMENTS + ")([^\n]*)"; - const string HISTORY = "CommandHistory="; - const string FILE_LIST = "FileList="; - const string HISTORY_REGEX = "(" + HISTORY + ")([^\n]*)"; - const string FILE_LIST_REGEX = "(" + FILE_LIST + ")([^\n]*)"; - - static readonly string filePath = Path.Combine(Directory.GetCurrentDirectory(),CONFIG_FILE); + const string START_ARGUMENTS = "StartArgs"; + const string START_ARGUMENTS_REGEX = "(" + START_ARGUMENTS + "=)([^\n]*)"; + const string HISTORY = "CommandHistory"; + const string FILE_LIST = "FileList"; + const string HISTORY_REGEX = "(" + HISTORY + "=)([^\n]*)"; + const string FILE_LIST_REGEX = "(" + FILE_LIST + "=)([^\n]*)"; + public const string SETTING_PORT = "Port"; + public const string SETTING_BAUDRATE = "BaudRate"; + public const string SETTING_SHOWTIME = "ShowTime"; + public const string SETTING_SHOWTIMEGAP = "ShowTimeGap"; + public const string SETTING_SHOWSENTDATA = "ShowSentData"; + + static readonly string filePath = Path.Combine(Directory.GetCurrentDirectory(), CONFIG_FILE); /// /// Save started parameters @@ -35,12 +37,7 @@ class Config /// public static bool SaveStarters(string[] args) { - string cfgRecord = START_ARGUMENTS + String.Join(";", args); - - string cfg = ReadConfigFileAndPrepareSave(START_ARGUMENTS_REGEX, cfgRecord); - - if (string.IsNullOrEmpty(cfg)) - cfg = cfgRecord; + string cfg = ReadConfigFileAndPrepareSave(START_ARGUMENTS, String.Join(";", args)); return SaveConfigFile(cfg); } @@ -52,12 +49,7 @@ public static bool SaveStarters(string[] args) /// public static bool SaveHistory(IEnumerable args) { - string cfgRecord = HISTORY + String.Join(";", args); - - string cfg = ReadConfigFileAndPrepareSave(HISTORY, cfgRecord); - - if (string.IsNullOrEmpty(cfg)) - cfg = cfgRecord; + string cfg = ReadConfigFileAndPrepareSave(HISTORY, String.Join(";", args)); return SaveConfigFile(cfg); } @@ -69,12 +61,28 @@ public static bool SaveHistory(IEnumerable args) /// public static bool SaveFileList(IEnumerable args) { - string cfgRecord = FILE_LIST + String.Join(";", args); + string cfg = ReadConfigFileAndPrepareSave(FILE_LIST, String.Join(";", args)); - string cfg = ReadConfigFileAndPrepareSave(FILE_LIST, cfgRecord); + return SaveConfigFile(cfg); + } - if (string.IsNullOrEmpty(cfg)) - cfg = cfgRecord; + /// + /// Save user setting + /// + /// + /// + /// + /// + /// + /// + internal static bool SaveSetting(string device, int baudrate, bool showTime, bool showTimeGap, bool showSentData) + { + string? cfg = ReadConfiguration(); + cfg = PrepareSave(cfg, SETTING_PORT, device); + cfg = PrepareSave(cfg, SETTING_BAUDRATE, baudrate.ToString()); + cfg = PrepareSave(cfg, SETTING_SHOWTIME, showTime ? "1" : "0"); + cfg = PrepareSave(cfg, SETTING_SHOWTIMEGAP, showTimeGap ? "1" : "0"); + cfg = PrepareSave(cfg, SETTING_SHOWSENTDATA, showSentData ? "1" : "0"); return SaveConfigFile(cfg); } @@ -116,40 +124,32 @@ private static bool SaveConfigFile(string configuration) /// Prepare configuration file /// /// - /// + /// /// - private static string ReadConfigFileAndPrepareSave(string itemName, string newConfigRecord) + private static string ReadConfigFileAndPrepareSave(string itemName, string itemValue) { - string cfg = ""; + return PrepareSave(ReadConfiguration(), itemName, itemValue); + } - if (File.Exists(filePath)) - { - try - { - using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); - if (fs.Length > 0) - { - using (TextReader sr = new StreamReader(fs, Encoding.UTF8)) - { - cfg = sr.ReadToEnd(); - } - - Regex rg = new Regex($"{itemName}.*"); - if (rg.IsMatch(cfg)) - cfg = rg.Replace(cfg, newConfigRecord); - else - cfg += "\n" + newConfigRecord; - } - } - catch (FileNotFoundException ex) - { - } - catch (Exception ex) - { - Console.WriteLine($"Error while open config file. {ex}"); - } - } - return cfg; + /// + /// Replace old configuration record per item + /// + /// + /// + /// + /// + private static string PrepareSave(string? configuration, string itemName, string itemValue) + { + var record = $"{itemName}={itemValue}"; + if (string.IsNullOrEmpty(configuration)) + return record; + + Regex rg = new Regex($"{itemName}=.*"); + if (rg.IsMatch(configuration)) + configuration = rg.Replace(configuration, record); + else + configuration += "\n" + record; + return configuration; } /// @@ -229,6 +229,20 @@ private static string ReadConfigFileAndPrepareSave(string itemName, string newCo return null; } + internal static string? LoadSetting(string parameterName) + { + string? cfg = ReadConfiguration(); + + if (string.IsNullOrEmpty(cfg)) + return null; + + Regex rg = new Regex($"{parameterName}=(.*)"); + Match mc = rg.Match(cfg); + if (mc.Success) + return mc.Groups[1].Value; + return null; + } + private static string? ReadConfiguration() { string cfg = ""; diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 0a1685c..3326d64 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -19,7 +19,7 @@ class Program { static readonly ArgumentCollection arguments = new ArgumentCollection(new string[] { "baudrate", "parity", "databits", "stopbits", "repeatfile", "logfile", "logincomingonly", "showascii", "notime", "gaptolerance", "continuousmode", "nogui" }); - static readonly string version = System.Reflection.Assembly.GetEntryAssembly().GetName().Version?.ToString(3); + static readonly string? version = System.Reflection.Assembly.GetEntryAssembly()?.GetName().Version?.ToString(3); static long lastTimeReceved = 0; static bool repeaterEnabled = false; static bool repeaterUseHex = false; @@ -28,7 +28,6 @@ class Program static bool logfile = false; static bool logincomingonly = false; static string logFilename = ""; - static bool noTime = false; static int gapTolerance = 0; static bool gapToleranceEnable = false; static bool continuousMode = false; @@ -44,10 +43,15 @@ class Program /// Incoming data buffer /// static byte[] incoming = new byte[32]; - + /// + /// Setting data + /// + static readonly Setting setting = new Setting(); + /// + /// Port instance + /// static readonly SerialPort port = new SerialPort(); - /// /// Main loop /// @@ -55,7 +59,7 @@ class Program static void Main(string[] args) { DateTime lastTry = DateTime.MinValue; - string portName = System.OperatingSystem.IsWindows() ? "COM3" : "/dev/ttyS1"; + setting.Port = System.OperatingSystem.IsWindows() ? "COM1" : "/dev/ttyS1"; if (args.Length > 0) { @@ -68,7 +72,7 @@ static void Main(string[] args) return; } else - portName = args[0]; + setting.Port = args[0]; } else { @@ -76,71 +80,91 @@ static void Main(string[] args) if (savedArgs != null) { - portName = savedArgs[0]; + setting.Port = savedArgs[0]; args = savedArgs; } - } + else + { + string? value = Config.LoadSetting(Config.SETTING_PORT); + if (!string.IsNullOrEmpty(value)) + setting.Port = value; + } + } + // parse commandline arguments arguments.Parse(args); - continuousMode = arguments.GetArgument("continuousmode").Enabled || arguments.GetArgument("nogui").Enabled; ; + continuousMode = arguments.GetArgument("continuousmode").Enabled || arguments.GetArgument("nogui").Enabled; if (!continuousMode) UI.Init(); else ConsoleWriteLineNoTrace($"SerialMonitor v.{version}"); - - showAscii = arguments.GetArgument("showascii").Enabled; - noTime = arguments.GetArgument("notime").Enabled; - - int baudrate = 9600; - Parity parity = Parity.None; - int dataBits = 8; - StopBits stopBits = StopBits.One; + + setting.BaudRate = 9600; + setting.Parity = Parity.None; + setting.DataBits = 8; + setting.StopBits = StopBits.One; Argument arg = arguments.GetArgument("baudrate"); if (arg.Enabled) - int.TryParse(arg.Parameter, out baudrate); + { + int.TryParse(arg.Parameter, out setting.BaudRate); + } + else + { + string? value = Config.LoadSetting(Config.SETTING_BAUDRATE); + if (!string.IsNullOrEmpty(value)) + int.TryParse(value, out setting.BaudRate); + } arg = arguments.GetArgument("parity"); if (arg.Enabled) { if (arg.Parameter.ToLower().Equals("odd")) - parity = Parity.Odd; + setting.Parity = Parity.Odd; else if (arg.Parameter.ToLower().Equals("even")) - parity = Parity.Even; + setting.Parity = Parity.Even; else if (arg.Parameter.ToLower().Equals("mark")) - parity = Parity.Mark; + setting.Parity = Parity.Mark; else if (arg.Parameter.ToLower().Equals("space")) - parity = Parity.Space; + setting.Parity = Parity.Space; } arg = arguments.GetArgument("databits"); if (arg.Enabled) - int.TryParse(arg.Parameter, out dataBits); + int.TryParse(arg.Parameter, out setting.DataBits); arg = arguments.GetArgument("stopbits"); if (arg.Enabled) { if (arg.Parameter.ToLower().Equals("1")) - stopBits = StopBits.One; + setting.StopBits = StopBits.One; else if (arg.Parameter.ToLower().Equals("1.5")) - stopBits = StopBits.OnePointFive; + setting.StopBits = StopBits.OnePointFive; else if (arg.Parameter.ToLower().Equals("2")) - stopBits = StopBits.Two; + setting.StopBits = StopBits.Two; else if (arg.Parameter.ToLower().Equals("0")) - stopBits = StopBits.None; + setting.StopBits = StopBits.None; } - port.PortName = portName; - port.BaudRate = baudrate; - port.Parity = parity; - port.DataBits = dataBits; - port.StopBits = stopBits; + port.PortName = setting.Port; + port.BaudRate = setting.BaudRate; + port.Parity = setting.Parity; + port.DataBits = setting.DataBits; + port.StopBits = setting.StopBits; port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); port.ErrorReceived += new SerialErrorReceivedEventHandler(port_ErrorReceived); port.PinChanged += new SerialPinChangedEventHandler(port_PinChanged); + arg = arguments.GetArgument("notime"); + if (arg.Enabled) + setting.ShowTime = false; + else + setting.ShowTime = Config.LoadSetting(Config.SETTING_SHOWTIME) != "0"; + + showAscii = arguments.GetArgument("showascii").Enabled; + //log option arg = arguments.GetArgument("logfile"); if (arg.Enabled) @@ -270,7 +294,9 @@ static void Main(string[] args) } } else - { + { + setting.ShowTimeGap = Config.LoadSetting(Config.SETTING_SHOWTIMEGAP) == "1"; + setting.ShowSentData = Config.LoadSetting(Config.SETTING_SHOWSENTDATA) == "1"; UI.ActionHelp = () => { PrintHelp(); }; UI.ActionPrint = (print) => { pausePrint = !print; }; UI.ActionPrintAsHex = (hex) => { showAscii = !hex; }; @@ -280,6 +306,29 @@ static void Main(string[] args) UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); }; UI.ActionCommand = (text) => { ProcessCommand(text); }; + UI.ActionSettingLoad = () => { return setting; }; + UI.ActionSettingSave = (setting) => { + if(port.PortName != setting.Port || port.BaudRate != setting.BaudRate) + { + if (port.IsOpen) + { + pauseConnection = true; + port.Close(); + port.PortName = setting.Port; + port.BaudRate = setting.BaudRate; + pauseConnection = false; + port.Open(); + } + else + { + port.PortName = setting.Port; + port.BaudRate = setting.BaudRate; + } + UI.SetPortStatus(port); + } + + return Config.SaveSetting(setting.Port, setting.BaudRate, setting.ShowTime, setting.ShowTimeGap, setting.ShowSentData); + }; UI.SetPortStatus(port); UI.Run((loop) => @@ -399,10 +448,13 @@ private static bool UserDataSend(SerialPort port, string? line) { port.Write(data, 0, data.Length); - if (noTime) - ConsoleWriteCommunication(ConsoleColor.Green, "\n" + line); - else - ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + line); + if (setting.ShowSentData) + { + if (!setting.ShowTime) + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + line); + else + ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + line); + } } catch (Exception ex) { @@ -516,37 +568,7 @@ private static void PortClose(SerialPort port) if (port.IsOpen) port.Close(); } - /* - /// - /// Provide connect (pause/resume) command - /// - private static void connectCommand(SerialPort port) - { - pauseConnection = !pauseConnection; - - if (pauseConnection) - { - consoleWriteLine(" Connection paused. Port closed."); - port.Close(); - - UI.SetPortStatus(port); - } - else - { - consoleWriteLine(" Resuming connection..."); - - portConnectInfinite(port); - - if (port.IsOpen) - { - consoleWriteLine(" Connection resumed"); - - UI.SetPortStatus(port); - UI.SetPinStatus(port); - } - } - } - */ + /// /// Validating file name(path) /// @@ -763,7 +785,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) double sinceLastReceive = ((double)(time.Ticks - lastTimeReceved) / 10000); applyGapTolerance = (gapToleranceEnable && sinceLastReceive <= gapTolerance); - if (!noTime && (!gapToleranceEnable || !applyGapTolerance)) + if (setting.ShowTimeGap && (!gapToleranceEnable || !applyGapTolerance)) ConsoleWriteCommunication(ConsoleColor.Magenta, "\n+" + sinceLastReceive.ToString("F3") + " ms"); } @@ -772,14 +794,14 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) if (showAscii) { - if (noTime || applyGapTolerance) + if (!setting.ShowTime || applyGapTolerance) line = ASCIIEncoding.ASCII.GetString(incoming,0,byteCount); else line = time.ToString() + " " + Encoding.ASCII.GetString(incoming, 0, byteCount); } else { - if (noTime || applyGapTolerance) + if (!setting.ShowTime || applyGapTolerance) line = string.Join(" ", incoming.Take(byteCount).Select(x=> $"0x{x:X2}")); else line = time.ToString() + " " + string.Join(" ", incoming.Take(byteCount).Select(x => $"0x{x:X2}")); @@ -836,7 +858,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) data[i] = Convert.ToByte(answer.Substring(2 * i, 2), 16); } - if (noTime) + if (!setting.ShowTime) ConsoleWriteCommunication(ConsoleColor.Green, string.Join("\n ", Array.ConvertAll(data, x => $"0x{x:X2}"))); else ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + string.Join(" ", Array.ConvertAll(data, x => $"0x{x:X2}"))); @@ -856,7 +878,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) { string answer = repeaterMap[ask]; - if (noTime) + if (!setting.ShowTime) ConsoleWriteCommunication(ConsoleColor.Green, "\n" + answer); else ConsoleWriteCommunication(ConsoleColor.Green, "\n" + DateTime.Now.TimeOfDay.ToString() + " " + answer); @@ -1001,25 +1023,6 @@ private static void ConsoleWriteCommunication(ConsoleColor color, string message Trace.Write(string.Format(message, parameters)); } - ///// - ///// Print line that is involved in communication - ///// - ///// - ///// - //private static void consoleWriteLineCommunication(string message, params object[] parameters) - //{ - // if(!pausePrint) - // { - // if(!continuousMode) - // Cinout.WriteLine(message, parameters); - // else - // consoleWriteLine(message, parameters); - // } - - // if(logfile) - // Trace.WriteLine(string.Format(message, parameters)); - //} - /// /// Move console cursor in current line /// @@ -1062,7 +1065,7 @@ private static void PrintHelp() ConsoleWriteLineNoTrace("-showascii: communication would be show in ASCII format (otherwise HEX is used)"); ConsoleWriteLineNoTrace("-notime: time information about incoming data would not be printed"); ConsoleWriteLineNoTrace("-gaptolerance {{time gap in ms}}: messages received within specified time gap will be printed together"); - ConsoleWriteLineNoTrace("-continuousmode or -nogui: start program in normal console mode (scrolling list). Not with primitive text GUI"); + ConsoleWriteLineNoTrace("-nogui: start program in normal console mode (scrolling list). Not with primitive text GUI"); ConsoleWriteLineNoTrace(""); ConsoleWriteLineNoTrace("Example: serialmonitor COM1"); @@ -1081,6 +1084,7 @@ private static void PrintHelp() ConsoleWriteLineNoTrace("F10: program exit"); ConsoleWriteLineNoTrace("F11: toggle RTS pin"); ConsoleWriteLineNoTrace("F12: toggle DTR pin"); + ConsoleWriteLineNoTrace("^F12: setting"); ConsoleWriteLineNoTrace(""); ConsoleWriteLineNoTrace("In program commands:"); diff --git a/SerialMonitor/Setting.cs b/SerialMonitor/Setting.cs new file mode 100644 index 0000000..57d32f2 --- /dev/null +++ b/SerialMonitor/Setting.cs @@ -0,0 +1,26 @@ +//--------------------------------------------------------------------------- +// +// Name: Program.cs +// Author: Vita Tucek +// Created: 4.3.2022 +// License: MIT +// Description: setting +// +//--------------------------------------------------------------------------- + +using System.IO.Ports; + +namespace SerialMonitor +{ + public class Setting + { + public string Port; + public int BaudRate; + public Parity Parity; + public int DataBits; + public StopBits StopBits; + public bool ShowTime; + public bool ShowTimeGap; + public bool ShowSentData; + } +} diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 97d4c0e..1ca8e5b 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -1,4 +1,14 @@ -using System.IO.Ports; +//--------------------------------------------------------------------------- +// +// Name: Program.cs +// Author: Vita Tucek +// Created: 20.2.2022 +// License: MIT +// Description: UI +// +//--------------------------------------------------------------------------- + +using System.IO.Ports; using Terminal.Gui; namespace SerialMonitor @@ -20,7 +30,7 @@ internal class UI static readonly Label pinBreak = new Label() { Text = "Break(?)", X = Pos.Right(pinCD) + 2, Y = 1 }; static readonly Label timeLabel = new Label() { Text = "", X = 50, Y = 0 }; - static readonly Label debugLabel = new Label() { Text = "", X = 40, Y = 0 }; + // properties public static bool PrintToLogView { get; set; } = true; public static bool PrintAsHexToLogView { get; set; } = true; @@ -39,6 +49,8 @@ internal class UI public static Action? ActionRts; public static Action? ActionDtr; public static Action? ActionCommand; + public static Func? ActionSettingLoad; + public static Func? ActionSettingSave; // data view static readonly ListView logView = new ListView() @@ -82,7 +94,7 @@ public static void Init() }; frameStatus.Add(portLabel, pinsLabel, portName, portStatus, portSpeed, - pinRTS, pinCTS, pinDTR, pinDSR, pinCD, pinBreak, debugLabel, timeLabel); + pinRTS, pinCTS, pinDTR, pinDSR, pinCD, pinBreak, timeLabel); timeLabel.X = Pos.Right(frameStatus) - 10; // data frame @@ -130,13 +142,17 @@ public static void Init() if (!CommandHistory.Any()) return; if (commandId < 0 || commandId + 1 >= CommandHistory.Count) + { + if(!commandline.Text.IsEmpty) + commandline.Text = ""; return; + } commandline.Text = CommandHistory[++commandId]; break; case Key.Enter: e.Handled = true; commandId = -1; - string? text = commandline.Text.ToString(); + string? text = commandline.Text.ToString(); if (string.IsNullOrEmpty(text)) return; commandline.Text = ""; @@ -345,9 +361,61 @@ private static bool ProcessHotKey(KeyEvent keyEvent) { ActionRts?.Invoke(); } - else if (keyEvent.Key == Key.F12) + else if ((keyEvent.Key & Key.F12) == Key.F12) { - ActionDtr?.Invoke(); + if (keyEvent.IsCtrl) + { + var ok = new Button("Ok"); + var cancel = new Button("Cancel"); + var dialog = new Dialog("Setting", 50, 11, ok, cancel); + var lbPort = new Label("Port:") { X = 1, Y = 1 }; + var lbSpeed = new Label("Baud rate:") { X = 1, Y = 2 }; + var tbPort = new TextField() { X = 15, Y = 1, Width = 15, Text = "" }; + var tbSpeed = new TextField() { X = 15, Y = 2, Width = 10, Text = "" }; + var cbTime = new CheckBox("Show transaction time") { X = 1, Y = 4 }; + var cbTimeGap = new CheckBox("Show time between 2 transactions") { X = 1, Y = 5 }; + var cbSent = new CheckBox("Show sent data") { X = 1, Y = 6 }; + + dialog.Add(lbPort, lbSpeed, tbPort, tbSpeed, cbTime, cbTimeGap, cbSent); + + if (ActionSettingLoad == null) + return false; + + Setting setting = ActionSettingLoad.Invoke(); + + tbPort.Text = setting.Port; + tbSpeed.Text = setting.BaudRate.ToString(); + cbTime.Checked = setting.ShowTime; + cbTimeGap.Checked = setting.ShowTimeGap; + cbSent.Checked = setting.ShowSentData; + + ok.Clicked += () => + { + var port = tbPort.Text.ToString(); + if (string.IsNullOrEmpty(port) || !int.TryParse(tbSpeed.Text.ToString(), out int baudrate)) + return; + + setting.Port = port; + setting.BaudRate = baudrate; + setting.ShowTime = cbTime.Checked; + setting.ShowTimeGap = cbTimeGap.Checked; + setting.ShowSentData = cbSent.Checked; + + if (ActionSettingSave?.Invoke(setting) == true) + { + Application.RequestStop(); + } + }; + cancel.Clicked += () => + { + Application.RequestStop(); + }; + Application.Run(dialog); + } + else + { + ActionDtr?.Invoke(); + } } else { @@ -364,7 +432,7 @@ private static bool ProcessHotKey(KeyEvent keyEvent) private static void SetBottomMenuText() { - menu.Text = $" F1 Help | F2 {(!PrintToLogView ? "Print " : "No Print")} | F3 {(!PrintAsHexToLogView ? "Hex " : "Text")} | F4 {(!RequestPortClose ? "Close" : "Open ")} | F5 Send | F6 SendFile | F10 Exit | F11 RTS | F12 DTR"; + menu.Text = $" F1 Help | F2 {(!PrintToLogView ? "Print " : "No Print")} | F3 {(!PrintAsHexToLogView ? "Hex " : "Text")} | F4 {(!RequestPortClose ? "Close" : "Open ")} | F5 Send | F6 SendFile | F10 Exit | F11 RTS | F12 DTR | ^F12 Setting"; } public static void Run(Func action) @@ -399,8 +467,6 @@ internal static void WriteLine(string message, ConsoleColor color = ConsoleColor if (logView.SelectedItem >= lines.Count - 2) logView.MoveDown(); - - debugLabel.Text = $"xx/{lines.Count}"; } internal static void WriteLine(string message, object[] parameters, ConsoleColor color = ConsoleColor.White) From 96af394eae8259b8a5193ecffaa4a4faa3746c1b Mon Sep 17 00:00:00 2001 From: docbender Date: Fri, 4 Mar 2022 20:45:21 +0100 Subject: [PATCH 11/18] Send file --- SerialMonitor/Program.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 3326d64..f573101 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -481,9 +481,20 @@ private static bool UserDataSendFile(SerialPort port, string? filePath) return false; } - ConsoleWriteError("Not implemented"); - //TODO: file send - return false; + try + { + var data = File.ReadAllBytes(filePath); + port.Write(data, 0, data.Length); + + ConsoleWriteLineNoTrace(ConsoleColor.White, "File sent."); + } + catch (Exception ex) + { + ConsoleWriteError(ex.ToString()); + + return false; + } + return true; } /// From aad56c38fa55f57bcb6f8f4ef8e486376abbcd77 Mon Sep 17 00:00:00 2001 From: docbender Date: Fri, 4 Mar 2022 21:13:11 +0100 Subject: [PATCH 12/18] Simplify text formatting --- SerialMonitor/Program.cs | 75 ++++++++++++++++++---------------------- SerialMonitor/UI.cs | 17 +++------ 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index f573101..19a1102 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -260,7 +260,7 @@ static void Main(string[] args) PrepareRepeatFile(repeatfile.Parameter); } - ConsoleWriteLine("Opening port {0}: baudrate={1}b/s, parity={2}, databits={3}, stopbits={4}", port.PortName, port.BaudRate.ToString(), port.Parity.ToString(), port.DataBits.ToString(), port.StopBits.ToString()); + ConsoleWriteLine($"Opening port {port.PortName}: baudrate={port.BaudRate}b/s, parity={port.Parity}, databits={port.DataBits}, stopbits={port.StopBits}"); bool exit = false; @@ -280,7 +280,6 @@ static void Main(string[] args) fileList = null; } - if (continuousMode) { while (!exit) @@ -591,7 +590,7 @@ private static bool IsFileNameValid(string filePath) { if (filePath.Contains(c.ToString())) { - ConsoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); + ConsoleWriteError($"File name {filePath} contains invalid character [{c}]. Enter right file name."); return false; } @@ -601,7 +600,7 @@ private static bool IsFileNameValid(string filePath) { if (System.IO.Path.GetFileName(filePath).Contains(c.ToString())) { - ConsoleWriteError("File name {0} contains invalid character [{1}]. Enter right file name.", filePath, c); + ConsoleWriteError($"File name {filePath} contains invalid character [{c}]. Enter right file name."); return false; } @@ -617,7 +616,7 @@ private static bool IsFileNameValid(string filePath) private static void PrepareRepeatFile(string fileName) { if (!File.Exists(fileName)) - ConsoleWriteError("File {0} was not found", fileName); + ConsoleWriteError($"File {fileName} was not found"); else { try @@ -625,9 +624,9 @@ private static void PrepareRepeatFile(string fileName) string[] lines = File.ReadAllLines(fileName); if (lines.Length == 0) - ConsoleWriteError("Zero lines in file {0}", fileName); + ConsoleWriteError($"Zero lines in file {fileName}"); - ConsoleWriteLine("File {0} opened and {1} lines has been read", fileName, lines.Length); + ConsoleWriteLine($"File {fileName} opened and {lines.Length} lines has been read"); repeaterMap.Clear(); @@ -719,15 +718,15 @@ private static void PrepareRepeatFile(string fileName) } if (linesWithData % 2 == 1) - ConsoleWriteError("Odd number of lines in file {0} with code. One line ask, one line answer.", fileName); + ConsoleWriteError($"Odd number of lines in file {fileName} with code. One line ask, one line answer."); repeaterEnabled = true; - ConsoleWriteLine("{0} pairs ask/answer ready", repeaterMap.Count); + ConsoleWriteLine($"{repeaterMap.Count} pairs ask/answer ready"); } catch (Exception ex) { - ConsoleWriteError("Cannot read file {0}", fileName); + ConsoleWriteError($"Cannot read file {fileName}"); ConsoleWriteError(ex.ToString()); } } @@ -909,48 +908,45 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) /// Print error /// /// - /// - private static void ConsoleWriteError(string text, params object[] arg) + private static void ConsoleWriteError(string text) { - ConsoleWriteLine(ConsoleColor.Red, text, arg); + ConsoleWriteLine(ConsoleColor.Red, text); } /// /// Print /// /// - /// - private static void ConsoleWrite(string message, params object[] parameters) + private static void ConsoleWrite(string message) { if (!continuousMode) - UI.Write(message, parameters); + UI.Write(message); else - Console.Write(message, parameters); + Console.Write(message); if (logfile && !logincomingonly) - Trace.Write(string.Format(message, parameters)); + Trace.Write(message); } /// /// Print single line /// /// - /// - private static void ConsoleWriteLine(string message, params object[] parameters) + private static void ConsoleWriteLine(string message) { if (!continuousMode) { - UI.WriteLine(message, parameters); + UI.WriteLine(message); } else { if (Console.CursorLeft > 0) Console.WriteLine(""); - Console.WriteLine(message, parameters); + Console.WriteLine(message); } if (logfile && !logincomingonly) - Trace.WriteLine(string.Format(message, parameters)); + Trace.WriteLine(string.Format(message)); } /// @@ -958,35 +954,33 @@ private static void ConsoleWriteLine(string message, params object[] parameters) /// /// /// - /// - private static void ConsoleWriteLine(ConsoleColor color, string message, params object[] parameters) + private static void ConsoleWriteLine(ConsoleColor color, string message) { if (!continuousMode) { - UI.WriteLine(message, parameters, color); + UI.WriteLine(message, color); } else { Console.ForegroundColor = color; - Console.WriteLine(message, parameters); + Console.WriteLine(message); Console.ResetColor(); } if (logfile && !logincomingonly) - Trace.WriteLine(string.Format(message, parameters)); + Trace.WriteLine(string.Format(message)); } /// /// Print single line without trace log /// /// - /// - private static void ConsoleWriteLineNoTrace(string message, params object[] parameters) + private static void ConsoleWriteLineNoTrace(string message) { if (!continuousMode) - UI.WriteLine(message, parameters); + UI.WriteLine(message); else - Console.WriteLine(message, parameters); + Console.WriteLine(message); } /// @@ -994,17 +988,16 @@ private static void ConsoleWriteLineNoTrace(string message, params object[] para /// /// /// - /// - private static void ConsoleWriteLineNoTrace(ConsoleColor color, string message, params object[] parameters) + private static void ConsoleWriteLineNoTrace(ConsoleColor color, string message) { if (!continuousMode) { - UI.WriteLine(message, parameters, color); + UI.WriteLine(message, color); } else { Console.ForegroundColor = color; - Console.WriteLine(message, parameters); + Console.WriteLine(message); Console.ResetColor(); } } @@ -1012,26 +1005,26 @@ private static void ConsoleWriteLineNoTrace(ConsoleColor color, string message, /// /// Print line that is involved in communication /// + /// /// - /// - private static void ConsoleWriteCommunication(ConsoleColor color, string message, params object[] parameters) + private static void ConsoleWriteCommunication(ConsoleColor color, string message) { if (!pausePrint) { if (!continuousMode) { - UI.Write(message, parameters, color); + UI.Write(message, color); } else { Console.ForegroundColor = color; - ConsoleWrite(message, parameters); + ConsoleWrite(message); Console.ResetColor(); } } if (logfile) - Trace.Write(string.Format(message, parameters)); + Trace.Write(string.Format(message)); } /// diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 1ca8e5b..431d462 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -469,12 +469,7 @@ internal static void WriteLine(string message, ConsoleColor color = ConsoleColor logView.MoveDown(); } - internal static void WriteLine(string message, object[] parameters, ConsoleColor color = ConsoleColor.White) - { - WriteLine(string.Format(message, parameters), color); - } - - internal static void Write(string message, ConsoleColor color = ConsoleColor.White) + private static void WriteInternally(string message, ConsoleColor color = ConsoleColor.White) { if (lines.IsEmpty) lines.Add(message); @@ -482,24 +477,22 @@ internal static void Write(string message, ConsoleColor color = ConsoleColor.Whi lines.Last += message; } - internal static void Write(string message, object[] parameters, ConsoleColor color = ConsoleColor.White) + internal static void Write(string message, ConsoleColor color = ConsoleColor.White) { - var msg = string.Format(message, parameters); - - if (msg.Contains("\r\n") || msg.Contains('\n')) + if (message.Contains("\r\n") || message.Contains('\n')) { var msgLines = message.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None); for (int i = 0; i < msgLines.Length; i++) { if (i == 0) - Write(msgLines[i], color); + WriteInternally(msgLines[i], color); else WriteLine(msgLines[i], color); } } else { - Write(msg, color); + WriteInternally(message, color); } } } From 7e815b5cacac5abfa50126919b0200a9b2a1aaf1 Mon Sep 17 00:00:00 2001 From: docbender Date: Fri, 4 Mar 2022 21:34:31 +0100 Subject: [PATCH 13/18] Persist hex/text setting --- SerialMonitor/Config.cs | 5 ++++- SerialMonitor/Program.cs | 24 +++++++++++++++--------- SerialMonitor/Setting.cs | 1 + SerialMonitor/UI.cs | 15 +++++---------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/SerialMonitor/Config.cs b/SerialMonitor/Config.cs index e3f55ec..2695a26 100644 --- a/SerialMonitor/Config.cs +++ b/SerialMonitor/Config.cs @@ -27,6 +27,7 @@ class Config public const string SETTING_SHOWTIME = "ShowTime"; public const string SETTING_SHOWTIMEGAP = "ShowTimeGap"; public const string SETTING_SHOWSENTDATA = "ShowSentData"; + public const string SETTING_SHOWASCII = "ShowAscii"; static readonly string filePath = Path.Combine(Directory.GetCurrentDirectory(), CONFIG_FILE); @@ -74,8 +75,9 @@ public static bool SaveFileList(IEnumerable args) /// /// /// + /// /// - internal static bool SaveSetting(string device, int baudrate, bool showTime, bool showTimeGap, bool showSentData) + internal static bool SaveSetting(string device, int baudrate, bool showTime, bool showTimeGap, bool showSentData, bool showAscii) { string? cfg = ReadConfiguration(); cfg = PrepareSave(cfg, SETTING_PORT, device); @@ -83,6 +85,7 @@ internal static bool SaveSetting(string device, int baudrate, bool showTime, boo cfg = PrepareSave(cfg, SETTING_SHOWTIME, showTime ? "1" : "0"); cfg = PrepareSave(cfg, SETTING_SHOWTIMEGAP, showTimeGap ? "1" : "0"); cfg = PrepareSave(cfg, SETTING_SHOWSENTDATA, showSentData ? "1" : "0"); + cfg = PrepareSave(cfg, SETTING_SHOWASCII, showAscii ? "1" : "0"); return SaveConfigFile(cfg); } diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index 19a1102..d34e144 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -23,7 +23,6 @@ class Program static long lastTimeReceved = 0; static bool repeaterEnabled = false; static bool repeaterUseHex = false; - static bool showAscii = false; static readonly Dictionary repeaterMap = new Dictionary(); static bool logfile = false; static bool logincomingonly = false; @@ -163,7 +162,14 @@ static void Main(string[] args) else setting.ShowTime = Config.LoadSetting(Config.SETTING_SHOWTIME) != "0"; - showAscii = arguments.GetArgument("showascii").Enabled; + arg = arguments.GetArgument("showascii"); + if (arg.Enabled) + setting.ShowAscii = true; + else + setting.ShowAscii = Config.LoadSetting(Config.SETTING_SHOWASCII) == "1"; + + setting.ShowTimeGap = Config.LoadSetting(Config.SETTING_SHOWTIMEGAP) == "1"; + setting.ShowSentData = Config.LoadSetting(Config.SETTING_SHOWSENTDATA) == "1"; //log option arg = arguments.GetArgument("logfile"); @@ -259,7 +265,7 @@ static void Main(string[] args) } PrepareRepeatFile(repeatfile.Parameter); } - + ConsoleWriteLine($"Opening port {port.PortName}: baudrate={port.BaudRate}b/s, parity={port.Parity}, databits={port.DataBits}, stopbits={port.StopBits}"); bool exit = false; @@ -293,12 +299,11 @@ static void Main(string[] args) } } else - { - setting.ShowTimeGap = Config.LoadSetting(Config.SETTING_SHOWTIMEGAP) == "1"; - setting.ShowSentData = Config.LoadSetting(Config.SETTING_SHOWSENTDATA) == "1"; + { + UI.PrintAsHexToLogView = !setting.ShowAscii; UI.ActionHelp = () => { PrintHelp(); }; UI.ActionPrint = (print) => { pausePrint = !print; }; - UI.ActionPrintAsHex = (hex) => { showAscii = !hex; }; + UI.ActionPrintAsHex = (hex) => { setting.ShowAscii = !hex; }; UI.ActionOpenClose = (close) => { pauseConnection = close; if (close) port.Close(); UI.SetPortStatus(port); }; UI.ActionSend = (data) => { UserDataSend(port,data); }; UI.ActionSendFile = (file) => { UserDataSendFile(port, file); }; @@ -326,7 +331,7 @@ static void Main(string[] args) UI.SetPortStatus(port); } - return Config.SaveSetting(setting.Port, setting.BaudRate, setting.ShowTime, setting.ShowTimeGap, setting.ShowSentData); + return Config.SaveSetting(setting.Port, setting.BaudRate, setting.ShowTime, setting.ShowTimeGap, setting.ShowSentData, setting.ShowAscii); }; UI.SetPortStatus(port); @@ -802,7 +807,7 @@ static void port_DataReceived(object sender, SerialDataReceivedEventArgs e) //Write to output string line = ""; - if (showAscii) + if (setting.ShowAscii) { if (!setting.ShowTime || applyGapTolerance) line = ASCIIEncoding.ASCII.GetString(incoming,0,byteCount); @@ -1116,6 +1121,7 @@ private static void PrintHelp() /// private static void Exit() { + Config.SaveSetting(setting.Port, setting.BaudRate, setting.ShowTime, setting.ShowTimeGap, setting.ShowSentData, setting.ShowAscii); Config.SaveHistory(UI.CommandHistory); Config.SaveFileList(UI.FileHistory); } diff --git a/SerialMonitor/Setting.cs b/SerialMonitor/Setting.cs index 57d32f2..64c5cf4 100644 --- a/SerialMonitor/Setting.cs +++ b/SerialMonitor/Setting.cs @@ -22,5 +22,6 @@ public class Setting public bool ShowTime; public bool ShowTimeGap; public bool ShowSentData; + public bool ShowAscii; } } diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 431d462..57b2996 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -30,10 +30,11 @@ internal class UI static readonly Label pinBreak = new Label() { Text = "Break(?)", X = Pos.Right(pinCD) + 2, Y = 1 }; static readonly Label timeLabel = new Label() { Text = "", X = 50, Y = 0 }; - + + private static bool printAsHexToLogView = true; // properties public static bool PrintToLogView { get; set; } = true; - public static bool PrintAsHexToLogView { get; set; } = true; + public static bool PrintAsHexToLogView { get => printAsHexToLogView; set { printAsHexToLogView = value; SetBottomMenuText(); } } public static bool RequestPortClose { get; set; } = false; public static List CommandHistory { get; } = new List(); public static List FileHistory { get; } = new(); @@ -51,7 +52,7 @@ internal class UI public static Action? ActionCommand; public static Func? ActionSettingLoad; public static Func? ActionSettingSave; - + // data view static readonly ListView logView = new ListView() { @@ -143,7 +144,7 @@ public static void Init() return; if (commandId < 0 || commandId + 1 >= CommandHistory.Count) { - if(!commandline.Text.IsEmpty) + if (!commandline.Text.IsEmpty) commandline.Text = ""; return; } @@ -210,7 +211,6 @@ private static bool ProcessHotKey(KeyEvent keyEvent) { PrintAsHexToLogView = !PrintAsHexToLogView; ActionPrintAsHex?.Invoke(PrintAsHexToLogView); - SetBottomMenuText(); } else if (keyEvent.Key == Key.F4) { @@ -423,11 +423,6 @@ private static bool ProcessHotKey(KeyEvent keyEvent) } return true; - - //int calcDlgHeight() - //{ - // return 5 + (FileHistory.Count > 0 ? 2 : 0) + FileHistory.Count; - //} } private static void SetBottomMenuText() From 862d123dfd1daa55cba385b6883cdeabd604f1c0 Mon Sep 17 00:00:00 2001 From: docbender Date: Sun, 6 Mar 2022 22:24:08 +0100 Subject: [PATCH 14/18] Fix Linux issues --- SerialMonitor/Program.cs | 6 ++ SerialMonitor/UI.cs | 135 +++++++++++++++++++++------------------ 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index d34e144..deab2ea 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -245,6 +245,7 @@ static void Main(string[] args) listener.LogFileName = logFilename; } + /* if (args.Length > 0) { if (Config.SaveStarters(args)) @@ -252,6 +253,7 @@ static void Main(string[] args) else ConsoleWriteLine("Warning: Program parameters cannot be saved."); } + */ Argument repeatfile = arguments.GetArgument("repeatfile"); if (repeatfile.Enabled) @@ -1121,9 +1123,13 @@ private static void PrintHelp() /// private static void Exit() { + port.Close(); + Config.SaveSetting(setting.Port, setting.BaudRate, setting.ShowTime, setting.ShowTimeGap, setting.ShowSentData, setting.ShowAscii); Config.SaveHistory(UI.CommandHistory); Config.SaveFileList(UI.FileHistory); + + UI.Exit(); } } } diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index 57b2996..fc5f080 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -30,11 +30,12 @@ internal class UI static readonly Label pinBreak = new Label() { Text = "Break(?)", X = Pos.Right(pinCD) + 2, Y = 1 }; static readonly Label timeLabel = new Label() { Text = "", X = 50, Y = 0 }; + static readonly Label debugLabel = new Label() { Text = "", X = 35, Y = 0 }; private static bool printAsHexToLogView = true; // properties public static bool PrintToLogView { get; set; } = true; - public static bool PrintAsHexToLogView { get => printAsHexToLogView; set { printAsHexToLogView = value; SetBottomMenuText(); } } + public static bool PrintAsHexToLogView { get => printAsHexToLogView; set { printAsHexToLogView = value; SetBottomMenuText(); } } public static bool RequestPortClose { get; set; } = false; public static List CommandHistory { get; } = new List(); public static List FileHistory { get; } = new(); @@ -52,7 +53,7 @@ internal class UI public static Action? ActionCommand; public static Func? ActionSettingLoad; public static Func? ActionSettingSave; - + // data view static readonly ListView logView = new ListView() { @@ -64,7 +65,7 @@ internal class UI public static void Init() { - Application.Init(); + Application.Init(); // main window var win = new Window() { @@ -95,7 +96,7 @@ public static void Init() }; frameStatus.Add(portLabel, pinsLabel, portName, portStatus, portSpeed, - pinRTS, pinCTS, pinDTR, pinDSR, pinCD, pinBreak, timeLabel); + pinRTS, pinCTS, pinDTR, pinDSR, pinCD, pinBreak, timeLabel, debugLabel); timeLabel.X = Pos.Right(frameStatus) - 10; // data frame @@ -195,17 +196,67 @@ public static void Init() commandline.SetFocus(); } - private static bool ProcessHotKey(KeyEvent keyEvent) + public static void Exit() { + Application.Driver.Suspend(); + Application.Refresh(); + } + + private static bool ProcessHotKey(KeyEvent keyEvent) + { if (keyEvent.Key == Key.F1) { ActionHelp?.Invoke(); } else if (keyEvent.Key == Key.F2) { - PrintToLogView = !PrintToLogView; - ActionPrint?.Invoke(PrintToLogView); - SetBottomMenuText(); + var ok = new Button("Ok"); + var cancel = new Button("Cancel"); + var dialog = new Dialog("Setting", 50, 11, ok, cancel); + var lbPort = new Label("Port:") { X = 1, Y = 1 }; + var lbSpeed = new Label("Baud rate:") { X = 1, Y = 2 }; + var tbPort = new TextField() { X = 15, Y = 1, Width = 15, Text = "" }; + var tbSpeed = new TextField() { X = 15, Y = 2, Width = 10, Text = "" }; + var cbTime = new CheckBox("Show transaction time") { X = 1, Y = 4 }; + var cbTimeGap = new CheckBox("Show time between 2 transactions") { X = 1, Y = 5 }; + var cbSent = new CheckBox("Show sent data") { X = 1, Y = 6 }; + + dialog.Add(lbPort, lbSpeed, tbPort, tbSpeed, cbTime, cbTimeGap, cbSent); + dialog.ColorScheme = Colors.Dialog; + + if (ActionSettingLoad == null) + return false; + + Setting setting = ActionSettingLoad.Invoke(); + + tbPort.Text = setting.Port; + tbSpeed.Text = setting.BaudRate.ToString(); + cbTime.Checked = setting.ShowTime; + cbTimeGap.Checked = setting.ShowTimeGap; + cbSent.Checked = setting.ShowSentData; + + ok.Clicked += () => + { + var port = tbPort.Text.ToString(); + if (string.IsNullOrEmpty(port) || !int.TryParse(tbSpeed.Text.ToString(), out int baudrate)) + return; + + setting.Port = port; + setting.BaudRate = baudrate; + setting.ShowTime = cbTime.Checked; + setting.ShowTimeGap = cbTimeGap.Checked; + setting.ShowSentData = cbSent.Checked; + + if (ActionSettingSave?.Invoke(setting) == true) + { + Application.RequestStop(); + } + }; + cancel.Clicked += () => + { + Application.RequestStop(); + }; + Application.Run(dialog); } else if (keyEvent.Key == Key.F3) { @@ -361,61 +412,15 @@ private static bool ProcessHotKey(KeyEvent keyEvent) { ActionRts?.Invoke(); } - else if ((keyEvent.Key & Key.F12) == Key.F12) + else if (keyEvent.Key == Key.F12) { - if (keyEvent.IsCtrl) - { - var ok = new Button("Ok"); - var cancel = new Button("Cancel"); - var dialog = new Dialog("Setting", 50, 11, ok, cancel); - var lbPort = new Label("Port:") { X = 1, Y = 1 }; - var lbSpeed = new Label("Baud rate:") { X = 1, Y = 2 }; - var tbPort = new TextField() { X = 15, Y = 1, Width = 15, Text = "" }; - var tbSpeed = new TextField() { X = 15, Y = 2, Width = 10, Text = "" }; - var cbTime = new CheckBox("Show transaction time") { X = 1, Y = 4 }; - var cbTimeGap = new CheckBox("Show time between 2 transactions") { X = 1, Y = 5 }; - var cbSent = new CheckBox("Show sent data") { X = 1, Y = 6 }; - - dialog.Add(lbPort, lbSpeed, tbPort, tbSpeed, cbTime, cbTimeGap, cbSent); - - if (ActionSettingLoad == null) - return false; - - Setting setting = ActionSettingLoad.Invoke(); - - tbPort.Text = setting.Port; - tbSpeed.Text = setting.BaudRate.ToString(); - cbTime.Checked = setting.ShowTime; - cbTimeGap.Checked = setting.ShowTimeGap; - cbSent.Checked = setting.ShowSentData; - - ok.Clicked += () => - { - var port = tbPort.Text.ToString(); - if (string.IsNullOrEmpty(port) || !int.TryParse(tbSpeed.Text.ToString(), out int baudrate)) - return; - - setting.Port = port; - setting.BaudRate = baudrate; - setting.ShowTime = cbTime.Checked; - setting.ShowTimeGap = cbTimeGap.Checked; - setting.ShowSentData = cbSent.Checked; - - if (ActionSettingSave?.Invoke(setting) == true) - { - Application.RequestStop(); - } - }; - cancel.Clicked += () => - { - Application.RequestStop(); - }; - Application.Run(dialog); - } - else - { - ActionDtr?.Invoke(); - } + ActionDtr?.Invoke(); + } + else if (keyEvent.Key == (Key.P | Key.CtrlMask)) + { + PrintToLogView = !PrintToLogView; + ActionPrint?.Invoke(PrintToLogView); + SetBottomMenuText(); } else { @@ -427,7 +432,7 @@ private static bool ProcessHotKey(KeyEvent keyEvent) private static void SetBottomMenuText() { - menu.Text = $" F1 Help | F2 {(!PrintToLogView ? "Print " : "No Print")} | F3 {(!PrintAsHexToLogView ? "Hex " : "Text")} | F4 {(!RequestPortClose ? "Close" : "Open ")} | F5 Send | F6 SendFile | F10 Exit | F11 RTS | F12 DTR | ^F12 Setting"; + menu.Text = $" F1 Help | F2 Setup | F3 {(!PrintAsHexToLogView ? "Hex " : "Text")} | F4 {(!RequestPortClose ? "Close" : "Open ")} | F5 Send | F6 SendFile | F10 Exit | F11 RTS | F12 DTR | ^P {(!PrintToLogView ? "Print" : "Pause")}"; } public static void Run(Func action) @@ -456,6 +461,8 @@ internal static void SetPinStatus(SerialPort port) internal static void WriteLine(string message, ConsoleColor color = ConsoleColor.White) { + if (!PrintToLogView) + return; lines.Add(message); if (!logView.IsInitialized) return; @@ -466,6 +473,8 @@ internal static void WriteLine(string message, ConsoleColor color = ConsoleColor private static void WriteInternally(string message, ConsoleColor color = ConsoleColor.White) { + if (!PrintToLogView) + return; if (lines.IsEmpty) lines.Add(message); else From 5d53c7514209ff748de2f5047021b8b605176eea Mon Sep 17 00:00:00 2001 From: docbender Date: Sun, 6 Mar 2022 22:44:25 +0100 Subject: [PATCH 15/18] Show port's pin status --- SerialMonitor/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index deab2ea..c69bfa3 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -306,11 +306,11 @@ static void Main(string[] args) UI.ActionHelp = () => { PrintHelp(); }; UI.ActionPrint = (print) => { pausePrint = !print; }; UI.ActionPrintAsHex = (hex) => { setting.ShowAscii = !hex; }; - UI.ActionOpenClose = (close) => { pauseConnection = close; if (close) port.Close(); UI.SetPortStatus(port); }; + UI.ActionOpenClose = (close) => { pauseConnection = close; if (close) port.Close(); UI.SetPortStatus(port); UI.SetPinStatus(port); }; UI.ActionSend = (data) => { UserDataSend(port,data); }; UI.ActionSendFile = (file) => { UserDataSendFile(port, file); }; - UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); }; - UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); }; + UI.ActionRts = () => { port.RtsEnable = !port.RtsEnable; UI.SetPortStatus(port); UI.SetPinStatus(port); }; + UI.ActionDtr = () => { port.DtrEnable = !port.DtrEnable; UI.SetPortStatus(port); UI.SetPinStatus(port); }; UI.ActionCommand = (text) => { ProcessCommand(text); }; UI.ActionSettingLoad = () => { return setting; }; UI.ActionSettingSave = (setting) => { From 3f19e308ea97666b194b9177c56785e5a583f753 Mon Sep 17 00:00:00 2001 From: docbender Date: Sun, 6 Mar 2022 23:46:24 +0100 Subject: [PATCH 16/18] Add exit command --- SerialMonitor/Program.cs | 15 +++++++++++++-- SerialMonitor/UI.cs | 8 ++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/SerialMonitor/Program.cs b/SerialMonitor/Program.cs index c69bfa3..2fd3be0 100644 --- a/SerialMonitor/Program.cs +++ b/SerialMonitor/Program.cs @@ -366,12 +366,23 @@ private static void ProcessCommand(string? text) { if (string.IsNullOrEmpty(text)) return; + if (text.Equals("help")) + { PrintHelp(); + } + else if (text.Equals("exit")) + { + UI.Shutdown(); + } else if (text.StartsWith("send ")) + { UserDataSend(port, text.Substring(5)); + } else + { ConsoleWriteLineNoTrace($"Unknown command: {text}"); + } } /// @@ -1086,7 +1097,7 @@ private static void PrintHelp() ConsoleWriteLineNoTrace(""); ConsoleWriteLineNoTrace("Program shortcuts:"); ConsoleWriteLineNoTrace("F1: print help"); - ConsoleWriteLineNoTrace("F2: pause/resume print on screen"); + ConsoleWriteLineNoTrace("F2: setup program"); ConsoleWriteLineNoTrace("F3: toggle between data print format (HEX / ASCII)"); ConsoleWriteLineNoTrace("F4: pause/resume connection to serial port"); ConsoleWriteLineNoTrace("F5: send specified data (in HEX format if data start with 0x otherwise ASCII is send)"); @@ -1095,7 +1106,7 @@ private static void PrintHelp() ConsoleWriteLineNoTrace("F10: program exit"); ConsoleWriteLineNoTrace("F11: toggle RTS pin"); ConsoleWriteLineNoTrace("F12: toggle DTR pin"); - ConsoleWriteLineNoTrace("^F12: setting"); + ConsoleWriteLineNoTrace("^P: pause / resume print on screen"); ConsoleWriteLineNoTrace(""); ConsoleWriteLineNoTrace("In program commands:"); diff --git a/SerialMonitor/UI.cs b/SerialMonitor/UI.cs index fc5f080..630205c 100644 --- a/SerialMonitor/UI.cs +++ b/SerialMonitor/UI.cs @@ -202,6 +202,11 @@ public static void Exit() Application.Refresh(); } + public static void Shutdown() + { + Application.RequestStop(); + } + private static bool ProcessHotKey(KeyEvent keyEvent) { if (keyEvent.Key == Key.F1) @@ -451,6 +456,9 @@ internal static void SetPortStatus(SerialPort port) internal static void SetPinStatus(SerialPort port) { + if (!port.IsOpen) + return; + pinRTS.Text = $"RTS({(port.RtsEnable ? 1 : "0")})"; pinCTS.Text = $"CTS({(port.CtsHolding ? 1 : "0")})"; pinDTR.Text = $"DTR({(port.DtrEnable ? 1 : "0")})"; From 4848df591e4ffccb8c7d2db955de0697130235f4 Mon Sep 17 00:00:00 2001 From: docbender Date: Sun, 6 Mar 2022 23:47:02 +0100 Subject: [PATCH 17/18] Update README.md --- README.md | 24 +++++++++++++++--------- img/SM3.png | Bin 0 -> 14699 bytes 2 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 img/SM3.png diff --git a/README.md b/README.md index 69c88dd..32495d0 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ # SerialMonitor Program is simple piece of software designed for serial port data monitoring together with the possibility to automatically reply to sender. +[![Version](https://img.shields.io/github/v/release/docbender/SerialMonitor?include_prereleases)](https://github.com/docbender/SerialMonitor/releases) +[![Download](https://img.shields.io/github/downloads/docbender/SerialMonitor/total.svg)](https://github.com/docbender/SerialMonitor/releases) +[![Issues](https://img.shields.io/github/issues/docbender/SerialMonitor)](https://github.com/docbender/SerialMonitor/issues) + Time between received data messages is displayed (in miliseconds). In addition to the printing on the screen it allows write everything (or just communication) to a specified file. -Windows and also Linux are supported. Program isn't serial port sniffer so can't monitor port that is already open by another program. Program is written in C# so .NET (version 2.0) or Mono is necessary. +Program supported .NET6. Program is running under Windows or Linux. Program isn't serial port sniffer so can't monitor port that is already open by another program. -![](https://github.com/docbender/SerialMonitor/blob/master/img/SM1.png) +![](https://github.com/docbender/SerialMonitor/blob/master/img/SM3.png) Program has also feature that allows answer to sender for specific message. This could be used for simple simulation of some device. To use this feature it is necessary to prepare file with pairs ask/answer. In file first(odd) line represent ask and second(even) line answer. File can contain several pairs ask/answer which can be separated by empty lines (not necessary). File example: @@ -30,10 +34,13 @@ Switches: * -parity {used parity}: set used port parity. Default none. Available parameters odd, even, mark and space. * -databits {used databits}: set data bits count. Default 8 data bits. * -stopbits {used stopbits}: set stop bits count. Default 1 stop bit. Available parameters 0, 1, 1.5 and 2. -* -repeatfile {file name}: enable repeat mode with protocol specified in file -* -logfile {file name}: set file name for log into that file -* -logincomingonly: log into file would be only incoming data -* -showascii: communication would be show in ASCII format (otherwise HEX is used) +* -repeatfile {file name}: enable repeat mode with protocol specified in file. +* -logfile {file name}: set file name for log into that file. +* -logincomingonly: log into file would be only incoming data. +* -showascii: communication would be show in ASCII format (otherwise HEX is used). +* -notime: time information about incoming data would not be printed. +* -gaptolerance {time gap in ms}: messages received within specified time gap will be printed together. +* -nogui: start program in normal console mode (scrolling list). Not with text GUI. Example: @@ -43,6 +50,5 @@ Example: serialmonitor COM83 -baudrate 19200 -repeatfile protocol.txt In program commands can be typed: -* exit or ^C: program exit -* send {data to send}: send specified data (in HEX format if data start with 0x otherwise ASCII is send) - +* exit: program exit +* send {data to send}: send specified data (in HEX format if data start with 0x otherwise ASCII is send) \ No newline at end of file diff --git a/img/SM3.png b/img/SM3.png new file mode 100644 index 0000000000000000000000000000000000000000..6c0ac136902fd105492e44b08983d637a946d0ba GIT binary patch literal 14699 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 Date: Mon, 7 Mar 2022 07:25:32 +0100 Subject: [PATCH 18/18] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 32495d0..7ed2253 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Program is simple piece of software designed for serial port data monitoring tog Time between received data messages is displayed (in miliseconds). In addition to the printing on the screen it allows write everything (or just communication) to a specified file. -Program supported .NET6. Program is running under Windows or Linux. Program isn't serial port sniffer so can't monitor port that is already open by another program. +Program requires .NET6. Program is running under Windows and Linux. Program isn't serial port sniffer so can't monitor port that is already open by another program. ![](https://github.com/docbender/SerialMonitor/blob/master/img/SM3.png) @@ -51,4 +51,4 @@ Example: In program commands can be typed: * exit: program exit -* send {data to send}: send specified data (in HEX format if data start with 0x otherwise ASCII is send) \ No newline at end of file +* send {data to send}: send specified data (in HEX format if data start with 0x otherwise ASCII is send)