コード例 #1
0
ファイル: ModbusPoll.cs プロジェクト: firebitsbr/scada-36
        /// <summary>
        /// Выполнить запрос в режиме TCP
        /// </summary>
        public bool TcpRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            bool   result = false;
            string logText;

            // отправка запроса
            WriteToLog(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length,
                             CommUtils.ProtocolLogFormats.Hex, out logText);
            ExecWriteToLog(logText);

            // приём ответа
            // считывание MBAP Header
            int readCnt = Connection.Read(InBuf, 0, 7, Timeout, CommUtils.ProtocolLogFormats.Hex, out logText);

            ExecWriteToLog(logText);

            if (readCnt == 7)
            {
                int pduLen = InBuf[4] * 256 + InBuf[5] - 1;

                if (InBuf[0] == 0 && InBuf[1] == 0 && InBuf[2] == 0 && InBuf[3] == 0 && pduLen > 0 &&
                    InBuf[6] == dataUnit.ReqADU[6])
                {
                    // считывание PDU
                    readCnt = Connection.Read(InBuf, 7, pduLen, Timeout,
                                              CommUtils.ProtocolLogFormats.Hex, out logText);
                    ExecWriteToLog(logText);

                    if (readCnt == pduLen)
                    {
                        // расшифровка ответа
                        string errMsg;

                        if (dataUnit.DecodeRespPDU(InBuf, 7, pduLen, out errMsg))
                        {
                            ExecWriteToLog(ModbusPhrases.OK);
                            result = true;
                        }
                        else
                        {
                            ExecWriteToLog(errMsg + "!");
                        }
                    }
                    else
                    {
                        WriteToLog(ModbusPhrases.CommErrorWithExclamation);
                    }
                }
                else
                {
                    WriteToLog(ModbusPhrases.IncorrectMbap);
                }
            }
            else
            {
                WriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }
コード例 #2
0
ファイル: ModbusPoll.cs プロジェクト: firebitsbr/scada-36
        /// <summary>
        /// Выполнить запрос в режиме ASCII
        /// </summary>
        public bool AsciiRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            bool   result = false;
            string logText;

            // отправка запроса
            ExecWriteToLog(dataUnit.ReqDescr);
            Connection.WriteLine(dataUnit.ReqStr, out logText);
            ExecWriteToLog(logText);

            // приём ответа
            string line = Connection.ReadLine(Timeout, out logText);

            ExecWriteToLog(logText);
            int lineLen = line == null ? 0 : line.Length;

            if (lineLen >= 3)
            {
                int aduLen = (lineLen - 1) / 2;

                if (aduLen == dataUnit.RespAduLen && lineLen % 2 == 1)
                {
                    // получение ADU ответа
                    byte[] aduBuf  = new byte[aduLen];
                    bool   parseOK = true;

                    for (int i = 0, j = 1; i < aduLen && parseOK; i++, j += 2)
                    {
                        try
                        {
                            aduBuf[i] = byte.Parse(line.Substring(j, 2), NumberStyles.HexNumber);
                        }
                        catch
                        {
                            ExecWriteToLog(ModbusPhrases.IncorrectSymbol);
                            parseOK = false;
                        }
                    }

                    if (parseOK)
                    {
                        if (aduBuf[aduLen - 1] == ModbusUtils.CalcLRC(aduBuf, 0, aduLen - 1))
                        {
                            // расшифровка ответа
                            string errMsg;

                            if (dataUnit.DecodeRespPDU(aduBuf, 1, aduLen - 2, out errMsg))
                            {
                                ExecWriteToLog(ModbusPhrases.OK);
                                result = true;
                            }
                            else
                            {
                                ExecWriteToLog(errMsg + "!");
                            }
                        }
                        else
                        {
                            ExecWriteToLog(ModbusPhrases.LrcError);
                        }
                    }
                }
                else
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectAduLength);
                }
            }
            else
            {
                ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }
