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

org.bdware.dogp.codec.DOGPMessageCodec Maven / Gradle / Ivy

The newest version!
/*
 *    Copyright (c) [2021] [Peking University]
 *    [BDWare DOIP SDK] is licensed under Mulan PSL v2.
 *    You can use this software according to the terms and conditions of the Mulan PSL v2.
 *    You may obtain a copy of Mulan PSL v2 at:
 *             http://license.coscl.org.cn/MulanPSL2
 *    THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 *    See the Mulan PSL v2 for more details.
 */

package org.bdware.dogp.codec;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bdware.doip.codec.exception.MessageCodecException;

import java.util.List;

// USED In Address System
// Handle Request opcode = 1; Response opcode = 2, filled with dest(ip: port, 6bytes, big endian)
// USED In Client And Server n77
public class DOGPMessageCodec extends ByteToMessageCodec {
    static Logger LOGGER = LogManager.getLogger(DOGPMessageCodec.class);

    @Override
    protected void encode(ChannelHandlerContext ctx, DOGPMessage msg, ByteBuf out) throws Exception {
        dogpMsgToBytes(msg, out);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception {
        DOGPMessage envelope = new DOGPMessage();
        byteBufToDOGPMsg(in, envelope);
        out.add(envelope);
    }

    static byte[] EMPTY5 = new byte[]{0, 0, 0, 0, 0};
    static byte[] EMPTY6 = new byte[]{0, 0, 0, 0, 0, 0};
    static byte[] EMPTY16 = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    public static void dogpMsgToBytes(DOGPMessage dogpMessage, ByteBuf bf) throws MessageCodecException {
        if (dogpMessage.contentLength != dogpMessage.content.readableBytes()) {
            throw new MessageCodecException("unequal content length");
        }
        bf.writeByte(dogpMessage.opcode);
        if (dogpMessage.dataSpaceAddress == null || dogpMessage.dataSpaceAddress.length != 16) {
            dogpMessage.dataSpaceAddress = EMPTY16;
        }
        bf.writeBytes(dogpMessage.dataSpaceAddress);
        if (dogpMessage.dataAddress == null || dogpMessage.dataAddress.length != 16) {
            dogpMessage.dataAddress = EMPTY16;
        }
        bf.writeBytes(dogpMessage.dataAddress);
        if (dogpMessage.reserved == null || dogpMessage.reserved.length != 5) {
            dogpMessage.reserved = EMPTY5;
        }
        bf.writeBytes(dogpMessage.reserved);
        if (dogpMessage.srcIpAndPort == null || dogpMessage.srcIpAndPort.length != 6) {
            dogpMessage.srcIpAndPort = EMPTY6;
        }
        bf.writeBytes(dogpMessage.srcIpAndPort);

        if (dogpMessage.dstIpAndPort == null || dogpMessage.dstIpAndPort.length != 6) {
            dogpMessage.dstIpAndPort = EMPTY6;
        }
        bf.writeBytes(dogpMessage.dstIpAndPort);
        bf.writeInt(dogpMessage.contentLength);
        bf.writeBytes(dogpMessage.content);
        dogpMessage.content.release();
        return;
    }

    public static void byteBufToDOGPMsg(ByteBuf bf, DOGPMessage dogpMessage) throws MessageCodecException {
        dogpMessage.opcode = bf.readByte();
        dogpMessage.dataSpaceAddress = new byte[16];
        bf.readBytes(dogpMessage.dataSpaceAddress);
        dogpMessage.dataAddress = new byte[16];
        bf.readBytes(dogpMessage.dataAddress);
        dogpMessage.reserved = new byte[5];
        bf.readBytes(dogpMessage.reserved);
        dogpMessage.srcIpAndPort = new byte[6];
        bf.readBytes(dogpMessage.srcIpAndPort);
        dogpMessage.dstIpAndPort = new byte[6];
        bf.readBytes(dogpMessage.dstIpAndPort);
        dogpMessage.contentLength = bf.readInt();
        if (dogpMessage.contentLength != bf.readableBytes()) {
            throw new MessageCodecException("unequal content length: " + dogpMessage.contentLength + ":" + bf.readableBytes());
        }
        dogpMessage.content = bf.retainedSlice(bf.readerIndex(), bf.readableBytes());
      //  bf.release();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        LOGGER.debug("got exception: " + cause.getMessage());
        cause.printStackTrace();
        if (ctx.channel().isActive()) ctx.close();
    }
}