private static void Main(string[] args) { Initialize(); Start(); Output.Report(StandartMessages.AppStarted()); //Console.WriteLine(Environment.NewLine + "Press ESC to Exit" + Environment.NewLine); //while (!(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)) while (true) { try { if (Messenger.MessageCount > 0) { string message = Messenger.Dequeue(); Output.Report(message); } } finally { Thread.Sleep(250); } } //Stop(); //Output.Report(StandartMessages.AppClosed()); }
private static void Respond(SerialPort serialPort, Telegram telegram, ref byte[] lastResponse) { if (telegram.response != null && telegram.responseLength > 0) { lastResponse = telegram.response; Respond(serialPort, telegram.response); Messenger.Enqueue(StandartMessages.RespondingToMaster(serialPort, telegram)); } else { Messenger.Enqueue(StandartMessages.NoResponse(serialPort, telegram)); } }
/// <summary> /// Gets the response message from the buffer and clears the buffer /// </summary> /// <param name="masterLength"></param> /// <param name="slaveLength"></param> /// <returns></returns> private static ResponseResult GetResponseMessage(SerialPortPlus serialPort, Telegram telegram, out byte[] result) { if (telegram.responseLength == 0) { Messenger.Enqueue(StandartMessages.TelegramSkiped(telegram)); result = null; return(ResponseResult.Skiped); } //If the telegrams dictionary is filled, ask for it instead byte[] request = telegram.dictionary.Length > 1 ? telegram.dictionary : telegram.request; List <byte> buffer = GetRawResponse(serialPort, request); //If the first byte in the buffer is not 68 or E5, add 68 in front //if (!((buffer[0] == HexToByte("68")[0]) || (buffer[0] == HexToByte("E5")[0]))) buffer.Insert(0, HexToByte("68")[0]); if (buffer.Count == telegram.responseLength) //correct response { result = buffer.ToArray(); //Check checksum if (Checksum.Check(result)) { //If the checksum is correct, proceed Messenger.Enqueue(StandartMessages.SlaveResponded(serialPort, result, request)); return(ResponseResult.Correct); } else { //Return bad checksum Messenger.Enqueue(StandartMessages.BadChecksum(serialPort, telegram, buffer)); return(ResponseResult.Checksum_Error); } } else if (buffer.Count == 0) //no response { Messenger.Enqueue(StandartMessages.RequestTimeout(serialPort, telegram)); result = null; return(ResponseResult.Timeout); } else //unexpected response { Messenger.Enqueue(StandartMessages.UnexpectedResponse(serialPort, telegram, buffer)); result = buffer.ToArray(); return(ResponseResult.Incorrect); } }
private static void Initialize() { mySetting = new DataSet(); telegrams = new List <Telegram>(); try { //Read and save the settings mySetting.ReadXml($"{AppDomain.CurrentDomain.BaseDirectory}Settings.xml"); //Initializa the ports InitializePorts(); //Get General setting GetGeneralSettings(); //Set database settings SetDBManager(); Output.ConsoleTimeStamp = true; //Fill the telegrams table if (mySetting.Tables["tblTelegrams"] != null) { FillTelegramsList(); } else { Messenger.Enqueue(StandartMessages.MissingTable("tblTelegrams")); } } catch (Exception ex) { Messenger.Enqueue(ex.Message); } }
private static void SlaveThread(SerialPortPlus serialPort) { List <byte> serialBuffer = new List <byte>(); byte[] lastResponse = new byte[0]; //Try to open the port OpenPort(serialPort); //If the port didnt open return if (!serialPort.IsOpen) { return; } //clear the buffer serialPort.DiscardInBuffer(); //Messenger.Enqueue($"{Thread.CurrentThread.Name} status: {Thread.CurrentThread.IsAlive.ToString()}"); while (MainThread.IsAlive) { try { int bytesToRead = serialPort.BytesToRead; //Wait for a full telegram if (serialPort.BytesToRead > 0) { Thread.Sleep(100); if (serialPort.BytesToRead > bytesToRead) { continue; } else { bytesToRead = serialPort.BytesToRead; } } else { Thread.Sleep(250); continue; } //Read and save everything from the buffer byte[] receivedBytes = new byte[bytesToRead]; //Console.WriteLine($"Bytes to read: {receivedBytes.Length}"); serialPort.Read(receivedBytes, 0, bytesToRead); //If the received message is just an echo, ignore it if (echoCancellation && IsEcho(lastResponse, receivedBytes)) { Messenger.Enqueue(StandartMessages.EchoIgnored(serialPort, receivedBytes)); continue; } //Save the read bytes into the buffer serialBuffer.InsertRange(serialBuffer.Count, receivedBytes); //If there are known telegrams to listen for, do so if (telegrams.Count > 0) { //For each telegram in the list for (int i = 0; i < telegrams.Count; i++) { Telegram telegram = telegrams[i]; //If a telegram is recognized if (FindInBuffer(telegram.request, serialBuffer)) { Respond(serialPort, telegram, ref lastResponse); //If the telegram is of the default type clear the buffer, //else keep the bytes and wait for next telegram if (telegram.teleType != TeleType.Complex) { serialBuffer.Clear(); } break; } else if (i >= telegrams.Count - 1) { //Check if any of the master ports have TransferCommand enabled SerialPortPlus sp; if ((sp = GetPlcPort()) != null) { lock (sp) { Messenger.Enqueue(StandartMessages.UnrecognizedTelegram(serialPort, serialBuffer) + $"...sending to {sp.PortName}"); //Send the bytes to the port and get response List <byte> response = GetRawResponse(sp, serialBuffer.ToArray()); byte[] arrResponse = response.ToArray(); Messenger.Enqueue($"[{sp.PortName}]response is: [{Convertor.ByteToHex(arrResponse)}], transfering response to master..."); //Send the responce back to the port that requested it Respond(serialPort, arrResponse); lastResponse = arrResponse; serialBuffer.Clear(); } } else { Messenger.Enqueue(StandartMessages.UnrecognizedTelegram(serialPort, serialBuffer)); serialBuffer.Clear(); } } } } else //Sniff the port { Messenger.Enqueue(StandartMessages.CurrentBytes(serialPort, serialBuffer)); serialBuffer.Clear(); } //Check connection if (!serialPort.IsOpen) { Reconnect(serialPort); } //Sleep between readings Thread.Sleep(250); } catch (Exception ex) { Messenger.Enqueue(ex.Message); serialBuffer.Clear(); serialPort.DiscardInBuffer(); Thread.Sleep(250); } } serialPort.Close(); }