Exemple #1
0
        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);
        }
Exemple #2
0
        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();
        }