public ModbusResponse readResponse()
throws ModbusIOException {
boolean done = false;
ModbusResponse response = null;
int dlength = 0;
try {
do {
//1. read to function code, create request and read function specific bytes
synchronized (m_ByteIn) {
int uid = m_InputStream.read();
if (uid != -1) {
int fc = m_InputStream.read();
m_ByteInOut.reset();
m_ByteInOut.writeByte(uid);
m_ByteInOut.writeByte(fc);
//create response to acquire length of message
response = ModbusResponse.createModbusResponse(fc);
response.setHeadless();
// With Modbus RTU, there is no end frame. Either we assume
// the message is complete as is or we must do function
// specific processing to know the correct length. To avoid
// moving frame timing to the serial input functions, we set the
// timeout and to message specific parsing to read a response.
getResponse(fc, m_ByteInOut);
dlength = m_ByteInOut.size() - 2; // less the crc
if (Modbus.debug) System.out.println("Response: " +
ModbusUtil.toHex(m_ByteInOut.getBuffer(), 0, dlength + 2));
m_ByteIn.reset(m_InBuffer, dlength);
//check CRC
int[] crc = ModbusUtil.calculateCRC(m_InBuffer, 0, dlength); //does not include CRC
if (ModbusUtil.unsignedByteToInt(m_InBuffer[dlength]) != crc[0]
&& ModbusUtil.unsignedByteToInt(m_InBuffer[dlength + 1]) != crc[1]) {
throw new IOException("CRC Error in received frame: " + dlength + " bytes: " + ModbusUtil.toHex(m_ByteIn.getBuffer(), 0, dlength));
}
} else {
throw new IOException("Error reading response");
}
//read response
m_ByteIn.reset(m_InBuffer, dlength);
if (response != null) {
response.readFrom(m_ByteIn);
}
done = true;
}//synchronized
} while (!done);
return response;