package com.walker.tcp.coder; import java.util.Arrays; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.walker.tcp.msg.MyAbstractMessage; import com.walker.tcp.msg.MyOEMMessage; import com.walker.tcp.util.ByteUtils; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageDecoder; /** * 描述:(充电)设备解码器,目前只有一种设备 * @author 时克英 * @date 2020年8月18日 下午6:24:30 */ public class MessageDecoder extends MessageToMessageDecoder { protected final transient Log logger = LogFactory.getLog(this.getClass()); // 目前只有这一家,开头特征 private final byte[] feature = new byte[] { (byte) 0xAA, (byte) 0xf5 }; // 不包含业务数据的报文其他字段长度(固定) private final int sizeWithoutData = 9; @Override protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { // 1-特征(2字节) byte[] msgFeature = new byte[2]; msg.readBytes(msgFeature); if(msgFeature[0] != feature[0] || msgFeature[1] != feature[1]){ logger.warn("未识别的设备请求特征:" + Arrays.toString(msgFeature)); out.add(null); return; } // 2-长度(2字节) msg.readBytes(msgFeature); int contentSize = ByteUtils.toInt2(msgFeature); if(contentSize != msg.capacity()){ logger.error("请求设备数据长度错误,数据提供长度:" + contentSize + ",实际长度:" + msg.capacity()); out.add(null); return; } // 这里先实现了一种设备解码,如果后续更多设备,改解码器需要重构。 MyAbstractMessage message = new MyOEMMessage(); message.setTotalSize(contentSize); // 3-信息域(1字节) byte info = msg.readByte(); // 4-序列号域(1字节) byte serialNum = msg.readByte(); // 5-命令字(2字节) msg.readBytes(msgFeature); // int command = ByteUtils.toInt2(msgFeature); // logger.debug("command = " + command); // if(command == 106){ // logger.debug("设备连接签到请求,这里需要判断如果不再命令集合中则丢掉数据"); // } message.setProtocol(ByteUtils.getCommand(msgFeature)); // 6-业务内容 byte[] data = new byte[contentSize - sizeWithoutData]; msg.readBytes(data); message.setPayload(data); out.add(message); } }