/// <summary> /// Performs a request in the ASCII mode. /// </summary> protected bool AsciiRequest(DataUnit dataUnit) { bool result = false; // send request log.WriteLine(dataUnit.ReqDescr); Connection.WriteLine(dataUnit.ReqStr, out string logText); log.WriteLine(logText); // receive response string line = Connection.ReadLine(Timeout, out logText); log.WriteLine(logText); int lineLen = line == null ? 0 : line.Length; if (lineLen >= 3) { int aduLen = (lineLen - 1) / 2; if (aduLen == dataUnit.RespAduLen && lineLen % 2 == 1) { // receive response 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 { log.WriteLine(ModbusPhrases.IncorrectSymbol); parseOK = false; } } if (parseOK) { if (aduBuf[aduLen - 1] == ModbusUtils.LRC(aduBuf, 0, aduLen - 1)) { // decode response if (dataUnit.DecodeRespPDU(aduBuf, 1, aduLen - 2, out string errMsg)) { log.WriteLine(ModbusPhrases.OK); result = true; } else { log.WriteLine(errMsg + "!"); } } else { log.WriteLine(ModbusPhrases.LrcError); } } } else { log.WriteLine(ModbusPhrases.IncorrectAduLength); } } else { log.WriteLine(ModbusPhrases.CommErrorWithExclamation); } return(result); }
/// <summary> /// Performs a request in the TCP mode. /// </summary> protected bool TcpRequest(DataUnit dataUnit) { bool result = false; // specify transaction ID if (++TransactionID == 0) { TransactionID = 1; } dataUnit.ReqADU[0] = (byte)(TransactionID / 256); dataUnit.ReqADU[1] = (byte)(TransactionID % 256); // send request log.WriteLine(dataUnit.ReqDescr); Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length, ProtocolFormat.Hex, out string logText); log.WriteLine(logText); // receive response // read MBAP header int readCnt = Connection.Read(InBuf, 0, 7, Timeout, ProtocolFormat.Hex, out logText); log.WriteLine(logText); if (readCnt == 7) { int pduLen = InBuf[4] * 256 + InBuf[5] - 1; if (InBuf[0] == dataUnit.ReqADU[0] && InBuf[1] == dataUnit.ReqADU[1] && // transaction ID InBuf[2] == 0 && InBuf[3] == 0 && pduLen > 0 && // protocol ID InBuf[6] == dataUnit.ReqADU[6]) // unit ID { // read PDU readCnt = Connection.Read(InBuf, 7, pduLen, Timeout, ProtocolFormat.Hex, out logText); log.WriteLine(logText); if (readCnt == pduLen) { // decode response if (dataUnit.DecodeRespPDU(InBuf, 7, pduLen, out string errMsg)) { log.WriteLine(ModbusPhrases.OK); result = true; } else { log.WriteLine(errMsg + "!"); } } else { log.WriteLine(ModbusPhrases.CommErrorWithExclamation); } } else { log.WriteLine(ModbusPhrases.IncorrectMbap); } } else { log.WriteLine(ModbusPhrases.CommErrorWithExclamation); } return(result); }
/// <summary> /// Performs a request in the PDU mode. /// </summary> protected bool RtuRequest(DataUnit dataUnit) { bool result = false; // send request log.WriteLine(dataUnit.ReqDescr); Connection.Write(dataUnit.ReqADU, 0, dataUnit.ReqADU.Length, ProtocolFormat.Hex, out string logText); log.WriteLine(logText); // receive response // partial read to calculate PDU length const int FirstCount = 2; int readCnt = Connection.Read(InBuf, 0, FirstCount, Timeout, ProtocolFormat.Hex, out logText); log.WriteLine(logText); if (readCnt != FirstCount) { log.WriteLine(ModbusPhrases.CommErrorWithExclamation); } else if (InBuf[0] != dataUnit.ReqADU[0]) // validate device address { log.WriteLine(ModbusPhrases.IncorrectDevAddr); } else if (!(InBuf[1] == dataUnit.FuncCode || InBuf[1] == dataUnit.ExcFuncCode)) // validate function code { log.WriteLine(ModbusPhrases.IncorrectPduFuncCode); } else { int pduLen; int count; if (InBuf[1] == dataUnit.FuncCode) { pduLen = dataUnit.RespPduLen; count = dataUnit.RespAduLen - FirstCount; } else // exception received { pduLen = 2; count = 3; } // read rest of response readCnt = Connection.Read(InBuf, FirstCount, count, Timeout, ProtocolFormat.Hex, out logText); log.WriteLine(logText); if (readCnt != count) { log.WriteLine(ModbusPhrases.CommErrorWithExclamation); } else if (InBuf[pduLen + 1] + InBuf[pduLen + 2] * 256 != ModbusUtils.CRC16(InBuf, 0, pduLen + 1)) { log.WriteLine(ModbusPhrases.CrcError); } else if (dataUnit.DecodeRespPDU(InBuf, 1, pduLen, out string errMsg)) { log.WriteLine(ModbusPhrases.OK); result = true; } else { log.WriteLine(errMsg + "!"); } } return(result); }