All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gurux.dlms.GXPlcSettings Maven / Gradle / Ivy

There is a newer version: 4.0.72
Show newest version
//
// --------------------------------------------------------------------------
//  Gurux Ltd
// 
//
//
// Filename:        $HeadURL$
//
// Version:         $Revision$,
//                  $Date$
//                  $Author$
//
// Copyright (c) Gurux Ltd
//
//---------------------------------------------------------------------------
//
//  DESCRIPTION
//
// This file is a part of Gurux Device Framework.
//
// Gurux Device Framework is Open Source software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License 
// as published by the Free Software Foundation; version 2 of the License.
// Gurux Device Framework is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
// See the GNU General Public License for more details.
//
// More information of Gurux products: https://www.gurux.org
//
// This code is licensed under the GNU General Public License v2. 
// Full text may be retrieved at http://www.gnu.org/licenses/gpl-2.0.txt
//---------------------------------------------------------------------------

package gurux.dlms;

import java.util.ArrayList;
import java.util.List;

import gurux.dlms.enums.Command;
import gurux.dlms.enums.InterfaceType;
import gurux.dlms.internal.GXCommon;
import gurux.dlms.plc.GXDLMSPlcMeterInfo;
import gurux.dlms.plc.GXDLMSPlcRegister;
import gurux.dlms.plc.enums.PlcDestinationAddress;
import gurux.dlms.plc.enums.PlcHdlcSourceAddress;
import gurux.dlms.plc.enums.PlcSourceAddress;

/**
 * PLC communication settings.
 */
public class GXPlcSettings {
    private byte[] systemTitle;
    private GXDLMSSettings settings;
    /**
     * Initial credit (IC) tells how many times the frame must be repeated.
     * Maximum value is 7.
     */
    private int initialCredit;
    /**
     * The current credit (CC) initial value equal to IC and automatically
     * decremented by the MAC layer after each repetition. Maximum value is 7.
     */
    private int currentCredit;

    /**
     * Delta credit (DC) is used by the system management application entity
     * (SMAE) of the Client for credit management, while it has no meaning for a
     * Server or a REPEATER. It represents the difference(IC-CC) of the last
     * communication originated by the system identified by the DA address to
     * the system identified by the SA address. Maximum value is 3.
     */
    private byte deltaCredit;
    /**
     * Source MAC address.
     */
    private int macSourceAddress;
    /**
     * Destination MAC address.
     */
    private int macDestinationAddress;
    /**
     * Response probability.
     */
    private byte responseProbability;
    /**
     * Allowed time slots.
     */
    private int allowedTimeSlots;
    /**
     * Server saves client system title.
     */
    private byte[] clientSystemTitle;

    /**
     * @return Initial credit (IC) tells how many times the frame must be
     *         repeated. Maximum value is 7.
     */
    public final int getInitialCredit() {
        return initialCredit;
    }

    /**
     * @param value
     *            Initial credit (IC) tells how many times the frame must be
     *            repeated. Maximum value is 7.
     */
    public final void setInitialCredit(final int value) {
        initialCredit = value;
    }

    /**
     * @return The current credit (CC) initial value equal to IC and
     *         automatically decremented by the MAC layer after each repetition.
     *         Maximum value is 7.
     */
    public final int getCurrentCredit() {
        return currentCredit;
    }

    /**
     * @param value
     *            The current credit (CC) initial value equal to IC and
     *            automatically decremented by the MAC layer after each
     *            repetition. Maximum value is 7.
     */
    public final void setCurrentCredit(final int value) {
        currentCredit = value;
    }

    /**
     * @return Delta credit (DC) value.
     */
    public final byte getDeltaCredit() {
        return deltaCredit;
    }

    /**
     * @param value
     *            Delta credit (DC) value.
     */
    public final void setDeltaCredit(final byte value) {
        deltaCredit = value;
    }

    /**
     * @return IEC 61334-4-32 LLC uses 6 bytes long system title. IEC 61334-5-1
     *         uses 8 bytes long system title so we can use the default one.
     */
    public final byte[] getSystemTitle() {
        if (settings != null && settings.getInterfaceType() != InterfaceType.PLC
                && settings.getCipher() != null) {
            return settings.getCipher().getSystemTitle();
        }
        return systemTitle;
    }

