private static List <byte> GetRawResponse(SerialPortPlus serialPort, byte[] request) { List <byte> output = new List <byte>(); Stopwatch stopWatch = new Stopwatch(); //Open port OpenPort(serialPort); //Send request and start timeout timer serialPort.DiscardInBuffer(); stopWatch.Start(); //Send request Respond(serialPort, request); //Get response while (stopWatch.Elapsed.TotalMilliseconds < serialPort.ReadTimeout) { if (serialPort.BytesToRead > 0) { do { //Read and save everything from the buffer byte[] receivedBytes = new byte[serialPort.BytesToRead]; serialPort.Read(receivedBytes, 0, serialPort.BytesToRead); //Save the read bytes into the buffer output.InsertRange(output.Count, receivedBytes); Thread.Sleep(200); } while ((serialPort.BytesToRead > 0) && (stopWatch.Elapsed.TotalMilliseconds < serialPort.ReadTimeout)); stopWatch.Stop(); break; } else { Thread.Sleep(50); } } stopWatch.Stop(); stopWatch = null; //Close port ClosePort(serialPort); return(output); }
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(); }