diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java index b9aec95..9ae58ee 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java @@ -59,9 +59,15 @@ if (ReplyCommandEnum.REQUEST_UPGRADE == parseResult.getReplyCommand()) { String version = (String) parseResult.getBizDataMap().get(BEFORE_UPGRADE); UpgradeFileResult upgradeFileResult = UpgradeFileProvider.intendUpgradeFile(deviceType, version); - bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); - bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); - bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + if (ObjectUtils.isNotEmpty(upgradeFileResult)) { + bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); + bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); + bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + } else { + bizDataMap.put(UPGRADE_TEXT_LENGTH, null); + bizDataMap.put(CRC, null); + bizDataMap.put(IS_UPGRADE, 0); + } return bizDataMap; } //3状态升级的时候,已经完成了升级文件的缓存,这里已经拿不到版本号 @@ -72,6 +78,7 @@ //获取版本号 UpgradeFileResult upgradeFileResult = UpgradeFileProvider.upgradeFile(key, startPoint, offsetLength, deviceType); bizDataMap.put(START_POINT, startPoint); + bizDataMap.put(SEQ, upgradeFileResult.getSeq()); ByteBuf upgradeLength = ByteBufAllocator.DEFAULT.buffer(); upgradeLength.writeBytes(upgradeFileResult.getBytes()); bizDataMap.put(UPGRADE_TEXT, ByteBufUtil.hexDump(upgradeLength)); @@ -98,7 +105,10 @@ List combinedFieldConfigs = configFactory.getCombinedFieldConfigProvider().prepareParseField(ruleConfig); List fieldConfigs = configFactory.getFieldConfigProvider().prepareParseField(ruleConfig); for (CombinedFieldConfig combinedFieldConfig : combinedFieldConfigs) { - replyBytes.writeBytes(FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap)); + ByteBuf byteBuf = FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap); + if (ObjectUtils.isNotEmpty(byteBuf)) { + replyBytes.writeBytes(byteBuf); + } } System.out.println(ByteBufUtil.hexDump(replyBytes)); FieldReverseDecorator.simpleField(fieldConfigs, null, replyBytes, fieldRuleConfigMap, null); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java index b9aec95..9ae58ee 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java @@ -59,9 +59,15 @@ if (ReplyCommandEnum.REQUEST_UPGRADE == parseResult.getReplyCommand()) { String version = (String) parseResult.getBizDataMap().get(BEFORE_UPGRADE); UpgradeFileResult upgradeFileResult = UpgradeFileProvider.intendUpgradeFile(deviceType, version); - bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); - bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); - bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + if (ObjectUtils.isNotEmpty(upgradeFileResult)) { + bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); + bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); + bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + } else { + bizDataMap.put(UPGRADE_TEXT_LENGTH, null); + bizDataMap.put(CRC, null); + bizDataMap.put(IS_UPGRADE, 0); + } return bizDataMap; } //3状态升级的时候,已经完成了升级文件的缓存,这里已经拿不到版本号 @@ -72,6 +78,7 @@ //获取版本号 UpgradeFileResult upgradeFileResult = UpgradeFileProvider.upgradeFile(key, startPoint, offsetLength, deviceType); bizDataMap.put(START_POINT, startPoint); + bizDataMap.put(SEQ, upgradeFileResult.getSeq()); ByteBuf upgradeLength = ByteBufAllocator.DEFAULT.buffer(); upgradeLength.writeBytes(upgradeFileResult.getBytes()); bizDataMap.put(UPGRADE_TEXT, ByteBufUtil.hexDump(upgradeLength)); @@ -98,7 +105,10 @@ List combinedFieldConfigs = configFactory.getCombinedFieldConfigProvider().prepareParseField(ruleConfig); List fieldConfigs = configFactory.getFieldConfigProvider().prepareParseField(ruleConfig); for (CombinedFieldConfig combinedFieldConfig : combinedFieldConfigs) { - replyBytes.writeBytes(FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap)); + ByteBuf byteBuf = FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap); + if (ObjectUtils.isNotEmpty(byteBuf)) { + replyBytes.writeBytes(byteBuf); + } } System.out.println(ByteBufUtil.hexDump(replyBytes)); FieldReverseDecorator.simpleField(fieldConfigs, null, replyBytes, fieldRuleConfigMap, null); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java index 3b3e693..8f3c0f1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java @@ -40,7 +40,6 @@ public static ByteBuf combinedField(Map fieldConfigsMap, CombinedFieldConfig combinedFieldConfig, Map bizDataMap, Map fieldRuleConfigMap) { if (ObjectUtils.isEmpty(combinedFieldConfig)) { - return null; } ByteBuf fragmentByte = ByteBufAllocator.DEFAULT.buffer(); @@ -60,6 +59,11 @@ throw new EngineException(EngineExceptionEnum.COMBINED_DATA_CONFIG_NULL); }); if (dataFieldIds.length == 1) { + if (ObjectUtils.isNotEmpty(bizDataMap) && bizDataMap.containsKey(combinedFieldConfig.getDataFieldName())) { + if (bizDataMap.get(combinedFieldConfig.getDataFieldName()) == null) { + return null; + } + } fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); } fieldConfigs.add(fieldConfig); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java index b9aec95..9ae58ee 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java @@ -59,9 +59,15 @@ if (ReplyCommandEnum.REQUEST_UPGRADE == parseResult.getReplyCommand()) { String version = (String) parseResult.getBizDataMap().get(BEFORE_UPGRADE); UpgradeFileResult upgradeFileResult = UpgradeFileProvider.intendUpgradeFile(deviceType, version); - bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); - bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); - bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + if (ObjectUtils.isNotEmpty(upgradeFileResult)) { + bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); + bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); + bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + } else { + bizDataMap.put(UPGRADE_TEXT_LENGTH, null); + bizDataMap.put(CRC, null); + bizDataMap.put(IS_UPGRADE, 0); + } return bizDataMap; } //3状态升级的时候,已经完成了升级文件的缓存,这里已经拿不到版本号 @@ -72,6 +78,7 @@ //获取版本号 UpgradeFileResult upgradeFileResult = UpgradeFileProvider.upgradeFile(key, startPoint, offsetLength, deviceType); bizDataMap.put(START_POINT, startPoint); + bizDataMap.put(SEQ, upgradeFileResult.getSeq()); ByteBuf upgradeLength = ByteBufAllocator.DEFAULT.buffer(); upgradeLength.writeBytes(upgradeFileResult.getBytes()); bizDataMap.put(UPGRADE_TEXT, ByteBufUtil.hexDump(upgradeLength)); @@ -98,7 +105,10 @@ List combinedFieldConfigs = configFactory.getCombinedFieldConfigProvider().prepareParseField(ruleConfig); List fieldConfigs = configFactory.getFieldConfigProvider().prepareParseField(ruleConfig); for (CombinedFieldConfig combinedFieldConfig : combinedFieldConfigs) { - replyBytes.writeBytes(FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap)); + ByteBuf byteBuf = FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap); + if (ObjectUtils.isNotEmpty(byteBuf)) { + replyBytes.writeBytes(byteBuf); + } } System.out.println(ByteBufUtil.hexDump(replyBytes)); FieldReverseDecorator.simpleField(fieldConfigs, null, replyBytes, fieldRuleConfigMap, null); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java index 3b3e693..8f3c0f1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java @@ -40,7 +40,6 @@ public static ByteBuf combinedField(Map fieldConfigsMap, CombinedFieldConfig combinedFieldConfig, Map bizDataMap, Map fieldRuleConfigMap) { if (ObjectUtils.isEmpty(combinedFieldConfig)) { - return null; } ByteBuf fragmentByte = ByteBufAllocator.DEFAULT.buffer(); @@ -60,6 +59,11 @@ throw new EngineException(EngineExceptionEnum.COMBINED_DATA_CONFIG_NULL); }); if (dataFieldIds.length == 1) { + if (ObjectUtils.isNotEmpty(bizDataMap) && bizDataMap.containsKey(combinedFieldConfig.getDataFieldName())) { + if (bizDataMap.get(combinedFieldConfig.getDataFieldName()) == null) { + return null; + } + } fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); } fieldConfigs.add(fieldConfig); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java index daaa63d..9f41797 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java @@ -49,12 +49,20 @@ } public static void main(String[] args) { + int parseValue1 = Float.floatToIntBits((float) 8.0); + String parseValue = Integer.toHexString(parseValue1); + System.out.println(parseValue1); + System.out.println(parseValue); + System.out.println(Integer.parseInt(parseValue, 16)); + System.out.println(); //加载自定义函数 - List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); - for (CustomizedFunction customizedFunction : customizedFunctions) { - AviatorEvaluator.addFunction(customizedFunction); - } - System.out.println(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); +// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); +// for (CustomizedFunction customizedFunction : customizedFunctions) { +// AviatorEvaluator.addFunction(customizedFunction); +// } +// Map map=new HashMap(); +// map.put("value","170901"); +// System.out.println(AviatorEvaluator.execute("strDateFormat(value)", map)); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java index b9aec95..9ae58ee 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java @@ -59,9 +59,15 @@ if (ReplyCommandEnum.REQUEST_UPGRADE == parseResult.getReplyCommand()) { String version = (String) parseResult.getBizDataMap().get(BEFORE_UPGRADE); UpgradeFileResult upgradeFileResult = UpgradeFileProvider.intendUpgradeFile(deviceType, version); - bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); - bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); - bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + if (ObjectUtils.isNotEmpty(upgradeFileResult)) { + bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); + bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); + bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + } else { + bizDataMap.put(UPGRADE_TEXT_LENGTH, null); + bizDataMap.put(CRC, null); + bizDataMap.put(IS_UPGRADE, 0); + } return bizDataMap; } //3状态升级的时候,已经完成了升级文件的缓存,这里已经拿不到版本号 @@ -72,6 +78,7 @@ //获取版本号 UpgradeFileResult upgradeFileResult = UpgradeFileProvider.upgradeFile(key, startPoint, offsetLength, deviceType); bizDataMap.put(START_POINT, startPoint); + bizDataMap.put(SEQ, upgradeFileResult.getSeq()); ByteBuf upgradeLength = ByteBufAllocator.DEFAULT.buffer(); upgradeLength.writeBytes(upgradeFileResult.getBytes()); bizDataMap.put(UPGRADE_TEXT, ByteBufUtil.hexDump(upgradeLength)); @@ -98,7 +105,10 @@ List combinedFieldConfigs = configFactory.getCombinedFieldConfigProvider().prepareParseField(ruleConfig); List fieldConfigs = configFactory.getFieldConfigProvider().prepareParseField(ruleConfig); for (CombinedFieldConfig combinedFieldConfig : combinedFieldConfigs) { - replyBytes.writeBytes(FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap)); + ByteBuf byteBuf = FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap); + if (ObjectUtils.isNotEmpty(byteBuf)) { + replyBytes.writeBytes(byteBuf); + } } System.out.println(ByteBufUtil.hexDump(replyBytes)); FieldReverseDecorator.simpleField(fieldConfigs, null, replyBytes, fieldRuleConfigMap, null); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java index 3b3e693..8f3c0f1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java @@ -40,7 +40,6 @@ public static ByteBuf combinedField(Map fieldConfigsMap, CombinedFieldConfig combinedFieldConfig, Map bizDataMap, Map fieldRuleConfigMap) { if (ObjectUtils.isEmpty(combinedFieldConfig)) { - return null; } ByteBuf fragmentByte = ByteBufAllocator.DEFAULT.buffer(); @@ -60,6 +59,11 @@ throw new EngineException(EngineExceptionEnum.COMBINED_DATA_CONFIG_NULL); }); if (dataFieldIds.length == 1) { + if (ObjectUtils.isNotEmpty(bizDataMap) && bizDataMap.containsKey(combinedFieldConfig.getDataFieldName())) { + if (bizDataMap.get(combinedFieldConfig.getDataFieldName()) == null) { + return null; + } + } fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); } fieldConfigs.add(fieldConfig); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java index daaa63d..9f41797 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java @@ -49,12 +49,20 @@ } public static void main(String[] args) { + int parseValue1 = Float.floatToIntBits((float) 8.0); + String parseValue = Integer.toHexString(parseValue1); + System.out.println(parseValue1); + System.out.println(parseValue); + System.out.println(Integer.parseInt(parseValue, 16)); + System.out.println(); //加载自定义函数 - List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); - for (CustomizedFunction customizedFunction : customizedFunctions) { - AviatorEvaluator.addFunction(customizedFunction); - } - System.out.println(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); +// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); +// for (CustomizedFunction customizedFunction : customizedFunctions) { +// AviatorEvaluator.addFunction(customizedFunction); +// } +// Map map=new HashMap(); +// map.put("value","170901"); +// System.out.println(AviatorEvaluator.execute("strDateFormat(value)", map)); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java index 6b40b4f..ad9e351 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java @@ -4,6 +4,8 @@ import io.netty.buffer.ByteBufUtil; import lombok.extern.slf4j.Slf4j; +import java.math.BigDecimal; + /** * @author 数值类型转换规则 */ @@ -34,13 +36,17 @@ case "float": parseValue = currentConfigValue; if (currentConfigValue instanceof Integer) { - parseValue = Integer.toHexString(Float.floatToIntBits((Integer)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((Integer) currentConfigValue)); } + if (currentConfigValue instanceof BigDecimal) { + parseValue = Integer.toHexString(Float.floatToIntBits(((BigDecimal) currentConfigValue).floatValue())); + } + if (currentConfigValue instanceof Float) { - parseValue = Integer.toHexString(Float.floatToIntBits((float)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((float) currentConfigValue)); } if (currentConfigValue instanceof Long) { - parseValue = Integer.toHexString(Float.floatToIntBits((long)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((long) currentConfigValue)); } break; case "int": @@ -52,16 +58,4 @@ } return parseValue; } - - public static void main(String[] args) { - float str = 25.00f; - System.out.println(Integer.toHexString(Float.floatToIntBits(str))); - //加载自定义函数 -// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); -// for (CustomizedFunction customizedFunction : customizedFunctions) { -// AviatorEvaluator.addFunction(customizedFunction); -// } -// Object value = String.valueOf(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); -// System.out.println(value); - } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java index b9aec95..9ae58ee 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java @@ -59,9 +59,15 @@ if (ReplyCommandEnum.REQUEST_UPGRADE == parseResult.getReplyCommand()) { String version = (String) parseResult.getBizDataMap().get(BEFORE_UPGRADE); UpgradeFileResult upgradeFileResult = UpgradeFileProvider.intendUpgradeFile(deviceType, version); - bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); - bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); - bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + if (ObjectUtils.isNotEmpty(upgradeFileResult)) { + bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); + bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); + bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + } else { + bizDataMap.put(UPGRADE_TEXT_LENGTH, null); + bizDataMap.put(CRC, null); + bizDataMap.put(IS_UPGRADE, 0); + } return bizDataMap; } //3状态升级的时候,已经完成了升级文件的缓存,这里已经拿不到版本号 @@ -72,6 +78,7 @@ //获取版本号 UpgradeFileResult upgradeFileResult = UpgradeFileProvider.upgradeFile(key, startPoint, offsetLength, deviceType); bizDataMap.put(START_POINT, startPoint); + bizDataMap.put(SEQ, upgradeFileResult.getSeq()); ByteBuf upgradeLength = ByteBufAllocator.DEFAULT.buffer(); upgradeLength.writeBytes(upgradeFileResult.getBytes()); bizDataMap.put(UPGRADE_TEXT, ByteBufUtil.hexDump(upgradeLength)); @@ -98,7 +105,10 @@ List combinedFieldConfigs = configFactory.getCombinedFieldConfigProvider().prepareParseField(ruleConfig); List fieldConfigs = configFactory.getFieldConfigProvider().prepareParseField(ruleConfig); for (CombinedFieldConfig combinedFieldConfig : combinedFieldConfigs) { - replyBytes.writeBytes(FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap)); + ByteBuf byteBuf = FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap); + if (ObjectUtils.isNotEmpty(byteBuf)) { + replyBytes.writeBytes(byteBuf); + } } System.out.println(ByteBufUtil.hexDump(replyBytes)); FieldReverseDecorator.simpleField(fieldConfigs, null, replyBytes, fieldRuleConfigMap, null); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java index 3b3e693..8f3c0f1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java @@ -40,7 +40,6 @@ public static ByteBuf combinedField(Map fieldConfigsMap, CombinedFieldConfig combinedFieldConfig, Map bizDataMap, Map fieldRuleConfigMap) { if (ObjectUtils.isEmpty(combinedFieldConfig)) { - return null; } ByteBuf fragmentByte = ByteBufAllocator.DEFAULT.buffer(); @@ -60,6 +59,11 @@ throw new EngineException(EngineExceptionEnum.COMBINED_DATA_CONFIG_NULL); }); if (dataFieldIds.length == 1) { + if (ObjectUtils.isNotEmpty(bizDataMap) && bizDataMap.containsKey(combinedFieldConfig.getDataFieldName())) { + if (bizDataMap.get(combinedFieldConfig.getDataFieldName()) == null) { + return null; + } + } fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); } fieldConfigs.add(fieldConfig); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java index daaa63d..9f41797 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java @@ -49,12 +49,20 @@ } public static void main(String[] args) { + int parseValue1 = Float.floatToIntBits((float) 8.0); + String parseValue = Integer.toHexString(parseValue1); + System.out.println(parseValue1); + System.out.println(parseValue); + System.out.println(Integer.parseInt(parseValue, 16)); + System.out.println(); //加载自定义函数 - List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); - for (CustomizedFunction customizedFunction : customizedFunctions) { - AviatorEvaluator.addFunction(customizedFunction); - } - System.out.println(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); +// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); +// for (CustomizedFunction customizedFunction : customizedFunctions) { +// AviatorEvaluator.addFunction(customizedFunction); +// } +// Map map=new HashMap(); +// map.put("value","170901"); +// System.out.println(AviatorEvaluator.execute("strDateFormat(value)", map)); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java index 6b40b4f..ad9e351 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java @@ -4,6 +4,8 @@ import io.netty.buffer.ByteBufUtil; import lombok.extern.slf4j.Slf4j; +import java.math.BigDecimal; + /** * @author 数值类型转换规则 */ @@ -34,13 +36,17 @@ case "float": parseValue = currentConfigValue; if (currentConfigValue instanceof Integer) { - parseValue = Integer.toHexString(Float.floatToIntBits((Integer)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((Integer) currentConfigValue)); } + if (currentConfigValue instanceof BigDecimal) { + parseValue = Integer.toHexString(Float.floatToIntBits(((BigDecimal) currentConfigValue).floatValue())); + } + if (currentConfigValue instanceof Float) { - parseValue = Integer.toHexString(Float.floatToIntBits((float)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((float) currentConfigValue)); } if (currentConfigValue instanceof Long) { - parseValue = Integer.toHexString(Float.floatToIntBits((long)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((long) currentConfigValue)); } break; case "int": @@ -52,16 +58,4 @@ } return parseValue; } - - public static void main(String[] args) { - float str = 25.00f; - System.out.println(Integer.toHexString(Float.floatToIntBits(str))); - //加载自定义函数 -// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); -// for (CustomizedFunction customizedFunction : customizedFunctions) { -// AviatorEvaluator.addFunction(customizedFunction); -// } -// Object value = String.valueOf(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); -// System.out.println(value); - } } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java index 87d741e..93e390f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java @@ -6,6 +6,22 @@ */ public interface ReplyCommandEnum { + + /** + * 解析失败,无需响应 + */ + Integer CONFIRM_CONFIG_ISSUE = -1; + + /** + * 下发配置确认的业务代码 + */ + String SYSYETM_TIMES = "系统时间"; + + /** + * 下发配置确认的业务代码 + */ + String IMEI = "imei"; + /** * 解析失败,无需响应 */ @@ -26,7 +42,6 @@ */ int UPGRADE_CONTENT = 3; - /** * 指定的升级解析字段 */ @@ -45,6 +60,7 @@ String IS_UPGRADE = "isUpgrade"; + String SEQ = "seq"; String START_POINT = "startPoint"; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java index d800382..2d0aeae 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/AepCommandSend.java @@ -48,6 +48,9 @@ if (CollectionUtils.isNotEmpty(list)) { AbstractBuildReplyCommand abstractBuildReplyCommand = new DefaultReplyCommand(); ByteBuf baseBytes = abstractBuildReplyCommand.excute((ParseResult) list.get(0)); + if (baseBytes == null) { + return; + } queryMap.put("Value", baseBytes.toString(Charset.forName("ISO-8859-1"))); dataGasMap.put("paras", queryMap); busConfigParam.setCommand(dataGasMap); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java new file mode 100644 index 0000000..e0f987f --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/function/StrDateFormatFunction.java @@ -0,0 +1,49 @@ +package com.casic.missiles.function; + +import com.alibaba.druid.util.StringUtils; +import com.googlecode.aviator.runtime.function.FunctionUtils; +import com.googlecode.aviator.runtime.type.AviatorObject; +import com.googlecode.aviator.runtime.type.AviatorStringBuilder; + +import java.util.Map; + +/** + * @author cz + * 自定义函数拆解 + */ +public class StrDateFormatFunction extends CustomizedFunction { + + /** + * @param env 自定义的参数 + * @param arg1 函数参数 + * @return + */ + @Override + public AviatorObject call(Map env, AviatorObject arg1) { + String timeFormat = FunctionUtils.getStringValue(arg1, env); + String dateTime = ""; + for (int i = 2; i <= timeFormat.length(); i += 2) { + String hexTimeSegment = timeFormat.substring(i - 2, i); + Integer strTimeSegment = Integer.parseInt(hexTimeSegment, 16); + if (i == 2) { + strTimeSegment += 2000; + } + //格式处理 + dateTime += StringUtils.isEmpty(dateTime) ? (strTimeSegment < 10 ? "0" + strTimeSegment : strTimeSegment) : dateTime.length() < 8 ? + ((strTimeSegment < 10 ? "-" + "0" + strTimeSegment : "-" + strTimeSegment)) + : ((strTimeSegment < 10 ? " " + "0" + strTimeSegment : " " + strTimeSegment)); + } + return new AviatorStringBuilder(dateTime); + } + + /** + * 函数自定义名称 + * + * @return + */ + @Override + public String getName() { + return "strDateFormat"; + } + +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java index 0c4e202..c8c54f8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/SensorhubDecoder.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * SensorhubDecoder 解码器 @@ -56,33 +58,4 @@ } } - public static void main(String[] args) throws IOException { - String filePathName = "C:\\Users\\77042\\Desktop\\解析文件\\RTU100N_v3.1"; - File file = new File(filePathName); - // 创建文件字节输入流对象 - FileInputStream fis = null; - // BufferedInputStream为另一个输入流添加了功能,即缓冲输入 - // FileInputStream就具备了缓冲的功能 - BufferedInputStream bis = null; - byte[] buf = new byte[Integer.valueOf(String.valueOf(file.length()))];//缓冲区4096字节 - //文件声明,每个byte[]保存1M的文件,一个文件会可能存在多个byte[]的文件 - try { - fis = new FileInputStream(file); - bis = new BufferedInputStream(fis); - //直接进行读取byte数据,进行数据存储,因为需要进行crc整体校验,所以文件并不是特别大 - bis.read(buf); - } catch (IOException ioex) { - log.error("读取文件失败,文件路径是{},异常信息为{}", filePathName, ioex); - } finally { - try { - bis.close(); - fis.close(); - return; - } catch (IOException ioex) { - log.error("读取升级文件异常,异常信息{}", ioex); - return; - } - } - } - } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java new file mode 100644 index 0000000..94e9877 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/processor/reply/ConfirmConfigIssue.java @@ -0,0 +1,34 @@ +package com.casic.missiles.parser.processor.reply; + +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.casic.missiles.factory.AbstractProtocolConfigFactory; +import com.casic.missiles.factory.AbstractRuleConfigFactory; +import com.casic.missiles.parser.processor.AbstractReplyCommandPostProcessing; +import com.casic.missiles.pojo.ParseResult; + +import java.util.List; +import java.util.Map; + +/** + * @author cz + */ +public class ConfirmConfigIssue implements AbstractReplyCommandPostProcessing { + + + @Override + public ParseResult obtainReplyCommand(List> bizDataMap, ParseResult result, + AbstractRuleConfigFactory ruleConfigFactory, AbstractProtocolConfigFactory protocolFactory) { + if (CollectionUtils.isEmpty(bizDataMap)) { + throw new RuntimeException("业务内容解析为空,解析配置存在问题,请分析查看"); + } + if (bizDataMap.get(0).containsKey(SYSYETM_TIMES) || bizDataMap.get(0).containsKey(IMEI)) { + result = ParseResult.builder().replyCommand(CONFIRM_CONFIG_ISSUE) + .devcode(bizDataMap.get(0).get(DEVCODE).toString()) + .bizDataMap(bizDataMap.get(0)) + .ruleConfigFactory(ruleConfigFactory) + .protocolFactory(protocolFactory) + .build(); + } + return result; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java index 65a126a..6320348 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/GenericFiledRuleResolver.java @@ -1,6 +1,7 @@ package com.casic.missiles.parser.resolver; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.parser.resolver.rule.ByteMergeResolver; import com.casic.missiles.parser.resolver.rule.ByteTypeResolver; import com.casic.missiles.parser.resolver.rule.DecorateResolver; @@ -10,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -29,10 +31,11 @@ * 值运算包括值缩放、格式转换、精度运算 * 这是一般的运算流程 */ - public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doResolveFieldByteRule(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object resolveRuleValue = ByteBufUtil.hexDump(byteBuf); List byteBufList = new ArrayList<>(); String[] ruleStrs = ruleIds.split(","); + //存放到数组里面 if (ruleStrs.length == 1) { byteBufList.add(byteBuf); @@ -40,6 +43,10 @@ for (int i = 0; i < byteBuf.writerIndex(); i++) { byteBufList.add(byteBuf.readBytes(1)); } + //如果是网络序 + if (networkOrder) { + Collections.reverse(byteBufList); + } } //通过类型可以控制aviator入参出参的数据 for (String ruleId : ruleStrs) { @@ -48,7 +55,10 @@ //合并规则进行执行字段合并 switch (ruleType) { case "combine": + List combineByteBufList = new ArrayList<>(); resolveRuleValue = ByteMergeResolver.resolveRule(byteBufList); + combineByteBufList.add(resolveRuleValue); + byteBufList = combineByteBufList; break; case "typeConvert": List tempByteBufList = new ArrayList<>(); 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 index 0375b81..f7a0b08 100644 --- 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 @@ -22,18 +22,19 @@ public class BitFieldParser extends GenericFiledRuleResolver { /** - * 位字段解析 + * 位字段解析 * 1、单个字节情况表示字段 * 2、多字节情况表示字段(暂未处理) */ - public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap) { + public static Object doParseBitField(ByteBuf byteBuf, AbstractFieldConfig fieldConfig, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; String binaryStr = convertBinaryStr(byteBuf, fieldConfig); if (StringUtils.isEmpty(fieldConfig.getRuleIds())) { + //暂时没处理网络序 fieldsResolveValue = defaultBitResolve(binaryStr); } else { - fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldBitRule(binaryStr, fieldConfig.getRuleIds(), fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } @@ -55,11 +56,11 @@ * * @return */ - private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap) { + private static Object doResolveFieldBitRule(String binaryStr, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { byte[] binaryBytes = getBytesFromBinaryStr(binaryStr); ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer(); byteBuf.writeBytes(binaryBytes); - return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + return doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } @@ -91,7 +92,7 @@ /** - * 从二进制字符串转为byte[] + * 从二进制字符串转为byte[] * * @param binaryStr * @return 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 index c0f277f..4c02a81 100644 --- 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 @@ -16,33 +16,37 @@ /** - * 字节字段解析核心类 + * 字节字段解析核心类 * 存在rule_json走自定义的规则设置,没有则支持默认配置的规则设置 * * @param byteBuf * @param ruleIds * @return */ - public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap) { + public static Object doParseByteField(ByteBuf byteBuf, String ruleIds, Map fieldRuleConfigMap, Boolean networkOrder) { Object fieldsResolveValue = null; if (StringUtils.isEmpty(ruleIds)) { - fieldsResolveValue = defaultResolve(byteBuf); + fieldsResolveValue = defaultResolve(byteBuf, networkOrder); } else { - fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap); + fieldsResolveValue = doResolveFieldByteRule(byteBuf, ruleIds, fieldRuleConfigMap, networkOrder); } return fieldsResolveValue; } /** - * 默认解析方法 + * 默认解析方法 * * @param byteBuf * @return */ - private static Object defaultResolve(ByteBuf byteBuf) { + private static Object defaultResolve(ByteBuf byteBuf, Boolean networkOrder) { Integer defaultResolveValue = 0; for (int i = 0; i < byteBuf.writerIndex(); i++) { +// if (networkOrder) { +// defaultResolveValue = defaultResolveValue | (int) byteBuf.readByte() & 0xff << 8 * i; +// } else { defaultResolveValue = defaultResolveValue << 8 | (int) byteBuf.readByte() & 0xff; +// } } return defaultResolveValue; } 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 4ec91e8..aea21e8 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,6 +1,7 @@ package com.casic.missiles.parser.resolver.fields; import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.casic.missiles.pojo.AbstractFieldConfig; import com.casic.missiles.pojo.FieldRuleConfig; import io.netty.buffer.ByteBuf; @@ -14,7 +15,7 @@ /** * @author cz - * + *