    /**
     * @param value
     *            IEC 61334-4-32 LLC uses 6 bytes long system title. IEC
     *            61334-5-1 uses 8 bytes long system title so we can use the
     *            default one.
     */
    public final void setSystemTitle(final byte[] value) {
        if (settings != null && settings.getInterfaceType() != InterfaceType.PLC
                && settings.getCipher() != null) {
            settings.getCipher().setSystemTitle(value);
        }
        systemTitle = value;
    }

    /**
     * @return Source MAC address.
     */
    public final int getMacSourceAddress() {
        return macSourceAddress;
    }

    /**
     * @param value
     *            Source MAC address.
     */
    public final void setMacSourceAddress(final int value) {
        macSourceAddress = value;
    }

    /**
     * @return Destination MAC address.
     */
    public final int getMacDestinationAddress() {
        return macDestinationAddress;
    }

    /**
     * @param value
     *            Destination MAC address.
     */
    public final void setMacDestinationAddress(final int value) {
        macDestinationAddress = value;
    }

    /**
     * @return Response probability.
     */
    public final byte getResponseProbability() {
        return responseProbability;
    }

    /**
     * @param value
     *            Response probability.
     */
    public final void setResponseProbability(final byte value) {
        responseProbability = value;
    }

    /**
     * @return Allowed time slots.
     */
    public final int getAllowedTimeSlots() {
        return allowedTimeSlots;
    }

    /**
     * @param value
     *            Allowed time slots.
     */
    public final void setAllowedTimeSlots(final int value) {
        allowedTimeSlots = value;
    }

    /**
     * @return Server saves client system title.
     */
    public final byte[] getClientSystemTitle() {
        return clientSystemTitle;
    }

    /**
     * @param value
     *            Server saves client system title.
     */
    public final void setClientSystemTitle(final byte[] value) {
        clientSystemTitle = value;
    }

    /**
     * Set default values.
     */
    public final void reset() {
        initialCredit = 7;
        currentCredit = 7;
        deltaCredit = 0;
        // New device addresses are used.
        if (settings.getInterfaceType() == InterfaceType.PLC) {
            if (settings.isServer()) {
                macSourceAddress = PlcSourceAddress.NEW.getValue();
                macDestinationAddress = PlcSourceAddress.INITIATOR.getValue();
            } else {
                macSourceAddress = PlcSourceAddress.INITIATOR.getValue();
                macDestinationAddress =
                        PlcDestinationAddress.ALL_PHYSICAL.getValue();
            }
        } else {
            if (settings.isServer()) {
                macSourceAddress = PlcSourceAddress.NEW.getValue();
                macDestinationAddress =
                        PlcHdlcSourceAddress.INITIATOR.getValue();
            } else {
                macSourceAddress = PlcHdlcSourceAddress.INITIATOR.getValue();
                macDestinationAddress =
                        PlcDestinationAddress.ALL_PHYSICAL.getValue();
            }
        }
        responseProbability = 100;
        if (settings.getInterfaceType() == InterfaceType.PLC) {
            allowedTimeSlots = 10;
        } else {
            allowedTimeSlots = 0x14;
        }
    }

    public GXPlcSettings(GXDLMSSettings s) {
        settings = s;
        reset();
    }