コード例 #3
0
ファイル: ModbusPoll.cs プロジェクト: firebitsbr/scada-36
        /// <summary>
        /// Выполнить запрос в режиме RTU
        /// </summary>
        public bool RtuRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            bool   result = false;
            string logText;

            // отправка запроса
            ExecWriteToLog(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length,
                             CommUtils.ProtocolLogFormats.Hex, out logText);
            ExecWriteToLog(logText);

            // приём ответа
            // считывание начала ответа для определения длины PDU
            int readCnt = Connection.Read(InBuf, 0, 5, Timeout, CommUtils.ProtocolLogFormats.Hex, out logText);

            ExecWriteToLog(logText);

            if (readCnt == 5)
            {
                int pduLen;
                int count;

                if (InBuf[0] != dataUnit.ReqADU[0]) // проверка адреса устройства в ответе
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectDevAddr);
                }
                else if (!(InBuf[1] == dataUnit.FuncCode || InBuf[1] == dataUnit.ExcFuncCode))
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectPduFuncCode);
                }
                else
                {
                    if (InBuf[1] == dataUnit.FuncCode)
                    {
                        // считывание окончания ответа
                        pduLen = dataUnit.RespPduLen;
                        count  = dataUnit.RespAduLen - 5;

                        readCnt = Connection.Read(InBuf, 5, count, Timeout,
                                                  CommUtils.ProtocolLogFormats.Hex, out logText);
                        ExecWriteToLog(logText);
                    }
                    else // устройство вернуло исключение
                    {
                        pduLen  = 2;
                        count   = 0;
                        readCnt = 0;
                    }

                    if (readCnt == count)
                    {
                        if (InBuf[pduLen + 1] + InBuf[pduLen + 2] * 256 == ModbusUtils.CalcCRC16(InBuf, 0, pduLen + 1))
                        {
                            // расшифровка ответа
                            string errMsg;

                            if (dataUnit.DecodeRespPDU(InBuf, 1, pduLen, out errMsg))
                            {
                                ExecWriteToLog(ModbusPhrases.OK);
                                result = true;
                            }
                            else
                            {
                                ExecWriteToLog(errMsg + "!");
                            }
                        }
                        else
                        {
                            ExecWriteToLog(ModbusPhrases.CrcError);
                        }
                    }
                    else
                    {
                        ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
                    }
                }
            }
            else
            {
                ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }
コード例 #4
0
        /// <summary>
        /// Run a TCP request
        /// </summary>
        public bool TcpRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            var result = false;

            // sending request
            WriteToLog(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length,
                             CommUtils.ProtocolLogFormats.Hex, out string logText);
            ExecWriteToLog(logText);

            // reception of the answer
            // read MBAP Header
            int readCnt = Connection.Read(InBuf, 0, 7, Timeout, CommUtils.ProtocolLogFormats.Hex, out logText);

            ExecWriteToLog(logText);

            if (readCnt == 7)
            {
                int pduLen = InBuf[4] * 256 + InBuf[5] - 1;

                if (InBuf[0] == 0 && InBuf[1] == 0 && InBuf[2] == 0 && InBuf[3] == 0 && pduLen > 0 &&
                    InBuf[6] == dataUnit.ReqADU[6])
                {
                    // PDU reading
                    readCnt = Connection.Read(InBuf, 7, pduLen, Timeout,
                                              CommUtils.ProtocolLogFormats.Hex, out logText);
                    ExecWriteToLog(logText);

                    if (readCnt == pduLen)
                    {
                        // answer decryption
                        string errMsg;

                        if (dataUnit.DecodeRespPDU(InBuf, 7, pduLen, out errMsg))
                        {
                            ExecWriteToLog(ModbusPhrases.OK);
                            result = true;
                        }
                        else
                        {
                            ExecWriteToLog(errMsg + "!");
                        }
                    }
                    else
                    {
                        WriteToLog(ModbusPhrases.CommErrorWithExclamation);
                    }
                }
                else
                {
                    WriteToLog(ModbusPhrases.IncorrectMbap);
                }
            }
            else
            {
                WriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }
