private static void ClosePort(SerialPortPlus serialPort) { try { Thread.Sleep(50); serialPort.Close(); //Messenger.Enqueue(serialPort.PortName + " closed."); } catch (Exception ex) { Messenger.Enqueue($"Can't close {serialPort.PortName}:" + 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(); }