diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(ByteBufUtil.hexDump(mergeWholeFrameByte)); + log.debug("--合并后--"+ByteBufUtil.hexDump(mergeWholeFrameByte)); return mergeWholeFrameByte; } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java index 8304dc6..5f5dcc8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java @@ -12,7 +12,7 @@ * 3、该表字段解析根据FieldEvaluatorConfig进行字段解析 */ @Data -@TableName("business_field_config") +@TableName("bussiness_field_config") public class FieldConfig extends AbstractFieldConfig { private Long id; diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java index 8304dc6..5f5dcc8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java @@ -12,7 +12,7 @@ * 3、该表字段解析根据FieldEvaluatorConfig进行字段解析 */ @Data -@TableName("business_field_config") +@TableName("bussiness_field_config") public class FieldConfig extends AbstractFieldConfig { private Long id; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java index 2e09879..97cb2d4 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java @@ -10,11 +10,12 @@ public class FieldRuleConfig { private Long id; + private Long ruleId; private String name; - private String desc; - private String condition; - private String excuteOperation; - private Date lasTime; + private Long ruleType; + private String descn; + private String expression; + private Date lastTime; private Date createTime; } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java index 8304dc6..5f5dcc8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java @@ -12,7 +12,7 @@ * 3、该表字段解析根据FieldEvaluatorConfig进行字段解析 */ @Data -@TableName("business_field_config") +@TableName("bussiness_field_config") public class FieldConfig extends AbstractFieldConfig { private Long id; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java index 2e09879..97cb2d4 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java @@ -10,11 +10,12 @@ public class FieldRuleConfig { private Long id; + private Long ruleId; private String name; - private String desc; - private String condition; - private String excuteOperation; - private Date lasTime; + private Long ruleType; + private String descn; + private String expression; + private Date lastTime; private Date createTime; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java index db794bd..9547040 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java @@ -28,10 +28,6 @@ */ private String isReplyFix; /** - * 按照字段评估进行字段解析 - */ - private Long fieldEvaluatorId; - /** * 回复规则 */ private String replyRule; diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java index 8304dc6..5f5dcc8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java @@ -12,7 +12,7 @@ * 3、该表字段解析根据FieldEvaluatorConfig进行字段解析 */ @Data -@TableName("business_field_config") +@TableName("bussiness_field_config") public class FieldConfig extends AbstractFieldConfig { private Long id; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java index 2e09879..97cb2d4 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java @@ -10,11 +10,12 @@ public class FieldRuleConfig { private Long id; + private Long ruleId; private String name; - private String desc; - private String condition; - private String excuteOperation; - private Date lasTime; + private Long ruleType; + private String descn; + private String expression; + private Date lastTime; private Date createTime; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java index db794bd..9547040 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java @@ -28,10 +28,6 @@ */ private String isReplyFix; /** - * 按照字段评估进行字段解析 - */ - private Long fieldEvaluatorId; - /** * 回复规则 */ private String replyRule; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java b/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java index 406fe65..b566ac8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java @@ -14,9 +14,14 @@ @Override public List getFieldRuleConfigList(Long ruleId) { - QueryWrapper queryWrapper = new QueryWrapper() - .eq("rule_id", ruleId); - List fieldRuleConfigList = this.baseMapper.selectList(queryWrapper); + List fieldRuleConfigList = null; + try { + QueryWrapper queryWrapper = new QueryWrapper() + .eq("rule_id", ruleId); + fieldRuleConfigList = this.baseMapper.selectList(queryWrapper); + } catch (Exception ex) { + log.error("字段规则表查询异常,异常信息为{}",ex); + } return fieldRuleConfigList; } diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java index 8304dc6..5f5dcc8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java @@ -12,7 +12,7 @@ * 3、该表字段解析根据FieldEvaluatorConfig进行字段解析 */ @Data -@TableName("business_field_config") +@TableName("bussiness_field_config") public class FieldConfig extends AbstractFieldConfig { private Long id; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java index 2e09879..97cb2d4 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java @@ -10,11 +10,12 @@ public class FieldRuleConfig { private Long id; + private Long ruleId; private String name; - private String desc; - private String condition; - private String excuteOperation; - private Date lasTime; + private Long ruleType; + private String descn; + private String expression; + private Date lastTime; private Date createTime; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java index db794bd..9547040 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java @@ -28,10 +28,6 @@ */ private String isReplyFix; /** - * 按照字段评估进行字段解析 - */ - private Long fieldEvaluatorId; - /** * 回复规则 */ private String replyRule; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java b/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java index 406fe65..b566ac8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java @@ -14,9 +14,14 @@ @Override public List getFieldRuleConfigList(Long ruleId) { - QueryWrapper queryWrapper = new QueryWrapper() - .eq("rule_id", ruleId); - List fieldRuleConfigList = this.baseMapper.selectList(queryWrapper); + List fieldRuleConfigList = null; + try { + QueryWrapper queryWrapper = new QueryWrapper() + .eq("rule_id", ruleId); + fieldRuleConfigList = this.baseMapper.selectList(queryWrapper); + } catch (Exception ex) { + log.error("字段规则表查询异常,异常信息为{}",ex); + } return fieldRuleConfigList; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/util/AutoCodeGenerator.java b/sensorhub-support/src/main/java/com/casic/missiles/util/AutoCodeGenerator.java deleted file mode 100644 index f24d2ae..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/util/AutoCodeGenerator.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.casic.missiles.util; - -import com.baomidou.mybatisplus.generator.FastAutoGenerator; -import com.baomidou.mybatisplus.generator.config.DataSourceConfig; -import com.baomidou.mybatisplus.generator.config.rules.DateType; -import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; -import org.springframework.core.env.Environment; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @Description: mybatis-plus代码生成器 - * @Author: wangpeng - * @Date: 2022/8/11 17:52 - */ -@RestController -@RequestMapping("/code") -public class AutoCodeGenerator { - - private static String driverClassName; // 驱动名称 - private static String username; // 数据库用户名 - private static String password; // 数据库用户密码 - private static String url; // 数据库连接URL - private static String author; // 作者 - private static String tableName; // 待生成对象表名 - - /** - * 读取 application.properties 配置文件 - */ - private static void readProperty() { - Environment environment = SpringContextUtil.getApplicationContext().getEnvironment(); - driverClassName = environment.getProperty("spring.datasource.driver-class-name"); - username = environment.getProperty("spring.datasource.username"); - password = environment.getProperty("spring.datasource.password"); - url = environment.getProperty("spring.datasource.url"); - author = environment.getProperty("code.generate.author"); - tableName = environment.getProperty("code.generate.table-name"); - } - - /** - * MyBatis-Plus 代码生成器「新」 - * 适用版本:mybatis-plus-generator 3.5.1 及其以上版本,对历史版本不兼容 - */ - @GetMapping("generator") - public static void main(String [] args) { - // 加载数据库配置 - readProperty(); - // 项目路径 - String projectPath = System.getProperty("user.dir"); - // 根据数据源信息,创建文件,生成代码 - FastAutoGenerator.create(new DataSourceConfig.Builder(url,username,password)) - // 全局配置 - .globalConfig(builder -> builder - // 作者 - .author(author) - // 输出路径 - .outputDir(projectPath + "/target/generated-sources") - .dateType(DateType.TIME_PACK) - ) - // 包配置 - .packageConfig(builder -> builder - // 指定父包名 - .parent("com.casic.missiles") - .entity("model") - .service("Registry") - .serviceImpl("Registry.impl") - .mapper("mapper") - .controller("controller")) - // 模版配置 -// .templateConfig(builder -> builder -// .entity("/templates/entity.java") -// .Registry("/templates/Registry.java") -// .ServiceImpl("/templates/ServiceImpl.java") -// .mapper("/templates/mapper.java") -// .controller("/templates/controller.java")) - // 策略配置 - .strategyConfig(builder -> builder - // 指定表名,用逗号分隔 - .addInclude(tableName.split(",")) - // 先开启 Controller 配置 - .controllerBuilder() - // 开启生成 @RestController 控制器 - .enableRestStyle() - // 开启驼峰转连字符 - .enableHyphenStyle() - // 先开启 Entity 配置 - .entityBuilder() - // 开启主键自增 -// .idType(IdType.AUTO) - // 数据库表映射到实体的命名策略,驼峰命名 - .naming(NamingStrategy.underline_to_camel) - // 数据库表字段映射到实体的命名策略,驼峰命名 - .columnNaming(NamingStrategy.underline_to_camel) - // 开启生成实体时生成字段注解 - .enableTableFieldAnnotation() - .enableLombok() - .mapperBuilder() - .enableBaseResultMap() - .enableBaseColumnList()) - // 执行 - .execute(); - } -} diff --git a/pom.xml b/pom.xml index c8bc07e..1a6a44e 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT sensorhub pom @@ -28,92 +28,70 @@ 3.5.2 4.1.66.Final 5.2.7 - 2.4.8 + 2.4.8 + 3.5.2 - - - - org.springframework.boot - spring-boot-starter-web - ${boot.version} - - - - com.casic - casic-core - ${core.version} - - - mysql - mysql-connector-java - ${mysql.driver.version} - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus-boot-starter} - - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - - - com.alibaba - druid - ${druid.version} - - - com.alibaba - fastjson - ${fastjson.version} - - - - - com.casic - casic-core - ${core.version} - provided - - - com.casic - casic-admin-support - ${admin.version} - provided - - - com.casic - casic-file-support - ${admin.version} - - - - com.casic - casic-export-support - ${extension.version} - - - com.casic - casic-file - ${admin.version} - - - org.springframework.boot spring-boot-starter-web ${boot.version} - + org.springframework.boot + spring-boot-starter-test + ${boot.version} + test + + + + + + + + + mysql + mysql-connector-java + ${mysql.driver.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + com.alibaba + druid + ${druid.version} + + + com.alibaba fastjson ${fastjson.version} + + + org.apache.commons + commons-lang3 + 3.1 + + + + cn.hutool + hutool-core + 5.7.2 + + + + org.projectlombok + lombok + 1.18.20 + + @@ -125,58 +103,9 @@ maven-compiler-plugin ${maven.compiler.plugin.version} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + \ No newline at end of file diff --git a/sensorhub-core/pom.xml b/sensorhub-core/pom.xml index 2a77c72..3a55d51 100644 --- a/sensorhub-core/pom.xml +++ b/sensorhub-core/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic @@ -15,39 +15,6 @@ sensorhub-server - - - org.springframework.boot - spring-boot-starter - 2.4.5 - - - - org.projectlombok - lombok - 1.18.20 - - - - - org.springframework.boot - spring-boot-starter-jdbc - 2.4.5 - - - - mysql - mysql-connector-java - 8.0.16 - compile - - - - com.baomidou - mybatis-plus-boot-starter - 3.4.3 - - org.apache.httpcomponents @@ -55,12 +22,6 @@ 4.5.7 - - org.bouncycastle - bcprov-jdk15to18 - 1.71 - - redis.clients @@ -75,6 +36,12 @@ 0.0.1-SNAPSHOT + + org.bouncycastle + bcprov-jdk15to18 + 1.71 + + @@ -86,7 +53,7 @@ true - com.casic.missiles.SensorhubServerApplication + com.casic.missiles.ServerApplication exec diff --git a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java deleted file mode 100644 index 24b1e76..0000000 --- a/sensorhub-core/src/main/java/com/casic/missiles/SensorhubServerApplication.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.casic.missiles; - -import com.casic.missiles.netty.SensorhubServer; -import lombok.extern.slf4j.Slf4j; -import org.mybatis.spring.annotation.MapperScan; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.CommandLineRunner; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.transaction.annotation.EnableTransactionManagement; - - -@SpringBootApplication(scanBasePackages = "com.casic.missiles") -@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) -@EnableTransactionManagement(proxyTargetClass = true) -@Slf4j -public class SensorhubServerApplication implements CommandLineRunner { - - @Autowired - private SensorhubServer nettyServer; - public static void main(String[] args) { - SpringApplication.run(SensorhubServerApplication.class, args); - } - - @Override - public void run(String... args) { - this.nettyServer.startServer(); - } - -} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java new file mode 100644 index 0000000..7820203 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/ServerApplication.java @@ -0,0 +1,30 @@ +package com.casic.missiles; + +import com.casic.missiles.netty.SensorhubServer; +import lombok.extern.slf4j.Slf4j; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.transaction.annotation.EnableTransactionManagement; + + +@SpringBootApplication(scanBasePackages = "com.casic.missiles") +@MapperScan(basePackages = {"com.casic.missiles.**.dao", "com.casic.missiles.**.mapper"}) +@EnableTransactionManagement(proxyTargetClass = true) +@Slf4j +public class ServerApplication implements CommandLineRunner { + + @Autowired + private SensorhubServer nettyServer; + public static void main(String[] args) { + SpringApplication.run(ServerApplication.class, args); + } + + @Override + public void run(String... args) { + this.nettyServer.startServer(); + } + +} 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 dc1ab97..1c68e1a 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 @@ -38,47 +38,49 @@ @Override public Boolean doParseProtocol(ByteBuf byteBuf) { //匹配前导码 - ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); + ProtocolConfig protocolConfig = LeadingCodeMatcher.matchFrameLeadingCode(byteBuf); //如果匹配不到前导码,则重置byteByf,判断是否是二次拆包发送,进行再次匹配 if (protocolConfig == null) { return rematch(byteBuf); } //暂时先取第一个, 减少类的创建销毁与构建 AbstractProtocolConfigFactory protocolFactory = new DefaultProtocolConfigFactory(protocolConfig); - ByteBuf wholeDatagramByte = null; - //通过匹配帧结构获取完整的数据包 + // 通过协议工厂匹配,匹配规则,获取规则配置 + RuleConfig ruleConfig = getRuleConfig(protocolFactory, byteBuf); + if (ruleConfig == null) { + return false; + } + //创建规则相关的工厂,流程实例、字节解析、组合字段解析、字段解析规则等有关业务解析配置 + AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); + //获取报文的业务内容 + ByteBuf bizDataByteBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(byteBuf); + //获取流程实例配置 + ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); + //密文解析 + ByteBuf clearZeroPlainBuf = datagramEventProvider.getSafeDatagram(bizDataByteBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); + ByteBuf wholePlainBuf = byteBuf; + //如果加密,帧结构肯定发生了变化 + if (clearZeroPlainBuf != bizDataByteBuf) { + //获取报文的业务内容 + wholePlainBuf = protocolFactory.getProtocolFieldConfigProvider().createDataContentBuf(clearZeroPlainBuf); + } + ByteBuf wholeNewPlainBuf=null; + //通过匹配帧结构获取完整的数据包,验证是否是一个完整的帧结构 for (FrameStructMatcher frameStructMatcher : frameStructDispenserList) { //帧结构该协议,经过帧结构判断选定帧协议完整的数据报文 - if ((wholeDatagramByte = frameStructMatcher.getWholeDatagram(byteBuf, protocolFactory)) != null) { + if ((wholeNewPlainBuf = frameStructMatcher.getWholeDatagram(wholePlainBuf, protocolFactory)) != null) { break; } } //没有匹配成功 - if (wholeDatagramByte == null) { + if (wholeNewPlainBuf == null) { return false; } - /** - * 统一固定字段解析=>进行规则的查询的判断 - * 计算固定字段业务值及对应管理=> 规则解析,规则循环匹配 =>选取规则对应的流程=>选定业务字段内容=>执行加密/解密=> 选定业务数据包内容 - * =>业务字段解析=> 数据验证=>数据构建=> 数据发送 - */ - //进行规则字段解析,进行匹配规则 - RuleConfig ruleConfig = getRuleConfig(protocolFactory, wholeDatagramByte); - if (ruleConfig == null) { - return false; - } - //选定业务字段内容 - ByteBuf bizDataContentBuf = protocolFactory.getProtocolFieldConfigProvider().getDataContentBuf(wholeDatagramByte); - //以下进行业务的规则解析,同时选定流程实例 - AbstractRuleConfigFactory ruleConfigFactory = new DefaultRuleFactory(ruleConfig.getId()); - ProcessorInstanceProvider datagramEventProvider = ruleConfigFactory.getDatagramEventProvider(); - //密文解析 - String clearZeroPlain = datagramEventProvider.getSafeDatagram(bizDataContentBuf,ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - - ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain, + //解析组合业务字段 + ruleConfigFactory.getCombinedFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf, ruleConfigFactory.getFieldConfigProvider().getFieldConfigsMap()); - //解析业务字段 - ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlain); + //解析单个业务字段 + ruleConfigFactory.getFieldConfigProvider().parseDataField(ruleConfig, clearZeroPlainBuf); //构建发送解析任务 Map bizDataMap = buildStoreData(ruleConfigFactory, protocolFactory); //数据发送 @@ -90,7 +92,7 @@ * 如果是拆包序列2进入,需要重置byteBuf的读位置,进行重新匹配 */ private Boolean rematch(ByteBuf byteBuf) { - String oldDataContent =ByteBufUtil.hexDump(byteBuf); + String oldDataContent = ByteBufUtil.hexDump(byteBuf); //重置位判断 byteBuf.resetReaderIndex(); //判断重置是否前移,如果没有前移,则直接判为匹配失败 @@ -132,9 +134,11 @@ Map bizDataMap = new HashMap<>(); Map protocolStoreObjectMap = protocolFactory.getProtocolFieldConfigProvider().getStoreObjectMap(); Map ruleStoreObjectMap = ruleConfigFactory.getFieldConfigProvider().getStoreObjectMap(); + Map combinedStoreObjectMap = ruleConfigFactory.getCombinedFieldConfigProvider().getStoreObjectMap(); //加上固定字段的数据 bizDataMap.putAll(ruleStoreObjectMap); bizDataMap.putAll(protocolStoreObjectMap); + bizDataMap.putAll(combinedStoreObjectMap); return bizDataMap; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java index d19cadd..8228273 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/matcher/LeadingCodeMatcher.java @@ -15,17 +15,25 @@ //** 帧结构前导码匹配 // 1、首字母匹配前导码, // 2、以匹配出的前导码是否在报文中条件进行前导码的匹配二次筛选 - public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { + public static ProtocolConfig matchFrameLeadingCode(ByteBuf byteBuf) { String protocolContent = ByteBufUtil.hexDump(byteBuf); List firstMatchConfigs = initialMatch(protocolContent); - for(ProtocolConfig firstMatchConfig:firstMatchConfigs){ - if(doMacthLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)){ - return firstMatchConfig; + for (ProtocolConfig firstMatchConfig : firstMatchConfigs) { + if (doMatchLeadCode(firstMatchConfig.getPreFix().toLowerCase(), protocolContent)) { + return firstMatchConfig; } } return null; } + + //初始化匹配前导码内容 + private static List initialMatch(String protocolContent) { + String firstFrameChar = protocolContent.charAt(0) + ""; + ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); + return protocolConfigProvider.getMatchList(); + } + //** 解析字组合前导码匹配 // 1、解析字前导码长度,根据长度进行匹配 // 2、采用有限匹配原则,不允许匹配字符包含 @@ -34,7 +42,7 @@ Set> en = fieldFixedMap.entrySet(); for (Map.Entry entry : en) { String key = entry.getKey(); - if (doMacthLeadCode(protocolContent, key)) { + if (doMatchLeadCode(key, protocolContent)) { return entry.getValue(); } } @@ -42,20 +50,17 @@ return null; } - //初始化匹配前导码内容 - private static List initialMatch(String protocolContent) { - String firstFrameChar = protocolContent.charAt(0) + ""; - ProtocolConfigProvider protocolConfigProvider = new ProtocolConfigProvider(firstFrameChar); - return protocolConfigProvider.getMatchList(); - } - - /** * 以前导码长度进行截图,是否相等,保证匹配的前导准确性 */ - private static Boolean doMacthLeadCode(String preFix, String matchContent) { + private static Boolean doMatchLeadCode(String preFix, String matchContent) { + if (preFix.endsWith("x")) { + while (preFix.endsWith("x")) { + preFix = preFix.substring(0, preFix.length() - 1); + } + } Integer preFixLength = preFix.length(); - String beMatchContent = matchContent.substring(0, preFixLength); - return beMatchContent.equals(preFix); + String beMatchContent = matchContent.substring(0, preFixLength).toLowerCase(); + return beMatchContent.equals(preFix.toLowerCase()); } } 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 50f23fc..fff23f3 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 @@ -11,6 +11,9 @@ import org.springframework.stereotype.Component; import org.springframework.util.ObjectUtils; +/** + * @author cz + */ @Order(0) @Component public class FrameLengthMatcher implements FrameStructMatcher { @@ -28,10 +31,10 @@ if (ObjectUtils.isEmpty(protocolConfig.getUnpackId()) && ObjectUtils.isEmpty(protocolConfig.getTailStr())) { Integer totalLength = protocolFieldConfigProvider.getTotalLength(byteBuf, protocolConfig); if (ObjectUtil.isEmpty(totalLength)) { - if (dataGramContent.length() >= totalLength) {//等于长度返回true,超出长度,切断 + if (dataGramContent.length() == totalLength) {//等于长度返回true,超出长度,切断 ByteBuf wholeDatagramByte = this.doGetWholeDatagramByte(byteBuf, totalLength); return wholeDatagramByte; - } else { + }else { //读的标志位前移舍弃 byteBuf.markReaderIndex(); return null; @@ -42,7 +45,6 @@ } - private ByteBuf doGetWholeDatagramByte(ByteBuf byteBuf, Integer totalLength) { byteBuf.readBytes(totalLength); byteBuf.markReaderIndex();//读的标志位前移 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 d527ad0..cb1ca7a 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 @@ -10,7 +10,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; -import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -23,7 +23,7 @@ */ @Order(1) @Component -@AllArgsConstructor +@Slf4j public class FrameMarkMatcher implements FrameStructMatcher, FixedPropertyEnum { //帧后续标志=>结束,进行帧的重组=>有后续,1、帧移位判别 2、继续接收帧 @@ -65,7 +65,7 @@ ByteBuf mergeWholeFrameByte = ByteBufAllocator.DEFAULT.buffer(); String mergeFrameStr = ""; String tail = ""; - System.out.println(ByteBufUtil.hexDump(byteBufContent)); + log.debug("--合并前"+ByteBufUtil.hexDump(byteBufContent)); //会存在多个帧拼接在一起的的情况,进行合并处理 while (hasNextFullFrame(byteBufContent, protocolConfig, protocolFieldConfigProvider)) { Integer currentFrameLength = protocolFieldConfigProvider.getTotalLength(byteBufContent, protocolConfig); @@ -87,7 +87,7 @@ } mergeFrameStr += tail; mergeWholeFrameByte.writeBytes(mergeFrameStr.getBytes(Charset.forName("ISO-8859-1"))); - System.out.println(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 c3a1bab..9e8cceb 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 @@ -20,11 +20,8 @@ @Override public ByteBuf getWholeDatagram(ByteBuf byteBuf, AbstractProtocolConfigFactory protocolFactory) { ProtocolConfig protocolConfig = protocolFactory.getProtocolConfigProvider().getCurrentProtocolConfig(); - if (protocolConfig == null) { - return null; - } ProtocolFieldConfigProvider fieldConfigProvider = protocolFactory.getProtocolFieldConfigProvider(); - if (protocolConfig == null) { + if (protocolConfig == null||fieldConfigProvider == null) { return null; } ProtocolFieldConfig protocolFieldConfig = ObjectUtils.isEmpty(protocolConfig.getTailStr()) ? null : diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java index 5f1c177..d18759f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/CombinedFieldConfigProvider.java @@ -1,6 +1,5 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.combined.GenericCombinedFieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; @@ -9,7 +8,7 @@ import com.casic.missiles.registry.CombinedFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufAllocator; +import org.apache.commons.lang3.StringUtils; import java.nio.charset.Charset; import java.util.HashMap; @@ -26,20 +25,23 @@ private final List combinedFieldConfigList; private Map storeObjectMap = new HashMap<>(); + public Map getStoreObjectMap() { + return storeObjectMap; + } + public CombinedFieldConfigProvider(Long ruleId) { CombinedFieldConfigRegistry combinedFieldConfigRegistry = SpringContextUtil.getBean(CombinedFieldConfigRegistry.class); combinedFieldConfigList = combinedFieldConfigRegistry.getCombinedFieldConfigList(ruleId); } - public void parseDataField(RuleConfig ruleConfig, String clearZeroPlain,Map fieldConfigsMap ) { - if (showSkip()) { + public void parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf, Map fieldConfigsMap) { + if (showSkip() || StringUtils.isEmpty(ruleConfig.getCombinedFieldIds())) { return; } - //匹配对应的数据,然后进行相关的字段解析 - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); + byteBuf.resetReaderIndex(); + List ruleCombinedConfigList=this.prepareParseField(ruleConfig); GenericCombinedFieldResolver combinedFieldResolver = new GenericCombinedFieldResolver(); - combinedFieldResolver.parseDataField(combinedFieldConfigList, byteBuf, storeObjectMap,fieldConfigsMap); + combinedFieldResolver.parseDataField(ruleCombinedConfigList, byteBuf, storeObjectMap, fieldConfigsMap); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java index 7e1fe0a..9a63bf4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldConfigProvider.java @@ -1,6 +1,6 @@ package com.casic.missiles.parser.provider; -import com.alibaba.druid.util.StringUtils; +import org.apache.commons.lang3.StringUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; @@ -41,15 +41,14 @@ return storeObjectMap; } - public Map parseDataField(RuleConfig ruleConfig, String clearZeroPlain) { + public Map parseDataField(RuleConfig ruleConfig, ByteBuf byteBuf) { if (showSkip()) { return null; } List prepareFieldConfig = prepareParseField(ruleConfig); if (CollectionUtils.isNotEmpty(prepareFieldConfig)) { - ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); - byteBuf.writeBytes(clearZeroPlain.getBytes(Charset.forName("ISO-8859-1"))); FieldParser fieldParser = new DefaultProtocolFieldParser(); + byteBuf.resetReaderIndex(); Map fixDataMap = fieldParser.doGetParseField(fieldConfigs, byteBuf, storeObjectMap); if (CollectionUtils.isNotEmpty(fixDataMap)) { return fixDataMap; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java index 817bfaf..28eb908 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/FieldRuleConfigProvider.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.casic.missiles.pojo.FieldRuleConfig; import com.casic.missiles.registry.FieldRuleConfigRegistry; import com.casic.missiles.util.SpringContextUtil; @@ -15,5 +16,12 @@ fieldRuleConfigList = ruleConfigRegistry.getFieldRuleConfigList(ruleId); } + /* 是否应该跳过 + * + * @return + */ + private Boolean showSkip() { + return CollectionUtils.isNotEmpty(fieldRuleConfigList) ? false : true; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java index a6a4377..b996e72 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProcessorInstanceProvider.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.provider; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.safe.SafeStrategy; import com.casic.missiles.parser.sender.DataSubscribeProvider; @@ -32,30 +33,34 @@ } public DatagramEventConfig getProcessorInstance(List datagramEventConfigList) { - if (showSkip()) { - return null; + if (CollectionUtils.isNotEmpty(datagramEventConfigList)) { + return datagramEventConfigList.get(0); } - return datagramEventConfigList.get(0); + return null; } // 是否有动态bean,没有去设置的bean,有则取之=>bean不为空,进行解密操作,否则返回原文 - public String getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { + public ByteBuf getSafeDatagram(ByteBuf bizDataContent, Map fieldConfigMap) { String safeName = StringUtils.isEmpty(processorInstance.getSafeFieldId()) ? processorInstance.getSafeBean() : fieldConfigMap.get(processorInstance.getSafeFieldId()).getFieldName(); if (!StringUtils.isEmpty(safeName)) { //需要加密 SafeStrategy safeStrategy = (SafeStrategy) ApplicationContextUtil.getBean(safeName); - String plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); + ByteBuf plain = safeStrategy.decryption(ByteBufUtil.hexDump(bizDataContent)); return clearComplementZero(plain); } - return ByteBufUtil.hexDump(bizDataContent); + return bizDataContent; } //解密清零操作 - private String clearComplementZero(String plain) { - plain = plain.substring(0, plain.lastIndexOf("00")); - return plain; + private ByteBuf clearComplementZero(ByteBuf plainBuf) { + Integer plainLength = ByteBufUtil.hexDump(plainBuf).length() / 2; + while (plainBuf.getByte(plainLength) == (byte) 0x00) { + plainLength--; + } + plainBuf = plainBuf.slice(0, ++plainLength); + return plainBuf; } //数据发送,数据发送者暂未构建 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java index 043927d..545d62d 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/provider/ProtocolFieldConfigProvider.java @@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.FixedPropertyEnum; import com.casic.missiles.parser.resolver.FieldParser; import com.casic.missiles.parser.resolver.fields.DefaultProtocolFieldParser; import com.casic.missiles.pojo.ProtocolConfig; @@ -10,8 +11,10 @@ import com.casic.missiles.registry.ProtocolFieldConfigRegistry; import com.casic.missiles.util.SpringContextUtil; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; import io.netty.buffer.ByteBufUtil; +import java.nio.charset.Charset; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -20,7 +23,7 @@ * @author cz * @date 2023-6-12 */ -public class ProtocolFieldConfigProvider { +public class ProtocolFieldConfigProvider implements FixedPropertyEnum { private static final String FIXED_FIELD_DS = "fixedFieldDs"; private static final String CONTENT_FIELD_DS = "contentFieldDs"; @@ -31,6 +34,7 @@ private final List protocolFieldConfigs; private Map singleObjects = new ConcurrentHashMap<>(); private Map storeObjectMap = new HashMap<>(); + private Map frameStructMap; public Map getStoreObjectMap() { return storeObjectMap; @@ -101,7 +105,7 @@ } Map fixedPropertyMap = new HashMap<>(); FieldParser fieldParser = new DefaultProtocolFieldParser(); - fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf,protocolConfig)); + fixedPropertyMap = fieldParser.doGetFixedProperty(protocolFieldConfigs, this.getTotalLength(byteBuf, protocolConfig)); if (CollectionUtils.isNotEmpty(fixedPropertyMap)) { this.singleObjects.put(catchKey, fixedPropertyMap); return fixedPropertyMap; @@ -175,7 +179,8 @@ return (ByteBuf) singleObjects.get(CONTENT_FIELD_DS); } FieldParser fieldParser = new DefaultProtocolFieldParser(); - ByteBuf bizDataByteBuf = fieldParser.getDataContentBuf(protocolFieldConfigs, wholeDatagramByte); + frameStructMap = fieldParser.getFrameStructBuf(protocolFieldConfigs, wholeDatagramByte); + ByteBuf bizDataByteBuf = frameStructMap.get(AROUND_BUSINESS_CONTENT); if (bizDataByteBuf != null) { this.singleObjects.put(CONTENT_FIELD_DS, bizDataByteBuf); return bizDataByteBuf; @@ -183,6 +188,24 @@ return null; } + /** + * 设置完整的数据报文 + * + * @param clearZeroPlainBuf 解密后的业务报文内容 + * @return + */ + public ByteBuf createDataContentBuf(ByteBuf clearZeroPlainBuf) { + ByteBuf wholePlainBuf = ByteBufAllocator.DEFAULT.buffer(); + if (frameStructMap.containsKey(BEFORE_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(BEFORE_BUSINESS_CONTENT)); + } + wholePlainBuf.writeBytes(clearZeroPlainBuf); + if (frameStructMap.containsKey(AFTER_BUSINESS_CONTENT)) { + wholePlainBuf.writeBytes(frameStructMap.get(AFTER_BUSINESS_CONTENT)); + } + return wholePlainBuf; + } + private ProtocolFieldConfig selectFieldConfig(Long id) { Optional optionalProtocolFieldConfig = this.protocolFieldConfigs.stream().filter( diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java index 856b399..f097f42 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/ByteMergeProvider.java @@ -30,7 +30,7 @@ env2.put("value" + i, valueList.get(i)); } } - values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExcuteOperation(), env2)); + values = String.valueOf(AviatorEvaluator.execute(fieldRuleEngine.getExpression(), env2)); return values; } catch (ExpressionNotFoundException enf) { log.error("字节合并出现异常,解析内容为{},aviator表达式为{},异常信息为{}", JSONObject.toJSON(valueList), JSONObject.toJSON(fieldRuleEngine), enf.getMessage()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java index 85d6bbf..da1cdf9 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/FieldParser.java @@ -19,7 +19,7 @@ Map doGetParseField(List protocolFieldConfigs, ByteBuf buffer, Map storeObjectMap); - ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer); + Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer); Integer getTotalFilterLength(ProtocolConfig protocolConfig, ByteBuf byteBuf, Map protocolFieldConfigMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java index 1d2aeab..4dcfc9c 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/ByteRuleResolver.java @@ -26,7 +26,7 @@ if(ObjectUtil.isEmpty(fieldRuleEngine)){ return byteResolverParam.getValue(); } - String aviatorExpressTion=fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion=fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", (byte) byteResolverParam.getValue()); String values = String.valueOf(AviatorEvaluator.execute("Double.longBitsToDouble(value)", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java index 786b71c..778cf56 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/LogicalShiftResolver.java @@ -33,7 +33,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return byteResolverParam.getValue(); } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); if (!ObjectUtil.isEmpty(index)) { env2.put("i", index); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java index 01149bd..798355e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/OperationResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", Double.valueOf(value.toString())); value = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java index 79abcce..64d4402 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/bytes/PrecisionResolver.java @@ -32,7 +32,7 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } - String aviatorExpressTion = fieldRuleEngine.getExcuteOperation(); + String aviatorExpressTion = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); String values = String.valueOf(AviatorEvaluator.execute("value + options", env2)); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java new file mode 100644 index 0000000..a8212a6 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/CombinedFieldSupport.java @@ -0,0 +1,40 @@ +package com.casic.missiles.parser.resolver.combined; + +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.pojo.FieldConfig; +import org.springframework.beans.BeanUtils; + +import java.util.ArrayList; +import java.util.Map; + +/** + * @author cz + * + */ +public class CombinedFieldSupport { + + //深拷贝不影响存储的对象 + protected FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { + if (ObjectUtils.isNotEmpty(fieldId)) { + FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); + FieldConfig newDeepCopyFieldConfig = new FieldConfig(); + //通过深拷贝传入 + BeanUtils.copyProperties(fieldConfig, newDeepCopyFieldConfig); + return newDeepCopyFieldConfig; + } else { + return null; + } + } + + //通过strIds获取对应的config配置 + protected ArrayList getFieldConfigByIds(String combinedFieldIds, Map fieldConfigsMap) { + ArrayList fieldConfigs = new ArrayList<>(); + String[] dataFieldIds = combinedFieldIds.split(","); + for (String dataFieldId : dataFieldIds) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldId), fieldConfigsMap); + fieldConfigs.add(fieldConfig); + } + return fieldConfigs; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java index 21deac5..2170bb5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/GenericCombinedFieldResolver.java @@ -1,5 +1,6 @@ package com.casic.missiles.parser.resolver.combined; +import com.alibaba.fastjson.JSON; import com.casic.missiles.parser.resolver.combined.impl.BizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreBizFieldParseProcessor; import com.casic.missiles.parser.resolver.combined.impl.PreLeadCodeProcessor; @@ -8,7 +9,9 @@ import com.casic.missiles.pojo.FieldConfig; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; +import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -18,6 +21,7 @@ * @date 2023-6-13 */ //依次递增进行数据的解析, +@Slf4j public class GenericCombinedFieldResolver { //前导码失败或者读位置移到空位置 @@ -25,38 +29,50 @@ //通过查询,字段长度长度随机 public void parseDataField(List combinedFieldConfigList, ByteBuf byteBuf, Map storeObjectMap, Map fieldConfigsMap) { - Integer frameLength = Integer.valueOf(ByteBufUtil.hexDump(byteBuf)); + final Integer frameLength = ByteBufUtil.hexDump(byteBuf).length() / 2; Map fieldFixedMap = combinedFieldLeadCodeMap(combinedFieldConfigList); Object median = null; - AbstractCombinedFieldProcessor abstractProcessor = null; + List abstractProcessorList = CreateSortAbstractProcessors(); CombinedFieldProcessorParam combinedFieldParam = build(byteBuf, fieldFixedMap, fieldConfigsMap, storeObjectMap); //frameLength - Map combinedProcessorFields = null; - while (byteBuf.readableBytes() < frameLength) { - if (median == null) { - abstractProcessor = new PreLeadCodeProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - if (combinedProcessorFields == null || byteBuf.readableBytes() >= frameLength) { - return; - } - combinedFieldParam.setPreProcessorResult(median); - } - if (byteBuf.readableBytes() < frameLength) { - if (median instanceof CombinedFieldConfig) { - abstractProcessor = new PreBizFieldParseProcessor(); + while (byteBuf.readerIndex() < frameLength) { + for (AbstractCombinedFieldProcessor abstractProcessor : abstractProcessorList) { + try { + Integer oldLength = byteBuf.readerIndex(); median = abstractProcessor.invoke(combinedFieldParam); + if (byteBuf.readerIndex() >= frameLength) { + return; + } + if (oldLength == byteBuf.readerIndex()) { + log.error("解析失败,当前解析点为{}", ByteBufUtil.hexDump(byteBuf)); + return; + } + // 将前一个节点作为参数传入下一次,保留前一个节点的信息 combinedFieldParam.setPreProcessorResult(median); + } catch (RuntimeException ex) { + log.error("上个流程参数是{},异常信息{}", median, ex); } } - if (byteBuf.readableBytes() < frameLength) { - abstractProcessor = new BizFieldParseProcessor(); - median = abstractProcessor.invoke(combinedFieldParam); - } } + System.out.println(JSON.toJSON(storeObjectMap)); + } + + /** + * 创建有序的流程处理集合类 顺序为:前导码匹配->前置处理长度字段->业务字段解析 + */ + private List CreateSortAbstractProcessors() { + List abstractProcessorList = new ArrayList<>(); + AbstractCombinedFieldProcessor preLeadCodeProcessor = new PreLeadCodeProcessor(); + abstractProcessorList.add(preLeadCodeProcessor); + AbstractCombinedFieldProcessor preBizFieldParseProcessor = new PreBizFieldParseProcessor(); + abstractProcessorList.add(preBizFieldParseProcessor); + AbstractCombinedFieldProcessor bizFieldParseProcessor = new BizFieldParseProcessor(); + abstractProcessorList.add(bizFieldParseProcessor); + return abstractProcessorList; } - private CombinedFieldProcessorParam build( ByteBuf byteBuf, Map fieldFixedMap, + private CombinedFieldProcessorParam build(ByteBuf byteBuf, Map fieldFixedMap, Map fieldConfigsMap, Map storeObjectMap) { return CombinedFieldProcessorParam.builder() .byteBuf(byteBuf) diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java index b4a424c..82b698e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/BizFieldParseProcessor.java @@ -1,11 +1,17 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import java.util.List; + /** * @author cz * @date 2023-6-13 @@ -14,15 +20,35 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { - AbstractFieldConfig protocolFieldConfig = (AbstractFieldConfig) combinedFieldParam.getPreProcessorResult(); - if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { - Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { - combinedFieldParam.getStoreObjectMap().put(protocolFieldConfig.getFieldName(), fieldValue); + List protocolFieldConfigs = (List) combinedFieldParam.getPreProcessorResult(); + Assert.isFalse(CollectionUtils.isEmpty(protocolFieldConfigs), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + for (AbstractFieldConfig abstractFieldConfig : protocolFieldConfigs) { + if (!ObjectUtils.isEmpty(abstractFieldConfig.getOriginPositionByte())) { + abstractFieldConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + abstractFieldConfig.getOriginPositionByte()); + Object fieldValue = FieldResolver.parseField(combinedFieldParam.getByteBuf(), abstractFieldConfig, null); + if (ObjectUtils.isNotEmpty(abstractFieldConfig.getIsStorage()) && abstractFieldConfig.getIsStorage() == 1) { + combinedFieldParam.getStoreObjectMap().put(abstractFieldConfig.getFieldName(), fieldValue); + } } } - combinedFieldParam.getByteBuf().readBytes(protocolFieldConfig.getOffsetLength()); + combinedFieldParam.getByteBuf().readBytes(calculateProcessPosition(protocolFieldConfigs)); return null; } + /** + * 计算处理位置 + */ + private Integer calculateProcessPosition(List protocolFieldConfigs) { + AbstractFieldConfig newProtocolFieldConfig = protocolFieldConfigs.get(protocolFieldConfigs.size() - 1); + Integer mergeBitToByte = 0; + if (newProtocolFieldConfig.getOffsetUnit().equals("bit")) { + mergeBitToByte += (newProtocolFieldConfig.getOriginPositionBit() + newProtocolFieldConfig.getOffsetLength()) / 8; + } else { + mergeBitToByte += newProtocolFieldConfig.getOffsetLength(); + } + return mergeBitToByte; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java index d749855..ca18ba1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreBizFieldParseProcessor.java @@ -1,19 +1,23 @@ package com.casic.missiles.parser.resolver.combined.impl; -import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import cn.hutool.core.lang.Assert; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.parser.resolver.fields.FieldResolver; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; import com.casic.missiles.pojo.FieldConfig; -import java.util.Map; +import java.util.ArrayList; +import java.util.Objects; /** * @author cz * @date 2023-6-13 */ -public class PreBizFieldParseProcessor implements AbstractCombinedFieldProcessor { +public class PreBizFieldParseProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 把长度计算出来,同时拿到对应指定的字段解析配置 @@ -24,21 +28,33 @@ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { CombinedFieldConfig combinedFieldConfig = (CombinedFieldConfig) combinedFieldParam.getPreProcessorResult(); - FieldConfig fieldConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getCombinedFieldId(), combinedFieldParam.getFieldConfigsMap()); - if (lengthConfig == null || fieldConfig == null) { - return null; - } + Assert.isFalse(Objects.isNull(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_FIELD_NULL); + }); + String[] dataFieldIds = combinedFieldConfig.getDataFieldIds().split(","); + FieldConfig lengthConfig = getFieldConfigById(combinedFieldConfig.getDynamicLengthId(), combinedFieldParam.getFieldConfigsMap()); + Assert.isFalse(Objects.isNull(lengthConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_LENGTH_FIELD_NULL); + }); + lengthConfig.setOriginPositionByte(combinedFieldParam.getByteBuf().readerIndex() + lengthConfig.getOriginPositionByte()); Integer fieldValue = (Integer) FieldResolver.parseField(combinedFieldParam.getByteBuf(), lengthConfig, null); combinedFieldParam.getByteBuf().readBytes(lengthConfig.getOffsetLength()); - fieldConfig.setOffsetLength(fieldValue); - return fieldConfig; - } + ArrayList fieldConfigs = new ArrayList<>(); + //回填判断操作,只有一个配置 + if (dataFieldIds.length == 1) { + FieldConfig fieldConfig = getFieldConfigById(Long.valueOf(dataFieldIds[0]), combinedFieldParam.getFieldConfigsMap()); + if (fieldConfig == null) { + return null; + } + fieldConfig.setOffsetLength(fieldValue); + fieldConfig.setIsStorage(combinedFieldConfig.getIsStorge()); + fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); + fieldConfigs.add(fieldConfig); + return fieldConfigs; - private FieldConfig getFieldConfigById(Long fieldId, Map fieldConfigsMap) { - if (ObjectUtils.isNotEmpty(fieldId)) { - FieldConfig fieldConfig = fieldConfigsMap.get(fieldId); - return fieldConfig; + } else if (dataFieldIds.length > 1) {//含有多个字段的操作 + fieldConfigs =getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(),combinedFieldParam.getFieldConfigsMap()); + return fieldConfigs; } else { return null; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java index df0e676..4756502 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/combined/impl/PreLeadCodeProcessor.java @@ -1,14 +1,26 @@ package com.casic.missiles.parser.resolver.combined.impl; +import cn.hutool.core.lang.Assert; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.enums.EngineExceptionEnum; +import com.casic.missiles.exception.EngineException; import com.casic.missiles.parser.matcher.LeadingCodeMatcher; import com.casic.missiles.parser.resolver.combined.AbstractCombinedFieldProcessor; +import com.casic.missiles.parser.resolver.combined.CombinedFieldSupport; import com.casic.missiles.pojo.CombinedFieldConfig; import com.casic.missiles.pojo.CombinedFieldProcessorParam; +import com.casic.missiles.pojo.FieldConfig; +import io.netty.buffer.ByteBufUtil; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; + /** * @author cz * @date 2023-6-13 */ -public class PreLeadCodeProcessor implements AbstractCombinedFieldProcessor { +public class PreLeadCodeProcessor extends CombinedFieldSupport implements AbstractCombinedFieldProcessor { /** * 匹配获取前导码,找到对应的组合字段配置,并将报文读位置前移 @@ -17,10 +29,29 @@ */ @Override public Object invoke(CombinedFieldProcessorParam combinedFieldParam) { + System.out.println(ByteBufUtil.hexDump(combinedFieldParam.getByteBuf())); CombinedFieldConfig combinedFieldConfig = LeadingCodeMatcher.matchFieldLeadingCode(combinedFieldParam.getFieldFixedMap(), combinedFieldParam.getByteBuf()); - combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length()); + resolvePreCode(combinedFieldParam, combinedFieldConfig); + Assert.isFalse(ObjectUtils.isEmpty(combinedFieldConfig), () -> { + throw new EngineException(EngineExceptionEnum.COMBINED_PRE_CODE_FIELD_NULL); + }); + combinedFieldParam.getByteBuf().readBytes(combinedFieldConfig.getPrefixCode().length() / 2); return combinedFieldConfig; } + /** + * 如果前导码需要解析,则进行前导码的解析 + */ + private void resolvePreCode(CombinedFieldProcessorParam combinedFieldParam, CombinedFieldConfig combinedFieldConfig) { + //如果前导码组合字段不为空 + if (StringUtils.isEmpty(combinedFieldConfig.getCombinedFieldIds())) { + return; + } + ArrayList fieldConfigs = getFieldConfigByIds(combinedFieldConfig.getCombinedFieldIds(), combinedFieldParam.getFieldConfigsMap()); + combinedFieldParam.setPreProcessorResult(fieldConfigs); + AbstractCombinedFieldProcessor combinedFieldProcessor = new BizFieldParseProcessor(); + combinedFieldProcessor.invoke(combinedFieldParam); + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java new file mode 100644 index 0000000..11c5d64 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/BitFieldParser.java @@ -0,0 +1,95 @@ +package com.casic.missiles.parser.resolver.fields; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.pojo.AbstractFieldConfig; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +@Slf4j +public class BitFieldParser extends ByteMergeProvider { + + /** + * 1、单个字节情况表示字段 + * 2、多字节情况表示字段(暂未处理) + */ + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig) { + Object fieldValue = new Object(); + try { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + byte fields = 0x00; + //计算字节所占的比例位置 + Integer offsetByte = (fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) / 8; + if ((fieldConfig.getOffsetLength() + fieldConfig.getOriginPositionBit()) % 8 != 0) { + offsetByte++; + } + //将所需的bit字段转换成二进制,然后截取计算 + int visitIndex = offsetByte; + String binaryStr = ""; + //下标是由0开始,所以先- + while (--visitIndex > -1) { + fields = byteBuf.getByte(byteBuf.readerIndex() + originPosition + visitIndex); + binaryStr = binaryStr + getBinaryStrFromByte(fields); + } + binaryStr = binaryStr.substring(fieldConfig.getOriginPositionBit(), fieldConfig.getOriginPositionBit() +fieldConfig.getOffsetLength()); + fieldValue = Integer.parseInt(binaryStr, 2); + if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { + return fieldValue; + } + List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); + int i = 0; + //字节归并到一起=>继续根据规则进行判断 + while (i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(fieldValue) + .ruletypeId(ruletypeId).build(); + fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(fieldValue)); + return fieldValue; + } catch (RuntimeException ex) { + log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); + return null; + } + } + + /** + * 把byte转化成2进制字符串 + */ + private static String getBinaryStrFromByte(byte value) { + String result = ""; + byte a = value; + for (int i = 0; i < 8; i++) { + byte c = a; + a = (byte) (a >> 1);//每移一位如同将10进制数除以2并去掉余数。 + a = (byte) (a << 1); + if (a == c) { + result = "0" + result; + } else { + result = "1" + result; + } + a = (byte) (a >> 1); + } + return result; + } + + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java new file mode 100644 index 0000000..c95d20d --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/ByteFieldParser.java @@ -0,0 +1,101 @@ +package com.casic.missiles.parser.resolver.fields; + +import cn.hutool.core.util.ObjectUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.parser.resolver.ByteMergeProvider; +import com.casic.missiles.parser.resolver.ByteResolver; +import com.casic.missiles.parser.resolver.FieldParserSupport; +import com.casic.missiles.pojo.ByteResolverParam; +import com.casic.missiles.util.ApplicationContextUtil; +import io.netty.buffer.ByteBuf; +import lombok.extern.slf4j.Slf4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * @author cz + * + */ +@Slf4j +public class ByteFieldParser extends ByteMergeProvider { + + + //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, + //目前默认配置的规则设置暂不支持配置化,由实现完成 + public static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { + Object fieldsResolveValue = null; + List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); + if (ObjectUtil.isEmpty(ruleMapList)) { + fieldsResolveValue = defaultResolveBuilder(byteBuf); + } else { + fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); + } + return fieldsResolveValue; + } + + private static Object defaultResolveBuilder(ByteBuf byteBuf) { + Integer defaultResolveValue = 0; + for (int i = 0; i < byteBuf.writerIndex(); i++) { + defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; + } + return defaultResolveValue; + } + + //字段解析构建器(针对字节单位的) + //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 + // 字节归并结束或者规则结束=>继续根据规则进行判断 + private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { + Object customizeResolveValue = null; + try { + List bytStrList = new ArrayList<>(); + //存放到数组里面 + for (int i = 0; i < byteBuf.writerIndex(); i++) { + bytStrList.add(byteBuf.readByte()); + } + int i = 0; + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); + break; + } else { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + List tempBytStr = new ArrayList<>(); + for (int k = 0; i < bytStrList.size(); i++) { + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(k) + .value(bytStrList.get(k)) + .ruletypeId(ruletypeId).build(); + tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); + } + bytStrList = tempBytStr; + } + i++; + } + //字节归并到一起=>继续根据规则进行判断 + while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { + String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); + ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); + String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); + ByteResolverParam byteResolverParam = ByteResolverParam.builder() + .index(null) + .value(customizeResolveValue) + .ruletypeId(ruletypeId).build(); + customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); + i++; + } + System.out.println(JSON.toJSON(customizeResolveValue)); + return customizeResolveValue; + } catch (RuntimeException ex) { + log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); + return null; + } + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java index 643a934..272d927 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/DefaultProtocolFieldParser.java @@ -29,7 +29,7 @@ for (AbstractFieldConfig protocolFieldConfig : protocolFieldConfigs) { if (!ObjectUtils.isEmpty(protocolFieldConfig.getOriginPositionByte())) { Object fieldValue = FieldResolver.parseField(buffer, protocolFieldConfig, null); - if (protocolFieldConfig.getIsStorage() == 1) { + if (!ObjectUtils.isEmpty(protocolFieldConfig.getIsStorage()) && protocolFieldConfig.getIsStorage() == 1) { storeObjectMap.put(protocolFieldConfig.getFieldName(), fieldValue); } dataMap.put(protocolFieldConfig.getFieldName(), fieldValue); @@ -53,7 +53,8 @@ //** 获取业务内容的byteBuf // 固定字段列表=> 计算固定字段长度=> 计算业务内容起始位置=>结合总长度,计算业务内容长度=>得到业务内容 @Override - public ByteBuf getDataContentBuf(List protocolFieldConfigs, ByteBuf buffer) { + public Map getFrameStructBuf(List protocolFieldConfigs, ByteBuf buffer) { + Map frameStructBufMap = new HashMap<>(); //计算固定长度 Integer fixedLength = calculateLength(protocolFieldConfigs); //总长度获取 @@ -62,8 +63,10 @@ //计算固定长度最大长度 Integer maxFixedPosition = calculatePosition(protocolFieldConfigs); //计算数据报文内容 - ByteBuf bizDataFields = buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength)); - return bizDataFields; + frameStructBufMap.put(BEFORE_BUSINESS_CONTENT, buffer.slice(0, maxFixedPosition-1)); + frameStructBufMap.put(AROUND_BUSINESS_CONTENT, buffer.slice(maxFixedPosition - 1, (totalLength - fixedLength))); + frameStructBufMap.put(AFTER_BUSINESS_CONTENT, buffer.slice(maxFixedPosition-1+totalLength - fixedLength, fixedLength+1-maxFixedPosition)); + return frameStructBufMap; } /** diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java index d51e887..82b2770 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/fields/FieldResolver.java @@ -1,169 +1,32 @@ package com.casic.missiles.parser.resolver.fields; import cn.hutool.core.util.ObjectUtil; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.parser.resolver.ByteMergeProvider; -import com.casic.missiles.parser.resolver.ByteResolver; import com.casic.missiles.pojo.AbstractFieldConfig; -import com.casic.missiles.util.ApplicationContextUtil; -import com.casic.missiles.pojo.ByteResolverParam; import io.netty.buffer.ByteBuf; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; /** * 字段解析管理总类 */ @Slf4j -public class FieldResolver extends ByteMergeProvider { +public class FieldResolver{ //1、字段截取 => 2、简单的字节解析和复杂的字节解析 - public static Object parseField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); + public static Object parseField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Integer maxFixedPosition) { + Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); //最大固定位置不为空, if (!ObjectUtil.isEmpty(maxFixedPosition)) { - orignPosition -= maxFixedPosition; + originPosition -= maxFixedPosition; } Object fieldValue = 0; //待优化 - if (fieldConfig.getOffsetLength() == 1 || fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = doParseBitField(byteBuf, fieldConfig); + if (fieldConfig.getOffsetUnit().equals("bit")) { + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig); } else { - ByteBuf fieldBytes = byteBuf.slice(orignPosition, fieldConfig.getOffsetLength()); - fieldValue = doParseByteField(fieldBytes, fieldConfig.getRuleJson()); + ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleJson()); } return fieldValue; } - //存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置, - //目前默认配置的规则设置暂不支持配置化,由实现完成 - private static Object doParseByteField(ByteBuf byteBuf, String ruleJson) { - Object fieldsResolveValue = null; - List ruleMapList = JSONArray.parseArray(ruleJson, Map.class); - if (ObjectUtil.isEmpty(ruleMapList)) { - fieldsResolveValue = defaultResolveBuilder(byteBuf); - } else { - fieldsResolveValue = customizeResolveBuilder(byteBuf, ruleMapList); - } - return fieldsResolveValue; - } - - private static Object defaultResolveBuilder(ByteBuf byteBuf) { - Integer defaultResolveValue = 0; - for (int i = 0; i < byteBuf.writerIndex(); i++) { - defaultResolveValue = defaultResolveValue * 256 + byteBuf.readByte() & 0xff; - } - return defaultResolveValue; - } - - //字段解析构建器(针对字节单位的) - //转化数组=>去查询规则=> 获取bean,规则语句id,对范围进行过滤 =>直到规则结束或者遇到字节归并规则进行字节数据统一 - // 字节归并结束或者规则结束=>继续根据规则进行判断 - private static Object customizeResolveBuilder(ByteBuf byteBuf, List ruleMapList) { - Object customizeResolveValue = null; - try { - List bytStrList = new ArrayList<>(); - //存放到数组里面 - for (int i = 0; i < byteBuf.writerIndex(); i++) { - bytStrList.add(byteBuf.readByte()); - } - int i = 0; - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - if (ruleMapList.get(i).get("ruleType").equals("combine")) { //合并 - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - customizeResolveValue = resolveByteMerge(bytStrList, ruletypeId, vaildRange); - break; - } else { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - List tempBytStr = new ArrayList<>(); - for (int k = 0; i < bytStrList.size(); i++) { - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(k) - .value(bytStrList.get(k)) - .ruletypeId(ruletypeId).build(); - tempBytStr.add(byteResolverBean.resolveOperationRule(byteResolverParam)); - } - bytStrList = tempBytStr; - } - i++; - } - //字节归并到一起=>继续根据规则进行判断 - while (!ObjectUtil.isEmpty(ruleMapList) && i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(customizeResolveValue) - .ruletypeId(ruletypeId).build(); - customizeResolveValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(customizeResolveValue)); - return customizeResolveValue; - } catch (RuntimeException ex) { - log.error("自定义字段解析byte位出现异常,解析规则内容为{},异常信息为{}", JSONObject.toJSON(ruleMapList), ex.getMessage()); - return null; - } - } - - /** - * 1、单个字节情况表示字段 - * 2、多字节情况表示字段(暂未处理) - */ - private static Object doParseBitField(ByteBuf byteBuf,AbstractFieldConfig fieldConfig) { - Object fieldValue = new Object(); - try { - Integer orignPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); - byte fields = 0x00; - if (fieldConfig.getOffsetLength() == 2 && fieldConfig.getOffsetUnit().equals("byte")) { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition + 1); - } else { - fields = byteBuf.getByte(byteBuf.readerIndex() + orignPosition); - } - - if (!StringUtils.isEmpty(fieldConfig.getOffsetUnit()) && fieldConfig.getOffsetUnit().equals("bit")) { - if (!StringUtils.isEmpty(fieldConfig.getOriginPositionBit())) { - fieldValue = Integer.valueOf((fields & 0xff) << Integer.valueOf(fieldConfig.getOriginPositionBit())).byteValue() - >> Integer.valueOf(8 - fieldConfig.getOffsetLength()); - } else { - fieldValue = Integer.valueOf((fields & 0xff) >> Integer.valueOf(8 - fieldConfig.getOffsetLength())); - } - } else { - fieldValue = Integer.valueOf(fields & 0xff); - } - if (StringUtils.isEmpty(fieldConfig.getRuleJson())) { - return fieldValue; - } - List ruleMapList = JSONArray.parseArray(fieldConfig.getRuleJson(), Map.class); - int i = 0; - //字节归并到一起=>继续根据规则进行判断 - while (i < ruleMapList.size()) { - String vaildRange = String.valueOf(ruleMapList.get(i).get("vaildRange")); - ByteResolver byteResolverBean = (ByteResolver) ApplicationContextUtil.getBean(vaildRange); - String ruletypeId = String.valueOf(ruleMapList.get(i).get("ruleTypeId")); - ByteResolverParam byteResolverParam = ByteResolverParam.builder() - .index(null) - .value(fieldValue) - .ruletypeId(ruletypeId).build(); - fieldValue = byteResolverBean.resolveOperationRule(byteResolverParam); - i++; - } - System.out.println(JSON.toJSON(fieldValue)); - return fieldValue; - } catch (RuntimeException ex) { - log.error("字段解析bit位出现异常,解析内容为{},解析规则内容为{},异常信息为{}", fieldValue, JSONObject.toJSON(fieldConfig), ex.getMessage()); - return null; - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index bfa87a5..81457c2 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -1,9 +1,11 @@ package com.casic.missiles.parser.safe; +import io.netty.buffer.ByteBuf; + public interface SafeStrategy { - String decryption(String cipher); + ByteBuf decryption(String cipher); - String encryption(String lightText); + ByteBuf encryption(String lightText); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index 6e078a3..dce5af0 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -21,7 +21,7 @@ public static final int BlockSize = 16; @Override - public String decryption(String cipher) { + public ByteBuf decryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -29,12 +29,12 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); - return plain; + ByteBuf plainBuf = EcbDecrypt(in, keyBytes); + return plainBuf; } @Override - public String encryption(String cipher) { + public ByteBuf encryption(String cipher) { byte[] keyByte = { 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 }; @@ -42,7 +42,7 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - String plain = EcbDecrypt(in, keyBytes); + ByteBuf plain = EcbDecrypt(in, keyBytes); return plain; } @@ -122,10 +122,9 @@ * @param keyBytes 密钥 * @return */ - public static String EcbDecrypt(byte[] in, byte[] keyBytes) { + public static ByteBuf EcbDecrypt(byte[] in, byte[] keyBytes) { byte[] out = ecb_decrypt(in, keyBytes); - String plain = Hex.toHexString(out); - return plain; + return ByteBufAllocator.DEFAULT.buffer().writeBytes(out); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java index 40a5265..286cb95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/predecodec/impl/AepPreprocessing.java @@ -20,7 +20,7 @@ * @create: 2023-05-04 15:15 **/ @Slf4j -public class AepPreprocessing extends AbstractPreprocessing { +public class AepPreprocessing extends AbstractPreprocessing{ private final Base64Dialect dialect; @@ -45,7 +45,7 @@ ByteBuf bufferContent = ByteBufAllocator.DEFAULT.buffer(); bufferContent.writeBytes(values.getBytes(Charset.forName("ISO-8859-1"))); out.add(Base64.decode(bufferContent, bufferContent.readerIndex(), bufferContent.readableBytes(), this.dialect)); - }else { + } else { out.add(msg); } } diff --git a/sensorhub-support/pom.xml b/sensorhub-support/pom.xml index 761601c..5ceecfe 100644 --- a/sensorhub-support/pom.xml +++ b/sensorhub-support/pom.xml @@ -5,7 +5,7 @@ com.casic sensorhub - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT 4.0.0 @@ -13,7 +13,7 @@ sensorhub-support 0.0.1-SNAPSHOT sensorhub-support - sensorhub-server + sensorhub-support 8 @@ -22,7 +22,7 @@ - + io.netty netty-all @@ -42,12 +42,6 @@ ${redis.version} - - com.baomidou - mybatis-plus-generator - ${mybatis-plus-generator.version} - - org.reflections diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java new file mode 100644 index 0000000..1d31207 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/AbstractBaseExceptionEnum.java @@ -0,0 +1,15 @@ +package com.casic.missiles.enums; + + +/** + * @Description: + * @Author: cz + * @Date: 2022/11/24 17:57 + */ +public interface AbstractBaseExceptionEnum { + + Integer getCode(); + + String getMessage(); + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java deleted file mode 100644 index adc7aa3..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/DeviceTypeEnum.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.casic.missiles.enums; - -/** - * 设备类型 - */ -public enum DeviceTypeEnum { - NON_TYPE("未知设备类型", "", 0), - MULTI_TYPE("多功能漏损监测仪", "BIRMM-FPL", 1); - - /** - * 业务名称 - */ - private String name; - /** - * 型号 - */ - private String code; - /** - * 值 - */ - private int value; - - - DeviceTypeEnum(String name, String code, int value) { - this.name = name; - this.code = code; - this.value = value; - } - - public String getName() { - return name; - } - - public String getCode() { - return code; - } - - public int getValue() { - return value; - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java new file mode 100644 index 0000000..9dcbd61 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/EngineExceptionEnum.java @@ -0,0 +1,41 @@ +package com.casic.missiles.enums; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; + +/** + * @author cz + * @date 2023 + */ +public enum EngineExceptionEnum implements AbstractBaseExceptionEnum { + + COMBINED_LENGTH_FIELD_NULL(3001, "组合长度字段配置为空"), + COMBINED_PRE_CODE_FIELD_NULL(3001, "组合配合匹配前导码为空"), + COMBINED_FIELD_NULL(3002, "组合字段解析配置为空"); + + private Integer code; + private String message; + + EngineExceptionEnum(Integer code, String message) { + this.code = code; + this.message = message; + } + + @Override + public Integer getCode() { + return this.code; + } + + public void setCode(Integer code) { + this.code = code; + } + + @Override + public String getMessage() { + return this.message; + } + + public void setMessage(String message) { + this.message = message; + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java index 515ca53..00a5710 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/FixedPropertyEnum.java @@ -11,4 +11,10 @@ String TOTAL_LENGTH = "totalLength"; String TAIL_POSITION = "tailPosition"; + + String BEFORE_BUSINESS_CONTENT = "preBusinessContent"; + + String AROUND_BUSINESS_CONTENT = "businessContent"; + + String AFTER_BUSINESS_CONTENT = "afterBusinessContent"; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java new file mode 100644 index 0000000..a9937e4 --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/exception/EngineException.java @@ -0,0 +1,34 @@ +package com.casic.missiles.exception; + +import com.casic.missiles.enums.AbstractBaseExceptionEnum; +import lombok.Getter; +import lombok.Setter; + +/** + * @Description: 业务异常 + * @Author: wangpeng + * @Date: 2022/11/24 17:52 + */ +public class EngineException extends RuntimeException { + private static final long serialVersionUID = 1L; + + @Getter + @Setter + private Integer code; + @Getter + @Setter + private String message; + + public EngineException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } + + public EngineException(AbstractBaseExceptionEnum exceptionEnum) { + super(exceptionEnum.getMessage()); + this.code = exceptionEnum.getCode(); + this.message = exceptionEnum.getMessage(); + } + +} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java index ba9aea2..6e8d31d 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/AbstractFieldConfig.java @@ -5,7 +5,7 @@ @Data public class AbstractFieldConfig { /** - * 字段名称 + * 字段名称 */ private String fieldName; /** @@ -13,19 +13,19 @@ */ private String ruleJson; /** - * 起始位置(单位byte) + * 起始位置(单位byte) */ - private Integer OriginPositionByte; + private Integer OriginPositionByte; /** - * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 + * 起始位置,是否需要bit位置(单位bit)小于8, 没有不需要填写 */ - private String OriginPositionBit; + private Integer OriginPositionBit; /** - * 偏移长度 + * 偏移长度 */ private Integer offsetLength; /** - * 偏移单位(bit/byte) + * 偏移单位(bit/byte) */ private String offsetUnit; /** @@ -34,5 +34,4 @@ private Integer isStorage; - } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java index 8df2f3e..35c3e8f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/CombinedFieldConfig.java @@ -30,9 +30,16 @@ private String dataFieldIds; /** + * 对应的要解析字段的名称 + */ + private String dataFieldName; + + private Integer isStorge; + + /** * 字段动态的id */ - private Long combinedFieldId; + private String combinedFieldIds; private Date lastTime; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java index 8304dc6..5f5dcc8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldConfig.java @@ -12,7 +12,7 @@ * 3、该表字段解析根据FieldEvaluatorConfig进行字段解析 */ @Data -@TableName("business_field_config") +@TableName("bussiness_field_config") public class FieldConfig extends AbstractFieldConfig { private Long id; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java index 2e09879..97cb2d4 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/FieldRuleConfig.java @@ -10,11 +10,12 @@ public class FieldRuleConfig { private Long id; + private Long ruleId; private String name; - private String desc; - private String condition; - private String excuteOperation; - private Date lasTime; + private Long ruleType; + private String descn; + private String expression; + private Date lastTime; private Date createTime; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java index db794bd..9547040 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/ProtocolFieldConfig.java @@ -28,10 +28,6 @@ */ private String isReplyFix; /** - * 按照字段评估进行字段解析 - */ - private Long fieldEvaluatorId; - /** * 回复规则 */ private String replyRule; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java b/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java index 406fe65..b566ac8 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/registry/impl/FieldRuleConfigRegistryImpl.java @@ -14,9 +14,14 @@ @Override public List getFieldRuleConfigList(Long ruleId) { - QueryWrapper queryWrapper = new QueryWrapper() - .eq("rule_id", ruleId); - List fieldRuleConfigList = this.baseMapper.selectList(queryWrapper); + List fieldRuleConfigList = null; + try { + QueryWrapper queryWrapper = new QueryWrapper() + .eq("rule_id", ruleId); + fieldRuleConfigList = this.baseMapper.selectList(queryWrapper); + } catch (Exception ex) { + log.error("字段规则表查询异常,异常信息为{}",ex); + } return fieldRuleConfigList; } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/util/AutoCodeGenerator.java b/sensorhub-support/src/main/java/com/casic/missiles/util/AutoCodeGenerator.java deleted file mode 100644 index f24d2ae..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/util/AutoCodeGenerator.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.casic.missiles.util; - -import com.baomidou.mybatisplus.generator.FastAutoGenerator; -import com.baomidou.mybatisplus.generator.config.DataSourceConfig; -import com.baomidou.mybatisplus.generator.config.rules.DateType; -import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; -import org.springframework.core.env.Environment; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @Description: mybatis-plus代码生成器 - * @Author: wangpeng - * @Date: 2022/8/11 17:52 - */ -@RestController -@RequestMapping("/code") -public class AutoCodeGenerator { - - private static String driverClassName; // 驱动名称 - private static String username; // 数据库用户名 - private static String password; // 数据库用户密码 - private static String url; // 数据库连接URL - private static String author; // 作者 - private static String tableName; // 待生成对象表名 - - /** - * 读取 application.properties 配置文件 - */ - private static void readProperty() { - Environment environment = SpringContextUtil.getApplicationContext().getEnvironment(); - driverClassName = environment.getProperty("spring.datasource.driver-class-name"); - username = environment.getProperty("spring.datasource.username"); - password = environment.getProperty("spring.datasource.password"); - url = environment.getProperty("spring.datasource.url"); - author = environment.getProperty("code.generate.author"); - tableName = environment.getProperty("code.generate.table-name"); - } - - /** - * MyBatis-Plus 代码生成器「新」 - * 适用版本:mybatis-plus-generator 3.5.1 及其以上版本,对历史版本不兼容 - */ - @GetMapping("generator") - public static void main(String [] args) { - // 加载数据库配置 - readProperty(); - // 项目路径 - String projectPath = System.getProperty("user.dir"); - // 根据数据源信息,创建文件,生成代码 - FastAutoGenerator.create(new DataSourceConfig.Builder(url,username,password)) - // 全局配置 - .globalConfig(builder -> builder - // 作者 - .author(author) - // 输出路径 - .outputDir(projectPath + "/target/generated-sources") - .dateType(DateType.TIME_PACK) - ) - // 包配置 - .packageConfig(builder -> builder - // 指定父包名 - .parent("com.casic.missiles") - .entity("model") - .service("Registry") - .serviceImpl("Registry.impl") - .mapper("mapper") - .controller("controller")) - // 模版配置 -// .templateConfig(builder -> builder -// .entity("/templates/entity.java") -// .Registry("/templates/Registry.java") -// .ServiceImpl("/templates/ServiceImpl.java") -// .mapper("/templates/mapper.java") -// .controller("/templates/controller.java")) - // 策略配置 - .strategyConfig(builder -> builder - // 指定表名,用逗号分隔 - .addInclude(tableName.split(",")) - // 先开启 Controller 配置 - .controllerBuilder() - // 开启生成 @RestController 控制器 - .enableRestStyle() - // 开启驼峰转连字符 - .enableHyphenStyle() - // 先开启 Entity 配置 - .entityBuilder() - // 开启主键自增 -// .idType(IdType.AUTO) - // 数据库表映射到实体的命名策略,驼峰命名 - .naming(NamingStrategy.underline_to_camel) - // 数据库表字段映射到实体的命名策略,驼峰命名 - .columnNaming(NamingStrategy.underline_to_camel) - // 开启生成实体时生成字段注解 - .enableTableFieldAnnotation() - .enableLombok() - .mapperBuilder() - .enableBaseResultMap() - .enableBaseColumnList()) - // 执行 - .execute(); - } -} diff --git a/sensorhub-web/pom.xml b/sensorhub-web/pom.xml index 44fa4bb..384ba19 100644 --- a/sensorhub-web/pom.xml +++ b/sensorhub-web/pom.xml @@ -6,23 +6,13 @@ com.casic sensorhub ../pom.xml - 0.0.1-SNAPSHOT + 0.1.0-SNAPSHOT com.casic sensorhub-web 0.0.1-SNAPSHOT sensorhub-web sensorhub-server - - 4.1.66.Final - - - - mysql - mysql-connector-java - ${mysql.driver.version} - -