* 字段解析管理总类 */ @Slf4j @@ -27,19 +28,20 @@ * @param byteBuf * @return */ - public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { + public Function parseField(ByteBuf byteBuf, Map fieldRuleConfigMap) { return (AbstractFieldConfig fieldConfig) -> { Integer originPosition = Integer.valueOf(fieldConfig.getOriginPositionByte()); Object fieldValue = 0; //待优化 try { + Boolean networkOrder = ObjectUtils.isNotEmpty(fieldConfig.getNetworkOrder()) && fieldConfig.getNetworkOrder() == 1 ? true : false; if (fieldConfig.getOffsetUnit().equals("bit")) { - fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig,fieldRuleConfigMap); + fieldValue = BitFieldParser.doParseBitField(byteBuf, fieldConfig, fieldRuleConfigMap,networkOrder); } else { ByteBuf fieldBytes = byteBuf.slice(originPosition, fieldConfig.getOffsetLength()); fieldBytes.resetReaderIndex(); - fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(),fieldRuleConfigMap); + fieldValue = ByteFieldParser.doParseByteField(fieldBytes, fieldConfig.getRuleIds(), fieldRuleConfigMap,networkOrder); } } catch (RuntimeException ex) { throw new RuntimeException("解析失败,解析配置为" + JSON.toJSON(fieldConfig), ex); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java index 6288b9b..dc0e7eb 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/ByteTypeResolver.java @@ -19,28 +19,31 @@ * @param * @return */ - public static Object resolveRule(Object byteBuf, String convertType) { + public static Object resolveRule(Object object, String convertType) { Object parseValue = null; try { switch (convertType) { case "hexStr": - parseValue = ByteBufUtil.hexDump((ByteBuf) byteBuf); + parseValue = ByteBufUtil.hexDump((ByteBuf) object); break; case "charset": - parseValue = ((ByteBuf) byteBuf).toString(Charset.defaultCharset()); + parseValue = ((ByteBuf) object).toString(Charset.defaultCharset()); break; case "double": - parseValue = Double.longBitsToDouble((long) byteBuf); + parseValue = Double.longBitsToDouble((long) object); + break; + case "short": + parseValue = String.valueOf((Integer.valueOf((String) object, 16).shortValue())); break; case "float": - parseValue = Float.floatToIntBits((long) byteBuf); + parseValue = Float.intBitsToFloat(Integer.parseInt((String) object, 16)); break; case "int": - parseValue = (int) ((ByteBuf) byteBuf).getByte(0) & 0xff; + parseValue = (int) ((ByteBuf) object).getByte(0) & 0xff; break; } - }catch (RuntimeException rx){ - log.error("转换异常,转换类型为{},异常信息为{}", convertType,rx); + } catch (RuntimeException rx) { + log.error("转换异常,转换类型为{},异常信息为{}", convertType, rx); } return parseValue; } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java index 8afe2e0..3d16612 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/resolver/rule/DecorateResolver.java @@ -2,12 +2,15 @@ import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.function.CustomizedFunction; import com.casic.missiles.pojo.FieldRuleConfig; +import com.casic.missiles.util.ClazzUtil; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.ExpressionNotFoundException; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -29,6 +32,10 @@ if (ObjectUtil.isEmpty(fieldRuleEngine)) { return value; } + List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); + for (CustomizedFunction customizedFunction : customizedFunctions) { + AviatorEvaluator.addFunction(customizedFunction); + } String expression = fieldRuleEngine.getExpression(); Map env2 = new HashMap(); env2.put("value", value); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java index fb502cf..5feeaaf 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/ParseResult.java @@ -24,6 +24,7 @@ * 1、成功返回时间对应单独的规则配置 * 2、如果有下发配置,下发配置,配置查询数据库配置 * 同时下发的配置参数对应一个配置 + * */ private Integer replyCommand; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java index 74b42b5..bd44022 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/pojo/UpgradeFileResult.java @@ -18,6 +18,8 @@ private String crcStrBit; + private Integer seq; + /** * 1代表下位机升级,0代表不升级 */ diff --git a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java index 82416f7..b6543e4 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/provider/UpgradeFileProvider.java @@ -12,6 +12,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @author cz @@ -59,12 +61,15 @@ UpgradeFileResult upgradeFileResult = new UpgradeFileResult(); Integer currentPointIndex = offsetLength; UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = getCurrentFileBytes(deviceType, null); - upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); + + upgradeFileResult.setHistoryOffsetLength(typeVersionFileBytes.getBytes().length - 1 >= startPoint + offsetLength ? + offsetLength : typeVersionFileBytes.getBytes().length - offsetLength); //没有获取到,直接返回失败 if (typeVersionFileBytes == null || typeVersionFileBytes.getBytes() == null) { return null; } upgradeFileResult.setBytes(getCurrentFileFragmentBytes(typeVersionFileBytes.getBytes(), startPoint, currentPointIndex)); + upgradeFileResult.setSeq(startPoint / offsetLength + 1); //更新缓存 UpgradeFileStore.storeMap.put(key, currentPointIndex); return upgradeFileResult; @@ -83,6 +88,10 @@ */ private static UpgradeFileStore.deviceTypeVersionFileBytes getCurrentFileBytes(String deviceType, String version) { UpgradeFileStore.deviceTypeVersionFileBytes typeVersionFileBytes = null; + String findFileName = "BIRMM-P1000N-APP_v1.1.bin"; + if (StringUtils.isNotEmpty(version) && compareVersion(version, findFileName)) { + return null; + } byte[] bytes = null; //查询当前设备类型,并且版本号对应,否则重新读取,获取最新的版本号,读取不到则读取失败 if (UpgradeFileStore.versionFileStoreMap.containsKey(deviceType) @@ -96,7 +105,7 @@ typeVersionFileBytes = UpgradeFileStore.versionFileStoreMap.get(deviceType); } else { //读取文件 - bytes = readUpgradeFile(); + bytes = readUpgradeFile(findFileName); //crc校验 String crcCheckStr = CRC16.getCrcByByte(bytes); //获取总长度 @@ -117,6 +126,30 @@ } /** + * 版本号比较,传入的版本号,上传文件的版本号 + */ + private static Boolean compareVersion(String version, String findFileName) { + Float findFileVersion = getVersion(findFileName); + Float oldVersion = getVersion(version); + return findFileVersion <= oldVersion; + } + + /** + * 通过名称,根据正则表达式小数点为获取版本号 + * 注:用小数点区分与其他数字的区别 + */ + private static Float getVersion(String fileName) { + String pattern = "\\d+(\\.\\d+)+"; + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(fileName); + if (m.find()) { + return Float.valueOf(m.group()); + } else { + return null; + } + } + + /** * 获取升级文件内容 *

* 通过list 及偏移坐标 获取升级内容 @@ -130,9 +163,9 @@ return Arrays.copyOfRange(bytes, startPointIndex, startPointIndex + currentPointIndex); } - private static byte[] readUpgradeFile() { + private static byte[] readUpgradeFile(String fileName) { //路径暂定 - String filePathName = "D:\\casic\\file\\GT_BIR1000-APP_v1.1.bin"; + String filePathName = "D:\\casic\\file\\" + fileName; File file = new File(filePathName); // 创建文件字节输入流对象 FileInputStream fis = null; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java index d500ea6..aef5616 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/SensorhubReplier.java @@ -30,11 +30,14 @@ ParseResult parseResult = (ParseResult) obj; //构建指令 AbstractBuildReplyCommand abstractBuildReplyCommand = ClazzUtil.getSubClassByOrder(AbstractBuildReplyCommand.class, 1); - ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); - System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); - ((ByteBuf) replyByteBuf).resetReaderIndex(); - //进行回复 - ctx.channel().writeAndFlush(replyByteBuf); + //-1为当前下发配置确认,不用回复 + if (-1 != parseResult.getReplyCommand()) { + ByteBuf replyByteBuf = abstractBuildReplyCommand.excute(parseResult); + System.out.println("返回的报文内容为" + ByteBufUtil.hexDump((ByteBuf) replyByteBuf)); + ((ByteBuf) replyByteBuf).resetReaderIndex(); + //进行回复 + ctx.channel().writeAndFlush(replyByteBuf); + } } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java index b9aec95..9ae58ee 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/command/ReplyCommandSupport.java @@ -59,9 +59,15 @@ if (ReplyCommandEnum.REQUEST_UPGRADE == parseResult.getReplyCommand()) { String version = (String) parseResult.getBizDataMap().get(BEFORE_UPGRADE); UpgradeFileResult upgradeFileResult = UpgradeFileProvider.intendUpgradeFile(deviceType, version); - bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); - bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); - bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + if (ObjectUtils.isNotEmpty(upgradeFileResult)) { + bizDataMap.put(UPGRADE_TEXT_LENGTH, upgradeFileResult.getTotalLength()); + bizDataMap.put(CRC, upgradeFileResult.getCrcStrBit()); + bizDataMap.put(IS_UPGRADE, upgradeFileResult.getIsUpgrade()); + } else { + bizDataMap.put(UPGRADE_TEXT_LENGTH, null); + bizDataMap.put(CRC, null); + bizDataMap.put(IS_UPGRADE, 0); + } return bizDataMap; } //3状态升级的时候,已经完成了升级文件的缓存,这里已经拿不到版本号 @@ -72,6 +78,7 @@ //获取版本号 UpgradeFileResult upgradeFileResult = UpgradeFileProvider.upgradeFile(key, startPoint, offsetLength, deviceType); bizDataMap.put(START_POINT, startPoint); + bizDataMap.put(SEQ, upgradeFileResult.getSeq()); ByteBuf upgradeLength = ByteBufAllocator.DEFAULT.buffer(); upgradeLength.writeBytes(upgradeFileResult.getBytes()); bizDataMap.put(UPGRADE_TEXT, ByteBufUtil.hexDump(upgradeLength)); @@ -98,7 +105,10 @@ List combinedFieldConfigs = configFactory.getCombinedFieldConfigProvider().prepareParseField(ruleConfig); List fieldConfigs = configFactory.getFieldConfigProvider().prepareParseField(ruleConfig); for (CombinedFieldConfig combinedFieldConfig : combinedFieldConfigs) { - replyBytes.writeBytes(FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap)); + ByteBuf byteBuf = FieldReverseDecorator.combinedField(fieldConfigsMap, combinedFieldConfig, bizDataMap, fieldRuleConfigMap); + if (ObjectUtils.isNotEmpty(byteBuf)) { + replyBytes.writeBytes(byteBuf); + } } System.out.println(ByteBufUtil.hexDump(replyBytes)); FieldReverseDecorator.simpleField(fieldConfigs, null, replyBytes, fieldRuleConfigMap, null); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java index 3b3e693..8f3c0f1 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/FieldReverseDecorator.java @@ -40,7 +40,6 @@ public static ByteBuf combinedField(Map fieldConfigsMap, CombinedFieldConfig combinedFieldConfig, Map bizDataMap, Map fieldRuleConfigMap) { if (ObjectUtils.isEmpty(combinedFieldConfig)) { - return null; } ByteBuf fragmentByte = ByteBufAllocator.DEFAULT.buffer(); @@ -60,6 +59,11 @@ throw new EngineException(EngineExceptionEnum.COMBINED_DATA_CONFIG_NULL); }); if (dataFieldIds.length == 1) { + if (ObjectUtils.isNotEmpty(bizDataMap) && bizDataMap.containsKey(combinedFieldConfig.getDataFieldName())) { + if (bizDataMap.get(combinedFieldConfig.getDataFieldName()) == null) { + return null; + } + } fieldConfig.setFieldName(combinedFieldConfig.getDataFieldName()); } fieldConfigs.add(fieldConfig); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java index daaa63d..9f41797 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/AviatorDecorator.java @@ -49,12 +49,20 @@ } public static void main(String[] args) { + int parseValue1 = Float.floatToIntBits((float) 8.0); + String parseValue = Integer.toHexString(parseValue1); + System.out.println(parseValue1); + System.out.println(parseValue); + System.out.println(Integer.parseInt(parseValue, 16)); + System.out.println(); //加载自定义函数 - List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); - for (CustomizedFunction customizedFunction : customizedFunctions) { - AviatorEvaluator.addFunction(customizedFunction); - } - System.out.println(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); +// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); +// for (CustomizedFunction customizedFunction : customizedFunctions) { +// AviatorEvaluator.addFunction(customizedFunction); +// } +// Map map=new HashMap(); +// map.put("value","170901"); +// System.out.println(AviatorEvaluator.execute("strDateFormat(value)", map)); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java index 6b40b4f..ad9e351 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/replier/decorator/rule/ByteTypeDecorator.java @@ -4,6 +4,8 @@ import io.netty.buffer.ByteBufUtil; import lombok.extern.slf4j.Slf4j; +import java.math.BigDecimal; + /** * @author 数值类型转换规则 */ @@ -34,13 +36,17 @@ case "float": parseValue = currentConfigValue; if (currentConfigValue instanceof Integer) { - parseValue = Integer.toHexString(Float.floatToIntBits((Integer)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((Integer) currentConfigValue)); } + if (currentConfigValue instanceof BigDecimal) { + parseValue = Integer.toHexString(Float.floatToIntBits(((BigDecimal) currentConfigValue).floatValue())); + } + if (currentConfigValue instanceof Float) { - parseValue = Integer.toHexString(Float.floatToIntBits((float)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((float) currentConfigValue)); } if (currentConfigValue instanceof Long) { - parseValue = Integer.toHexString(Float.floatToIntBits((long)currentConfigValue)); + parseValue = Integer.toHexString(Float.floatToIntBits((long) currentConfigValue)); } break; case "int": @@ -52,16 +58,4 @@ } return parseValue; } - - public static void main(String[] args) { - float str = 25.00f; - System.out.println(Integer.toHexString(Float.floatToIntBits(str))); - //加载自定义函数 -// List customizedFunctions = ClazzUtil.getSubClassList(CustomizedFunction.class, false); -// for (CustomizedFunction customizedFunction : customizedFunctions) { -// AviatorEvaluator.addFunction(customizedFunction); -// } -// Object value = String.valueOf(AviatorEvaluator.execute("hexDateFormat(\"yy-MM-dd-HH-mm-ss\")", null)); -// System.out.println(value); - } } diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java index 87d741e..93e390f 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/ReplyCommandEnum.java @@ -6,6 +6,22 @@ */ public interface ReplyCommandEnum { + + /** + * 解析失败,无需响应 + */ + Integer CONFIRM_CONFIG_ISSUE = -1; + + /** + * 下发配置确认的业务代码 + */ + String SYSYETM_TIMES = "系统时间"; + + /** + * 下发配置确认的业务代码 + */ + String IMEI = "imei"; + /** * 解析失败,无需响应 */ @@ -26,7 +42,6 @@ */ int UPGRADE_CONTENT = 3; - /** * 指定的升级解析字段 */ @@ -45,6 +60,7 @@ String IS_UPGRADE = "isUpgrade"; + String SEQ = "seq"; String START_POINT = "startPoint"; diff --git a/sensorhub-support/src/main/java/com/casic/missiles/pojo/RuleConfig.java b/sensorhub-support/src/main/java/com/casic/missiles/pojo/RuleConfig.java index 2b04832..8f5f59c 100644 --- a/sensorhub-support/src/main/java/com/casic/missiles/pojo/RuleConfig.java +++ b/sensorhub-support/src/main/java/com/casic/missiles/pojo/RuleConfig.java @@ -7,7 +7,7 @@ /** * @author cz - * 匹配协议对应业务实例 + * 匹配协议对应业务实例 * 1、一个协议可以多种的流程规则 * 2、规则可以支持递归规则流程 */