예제 #1
0
 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());
 }
예제 #2
0
 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));
     }
 }
예제 #3
0
        /// <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);
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
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();
        }