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

org.openmuc.jdlms.sessionlayer.hdlc.FrameRejectReason Maven / Gradle / Ivy

/*
 * Copyright 2012-18 Fraunhofer ISE
 *
 * This file is part of jDLMS.
 * For more information visit http://www.openmuc.org
 *
 * jDLMS is free 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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jDLMS 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with jDLMS.  If not, see .
 *
 */
package org.openmuc.jdlms.sessionlayer.hdlc;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

/**
 * Class representing the information field of a FrameReject response frame. For more information, see ISO 13239 section
 * 5.5.3.4.2
 */
public class FrameRejectReason implements Serializable {

    private byte rejectedControlField;

    private int nextSendSequence;
    private int nextReceiveSequence;

    private List rejectReasons;

    FrameRejectReason(byte controlField) {
        this.rejectedControlField = controlField;

        this.rejectReasons = RejectReason.reasonsFor(controlField);
    }

    private FrameRejectReason() {
    }

    static FrameRejectReason decode(byte[] data) throws IOException {
        FrameRejectReason frameRejectReason = new FrameRejectReason();
        ByteArrayInputStream iStream = new ByteArrayInputStream(data);

        int buffer = iStream.read();

        frameRejectReason.rejectedControlField = (byte) buffer;

        buffer = iStream.read();

        frameRejectReason.nextSendSequence = ((buffer & 0x40) >> 6) | ((buffer & 0x20) >> 4) | ((buffer & 0x10) >> 2);

        frameRejectReason.nextReceiveSequence = ((buffer & 0x04) >> 2) | (buffer & 0x02) | ((buffer & 0x01) << 2);

        buffer = iStream.read();

        frameRejectReason.rejectReasons = RejectReason.reasonsFor((byte) buffer);

        return frameRejectReason;
    }

    public List rejectReasons() {
        return rejectReasons;
    }

    byte[] encode() {
        byte[] result = new byte[3];

        result[0] = rejectedControlField;

        byte encodedSendSequence = (byte) (((nextSendSequence & 0x01) << 6) | ((nextSendSequence & 0x02) << 4)
                | ((nextSendSequence & 0x04) << 2));

        byte encodedReceiveSequence = (byte) (((nextReceiveSequence & 0x01) << 2) | (nextReceiveSequence & 0x02)
                | ((nextReceiveSequence & 0x04) >> 2));

        result[1] = (byte) (encodedReceiveSequence | encodedSendSequence);
        result[1] |= rejectedControlField & 0x08;

        result[2] = 0;
        for (RejectReason reason : this.rejectReasons) {
            result[2] |= reason.mask();
        }

        return result;
    }

    public enum RejectReason {
        CONTOL_FIELD_UNDEFINED(0x80),
        INVALID_INFORMATION(0x40),
        INFORMATION_SIZE_EXCEEDED(0x20),
        INVALID_RECEIVE_SEQUENCE(0x10);

        private static final RejectReason[] VALUES = values();
        private byte mask;

        private RejectReason(int mask) {
            this.mask = (byte) mask;
        }

        public byte mask() {
            return this.mask;
        }

        public static List reasonsFor(byte bits) {
            List reasons = new LinkedList<>();

            for (RejectReason reason : VALUES) {
                if ((reason.mask & bits) == reason.mask) {
                    reasons.add(reason);
                }
            }

            return reasons;
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy