com.digitalpetri.modbus.codec.ModbusResponseDecoder.java Source code

Java tutorial

Introduction

Here is the source code for com.digitalpetri.modbus.codec.ModbusResponseDecoder.java

Source

/*
 * Copyright 2016 Kevin Herron
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.digitalpetri.modbus.codec;

import com.digitalpetri.modbus.ExceptionCode;
import com.digitalpetri.modbus.FunctionCode;
import com.digitalpetri.modbus.ModbusPdu;
import com.digitalpetri.modbus.UnsupportedPdu;
import com.digitalpetri.modbus.responses.ExceptionResponse;
import com.digitalpetri.modbus.responses.MaskWriteRegisterResponse;
import com.digitalpetri.modbus.responses.ReadCoilsResponse;
import com.digitalpetri.modbus.responses.ReadDiscreteInputsResponse;
import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
import com.digitalpetri.modbus.responses.ReadInputRegistersResponse;
import com.digitalpetri.modbus.responses.WriteMultipleCoilsResponse;
import com.digitalpetri.modbus.responses.WriteMultipleRegistersResponse;
import com.digitalpetri.modbus.responses.WriteSingleCoilResponse;
import com.digitalpetri.modbus.responses.WriteSingleRegisterResponse;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.DecoderException;

public class ModbusResponseDecoder implements ModbusPduDecoder {

    @Override
    public ModbusPdu decode(ByteBuf buffer) throws DecoderException {
        int code = buffer.readUnsignedByte();

        if (FunctionCode.isExceptionCode(code)) {
            FunctionCode functionCode = FunctionCode.fromCode(code - 0x80);
            if (functionCode == null) {
                throw new DecoderException("invalid function code: " + (code - 0x80));
            }

            return decodeException(functionCode, buffer);
        } else {
            FunctionCode functionCode = FunctionCode.fromCode(code);
            if (functionCode == null) {
                throw new DecoderException("invalid function code: " + code);
            }

            return decodeResponse(functionCode, buffer);
        }
    }

    private ModbusPdu decodeException(FunctionCode functionCode, ByteBuf buffer) throws DecoderException {
        int code = buffer.readUnsignedByte();

        ExceptionCode exceptionCode = ExceptionCode.fromCode(code);
        if (exceptionCode == null) {
            throw new DecoderException("invalid exception code: " + code);
        }

        return new ExceptionResponse(functionCode, exceptionCode);
    }

    private ModbusPdu decodeResponse(FunctionCode functionCode, ByteBuf buffer) throws DecoderException {
        switch (functionCode) {
        case ReadCoils:
            return decodeReadCoils(buffer);

        case ReadDiscreteInputs:
            return decodeReadDiscreteInputs(buffer);

        case ReadHoldingRegisters:
            return decodeReadHoldingRegisters(buffer);

        case ReadInputRegisters:
            return decodeReadInputRegisters(buffer);

        case WriteSingleCoil:
            return decodeWriteSingleCoil(buffer);

        case WriteSingleRegister:
            return decodeWriteSingleRegister(buffer);

        case WriteMultipleCoils:
            return decodeWriteMultipleCoils(buffer);

        case WriteMultipleRegisters:
            return decodeWriteMultipleRegisters(buffer);

        case MaskWriteRegister:
            return decodeMaskWriteRegister(buffer);

        default:
            return new UnsupportedPdu(functionCode);
        }
    }

    public ReadCoilsResponse decodeReadCoils(ByteBuf buffer) {
        int byteCount = buffer.readUnsignedByte();
        ByteBuf coilStatus = buffer.readSlice(byteCount).retain();

        return new ReadCoilsResponse(coilStatus);
    }

    public ReadDiscreteInputsResponse decodeReadDiscreteInputs(ByteBuf buffer) {
        int byteCount = buffer.readUnsignedByte();
        ByteBuf inputStatus = buffer.readSlice(byteCount).retain();

        return new ReadDiscreteInputsResponse(inputStatus);
    }

    public ReadHoldingRegistersResponse decodeReadHoldingRegisters(ByteBuf buffer) {
        int byteCount = buffer.readUnsignedByte();
        ByteBuf registers = buffer.readSlice(byteCount).retain();

        return new ReadHoldingRegistersResponse(registers);
    }

    public ReadInputRegistersResponse decodeReadInputRegisters(ByteBuf buffer) {
        int byteCount = buffer.readUnsignedByte();
        ByteBuf registers = buffer.readSlice(byteCount).retain();

        return new ReadInputRegistersResponse(registers);
    }

    public WriteSingleCoilResponse decodeWriteSingleCoil(ByteBuf buffer) {
        int address = buffer.readUnsignedShort();
        int value = buffer.readUnsignedShort();

        return new WriteSingleCoilResponse(address, value);
    }

    public WriteSingleRegisterResponse decodeWriteSingleRegister(ByteBuf buffer) {
        int address = buffer.readUnsignedShort();
        int value = buffer.readUnsignedShort();

        return new WriteSingleRegisterResponse(address, value);
    }

    public WriteMultipleCoilsResponse decodeWriteMultipleCoils(ByteBuf buffer) {
        int address = buffer.readUnsignedShort();
        int quantity = buffer.readUnsignedShort();

        return new WriteMultipleCoilsResponse(address, quantity);
    }

    public WriteMultipleRegistersResponse decodeWriteMultipleRegisters(ByteBuf buffer) {
        int address = buffer.readUnsignedShort();
        int quantity = buffer.readUnsignedShort();

        return new WriteMultipleRegistersResponse(address, quantity);
    }

    public MaskWriteRegisterResponse decodeMaskWriteRegister(ByteBuf buffer) {
        int address = buffer.readUnsignedShort();
        int andMask = buffer.readUnsignedShort();
        int orMask = buffer.readUnsignedShort();

        return new MaskWriteRegisterResponse(address, andMask, orMask);
    }

}