    /**
     * Discover available PLC meters.
     * 
     * @return Generated bytes.
     */
    public final byte[] discoverRequest() {
        GXByteBuffer bb = new GXByteBuffer();
        if (settings.getInterfaceType() != InterfaceType.PLC
                && settings.getInterfaceType() != InterfaceType.PLC_HDLC) {
            throw new IllegalArgumentException("Invalid interface type.");
        }
        if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
            bb.set(GXCommon.LLC_SEND_BYTES);
        }
        bb.setUInt8(Command.DISCOVER_REQUEST);
        bb.setUInt8(getResponseProbability());
        bb.setUInt16(getAllowedTimeSlots());
        // DiscoverReport initial credit
        bb.setUInt8(0);
        // IC Equal credit
        bb.setUInt8(0);
        int val = 0;
        int clientAddress = settings.getClientAddress();
        int serverAddress = settings.getServerAddress();
        int da = settings.getPlc().getMacDestinationAddress();
        int sa = settings.getPlc().getMacSourceAddress();
        try {
            // 10.4.6.4 Source and destination APs and addresses of CI-PDUs
            // Client address is No-station in discoverReport.
            if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
                settings.getPlc().setInitialCredit((byte) 0);
                settings.getPlc().setCurrentCredit((byte) 0);
                settings.getPlc().setMacSourceAddress(0xC01);
                settings.getPlc().setMacDestinationAddress(0xFFF);
                settings.setClientAddress(0x66);
                // All-station
                settings.setServerAddress(0x33FF);
            } else {
                val = settings.getPlc().getInitialCredit() << 5;
                val |= settings.getPlc().getCurrentCredit() << 2;
                val |= settings.getPlc().getDeltaCredit() & 0x3;
                settings.getPlc().setMacSourceAddress(0xC00);
                settings.setClientAddress(1);
                settings.setServerAddress(0);
            }
            return GXDLMS.getMacFrame(settings, (byte) 0x13, (byte) val, bb);
        } finally {
            settings.setClientAddress(clientAddress);
            settings.setServerAddress(serverAddress);
            settings.getPlc().setMacDestinationAddress(da);
            settings.getPlc().setMacSourceAddress(sa);
        }
    }

    /**
     * Generates discover report.
     * 
     * @param systemTitle
     *            System title
     * @param newMeter
     *            Is this a new meter.
     * @return Generated bytes.
     */
    public final byte[] discoverReport(final byte[] systemTitle,
            final boolean newMeter) {
        GXByteBuffer bb = new GXByteBuffer();
        if (settings.getInterfaceType() != InterfaceType.PLC
                && settings.getInterfaceType() != InterfaceType.PLC_HDLC) {
            throw new IllegalArgumentException("Invalid interface type.");
        }
        int alarmDescription;
        if (settings.getInterfaceType() == InterfaceType.PLC) {
            alarmDescription = (newMeter ? 1 : 0x82);
        } else {
            alarmDescription = 0;
        }
        if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
            bb.set(GXCommon.LLC_REPLY_BYTES);
        }
        bb.setUInt8(Command.DISCOVER_REPORT);
        bb.setUInt8(1);
        bb.set(systemTitle);
        if (alarmDescription != 0) {
            bb.setUInt8(1);
        }
        bb.setUInt8(alarmDescription);
        int clientAddress = settings.getClientAddress();
        int serverAddress = settings.getServerAddress();
        int macSourceAddress = settings.getPlc().getMacSourceAddress();
        int macTargetAddress = settings.getPlc().getMacDestinationAddress();
        try {
            // 10.4.6.4 Source and destination APs and addresses of CI-PDUs
            // Client address is No-station in discoverReport.
            if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
                settings.getPlc().setMacDestinationAddress(
                        PlcHdlcSourceAddress.INITIATOR.getValue());
            } else {
                settings.setClientAddress(0);
                settings.setServerAddress(0xFD);
            }
            return GXDLMS.getMacFrame(settings, (byte) 0x13, (byte) 0, bb);
        } finally {
            settings.setClientAddress(clientAddress);
            settings.setServerAddress(serverAddress);
            settings.getPlc().setMacSourceAddress(macSourceAddress);
            settings.getPlc().setMacDestinationAddress(macTargetAddress);
        }
    }

    /**
     * @param value
     */

    /**
     * Parse discover reply.
     * 
     * @param value
     *            Received data.
     * @param sa
     *            Source address.
     * @param da
     *            Destination address.
     * @return Array of system titles and alarm descriptor error code
     */
    public final List parseDiscover(
            final GXByteBuffer value, final int sa, final int da) {
        List list = new ArrayList();
        short count = value.getUInt8();
        byte[] st;
        for (int pos = 0; pos != count; ++pos) {
            GXDLMSPlcMeterInfo info = new GXDLMSPlcMeterInfo();
            info.setSourceAddress(sa);
            info.setDestinationAddress(da);
            // Get System title.
            if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
                st = new byte[8];
            } else {
                st = new byte[6];
            }
            value.get(st);
            info.setSystemTitle(st);
            // Alarm descriptor of the reporting system.
            // Alarm-Descriptor presence flag
            if (value.getUInt8() != 0) {
                // Alarm-Descriptor
                info.setAlarmDescriptor(value.getUInt8());
            }
            list.add(info);
        }
        return list;
    }

    /**
     * Register PLC meters.
     * 
     * @param initiatorSystemTitle
     *            Active initiator system title
     * @param systemTitle
     *            System title.
     * @return Generated bytes.
     */
    public final byte[] registerRequest(final byte[] initiatorSystemTitle,
            final byte[] systemTitle) {
        GXByteBuffer bb = new GXByteBuffer();
        bb.setUInt8(Command.REGISTER_REQUEST);
        bb.set(initiatorSystemTitle);
        // LEN
        bb.setUInt8(0x1);
        bb.set(systemTitle);
        // MAC address.
        bb.setUInt16(getMacSourceAddress());
        int val = settings.getPlc().getInitialCredit() << 5;
        val |= settings.getPlc().getCurrentCredit() << 2;
        val |= settings.getPlc().getDeltaCredit() & 0x3;

        int clientAddress = settings.getClientAddress();
        int serverAddress = settings.getServerAddress();
        int macSourceAddress = settings.getPlc().getMacSourceAddress();
        int macTargetAddress = settings.getPlc().getMacDestinationAddress();
        try {
            // 10.4.6.4 Source and destination APs and addresses of CI-PDUs
            // Client address is No-station in discoverReport.
            if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
                settings.getPlc().setInitialCredit(0);
                settings.getPlc().setCurrentCredit(0);
                settings.getPlc().setMacSourceAddress(0xC01);
                settings.getPlc().setMacDestinationAddress(0xFFF);
                settings.setClientAddress(0x66);
                // All-station
                settings.setServerAddress(0x33FF);
            } else {
                settings.setClientAddress(1);
                settings.setServerAddress(0);
                settings.getPlc().setMacSourceAddress(0xC00);
                settings.getPlc().setMacDestinationAddress(0xFFF);
            }
            return GXDLMS.getMacFrame(settings, (byte) 0x13, (byte) val, bb);
        } finally {
            settings.setClientAddress(clientAddress);
            settings.setServerAddress(serverAddress);
            settings.getPlc().setMacSourceAddress(macSourceAddress);
            settings.getPlc().setMacDestinationAddress(macTargetAddress);
        }
    }

    /**
     * Parse register request.
     * 
     * @param value
     *            Received data.
     */
    public final void parseRegisterRequest(GXByteBuffer value) {
        // Get System title.
        byte[] st;
        if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
            st = new byte[8];
        } else {
            st = new byte[6];
        }
        value.get(st);
        short count = value.getUInt8();
        for (int pos = 0; pos != count; ++pos) {
            // Get System title.
            if (settings.getInterfaceType() == InterfaceType.PLC_HDLC) {
                st = new byte[8];
            } else {
                st = new byte[6];
            }
            value.get(st);
            setSystemTitle(st);
            // MAC address.
            setMacSourceAddress(value.getUInt16());
        }
    }

    /**
     * Parse discover request.
     * 
     * @param value
     *            Received data.
     * @return Register information.
     */
    public final GXDLMSPlcRegister
            parseDiscoverRequest(final GXByteBuffer value) {
        GXDLMSPlcRegister ret = new GXDLMSPlcRegister();
        ret.setResponseProbability(value.getUInt8());
        ret.setAllowedTimeSlots(value.getUInt16());
        ret.setDiscoverReportInitialCredit(value.getUInt8());
        ret.setICEqualCredit(value.getUInt8());
        return ret;
    }

    /**
     * Ping PLC meter.
     * 
     * @param systemTitle
     *            System title.
     * @return Generated bytes.
     */
    public final byte[] pingRequest(final byte[] systemTitle) {
        GXByteBuffer bb = new GXByteBuffer();
        // Control byte.
        bb.setUInt8(Command.PING_REQUEST);
        bb.set(systemTitle);
        return GXDLMS.getMacFrame(settings, (byte) 0x13, (byte) 0, bb);
    }

    /**
     * Parse ping response.
     * 
     * @param value
     *            Received data.
     * @return System title.
     */
    public final byte[] parsePing(final GXByteBuffer value) {
        return value.subArray(1, 6);
    }

    /**
     * Repeater call request.
     * 
     * @return Generated bytes.
     */
    public final byte[] repeaterCallRequest() {
        GXByteBuffer bb = new GXByteBuffer();
        // Control byte.
        bb.setUInt8(Command.REPEAT_CALL_REQUEST);
        // MaxAdrMac.
        bb.setUInt16(0x63);
        // Nb_Tslot_For_New
        bb.setUInt8(0);
        // Reception-Threshold default value
        bb.setUInt8(0);
        return GXDLMS.getMacFrame(settings, (byte) 0x13, (byte) 0xFC, bb);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy