ModbusDecoderNetty,crc16modbus

/**
 *
 *ModbusDecoderNetty
 *
 */
@Slf4j
public class ModbusDecoderNetty extends ByteToMessageDecoder
{
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception
    {
        int iReadableBytes = in.readableBytes();
        if (iReadableBytes > 0)
        {
            int iReaderIndex = in.readerIndex();



            //判断是否已登录
            Session session = ChannelMap.getInstance().getClientInstance(ctx.channel());
            if (session == null || !session.hasAuth()) {
                //设备未登录。不做解析。直接返还
                if (in.getByte(in.readerIndex())==0){
                    //注册包
                    if(iReadableBytes < 16){
                        // 数据包未收齐
                        return;
                    }
                    ByteBuf bbPacket = Unpooled.buffer(16);
                    in.getBytes(iReaderIndex, bbPacket, 16);
                    out.add(bbPacket);

                    in.readerIndex(16 + iReaderIndex);
                    in.markReaderIndex();

                    log.info("[NettyServerPacketDecoder]注册解析成功");
                    return;
                }else {
                    log.error("[NettyServerPacketDecoder]注册解析失败");
                    in.readerIndex(iReadableBytes + iReaderIndex);
                    in.markReaderIndex();
                    return;
                }
            }else{

                int iStartFlag0 = NettyUtil.byte2Int(in.getByte(0 + iReaderIndex));
                int iStartFlag1 = NettyUtil.byte2Int(in.getByte(1 + iReaderIndex));


                if (iStartFlag0 == 0xFE || iStartFlag0 == 0xFF ){
                    //心跳包
                    ByteBuf bbPacket = Unpooled.buffer(1);
                    in.getBytes(iReaderIndex, bbPacket, 1);
                    out.add(bbPacket);

                    in.readerIndex(1 + iReaderIndex);
                    in.markReaderIndex();

                    return;
                }
                else
                {
                    // modbus
                    if (iReadableBytes < 5)
                    {
                        // 数据包未收齐
                        return;
                    }
                    for(int i = 1 + iReaderIndex ; i < iReadableBytes; i++){
                        int iStartFlag0_temp = NettyUtil.byte2Int(in.getByte(i - 1));
                        int iStartFlag1_temp = NettyUtil.byte2Int(in.getByte(i ));
                        if (iStartFlag1_temp == 0x03)
                        {
                            iReaderIndex = i -1;
                            iStartFlag0 = iStartFlag0_temp;
                            iStartFlag1 = iStartFlag1_temp;
                            break;
                        }
                    }


                    if(iStartFlag1 == 0x03){
                        // 确定报文长度,从索引11开始取2个字节低12位

                        int iFlagLen = in.getByte(2 + iReaderIndex);
                        int iPayloadLen = iFlagLen & 0x0FFF;
                        int iPacketLen = 5 + iPayloadLen;

                        if (iPacketLen <= iReadableBytes)
                        {
                            if(iPacketLen >= 120 || iStartFlag0 > 32){
                                in.readerIndex(1 + iReaderIndex);
                                in.markReaderIndex();
                                return;
                            }else{
                                // 有完整的数据包
                                ByteBuf bbPacket = Unpooled.buffer(iPacketLen);
                                in.getBytes(iReaderIndex, bbPacket, iPacketLen);
                                out.add(bbPacket);

                                in.readerIndex(iPacketLen + iReaderIndex);
                                in.markReaderIndex();


                            }

                        }
                        else
                        {
                            // 非完整的数据包
                            in.resetReaderIndex();

                        }
                        return;
                    }

                    return;
                }
            }




        }

    }

}

 

 

    public static int crc16(byte[] data) {
        int crc = 65535;
//        int pol = 'ꀁ';
        int pol = 40961;
        System.out.println("pol:" + pol);
        for(int i = 0; i < data.length; ++i) {
            crc ^= data[i] & 255;

            for(int j = 0; j < 8; ++j) {
                if ((crc & 1) != 0) {
                    crc >>= 1;
                    crc ^= pol;
                } else {
                    crc >>= 1;
                }
            }
        }

        crc = (crc & '\uff00') >> 8 | (crc & 255) << 8;
        return crc;
    }

 

 

    public static boolean hasValidCRC16MODBUS(byte[] buffer) {
        if (buffer.length < 3) {
            return false;
        } else {
            byte[] data = new byte[buffer.length - 2];
            System.arraycopy(buffer, 0, data, 0, data.length);
            int source = BytesUtils.beToInt(buffer, buffer.length - 2, 2);
            int target = crc16(data);
            return source == target;
        }
    }

 

posted on 2025-08-15 10:13  yebinghuai-qq-com  阅读(8)  评论(0)    收藏  举报

导航