Search in sources :

Example 1 with AmsSerialResetFrame

use of org.apache.plc4x.java.ads.api.serial.AmsSerialResetFrame in project plc4x by apache.

the class Payload2SerialProtocol method decode.

@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> out) throws Exception {
    LOGGER.trace("(-->IN): {}, {}, {}", channelHandlerContext, byteBuf, out);
    if (byteBuf.readableBytes() < MagicCookie.NUM_BYTES + TransmitterAddress.NUM_BYTES + ReceiverAddress.NUM_BYTES + FragmentNumber.NUM_BYTES) {
        return;
    }
    MagicCookie magicCookie = MagicCookie.of(byteBuf);
    TransmitterAddress transmitterAddress = TransmitterAddress.of(byteBuf);
    ReceiverAddress receiverAddress = ReceiverAddress.of(byteBuf);
    FragmentNumber fragmentNumber = FragmentNumber.of(byteBuf);
    int expectedFrameNumber = fragmentCounter.get() - 1;
    if (expectedFrameNumber < 0) {
        expectedFrameNumber = 255;
    }
    if (fragmentNumber.getAsByte() != expectedFrameNumber) {
        LOGGER.warn("Unexpected fragment {} received. Expected {}", fragmentNumber, expectedFrameNumber);
    }
    UserDataLength userDataLength = UserDataLength.of(byteBuf);
    UserData userData;
    byte userDataLengthAsByte = userDataLength.getAsByte();
    if (byteBuf.readableBytes() < userDataLengthAsByte) {
        return;
    }
    if (userDataLengthAsByte > 0) {
        byte[] userDataByteArray = new byte[userDataLengthAsByte];
        byteBuf.readBytes(userDataByteArray);
        userData = UserData.of(userDataByteArray);
    } else {
        userData = UserData.EMPTY;
    }
    CRC crc = CRC.of(byteBuf);
    // we don't need to retransmit
    ScheduledFuture<?> scheduledFuture = currentRetryer.get();
    if (scheduledFuture != null) {
        scheduledFuture.cancel(false);
    }
    Runnable postAction = null;
    switch(magicCookie.getAsInt()) {
        case AmsSerialFrame.ID:
            AmsSerialFrame amsSerialFrame = AmsSerialFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData, crc);
            LOGGER.debug("Ams Serial Frame received {}", amsSerialFrame);
            postAction = () -> {
                // TODO: check if this is the right way to ack a package.
                ChannelFuture channelFuture = channelHandlerContext.writeAndFlush(AmsSerialAcknowledgeFrame.of(transmitterAddress, receiverAddress, fragmentNumber).getByteBuf());
                // waiting for the ack-frame to be transmitted before we forward the package
                try {
                    channelFuture.await();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    throw new PlcRuntimeException(e);
                }
                out.add(userData.getByteBuf());
            };
            break;
        case AmsSerialAcknowledgeFrame.ID:
            AmsSerialAcknowledgeFrame amsSerialAcknowledgeFrame = AmsSerialAcknowledgeFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
            LOGGER.debug("Ams Serial ACK Frame received {}", amsSerialAcknowledgeFrame);
            ReferenceCountUtil.release(byteBuf);
            break;
        case AmsSerialResetFrame.ID:
            // TODO: how to react to a reset
            AmsSerialResetFrame amsSerialResetFrame = AmsSerialResetFrame.of(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, crc);
            LOGGER.debug("Ams Serial Reset Frame received {}", amsSerialResetFrame);
            ReferenceCountUtil.release(byteBuf);
            break;
        default:
            throw new PlcProtocolException("Unknown type: " + magicCookie);
    }
    CRC calculatedCrc = CRC.of(DigestUtil.calculateCrc16(magicCookie, transmitterAddress, receiverAddress, fragmentNumber, userDataLength, userData));
    if (!crc.equals(calculatedCrc)) {
        throw new PlcProtocolException("CRC checksum wrong. Got " + crc + " expected " + calculatedCrc);
    }
    if (postAction != null) {
        postAction.run();
    }
    if (byteBuf.readableBytes() > 0) {
        throw new IllegalStateException("Unread bytes left: " + byteBuf.readableBytes());
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AmsSerialFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialFrame) PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) AmsSerialResetFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialResetFrame) PlcProtocolException(org.apache.plc4x.java.api.exceptions.PlcProtocolException) AmsSerialAcknowledgeFrame(org.apache.plc4x.java.ads.api.serial.AmsSerialAcknowledgeFrame)

Aggregations

ChannelFuture (io.netty.channel.ChannelFuture)1 AmsSerialAcknowledgeFrame (org.apache.plc4x.java.ads.api.serial.AmsSerialAcknowledgeFrame)1 AmsSerialFrame (org.apache.plc4x.java.ads.api.serial.AmsSerialFrame)1 AmsSerialResetFrame (org.apache.plc4x.java.ads.api.serial.AmsSerialResetFrame)1 PlcProtocolException (org.apache.plc4x.java.api.exceptions.PlcProtocolException)1 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)1