/// <summary> /// Выполнить запрос в режиме TCP /// </summary> public bool TcpRequest(DataUnit dataUnit) { if (!CheckConnection()) { return(false); } bool result = false; // отправка запроса WriteToLog(dataUnit.ReqDescr); Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length, CommUtils.ProtocolLogFormats.Hex, out string 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); }
/// <summary> /// Выполнить запрос в режиме ASCII /// </summary> public bool AsciiRequest(DataUnit dataUnit) { if (!CheckConnection()) { return(false); } bool result = false; // отправка запроса ExecWriteToLog(dataUnit.ReqDescr); Connection.WriteLine(dataUnit.ReqStr, out string 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); }
/// <summary> /// Выполнить запрос в режиме RTU /// </summary> public bool RtuRequest(DataUnit dataUnit) { if (!CheckConnection()) { return(false); } bool result = false; // отправка запроса ExecWriteToLog(dataUnit.ReqDescr); Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length, CommUtils.ProtocolLogFormats.Hex, out string 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); }
/// <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); }
/// <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); }
/// <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); }