diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java index a2debd0..eb167d6 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java @@ -51,6 +51,7 @@ // 通过协议工厂匹配,匹配规则,获取规则配置 RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); if (ObjectUtil.isEmpty(ruleConfig)) { + //如果出现匹配情况 return ParseResult.builder().replyCommand(NONE_DATA).build(); } //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 @@ -58,6 +59,7 @@ //获取流程实例配置 ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); DatagramEventConfig datagramEventConfig = datagramEventProvider.getProcessorInstance(); + //处理粘包拆包的主要组合 List frameStructDispenserList = ClazzUtil.getSubClassList(FrameStructMatcher.class, true); ByteBuf wholeNewPlainBuf = null; //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java index a2debd0..eb167d6 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java @@ -51,6 +51,7 @@ // 通过协议工厂匹配,匹配规则,获取规则配置 RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); if (ObjectUtil.isEmpty(ruleConfig)) { + //如果出现匹配情况 return ParseResult.builder().replyCommand(NONE_DATA).build(); } //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 @@ -58,6 +59,7 @@ //获取流程实例配置 ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); DatagramEventConfig datagramEventConfig = datagramEventProvider.getProcessorInstance(); + //处理粘包拆包的主要组合 List frameStructDispenserList = ClazzUtil.getSubClassList(FrameStructMatcher.class, true); ByteBuf wholeNewPlainBuf = null; //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java new file mode 100644 index 0000000..54f4c0a --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java @@ -0,0 +1,86 @@ +package com.casic.missiles.parser.matcher; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.crc.CRC16; +import com.casic.missiles.pojo.ProtocolConfig; +import com.casic.missiles.provider.ProtocolFieldConfigProvider; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; + +/** + * @author cz + * @date 2023-7-7 + */ +public class FrameStructMatchSupport { + + /** + * 匹配长度分为以下情况,进行以下情况进行匹配 + * 分为加密大于等于,不加密大于等于的情况 + * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 + * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 + * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, + * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null + * 3、不满足1、2则不对协议进行解析,同时打印日志 + * + * @return + */ + protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { + ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); + ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); + Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); + //一次匹配 + ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); + if (ObjectUtils.isNotEmpty(matchByteBuf)) { + return matchByteBuf; + } + //如果没有匹配成功则进行二次,长度增加补0匹配 + if (ObjectUtils.isNotEmpty(groupLength)) { + protocolFactory.getProtocolFieldConfigProvider(); + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + //执行补零操作 + Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); + Integer remainder = fixedLength % groupLength; + Integer fillZero = groupLength - remainder; + totalLength += fillZero; + } + } + return doMatchLength(byteBuf, totalLength); + } + + /** + * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 + * 1、相等返回当前的byteBuf + * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 + * + * @param byteBuf + * @param totalLength + * @return + */ + private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { + //放在加密前进行计算, + if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { + byteBuf.readerIndex(totalLength); + return byteBuf; + } + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + ByteBuf preJudgment = byteBuf.slice(0, totalLength); + if (crcCheck(preJudgment)) { + byteBuf.readerIndex(totalLength); + return preJudgment; + } + } + return null; + } + + + public Boolean crcCheck(ByteBuf byteBuf) { + String contentHexStr = ByteBufUtil.hexDump(byteBuf); + String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); + String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); + String crcCalculatedValue = CRC16.getCRC(crcContentStr); + return crcRealValue.equals(crcCalculatedValue); + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java index a2debd0..eb167d6 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java @@ -51,6 +51,7 @@ // 通过协议工厂匹配,匹配规则,获取规则配置 RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); if (ObjectUtil.isEmpty(ruleConfig)) { + //如果出现匹配情况 return ParseResult.builder().replyCommand(NONE_DATA).build(); } //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 @@ -58,6 +59,7 @@ //获取流程实例配置 ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); DatagramEventConfig datagramEventConfig = datagramEventProvider.getProcessorInstance(); + //处理粘包拆包的主要组合 List frameStructDispenserList = ClazzUtil.getSubClassList(FrameStructMatcher.class, true); ByteBuf wholeNewPlainBuf = null; //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java new file mode 100644 index 0000000..54f4c0a --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java @@ -0,0 +1,86 @@ +package com.casic.missiles.parser.matcher; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.crc.CRC16; +import com.casic.missiles.pojo.ProtocolConfig; +import com.casic.missiles.provider.ProtocolFieldConfigProvider; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; + +/** + * @author cz + * @date 2023-7-7 + */ +public class FrameStructMatchSupport { + + /** + * 匹配长度分为以下情况,进行以下情况进行匹配 + * 分为加密大于等于,不加密大于等于的情况 + * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 + * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 + * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, + * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null + * 3、不满足1、2则不对协议进行解析,同时打印日志 + * + * @return + */ + protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { + ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); + ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); + Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); + //一次匹配 + ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); + if (ObjectUtils.isNotEmpty(matchByteBuf)) { + return matchByteBuf; + } + //如果没有匹配成功则进行二次,长度增加补0匹配 + if (ObjectUtils.isNotEmpty(groupLength)) { + protocolFactory.getProtocolFieldConfigProvider(); + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + //执行补零操作 + Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); + Integer remainder = fixedLength % groupLength; + Integer fillZero = groupLength - remainder; + totalLength += fillZero; + } + } + return doMatchLength(byteBuf, totalLength); + } + + /** + * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 + * 1、相等返回当前的byteBuf + * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 + * + * @param byteBuf + * @param totalLength + * @return + */ + private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { + //放在加密前进行计算, + if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { + byteBuf.readerIndex(totalLength); + return byteBuf; + } + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + ByteBuf preJudgment = byteBuf.slice(0, totalLength); + if (crcCheck(preJudgment)) { + byteBuf.readerIndex(totalLength); + return preJudgment; + } + } + return null; + } + + + public Boolean crcCheck(ByteBuf byteBuf) { + String contentHexStr = ByteBufUtil.hexDump(byteBuf); + String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); + String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); + String crcCalculatedValue = CRC16.getCRC(crcContentStr); + return crcRealValue.equals(crcCalculatedValue); + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java deleted file mode 100644 index 40d4b55..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.casic.missiles.parser.matcher; - -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; -import com.casic.missiles.factory.AbstractProtocolConfigFactory; -import com.casic.missiles.parser.crc.CRC16; -import com.casic.missiles.pojo.ProtocolConfig; -import com.casic.missiles.provider.ProtocolFieldConfigProvider; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; - -/** - * @author cz - * @date 2023-7-7 - */ -public class FrameStructMatcherSupport { - - /** - * 匹配长度分为以下情况,进行以下情况进行匹配 - * 分为加密大于等于,不加密大于等于的情况 - * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 - * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 - * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, - * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null - * 3、不满足1、2则不对协议进行解析,同时打印日志 - * - * @return - */ - protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { - ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); - //一次匹配 - ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); - if (ObjectUtils.isNotEmpty(matchByteBuf)) { - return matchByteBuf; - } - //如果没有匹配成功则进行二次,长度增加补0匹配 - if (ObjectUtils.isNotEmpty(groupLength)) { - protocolFactory.getProtocolFieldConfigProvider(); - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - //执行补零操作 - Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); - Integer remainder = fixedLength % groupLength; - Integer fillZero = groupLength - remainder; - totalLength += fillZero; - } - } - return doMatchLength(byteBuf, totalLength); - } - - /** - * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 - * 1、相等返回当前的byteBuf - * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 - * - * @param byteBuf - * @param totalLength - * @return - */ - private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { - //放在加密前进行计算, - if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { - return byteBuf; - } - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - ByteBuf preJudgment = byteBuf.slice(0, totalLength); - if (crcCheck(preJudgment)) { - return preJudgment; - } - } - return null; - } - - - public Boolean crcCheck(ByteBuf byteBuf) { - String contentHexStr = ByteBufUtil.hexDump(byteBuf); - String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); - String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); - String crcCalculatedValue = CRC16.getCRC(crcContentStr); - return crcRealValue.equals(crcCalculatedValue); - } - - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java index a2debd0..eb167d6 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java @@ -51,6 +51,7 @@ // 通过协议工厂匹配,匹配规则,获取规则配置 RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); if (ObjectUtil.isEmpty(ruleConfig)) { + //如果出现匹配情况 return ParseResult.builder().replyCommand(NONE_DATA).build(); } //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 @@ -58,6 +59,7 @@ //获取流程实例配置 ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); DatagramEventConfig datagramEventConfig = datagramEventProvider.getProcessorInstance(); + //处理粘包拆包的主要组合 List frameStructDispenserList = ClazzUtil.getSubClassList(FrameStructMatcher.class, true); ByteBuf wholeNewPlainBuf = null; //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java new file mode 100644 index 0000000..54f4c0a --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java @@ -0,0 +1,86 @@ +package com.casic.missiles.parser.matcher; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.crc.CRC16; +import com.casic.missiles.pojo.ProtocolConfig; +import com.casic.missiles.provider.ProtocolFieldConfigProvider; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; + +/** + * @author cz + * @date 2023-7-7 + */ +public class FrameStructMatchSupport { + + /** + * 匹配长度分为以下情况,进行以下情况进行匹配 + * 分为加密大于等于,不加密大于等于的情况 + * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 + * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 + * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, + * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null + * 3、不满足1、2则不对协议进行解析,同时打印日志 + * + * @return + */ + protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { + ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); + ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); + Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); + //一次匹配 + ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); + if (ObjectUtils.isNotEmpty(matchByteBuf)) { + return matchByteBuf; + } + //如果没有匹配成功则进行二次,长度增加补0匹配 + if (ObjectUtils.isNotEmpty(groupLength)) { + protocolFactory.getProtocolFieldConfigProvider(); + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + //执行补零操作 + Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); + Integer remainder = fixedLength % groupLength; + Integer fillZero = groupLength - remainder; + totalLength += fillZero; + } + } + return doMatchLength(byteBuf, totalLength); + } + + /** + * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 + * 1、相等返回当前的byteBuf + * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 + * + * @param byteBuf + * @param totalLength + * @return + */ + private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { + //放在加密前进行计算, + if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { + byteBuf.readerIndex(totalLength); + return byteBuf; + } + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + ByteBuf preJudgment = byteBuf.slice(0, totalLength); + if (crcCheck(preJudgment)) { + byteBuf.readerIndex(totalLength); + return preJudgment; + } + } + return null; + } + + + public Boolean crcCheck(ByteBuf byteBuf) { + String contentHexStr = ByteBufUtil.hexDump(byteBuf); + String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); + String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); + String crcCalculatedValue = CRC16.getCRC(crcContentStr); + return crcRealValue.equals(crcCalculatedValue); + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java deleted file mode 100644 index 40d4b55..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.casic.missiles.parser.matcher; - -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; -import com.casic.missiles.factory.AbstractProtocolConfigFactory; -import com.casic.missiles.parser.crc.CRC16; -import com.casic.missiles.pojo.ProtocolConfig; -import com.casic.missiles.provider.ProtocolFieldConfigProvider; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; - -/** - * @author cz - * @date 2023-7-7 - */ -public class FrameStructMatcherSupport { - - /** - * 匹配长度分为以下情况,进行以下情况进行匹配 - * 分为加密大于等于,不加密大于等于的情况 - * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 - * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 - * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, - * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null - * 3、不满足1、2则不对协议进行解析,同时打印日志 - * - * @return - */ - protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { - ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); - //一次匹配 - ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); - if (ObjectUtils.isNotEmpty(matchByteBuf)) { - return matchByteBuf; - } - //如果没有匹配成功则进行二次,长度增加补0匹配 - if (ObjectUtils.isNotEmpty(groupLength)) { - protocolFactory.getProtocolFieldConfigProvider(); - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - //执行补零操作 - Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); - Integer remainder = fixedLength % groupLength; - Integer fillZero = groupLength - remainder; - totalLength += fillZero; - } - } - return doMatchLength(byteBuf, totalLength); - } - - /** - * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 - * 1、相等返回当前的byteBuf - * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 - * - * @param byteBuf - * @param totalLength - * @return - */ - private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { - //放在加密前进行计算, - if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { - return byteBuf; - } - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - ByteBuf preJudgment = byteBuf.slice(0, totalLength); - if (crcCheck(preJudgment)) { - return preJudgment; - } - } - return null; - } - - - public Boolean crcCheck(ByteBuf byteBuf) { - String contentHexStr = ByteBufUtil.hexDump(byteBuf); - String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); - String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); - String crcCalculatedValue = CRC16.getCRC(crcContentStr); - return crcRealValue.equals(crcCalculatedValue); - } - - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java index ec0149d..4927c1e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java @@ -2,8 +2,8 @@ import cn.hutool.core.util.ObjectUtil; import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.matcher.FrameStructMatchSupport; import com.casic.missiles.parser.matcher.FrameStructMatcher; -import com.casic.missiles.parser.matcher.FrameStructMatcherSupport; import com.casic.missiles.pojo.DatagramEventConfig; import com.casic.missiles.provider.ProtocolFieldConfigProvider; import com.casic.missiles.pojo.ProtocolConfig; @@ -15,7 +15,7 @@ * @author cz */ @Order(0) -public class FrameLengthMatcher extends FrameStructMatcherSupport implements FrameStructMatcher { +public class FrameLengthMatcher extends FrameStructMatchSupport implements FrameStructMatcher { /** * 超过长度,增加容错长度,同时增加了CRC校验,对帧结构进行判别 @@ -31,13 +31,13 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (matchLength(byteBuf,datagramEventConfig.getSafeLength(),protocolFactory)) {//等于长度返回true,超出长度,切断 + ByteBuf matchByteBuf = matchLength(byteBuf, datagramEventConfig.getSafeLength(), protocolFactory); + if (matchByteBuf != null) {//等于长度返回true,超出长度,切断 //根据CRC校验取值,如果存在加密 - ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); - return wholeDatagramByte; + byteBuf.markReaderIndex();//读的标志位前移 + return matchByteBuf; } else { - //读的标志位前移舍弃 - byteBuf.markReaderIndex(); + //暂时不做处理 return null; } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java index a2debd0..eb167d6 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java @@ -51,6 +51,7 @@ // 通过协议工厂匹配,匹配规则,获取规则配置 RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); if (ObjectUtil.isEmpty(ruleConfig)) { + //如果出现匹配情况 return ParseResult.builder().replyCommand(NONE_DATA).build(); } //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 @@ -58,6 +59,7 @@ //获取流程实例配置 ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); DatagramEventConfig datagramEventConfig = datagramEventProvider.getProcessorInstance(); + //处理粘包拆包的主要组合 List frameStructDispenserList = ClazzUtil.getSubClassList(FrameStructMatcher.class, true); ByteBuf wholeNewPlainBuf = null; //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java new file mode 100644 index 0000000..54f4c0a --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java @@ -0,0 +1,86 @@ +package com.casic.missiles.parser.matcher; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.crc.CRC16; +import com.casic.missiles.pojo.ProtocolConfig; +import com.casic.missiles.provider.ProtocolFieldConfigProvider; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; + +/** + * @author cz + * @date 2023-7-7 + */ +public class FrameStructMatchSupport { + + /** + * 匹配长度分为以下情况,进行以下情况进行匹配 + * 分为加密大于等于,不加密大于等于的情况 + * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 + * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 + * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, + * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null + * 3、不满足1、2则不对协议进行解析,同时打印日志 + * + * @return + */ + protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { + ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); + ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); + Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); + //一次匹配 + ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); + if (ObjectUtils.isNotEmpty(matchByteBuf)) { + return matchByteBuf; + } + //如果没有匹配成功则进行二次,长度增加补0匹配 + if (ObjectUtils.isNotEmpty(groupLength)) { + protocolFactory.getProtocolFieldConfigProvider(); + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + //执行补零操作 + Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); + Integer remainder = fixedLength % groupLength; + Integer fillZero = groupLength - remainder; + totalLength += fillZero; + } + } + return doMatchLength(byteBuf, totalLength); + } + + /** + * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 + * 1、相等返回当前的byteBuf + * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 + * + * @param byteBuf + * @param totalLength + * @return + */ + private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { + //放在加密前进行计算, + if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { + byteBuf.readerIndex(totalLength); + return byteBuf; + } + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + ByteBuf preJudgment = byteBuf.slice(0, totalLength); + if (crcCheck(preJudgment)) { + byteBuf.readerIndex(totalLength); + return preJudgment; + } + } + return null; + } + + + public Boolean crcCheck(ByteBuf byteBuf) { + String contentHexStr = ByteBufUtil.hexDump(byteBuf); + String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); + String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); + String crcCalculatedValue = CRC16.getCRC(crcContentStr); + return crcRealValue.equals(crcCalculatedValue); + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java deleted file mode 100644 index 40d4b55..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.casic.missiles.parser.matcher; - -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; -import com.casic.missiles.factory.AbstractProtocolConfigFactory; -import com.casic.missiles.parser.crc.CRC16; -import com.casic.missiles.pojo.ProtocolConfig; -import com.casic.missiles.provider.ProtocolFieldConfigProvider; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; - -/** - * @author cz - * @date 2023-7-7 - */ -public class FrameStructMatcherSupport { - - /** - * 匹配长度分为以下情况,进行以下情况进行匹配 - * 分为加密大于等于,不加密大于等于的情况 - * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 - * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 - * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, - * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null - * 3、不满足1、2则不对协议进行解析,同时打印日志 - * - * @return - */ - protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { - ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); - //一次匹配 - ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); - if (ObjectUtils.isNotEmpty(matchByteBuf)) { - return matchByteBuf; - } - //如果没有匹配成功则进行二次,长度增加补0匹配 - if (ObjectUtils.isNotEmpty(groupLength)) { - protocolFactory.getProtocolFieldConfigProvider(); - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - //执行补零操作 - Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); - Integer remainder = fixedLength % groupLength; - Integer fillZero = groupLength - remainder; - totalLength += fillZero; - } - } - return doMatchLength(byteBuf, totalLength); - } - - /** - * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 - * 1、相等返回当前的byteBuf - * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 - * - * @param byteBuf - * @param totalLength - * @return - */ - private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { - //放在加密前进行计算, - if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { - return byteBuf; - } - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - ByteBuf preJudgment = byteBuf.slice(0, totalLength); - if (crcCheck(preJudgment)) { - return preJudgment; - } - } - return null; - } - - - public Boolean crcCheck(ByteBuf byteBuf) { - String contentHexStr = ByteBufUtil.hexDump(byteBuf); - String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); - String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); - String crcCalculatedValue = CRC16.getCRC(crcContentStr); - return crcRealValue.equals(crcCalculatedValue); - } - - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java index ec0149d..4927c1e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java @@ -2,8 +2,8 @@ import cn.hutool.core.util.ObjectUtil; import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.matcher.FrameStructMatchSupport; import com.casic.missiles.parser.matcher.FrameStructMatcher; -import com.casic.missiles.parser.matcher.FrameStructMatcherSupport; import com.casic.missiles.pojo.DatagramEventConfig; import com.casic.missiles.provider.ProtocolFieldConfigProvider; import com.casic.missiles.pojo.ProtocolConfig; @@ -15,7 +15,7 @@ * @author cz */ @Order(0) -public class FrameLengthMatcher extends FrameStructMatcherSupport implements FrameStructMatcher { +public class FrameLengthMatcher extends FrameStructMatchSupport implements FrameStructMatcher { /** * 超过长度,增加容错长度,同时增加了CRC校验,对帧结构进行判别 @@ -31,13 +31,13 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (matchLength(byteBuf,datagramEventConfig.getSafeLength(),protocolFactory)) {//等于长度返回true,超出长度,切断 + ByteBuf matchByteBuf = matchLength(byteBuf, datagramEventConfig.getSafeLength(), protocolFactory); + if (matchByteBuf != null) {//等于长度返回true,超出长度,切断 //根据CRC校验取值,如果存在加密 - ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); - return wholeDatagramByte; + byteBuf.markReaderIndex();//读的标志位前移 + return matchByteBuf; } else { - //读的标志位前移舍弃 - byteBuf.markReaderIndex(); + //暂时不做处理 return null; } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java index 232d439..c4e35c9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java @@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.matcher.FrameStructMatchSupport; import com.casic.missiles.parser.matcher.FrameStructMatcher; -import com.casic.missiles.parser.matcher.FrameStructMatcherSupport; import com.casic.missiles.pojo.DatagramEventConfig; import com.casic.missiles.provider.ProtocolFieldConfigProvider; import com.casic.missiles.pojo.ProtocolConfig; @@ -24,7 +24,7 @@ */ @Order(1) @Slf4j -public class FrameMarkMatcher extends FrameStructMatcherSupport implements FrameStructMatcher, FixedPropertyEnum { +public class FrameMarkMatcher extends FrameStructMatchSupport implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @Override @@ -36,17 +36,18 @@ } Integer unpackFlag = ObjectUtils.isEmpty(protocolConfig.getUnpackId()) ? null : protocolFieldConfigProvider.getProtocolFieldValue(protocolConfig.getUnpackId(), byteBuf); - ByteBuf mergeWholeFrameByte = null; + ByteBuf intactMessageByte = null; if (!ObjectUtil.isEmpty(unpackFlag)) { while (hasNextFullFrame(byteBuf, protocolConfig, protocolFieldConfigProvider)) { //是否存在后续位 - if (unpackFlag == 1) {//使用esayRule + if (unpackFlag == 1) { //表示可以截取 - mergeWholeFrameByte = getWholeDatagramByte(byteBuf, protocolFieldConfigProvider, protocolConfig); - return mergeWholeFrameByte; + intactMessageByte = mergeMarkFrame(byteBuf, protocolFieldConfigProvider, protocolConfig, datagramEventConfig); + return intactMessageByte; } else { byteBuf.readerIndex(byteBuf.readerIndex() + getNextFrameOffset(byteBuf, protocolConfig, protocolFieldConfigProvider)); } + } } return null; @@ -54,7 +55,8 @@ //选取第一个帧,将业务内容和后面部分分开 //计算数据报文-业务内容 - private ByteBuf getWholeDatagramByte(ByteBuf byteBuf, ProtocolFieldConfigProvider protocolFieldConfigProvider, ProtocolConfig protocolConfig) { + private ByteBuf mergeMarkFrame(ByteBuf byteBuf, ProtocolFieldConfigProvider protocolFieldConfigProvider, + ProtocolConfig protocolConfig, DatagramEventConfig datagramEventConfig) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); //截取完整报文 byteBuf.readBytes(totalLength); @@ -65,7 +67,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前" + ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +89,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - log.debug("--合并后--"+ByteBufUtil.hexDump(mergeWholeFrameByte)); + log.debug("--合并后--" + ByteBufUtil.hexDump(mergeWholeFrameByte)); return mergeWholeFrameByte; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java index a2debd0..eb167d6 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/GenericProtocolParser.java @@ -51,6 +51,7 @@ // 通过协议工厂匹配,匹配规则,获取规则配置 RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); if (ObjectUtil.isEmpty(ruleConfig)) { + //如果出现匹配情况 return ParseResult.builder().replyCommand(NONE_DATA).build(); } //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 @@ -58,6 +59,7 @@ //获取流程实例配置 ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); DatagramEventConfig datagramEventConfig = datagramEventProvider.getProcessorInstance(); + //处理粘包拆包的主要组合 List frameStructDispenserList = ClazzUtil.getSubClassList(FrameStructMatcher.class, true); ByteBuf wholeNewPlainBuf = null; //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java new file mode 100644 index 0000000..54f4c0a --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatchSupport.java @@ -0,0 +1,86 @@ +package com.casic.missiles.parser.matcher; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.crc.CRC16; +import com.casic.missiles.pojo.ProtocolConfig; +import com.casic.missiles.provider.ProtocolFieldConfigProvider; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; + +/** + * @author cz + * @date 2023-7-7 + */ +public class FrameStructMatchSupport { + + /** + * 匹配长度分为以下情况,进行以下情况进行匹配 + * 分为加密大于等于,不加密大于等于的情况 + * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 + * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 + * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, + * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null + * 3、不满足1、2则不对协议进行解析,同时打印日志 + * + * @return + */ + protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { + ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); + ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); + Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); + //一次匹配 + ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); + if (ObjectUtils.isNotEmpty(matchByteBuf)) { + return matchByteBuf; + } + //如果没有匹配成功则进行二次,长度增加补0匹配 + if (ObjectUtils.isNotEmpty(groupLength)) { + protocolFactory.getProtocolFieldConfigProvider(); + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + //执行补零操作 + Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); + Integer remainder = fixedLength % groupLength; + Integer fillZero = groupLength - remainder; + totalLength += fillZero; + } + } + return doMatchLength(byteBuf, totalLength); + } + + /** + * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 + * 1、相等返回当前的byteBuf + * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 + * + * @param byteBuf + * @param totalLength + * @return + */ + private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { + //放在加密前进行计算, + if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { + byteBuf.readerIndex(totalLength); + return byteBuf; + } + if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { + ByteBuf preJudgment = byteBuf.slice(0, totalLength); + if (crcCheck(preJudgment)) { + byteBuf.readerIndex(totalLength); + return preJudgment; + } + } + return null; + } + + + public Boolean crcCheck(ByteBuf byteBuf) { + String contentHexStr = ByteBufUtil.hexDump(byteBuf); + String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); + String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); + String crcCalculatedValue = CRC16.getCRC(crcContentStr); + return crcRealValue.equals(crcCalculatedValue); + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java deleted file mode 100644 index 40d4b55..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/FrameStructMatcherSupport.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.casic.missiles.parser.matcher; - -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; -import com.casic.missiles.factory.AbstractProtocolConfigFactory; -import com.casic.missiles.parser.crc.CRC16; -import com.casic.missiles.pojo.ProtocolConfig; -import com.casic.missiles.provider.ProtocolFieldConfigProvider; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; - -/** - * @author cz - * @date 2023-7-7 - */ -public class FrameStructMatcherSupport { - - /** - * 匹配长度分为以下情况,进行以下情况进行匹配 - * 分为加密大于等于,不加密大于等于的情况 - * 1、如果有加密方式,则在计算的原业务内容长度与实际长度相比较,如果长度小于实际长度 - * 对业务内容进行补零,最后进行CRC校验,截取对应的数据报文 - * 2、如果没有加密方式,则进行业务设定的长度与实例长度,比较,对最后两位进行CRC校验,如果小于实际长度, - * 则进行长度截取CRC校验,CRC校验通过,则截取对应的数据报文,否则返回null - * 3、不满足1、2则不对协议进行解析,同时打印日志 - * - * @return - */ - protected ByteBuf matchLength(ByteBuf byteBuf, Integer groupLength, AbstractProtocolConfigFactory protocolFactory) { - ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - ProtocolFieldConfigProvider protocolFieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); - //一次匹配 - ByteBuf matchByteBuf = doMatchLength(byteBuf, totalLength); - if (ObjectUtils.isNotEmpty(matchByteBuf)) { - return matchByteBuf; - } - //如果没有匹配成功则进行二次,长度增加补0匹配 - if (ObjectUtils.isNotEmpty(groupLength)) { - protocolFactory.getProtocolFieldConfigProvider(); - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - //执行补零操作 - Integer fixedLength = protocolFieldConfigProvider.getFixedLength(byteBuf, protocolConfig); - Integer remainder = fixedLength % groupLength; - Integer fillZero = groupLength - remainder; - totalLength += fillZero; - } - } - return doMatchLength(byteBuf, totalLength); - } - - /** - * 判断长度时候与指定长度相等,分为当前单包匹配,粘包截取长度匹配,以CRC验证作为整包依据 - * 1、相等返回当前的byteBuf - * 2、如果大于,进行预判断是否进行粘包,拆取数据帧 - * - * @param byteBuf - * @param totalLength - * @return - */ - private ByteBuf doMatchLength(ByteBuf byteBuf, Integer totalLength) { - //放在加密前进行计算, - if (ByteBufUtil.hexDump(byteBuf).length() / 2 == totalLength && crcCheck(byteBuf)) { - return byteBuf; - } - if (ByteBufUtil.hexDump(byteBuf).length() / 2 > totalLength) { - ByteBuf preJudgment = byteBuf.slice(0, totalLength); - if (crcCheck(preJudgment)) { - return preJudgment; - } - } - return null; - } - - - public Boolean crcCheck(ByteBuf byteBuf) { - String contentHexStr = ByteBufUtil.hexDump(byteBuf); - String crcRealValue = contentHexStr.substring(contentHexStr.length() - 4); - String crcContentStr = contentHexStr.substring(0, contentHexStr.length() - 4); - String crcCalculatedValue = CRC16.getCRC(crcContentStr); - return crcRealValue.equals(crcCalculatedValue); - } - - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java index ec0149d..4927c1e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameLengthMatcher.java @@ -2,8 +2,8 @@ import cn.hutool.core.util.ObjectUtil; import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.matcher.FrameStructMatchSupport; import com.casic.missiles.parser.matcher.FrameStructMatcher; -import com.casic.missiles.parser.matcher.FrameStructMatcherSupport; import com.casic.missiles.pojo.DatagramEventConfig; import com.casic.missiles.provider.ProtocolFieldConfigProvider; import com.casic.missiles.pojo.ProtocolConfig; @@ -15,7 +15,7 @@ * @author cz */ @Order(0) -public class FrameLengthMatcher extends FrameStructMatcherSupport implements FrameStructMatcher { +public class FrameLengthMatcher extends FrameStructMatchSupport implements FrameStructMatcher { /** * 超过长度,增加容错长度,同时增加了CRC校验,对帧结构进行判别 @@ -31,13 +31,13 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (matchLength(byteBuf,datagramEventConfig.getSafeLength(),protocolFactory)) {//等于长度返回true,超出长度,切断 + ByteBuf matchByteBuf = matchLength(byteBuf, datagramEventConfig.getSafeLength(), protocolFactory); + if (matchByteBuf != null) {//等于长度返回true,超出长度,切断 //根据CRC校验取值,如果存在加密 - ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); - return wholeDatagramByte; + byteBuf.markReaderIndex();//读的标志位前移 + return matchByteBuf; } else { - //读的标志位前移舍弃 - byteBuf.markReaderIndex(); + //暂时不做处理 return null; } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java index 232d439..c4e35c9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameMarkMatcher.java @@ -4,8 +4,8 @@ import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.matcher.FrameStructMatchSupport; import com.casic.missiles.parser.matcher.FrameStructMatcher; -import com.casic.missiles.parser.matcher.FrameStructMatcherSupport; import com.casic.missiles.pojo.DatagramEventConfig; import com.casic.missiles.provider.ProtocolFieldConfigProvider; import com.casic.missiles.pojo.ProtocolConfig; @@ -24,7 +24,7 @@ */ @Order(1) @Slf4j -public class FrameMarkMatcher extends FrameStructMatcherSupport implements FrameStructMatcher, FixedPropertyEnum { +public class FrameMarkMatcher extends FrameStructMatchSupport implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @Override @@ -36,17 +36,18 @@ } Integer unpackFlag = ObjectUtils.isEmpty(protocolConfig.getUnpackId()) ? null : protocolFieldConfigProvider.getProtocolFieldValue(protocolConfig.getUnpackId(), byteBuf); - ByteBuf mergeWholeFrameByte = null; + ByteBuf intactMessageByte = null; if (!ObjectUtil.isEmpty(unpackFlag)) { while (hasNextFullFrame(byteBuf, protocolConfig, protocolFieldConfigProvider)) { //是否存在后续位 - if (unpackFlag == 1) {//使用esayRule + if (unpackFlag == 1) { //表示可以截取 - mergeWholeFrameByte = getWholeDatagramByte(byteBuf, protocolFieldConfigProvider, protocolConfig); - return mergeWholeFrameByte; + intactMessageByte = mergeMarkFrame(byteBuf, protocolFieldConfigProvider, protocolConfig, datagramEventConfig); + return intactMessageByte; } else { byteBuf.readerIndex(byteBuf.readerIndex() + getNextFrameOffset(byteBuf, protocolConfig, protocolFieldConfigProvider)); } + } } return null; @@ -54,7 +55,8 @@ //选取第一个帧,将业务内容和后面部分分开 //计算数据报文-业务内容 - private ByteBuf getWholeDatagramByte(ByteBuf byteBuf, ProtocolFieldConfigProvider protocolFieldConfigProvider, ProtocolConfig protocolConfig) { + private ByteBuf mergeMarkFrame(ByteBuf byteBuf, ProtocolFieldConfigProvider protocolFieldConfigProvider, + ProtocolConfig protocolConfig, DatagramEventConfig datagramEventConfig) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); //截取完整报文 byteBuf.readBytes(totalLength); @@ -65,7 +67,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前" + ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +89,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - log.debug("--合并后--"+ByteBufUtil.hexDump(mergeWholeFrameByte)); + log.debug("--合并后--" + ByteBufUtil.hexDump(mergeWholeFrameByte)); return mergeWholeFrameByte; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameTailMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameTailMatcher.java index 5d00c71..b24be0e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameTailMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/impl/FrameTailMatcher.java @@ -2,8 +2,9 @@ import cn.hutool.core.util.ObjectUtil; import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.parser.matcher.FrameStructMatchSupport; import com.casic.missiles.parser.matcher.FrameStructMatcher; -import com.casic.missiles.parser.matcher.FrameStructMatcherSupport; + import com.casic.missiles.pojo.DatagramEventConfig; import com.casic.missiles.provider.ProtocolFieldConfigProvider; import com.casic.missiles.pojo.ProtocolConfig; @@ -14,7 +15,7 @@ import org.springframework.util.ObjectUtils; @Order(2) -public class FrameTailMatcher extends FrameStructMatcherSupport implements FrameStructMatcher { +public class FrameTailMatcher extends FrameStructMatchSupport implements FrameStructMatcher { //结尾标志位后面还有数据怎么办 @Override @@ -34,6 +35,7 @@ return null; } else if (dataGramContent.indexOf(tailStr) < dataGramContent.length() - tailStr.length()) { Integer length = dataGramContent.indexOf(tailStr) + tailStr.length(); + //标志位结尾的bytebuf的crc校验暂时不做处理 if (crcCheck(byteBuf)) { ByteBuf wholeDatagramByte = getWholeDatagramByte(byteBuf, length); return wholeDatagramByte; //存在粘包