コード例 #5
0
        /// <summary>
        /// Run ASCII query
        /// </summary>
        public bool AsciiRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            var result = false;

            // sending request
            ExecWriteToLog(dataUnit.ReqDescr);
            Connection.WriteLine(dataUnit.ReqStr, out string logText);
            ExecWriteToLog(logText);

            // reception of the answer
            string line = Connection.ReadLine(Timeout, out logText);

            ExecWriteToLog(logText);
            int lineLen = line == null ? 0 : line.Length;

            if (lineLen >= 3)
            {
                int aduLen = (lineLen - 1) / 2;

                if (aduLen == dataUnit.RespAduLen && lineLen % 2 == 1)
                {
                    // getting ADU response
                    var aduBuf  = new byte[aduLen];
                    var parseOK = true;

                    for (int i = 0,
                         j = 1;
                         i < aduLen && parseOK;
                         i++, j += 2)
                    {
                        try {
                            aduBuf[i] = byte.Parse(line.Substring(j, 2), NumberStyles.HexNumber);
                        } catch {
                            ExecWriteToLog(ModbusPhrases.IncorrectSymbol);
                            parseOK = false;
                        }
                    }

                    if (parseOK)
                    {
                        if (aduBuf[aduLen - 1] == ModbusUtils.CalcLRC(aduBuf, 0, aduLen - 1))
                        {
                            // answer decryption
                            string errMsg;

                            if (dataUnit.DecodeRespPDU(aduBuf, 1, aduLen - 2, out errMsg))
                            {
                                ExecWriteToLog(ModbusPhrases.OK);
                                result = true;
                            }
                            else
                            {
                                ExecWriteToLog(errMsg + "!");
                            }
                        }
                        else
                        {
                            ExecWriteToLog(ModbusPhrases.LrcError);
                        }
                    }
                }
                else
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectAduLength);
                }
            }
            else
            {
                ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }
コード例 #6
0
        /// <summary>
        /// Run RTU query
        /// </summary>
        public bool RtuRequest(DataUnit dataUnit)
        {
            if (!CheckConnection())
            {
                return(false);
            }

            var result = false;

            // sending request
            ExecWriteToLog(dataUnit.ReqDescr);
            Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length,
                             CommUtils.ProtocolLogFormats.Hex, out string logText);
            ExecWriteToLog(logText);

            // reception of the answer
            // reading the start of the response to determine the length of the PDU
            int readCnt = Connection.Read(InBuf, 0, 5, Timeout, CommUtils.ProtocolLogFormats.Hex, out logText);

            ExecWriteToLog(logText);

            if (readCnt == 5)
            {
                int pduLen;
                int count;

                if (InBuf[0] != dataUnit.ReqADU[0]) // checking device address in response
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectDevAddr);
                }
                else if (!(InBuf[1] == dataUnit.FuncCode || InBuf[1] == dataUnit.ExcFuncCode))
                {
                    ExecWriteToLog(ModbusPhrases.IncorrectPduFuncCode);
                }
                else
                {
                    if (InBuf[1] == dataUnit.FuncCode)
                    {
                        // read end of response
                        pduLen = dataUnit.RespPduLen;
                        count  = dataUnit.RespAduLen - 5;

                        readCnt = Connection.Read(InBuf, 5, count, Timeout,
                                                  CommUtils.ProtocolLogFormats.Hex, out logText);
                        ExecWriteToLog(logText);
                    }
                    else   // device returned exception
                    {
                        pduLen  = 2;
                        count   = 0;
                        readCnt = 0;
                    }

                    if (readCnt == count)
                    {
                        if (InBuf[pduLen + 1] + InBuf[pduLen + 2] * 256 ==
                            ModbusUtils.CalcCRC16(InBuf, 0, pduLen + 1))
                        {
                            // answer decryption
                            string errMsg;

                            if (dataUnit.DecodeRespPDU(InBuf, 1, pduLen, out errMsg))
                            {
                                ExecWriteToLog(ModbusPhrases.OK);
                                result = true;
                            }
                            else
                            {
                                ExecWriteToLog(errMsg + "!");
                            }
                        }
                        else
                        {
                            ExecWriteToLog(ModbusPhrases.CrcError);
                        }
                    }
                    else
                    {
                        ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
                    }
                }
            }
            else
            {
                ExecWriteToLog(ModbusPhrases.CommErrorWithExclamation);
            }

            return(result);
        }