package com.zhili.stationcontrol.chargeserver.handler; import com.zhili.stationcontrol.chargeserver.dto.ChargeMessage; import com.zhili.stationcontrol.util.BytesUtil; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.ArrayUtils; import java.util.List; /** * @author :HuangBin * @description:TODO * @date :2022/10/24 10:41 */ @Slf4j public class ChargeMessageDecoder extends ByteToMessageDecoder { public static final byte[] START = {(byte) 0xaa, (byte) 0xf5}; public static final int baseLen = 9; @Override protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List list) throws Exception { while (byteBuf.readableBytes() >= START.length) { // 寻找头部 byteBuf.markReaderIndex(); byte[] start = new byte[START.length]; byteBuf.readBytes(start); if (start[0] == START[0] && start[1] == START[1]) { //如果读到头部,继续解析 if (byteBuf.readableBytes() >= 2) { //解析长度 byte[] lenBytes = new byte[2]; byteBuf.readBytes(lenBytes); int len = BytesUtil.toIntWithLowerFirst(lenBytes); if (byteBuf.readableBytes() >= len - 4) { //解析剩下的部分 byte[] last = new byte[len - 4]; byteBuf.readBytes(last); byte[] checkSumObj = ArrayUtils.subarray(last, 2, last.length - 1); byte b = BytesUtil.sumCheck(checkSumObj); if (b == last[last.length - 1]) { //校验和正确,解析到一个正确的包 ChargeMessage chargeMessage = new ChargeMessage(); chargeMessage.setVersion(last[0]); chargeMessage.setSerialNo(last[1]); byte[] commandBytes = ArrayUtils.subarray(last, 2, 4); int i = BytesUtil.toIntWithLowerFirst(commandBytes); chargeMessage.setCommand(i); byte[] dataBytes = ArrayUtils.subarray(last, 4, last.length - 1); chargeMessage.setData(dataBytes); list.add(chargeMessage); } else { //包不正确,整体丢弃 } } else { //读不出一个整体的包,等待数据再读 byteBuf.resetReaderIndex(); return; } } else { //长度字段不够读,下次再读; byteBuf.resetReaderIndex(); return; } } else { //没有读到头部,继续往后读 byteBuf.resetReaderIndex(); byteBuf.skipBytes(1); // byteBuf.readByte(); } } } }