diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java new file mode 100644 index 0000000..d728e30 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java @@ -0,0 +1,86 @@ +package com.casic.missiles.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.util.BytesUtil; +import com.ctg.ag.sdk.biz.AepDeviceCommandLwmProfileClient; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileRequest; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileResponse; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Configuration +@Slf4j +@Data +public class AEPCommandServiceImpl implements IAEPCommandService { + + @Value("${sensorhub.aep.key}") + private String key; + + @Value("${sensorhub.aep.secret}") + private String secret; + + @Value("${sensorhub.aep.ttl}") + private Integer ttl = 7200; + private Integer level = 1; + + @Value("${sensorhub.aep.operator}") + private String operator = "birmm"; + + private String masterApiKey; + + private String deviceId; + private String productId; + + @Override + public int handleSendCommand(String command) { + return 0; + } + + @Override + public int handleSendCommandWithProfile(String command) { + AepDeviceCommandLwmProfileClient client = AepDeviceCommandLwmProfileClient.newClient().appKey(key).appSecret(secret).build(); + + JSONObject body = new JSONObject(); + JSONObject cmd = new JSONObject(); + JSONObject paras = new JSONObject(); + + int retCode = -1; + + try { + //组装请求返回的参数 + CreateCommandLwm2mProfileRequest request = new CreateCommandLwm2mProfileRequest(); + request.setParamMasterKey(masterApiKey); + + paras.put("Value", BytesUtil.hexStringToBytes(command)); + cmd.put("paras", paras); + cmd.put("serviceId", "Config"); + cmd.put("method", "Config"); + + body.put("command", cmd); + body.put("deviceId", deviceId); + body.put("operator", operator); + body.put("productId", productId); + + request.setBody(body.toJSONString().getBytes()); + log.info("向AEP平台发送指令:{}", body.toJSONString()); + + //调用电信平台的客服端发送报文回复 + CreateCommandLwm2mProfileResponse msgResponse = client.CreateCommandLwm2mProfile(request); + JSONObject retObj = JSON.parseObject(new String(msgResponse.getBody(), StandardCharsets.UTF_8)); + retCode = (int) retObj.get("code"); + + log.info("AEP平台返回消息:{}", retObj.toJSONString()); + } catch (Exception ex) { + log.error("电信平台发送失败,异常信息{}", ex.getMessage()); + } finally { + client.shutdown(); + } + return retCode; + } +} diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java new file mode 100644 index 0000000..d728e30 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java @@ -0,0 +1,86 @@ +package com.casic.missiles.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.util.BytesUtil; +import com.ctg.ag.sdk.biz.AepDeviceCommandLwmProfileClient; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileRequest; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileResponse; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Configuration +@Slf4j +@Data +public class AEPCommandServiceImpl implements IAEPCommandService { + + @Value("${sensorhub.aep.key}") + private String key; + + @Value("${sensorhub.aep.secret}") + private String secret; + + @Value("${sensorhub.aep.ttl}") + private Integer ttl = 7200; + private Integer level = 1; + + @Value("${sensorhub.aep.operator}") + private String operator = "birmm"; + + private String masterApiKey; + + private String deviceId; + private String productId; + + @Override + public int handleSendCommand(String command) { + return 0; + } + + @Override + public int handleSendCommandWithProfile(String command) { + AepDeviceCommandLwmProfileClient client = AepDeviceCommandLwmProfileClient.newClient().appKey(key).appSecret(secret).build(); + + JSONObject body = new JSONObject(); + JSONObject cmd = new JSONObject(); + JSONObject paras = new JSONObject(); + + int retCode = -1; + + try { + //组装请求返回的参数 + CreateCommandLwm2mProfileRequest request = new CreateCommandLwm2mProfileRequest(); + request.setParamMasterKey(masterApiKey); + + paras.put("Value", BytesUtil.hexStringToBytes(command)); + cmd.put("paras", paras); + cmd.put("serviceId", "Config"); + cmd.put("method", "Config"); + + body.put("command", cmd); + body.put("deviceId", deviceId); + body.put("operator", operator); + body.put("productId", productId); + + request.setBody(body.toJSONString().getBytes()); + log.info("向AEP平台发送指令:{}", body.toJSONString()); + + //调用电信平台的客服端发送报文回复 + CreateCommandLwm2mProfileResponse msgResponse = client.CreateCommandLwm2mProfile(request); + JSONObject retObj = JSON.parseObject(new String(msgResponse.getBody(), StandardCharsets.UTF_8)); + retCode = (int) retObj.get("code"); + + log.info("AEP平台返回消息:{}", retObj.toJSONString()); + } catch (Exception ex) { + log.error("电信平台发送失败,异常信息{}", ex.getMessage()); + } finally { + client.shutdown(); + } + return retCode; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java index 4b2c6be..d8593c5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java @@ -1,5 +1,7 @@ package com.casic.missiles.service; +import com.casic.missiles.enums.BirmmFrameAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.frame.BirmmFrameBuilderFactory; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Map; import javax.annotation.Resource; @@ -51,14 +54,14 @@ // 加密后的业务字段 String tagListStr = protocol.getTagListString(frame); - log.info("帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); + log.info("上行帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); // 解密 SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); byte[] plainBytes = safeStrategy.decryption(tagListStr); String plainTagListStr = HexUtils.toHexString(plainBytes).toUpperCase(); - log.info("业务字段:{}", plainTagListStr); + log.info("上行业务字段:{}", plainTagListStr); // 获得业务字段tagList Map tagList = protocol.getTagList(plainBytes); @@ -68,7 +71,11 @@ if (birmmFrame != null) { birmmFrame.setLogTime(LocalDateTime.now()); // 记录日志时间 取服务器本地时间 birmmFrame.setDevCode(devCode); + birmmFrame.setCommunicationType(commType); + birmmFrame.setDestinationAddr(destAddr); + birmmFrame.setSequence(seq); birmmFrame.setDeviceType(deviceType); + birmmFrame.setOperationType(operaType); birmmFrame.setRawBizFrameString(plainTagListStr); birmmFrame.setTagList(tagList); @@ -80,13 +87,68 @@ } @Override - public String replyMessage(BirmmBaseFrame frameObj) { - // 从数据库中查询需要下发配置项 + public BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame) { + BirmmBaseFrame configFrame = BirmmFrameBuilderFactory.createBirmmReplyFrame(uploadFrame.getDeviceType(), uploadFrame.getOperationType()); - // 设置校时Tag + if (null != configFrame) { + configFrame.setDevCode(uploadFrame.getDevCode()); + configFrame.setCommunicationType(uploadFrame.getCommunicationType()); + configFrame.setDestinationAddr(uploadFrame.getDestinationAddr()); + configFrame.setSequence(uploadFrame.getSequence()); - // 调用协议组装 + configFrame.setDeviceType(uploadFrame.getDeviceType()); + configFrame.replyPduType(); - return null; + configFrame.replyBizTag(); + } + + return configFrame; + } + + @Override + public String replyMessage(BirmmBaseFrame configFrame) { + StringBuilder frame = new StringBuilder(); + + // A320 + frame.append(configFrame.getPRE_CODE()); + frame.append(configFrame.getVERSION()); + + // 处理tag + String plainTagListStr = protocol.buildTagListStr(configFrame.getTagList()); + log.info("下行业务字段:{}", plainTagListStr); + + // 计算长度 + int length = BirmmFrameAttributeEnums.DEVICE_CODE.getLength() + + BirmmFrameAttributeEnums.COMM_TYPE.getLength() + + BirmmFrameAttributeEnums.DEST_ADDR.getLength() + + BirmmFrameAttributeEnums.PDU_TYPE.getLength() + + BirmmFrameAttributeEnums.SEQ.getLength() + + plainTagListStr.length() / 2; + // 两个字节的长度 + frame.append(String.format("%04x", length)); + + log.info("下行帧结构字段:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", + length, configFrame.getDevCode(), configFrame.getCommunicationType(), + configFrame.getDestinationAddr(), configFrame.getPduType(), configFrame.getSequence()); + + // 设备编号 - PDUType字段 + frame.append(configFrame.getDevCode()); + frame.append(configFrame.getCommunicationType()); + frame.append(configFrame.getDestinationAddr()); + frame.append(configFrame.getPduType()); + frame.append(configFrame.getSequence()); + + // 加密 + byte[] keyByte = { + 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 + }; + SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); + byte[] tagBytes = safeStrategy.encryption(plainTagListStr, keyByte); + frame.append(HexUtils.toHexString(tagBytes).toUpperCase()); + + // 计算CRC校验码 + frame.append(protocol.calculateCRC(frame.toString())); + + return frame.toString(); } } diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java new file mode 100644 index 0000000..d728e30 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java @@ -0,0 +1,86 @@ +package com.casic.missiles.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.util.BytesUtil; +import com.ctg.ag.sdk.biz.AepDeviceCommandLwmProfileClient; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileRequest; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileResponse; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Configuration +@Slf4j +@Data +public class AEPCommandServiceImpl implements IAEPCommandService { + + @Value("${sensorhub.aep.key}") + private String key; + + @Value("${sensorhub.aep.secret}") + private String secret; + + @Value("${sensorhub.aep.ttl}") + private Integer ttl = 7200; + private Integer level = 1; + + @Value("${sensorhub.aep.operator}") + private String operator = "birmm"; + + private String masterApiKey; + + private String deviceId; + private String productId; + + @Override + public int handleSendCommand(String command) { + return 0; + } + + @Override + public int handleSendCommandWithProfile(String command) { + AepDeviceCommandLwmProfileClient client = AepDeviceCommandLwmProfileClient.newClient().appKey(key).appSecret(secret).build(); + + JSONObject body = new JSONObject(); + JSONObject cmd = new JSONObject(); + JSONObject paras = new JSONObject(); + + int retCode = -1; + + try { + //组装请求返回的参数 + CreateCommandLwm2mProfileRequest request = new CreateCommandLwm2mProfileRequest(); + request.setParamMasterKey(masterApiKey); + + paras.put("Value", BytesUtil.hexStringToBytes(command)); + cmd.put("paras", paras); + cmd.put("serviceId", "Config"); + cmd.put("method", "Config"); + + body.put("command", cmd); + body.put("deviceId", deviceId); + body.put("operator", operator); + body.put("productId", productId); + + request.setBody(body.toJSONString().getBytes()); + log.info("向AEP平台发送指令:{}", body.toJSONString()); + + //调用电信平台的客服端发送报文回复 + CreateCommandLwm2mProfileResponse msgResponse = client.CreateCommandLwm2mProfile(request); + JSONObject retObj = JSON.parseObject(new String(msgResponse.getBody(), StandardCharsets.UTF_8)); + retCode = (int) retObj.get("code"); + + log.info("AEP平台返回消息:{}", retObj.toJSONString()); + } catch (Exception ex) { + log.error("电信平台发送失败,异常信息{}", ex.getMessage()); + } finally { + client.shutdown(); + } + return retCode; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java index 4b2c6be..d8593c5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java @@ -1,5 +1,7 @@ package com.casic.missiles.service; +import com.casic.missiles.enums.BirmmFrameAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.frame.BirmmFrameBuilderFactory; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Map; import javax.annotation.Resource; @@ -51,14 +54,14 @@ // 加密后的业务字段 String tagListStr = protocol.getTagListString(frame); - log.info("帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); + log.info("上行帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); // 解密 SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); byte[] plainBytes = safeStrategy.decryption(tagListStr); String plainTagListStr = HexUtils.toHexString(plainBytes).toUpperCase(); - log.info("业务字段:{}", plainTagListStr); + log.info("上行业务字段:{}", plainTagListStr); // 获得业务字段tagList Map tagList = protocol.getTagList(plainBytes); @@ -68,7 +71,11 @@ if (birmmFrame != null) { birmmFrame.setLogTime(LocalDateTime.now()); // 记录日志时间 取服务器本地时间 birmmFrame.setDevCode(devCode); + birmmFrame.setCommunicationType(commType); + birmmFrame.setDestinationAddr(destAddr); + birmmFrame.setSequence(seq); birmmFrame.setDeviceType(deviceType); + birmmFrame.setOperationType(operaType); birmmFrame.setRawBizFrameString(plainTagListStr); birmmFrame.setTagList(tagList); @@ -80,13 +87,68 @@ } @Override - public String replyMessage(BirmmBaseFrame frameObj) { - // 从数据库中查询需要下发配置项 + public BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame) { + BirmmBaseFrame configFrame = BirmmFrameBuilderFactory.createBirmmReplyFrame(uploadFrame.getDeviceType(), uploadFrame.getOperationType()); - // 设置校时Tag + if (null != configFrame) { + configFrame.setDevCode(uploadFrame.getDevCode()); + configFrame.setCommunicationType(uploadFrame.getCommunicationType()); + configFrame.setDestinationAddr(uploadFrame.getDestinationAddr()); + configFrame.setSequence(uploadFrame.getSequence()); - // 调用协议组装 + configFrame.setDeviceType(uploadFrame.getDeviceType()); + configFrame.replyPduType(); - return null; + configFrame.replyBizTag(); + } + + return configFrame; + } + + @Override + public String replyMessage(BirmmBaseFrame configFrame) { + StringBuilder frame = new StringBuilder(); + + // A320 + frame.append(configFrame.getPRE_CODE()); + frame.append(configFrame.getVERSION()); + + // 处理tag + String plainTagListStr = protocol.buildTagListStr(configFrame.getTagList()); + log.info("下行业务字段:{}", plainTagListStr); + + // 计算长度 + int length = BirmmFrameAttributeEnums.DEVICE_CODE.getLength() + + BirmmFrameAttributeEnums.COMM_TYPE.getLength() + + BirmmFrameAttributeEnums.DEST_ADDR.getLength() + + BirmmFrameAttributeEnums.PDU_TYPE.getLength() + + BirmmFrameAttributeEnums.SEQ.getLength() + + plainTagListStr.length() / 2; + // 两个字节的长度 + frame.append(String.format("%04x", length)); + + log.info("下行帧结构字段:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", + length, configFrame.getDevCode(), configFrame.getCommunicationType(), + configFrame.getDestinationAddr(), configFrame.getPduType(), configFrame.getSequence()); + + // 设备编号 - PDUType字段 + frame.append(configFrame.getDevCode()); + frame.append(configFrame.getCommunicationType()); + frame.append(configFrame.getDestinationAddr()); + frame.append(configFrame.getPduType()); + frame.append(configFrame.getSequence()); + + // 加密 + byte[] keyByte = { + 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 + }; + SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); + byte[] tagBytes = safeStrategy.encryption(plainTagListStr, keyByte); + frame.append(HexUtils.toHexString(tagBytes).toUpperCase()); + + // 计算CRC校验码 + frame.append(protocol.calculateCRC(frame.toString())); + + return frame.toString(); } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java new file mode 100644 index 0000000..14736e1 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java @@ -0,0 +1,12 @@ +package com.casic.missiles.service; + +public interface IAEPCommandService { + + int handleSendCommand(String command); + + int handleSendCommandWithProfile(String command); + + void setMasterApiKey(String key); + void setDeviceId(String deviceId); + void setProductId(String productId); +} diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java new file mode 100644 index 0000000..d728e30 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java @@ -0,0 +1,86 @@ +package com.casic.missiles.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.util.BytesUtil; +import com.ctg.ag.sdk.biz.AepDeviceCommandLwmProfileClient; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileRequest; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileResponse; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Configuration +@Slf4j +@Data +public class AEPCommandServiceImpl implements IAEPCommandService { + + @Value("${sensorhub.aep.key}") + private String key; + + @Value("${sensorhub.aep.secret}") + private String secret; + + @Value("${sensorhub.aep.ttl}") + private Integer ttl = 7200; + private Integer level = 1; + + @Value("${sensorhub.aep.operator}") + private String operator = "birmm"; + + private String masterApiKey; + + private String deviceId; + private String productId; + + @Override + public int handleSendCommand(String command) { + return 0; + } + + @Override + public int handleSendCommandWithProfile(String command) { + AepDeviceCommandLwmProfileClient client = AepDeviceCommandLwmProfileClient.newClient().appKey(key).appSecret(secret).build(); + + JSONObject body = new JSONObject(); + JSONObject cmd = new JSONObject(); + JSONObject paras = new JSONObject(); + + int retCode = -1; + + try { + //组装请求返回的参数 + CreateCommandLwm2mProfileRequest request = new CreateCommandLwm2mProfileRequest(); + request.setParamMasterKey(masterApiKey); + + paras.put("Value", BytesUtil.hexStringToBytes(command)); + cmd.put("paras", paras); + cmd.put("serviceId", "Config"); + cmd.put("method", "Config"); + + body.put("command", cmd); + body.put("deviceId", deviceId); + body.put("operator", operator); + body.put("productId", productId); + + request.setBody(body.toJSONString().getBytes()); + log.info("向AEP平台发送指令:{}", body.toJSONString()); + + //调用电信平台的客服端发送报文回复 + CreateCommandLwm2mProfileResponse msgResponse = client.CreateCommandLwm2mProfile(request); + JSONObject retObj = JSON.parseObject(new String(msgResponse.getBody(), StandardCharsets.UTF_8)); + retCode = (int) retObj.get("code"); + + log.info("AEP平台返回消息:{}", retObj.toJSONString()); + } catch (Exception ex) { + log.error("电信平台发送失败,异常信息{}", ex.getMessage()); + } finally { + client.shutdown(); + } + return retCode; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java index 4b2c6be..d8593c5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java @@ -1,5 +1,7 @@ package com.casic.missiles.service; +import com.casic.missiles.enums.BirmmFrameAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.frame.BirmmFrameBuilderFactory; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Map; import javax.annotation.Resource; @@ -51,14 +54,14 @@ // 加密后的业务字段 String tagListStr = protocol.getTagListString(frame); - log.info("帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); + log.info("上行帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); // 解密 SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); byte[] plainBytes = safeStrategy.decryption(tagListStr); String plainTagListStr = HexUtils.toHexString(plainBytes).toUpperCase(); - log.info("业务字段:{}", plainTagListStr); + log.info("上行业务字段:{}", plainTagListStr); // 获得业务字段tagList Map tagList = protocol.getTagList(plainBytes); @@ -68,7 +71,11 @@ if (birmmFrame != null) { birmmFrame.setLogTime(LocalDateTime.now()); // 记录日志时间 取服务器本地时间 birmmFrame.setDevCode(devCode); + birmmFrame.setCommunicationType(commType); + birmmFrame.setDestinationAddr(destAddr); + birmmFrame.setSequence(seq); birmmFrame.setDeviceType(deviceType); + birmmFrame.setOperationType(operaType); birmmFrame.setRawBizFrameString(plainTagListStr); birmmFrame.setTagList(tagList); @@ -80,13 +87,68 @@ } @Override - public String replyMessage(BirmmBaseFrame frameObj) { - // 从数据库中查询需要下发配置项 + public BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame) { + BirmmBaseFrame configFrame = BirmmFrameBuilderFactory.createBirmmReplyFrame(uploadFrame.getDeviceType(), uploadFrame.getOperationType()); - // 设置校时Tag + if (null != configFrame) { + configFrame.setDevCode(uploadFrame.getDevCode()); + configFrame.setCommunicationType(uploadFrame.getCommunicationType()); + configFrame.setDestinationAddr(uploadFrame.getDestinationAddr()); + configFrame.setSequence(uploadFrame.getSequence()); - // 调用协议组装 + configFrame.setDeviceType(uploadFrame.getDeviceType()); + configFrame.replyPduType(); - return null; + configFrame.replyBizTag(); + } + + return configFrame; + } + + @Override + public String replyMessage(BirmmBaseFrame configFrame) { + StringBuilder frame = new StringBuilder(); + + // A320 + frame.append(configFrame.getPRE_CODE()); + frame.append(configFrame.getVERSION()); + + // 处理tag + String plainTagListStr = protocol.buildTagListStr(configFrame.getTagList()); + log.info("下行业务字段:{}", plainTagListStr); + + // 计算长度 + int length = BirmmFrameAttributeEnums.DEVICE_CODE.getLength() + + BirmmFrameAttributeEnums.COMM_TYPE.getLength() + + BirmmFrameAttributeEnums.DEST_ADDR.getLength() + + BirmmFrameAttributeEnums.PDU_TYPE.getLength() + + BirmmFrameAttributeEnums.SEQ.getLength() + + plainTagListStr.length() / 2; + // 两个字节的长度 + frame.append(String.format("%04x", length)); + + log.info("下行帧结构字段:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", + length, configFrame.getDevCode(), configFrame.getCommunicationType(), + configFrame.getDestinationAddr(), configFrame.getPduType(), configFrame.getSequence()); + + // 设备编号 - PDUType字段 + frame.append(configFrame.getDevCode()); + frame.append(configFrame.getCommunicationType()); + frame.append(configFrame.getDestinationAddr()); + frame.append(configFrame.getPduType()); + frame.append(configFrame.getSequence()); + + // 加密 + byte[] keyByte = { + 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 + }; + SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); + byte[] tagBytes = safeStrategy.encryption(plainTagListStr, keyByte); + frame.append(HexUtils.toHexString(tagBytes).toUpperCase()); + + // 计算CRC校验码 + frame.append(protocol.calculateCRC(frame.toString())); + + return frame.toString(); } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java new file mode 100644 index 0000000..14736e1 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java @@ -0,0 +1,12 @@ +package com.casic.missiles.service; + +public interface IAEPCommandService { + + int handleSendCommand(String command); + + int handleSendCommandWithProfile(String command); + + void setMasterApiKey(String key); + void setDeviceId(String deviceId); + void setProductId(String productId); +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java index 6c876a7..06df723 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java @@ -12,6 +12,13 @@ BirmmBaseFrame doFrameParse(byte[] frame); /** + * 创建配置帧 + * @param uploadFrame 收到的消息帧 + * @return + */ + BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame); + + /** * 查找需要下发的配置 * 组装下发消息帧 * @return diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java new file mode 100644 index 0000000..d728e30 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java @@ -0,0 +1,86 @@ +package com.casic.missiles.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.util.BytesUtil; +import com.ctg.ag.sdk.biz.AepDeviceCommandLwmProfileClient; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileRequest; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileResponse; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Configuration +@Slf4j +@Data +public class AEPCommandServiceImpl implements IAEPCommandService { + + @Value("${sensorhub.aep.key}") + private String key; + + @Value("${sensorhub.aep.secret}") + private String secret; + + @Value("${sensorhub.aep.ttl}") + private Integer ttl = 7200; + private Integer level = 1; + + @Value("${sensorhub.aep.operator}") + private String operator = "birmm"; + + private String masterApiKey; + + private String deviceId; + private String productId; + + @Override + public int handleSendCommand(String command) { + return 0; + } + + @Override + public int handleSendCommandWithProfile(String command) { + AepDeviceCommandLwmProfileClient client = AepDeviceCommandLwmProfileClient.newClient().appKey(key).appSecret(secret).build(); + + JSONObject body = new JSONObject(); + JSONObject cmd = new JSONObject(); + JSONObject paras = new JSONObject(); + + int retCode = -1; + + try { + //组装请求返回的参数 + CreateCommandLwm2mProfileRequest request = new CreateCommandLwm2mProfileRequest(); + request.setParamMasterKey(masterApiKey); + + paras.put("Value", BytesUtil.hexStringToBytes(command)); + cmd.put("paras", paras); + cmd.put("serviceId", "Config"); + cmd.put("method", "Config"); + + body.put("command", cmd); + body.put("deviceId", deviceId); + body.put("operator", operator); + body.put("productId", productId); + + request.setBody(body.toJSONString().getBytes()); + log.info("向AEP平台发送指令:{}", body.toJSONString()); + + //调用电信平台的客服端发送报文回复 + CreateCommandLwm2mProfileResponse msgResponse = client.CreateCommandLwm2mProfile(request); + JSONObject retObj = JSON.parseObject(new String(msgResponse.getBody(), StandardCharsets.UTF_8)); + retCode = (int) retObj.get("code"); + + log.info("AEP平台返回消息:{}", retObj.toJSONString()); + } catch (Exception ex) { + log.error("电信平台发送失败,异常信息{}", ex.getMessage()); + } finally { + client.shutdown(); + } + return retCode; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java index 4b2c6be..d8593c5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java @@ -1,5 +1,7 @@ package com.casic.missiles.service; +import com.casic.missiles.enums.BirmmFrameAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.frame.BirmmFrameBuilderFactory; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Map; import javax.annotation.Resource; @@ -51,14 +54,14 @@ // 加密后的业务字段 String tagListStr = protocol.getTagListString(frame); - log.info("帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); + log.info("上行帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); // 解密 SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); byte[] plainBytes = safeStrategy.decryption(tagListStr); String plainTagListStr = HexUtils.toHexString(plainBytes).toUpperCase(); - log.info("业务字段:{}", plainTagListStr); + log.info("上行业务字段:{}", plainTagListStr); // 获得业务字段tagList Map tagList = protocol.getTagList(plainBytes); @@ -68,7 +71,11 @@ if (birmmFrame != null) { birmmFrame.setLogTime(LocalDateTime.now()); // 记录日志时间 取服务器本地时间 birmmFrame.setDevCode(devCode); + birmmFrame.setCommunicationType(commType); + birmmFrame.setDestinationAddr(destAddr); + birmmFrame.setSequence(seq); birmmFrame.setDeviceType(deviceType); + birmmFrame.setOperationType(operaType); birmmFrame.setRawBizFrameString(plainTagListStr); birmmFrame.setTagList(tagList); @@ -80,13 +87,68 @@ } @Override - public String replyMessage(BirmmBaseFrame frameObj) { - // 从数据库中查询需要下发配置项 + public BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame) { + BirmmBaseFrame configFrame = BirmmFrameBuilderFactory.createBirmmReplyFrame(uploadFrame.getDeviceType(), uploadFrame.getOperationType()); - // 设置校时Tag + if (null != configFrame) { + configFrame.setDevCode(uploadFrame.getDevCode()); + configFrame.setCommunicationType(uploadFrame.getCommunicationType()); + configFrame.setDestinationAddr(uploadFrame.getDestinationAddr()); + configFrame.setSequence(uploadFrame.getSequence()); - // 调用协议组装 + configFrame.setDeviceType(uploadFrame.getDeviceType()); + configFrame.replyPduType(); - return null; + configFrame.replyBizTag(); + } + + return configFrame; + } + + @Override + public String replyMessage(BirmmBaseFrame configFrame) { + StringBuilder frame = new StringBuilder(); + + // A320 + frame.append(configFrame.getPRE_CODE()); + frame.append(configFrame.getVERSION()); + + // 处理tag + String plainTagListStr = protocol.buildTagListStr(configFrame.getTagList()); + log.info("下行业务字段:{}", plainTagListStr); + + // 计算长度 + int length = BirmmFrameAttributeEnums.DEVICE_CODE.getLength() + + BirmmFrameAttributeEnums.COMM_TYPE.getLength() + + BirmmFrameAttributeEnums.DEST_ADDR.getLength() + + BirmmFrameAttributeEnums.PDU_TYPE.getLength() + + BirmmFrameAttributeEnums.SEQ.getLength() + + plainTagListStr.length() / 2; + // 两个字节的长度 + frame.append(String.format("%04x", length)); + + log.info("下行帧结构字段:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", + length, configFrame.getDevCode(), configFrame.getCommunicationType(), + configFrame.getDestinationAddr(), configFrame.getPduType(), configFrame.getSequence()); + + // 设备编号 - PDUType字段 + frame.append(configFrame.getDevCode()); + frame.append(configFrame.getCommunicationType()); + frame.append(configFrame.getDestinationAddr()); + frame.append(configFrame.getPduType()); + frame.append(configFrame.getSequence()); + + // 加密 + byte[] keyByte = { + 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 + }; + SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); + byte[] tagBytes = safeStrategy.encryption(plainTagListStr, keyByte); + frame.append(HexUtils.toHexString(tagBytes).toUpperCase()); + + // 计算CRC校验码 + frame.append(protocol.calculateCRC(frame.toString())); + + return frame.toString(); } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java new file mode 100644 index 0000000..14736e1 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java @@ -0,0 +1,12 @@ +package com.casic.missiles.service; + +public interface IAEPCommandService { + + int handleSendCommand(String command); + + int handleSendCommandWithProfile(String command); + + void setMasterApiKey(String key); + void setDeviceId(String deviceId); + void setProductId(String productId); +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java index 6c876a7..06df723 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java @@ -12,6 +12,13 @@ BirmmBaseFrame doFrameParse(byte[] frame); /** + * 创建配置帧 + * @param uploadFrame 收到的消息帧 + * @return + */ + BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame); + + /** * 查找需要下发的配置 * 组装下发消息帧 * @return diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagAttributeEnums.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagAttributeEnums.java deleted file mode 100644 index abc6e56..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagAttributeEnums.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.casic.missiles.enums; - -import lombok.Getter; - -import java.util.stream.Stream; - -/** - * 帧结构属性枚举 - */ -@Getter -public enum BirmmTagAttributeEnums { - RETRY_TIMES_TAG("1000000A", 1), - DESTINATION_IP_TAG("10000022", -1), - DESTINATION_PORT_TAG("10000023", -1), - DATE_TAG("10000050", 3), - DATETIME_TAG("10000051", 6), - UPLOAD_INTERVAL_TAG("10000062", 2), - START_TIME_TAG("10000104", 2), - COLLECT_INTERVAL_TAG("10000105", 2), - COLLECT_COUNT_TAG("10000106", 2), - LOWER_LIMIT_TAG("10000900", 4), - UPPER_LIMIT_TAG("10000901", 4), - SENSOR_STATE_1_TAG("60000009", 1), - SENSOR_STATE_2_TAG("6000000A", 1), - SENSOR_STATE_3_TAG("6000000B", 1), - SENSOR_STATE_4_TAG("6000000C", 1), - SENSOR_STATE_5_TAG("6000000D", 1), - CELL_TAG("60000020", 1), - SOFTWARE_VERSION_TAG("60000500", -1), - PCI_TAG("60000511", 2), - RSRP_TAG("60000513", 2), - SNR_TAG("60000516", 2); - - - /** - * 名称 - */ - private final String name; - - /** - * 属性字节长度 - */ - private final int length; - - BirmmTagAttributeEnums(String name, int length) { - this.name = name; - this.length = length; - } - - public static BirmmTagAttributeEnums toType(String oid) { - return Stream.of(BirmmTagAttributeEnums.values()).filter(p -> p.name.equalsIgnoreCase(oid)).findAny().orElse(null); - } -} diff --git a/casic-iot-web/pom.xml b/casic-iot-web/pom.xml index d3ab3f8..971cc61 100644 --- a/casic-iot-web/pom.xml +++ b/casic-iot-web/pom.xml @@ -76,6 +76,8 @@ true true + + true diff --git a/casic-iot-web/src/main/resources/config/application-dev.yml b/casic-iot-web/src/main/resources/config/application-dev.yml index c5c99b7..85ce8e4 100644 --- a/casic-iot-web/src/main/resources/config/application-dev.yml +++ b/casic-iot-web/src/main/resources/config/application-dev.yml @@ -1,5 +1,5 @@ server: - port: 7093 + port: 11608 ################### spring配置 ################### spring: datasource: diff --git a/casic-iot-web/src/main/resources/config/application.yml b/casic-iot-web/src/main/resources/config/application.yml index 7315582..70596b6 100644 --- a/casic-iot-web/src/main/resources/config/application.yml +++ b/casic-iot-web/src/main/resources/config/application.yml @@ -77,8 +77,8 @@ key: "ke4zM3hld29" secret: "35ykNutA1t" paramMasterKey: "0a77886fae4f4ff68d926adeb3a3ef5b" - ttl: 3000 - operator: "casic" + ttl: 7200 + operator: "birmm" #代码生成器配置 code: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java index faf5f84..b9c1e6b 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/controller/GeneralDataReceiver.java @@ -6,6 +6,7 @@ import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.model.DeviceFrameLog; import com.casic.missiles.model.response.ResponseData; +import com.casic.missiles.service.IAEPCommandService; import com.casic.missiles.service.IDeviceBizDataService; import com.casic.missiles.service.IDeviceFrameLogService; import com.casic.missiles.service.IGeneralService; @@ -29,6 +30,9 @@ IGeneralService defaultService; @Resource + IAEPCommandService aepCmdService; + + @Resource IDeviceFrameLogService frameLogService; @Resource @@ -49,19 +53,18 @@ @RequestMapping("/aep/data/hex") public Object aepDataHex(@RequestBody Map dataMap) { log.info("收到AEP平台推送消息:{}", JSONObject.toJSONString(dataMap)); - log.debug("deviceId: {}, productId: {}, IMEI: {}, timestamp: {}", dataMap.get("deviceId"), dataMap.get("productId"), dataMap.get("IMEI"), dataMap.get("timestamp")); // 从推送的数据中获取消息帧 byte[] frameBytes = getFrameStringFromData(dataMap); - log.info("HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); + log.info("上行HEX字节消息帧:{}", HexUtils.toHexString(frameBytes).toUpperCase()); BirmmBaseFrame birmmFrame = defaultService.doFrameParse(frameBytes); if (birmmFrame != null) { - log.info("HEX字节消息解析成功:{}", birmmFrame.getClass().getSimpleName()); - // 处理业务数据 birmmFrame.doParseBizTag(); + log.info("上行HEX字节消息解析成功:{}", birmmFrame.toJSON().toJSONString()); + // 保存日志 DeviceFrameLog frameLog = new DeviceFrameLog(); frameLog.setId(new SnowflakeUtil().nextId()); @@ -84,12 +87,36 @@ bizData.setLogtime(birmmFrame.getLogTime()); } + // 批量保存 bizDataService.saveBatch(bizDataList); } // 创建回复消息 - String replyMessage = defaultService.replyMessage(birmmFrame); - birmmFrame.reply(); + BirmmBaseFrame configFrame = defaultService.buildReplyFrame(birmmFrame); + if (configFrame != null) { + // 根据协议进行封装 + String replyMessage = defaultService.replyMessage(configFrame); + log.info("下行HEX字节消息帧:{}", replyMessage); + + int retCode; + // 判断是否有profile + boolean hasProfile = false; + if (dataMap.containsKey("profile")) { + hasProfile = (Boolean) dataMap.get("profile"); + } + aepCmdService.setMasterApiKey("d3f49d576baf4112b5e48f41c148e89b"); + aepCmdService.setDeviceId((String) dataMap.get("deviceId")); + aepCmdService.setProductId((String) dataMap.get("productId")); + if (hasProfile) { + retCode = aepCmdService.handleSendCommandWithProfile(replyMessage); + } else { + retCode = aepCmdService.handleSendCommand(replyMessage); + } + + if (retCode == 0) { + log.info("回复设备成功"); + } + } } // 返回给电信AEP平台 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java index 1b25138..faeee95 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseFrame.java @@ -1,12 +1,14 @@ package com.casic.missiles.frame; import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.frame.commanTag.DateTimeTag; import com.casic.missiles.model.DeviceBizData; import lombok.Data; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,6 +39,9 @@ // PDU类型 String pduType; + // 操作类型 + String operationType; + // 序号 String sequence; @@ -69,6 +74,16 @@ public void doParseBizTag() {} - public void reply() {} + public void replyPduType() { + + } + + public void replyBizTag() { + tagList = new HashMap<>(); + DateTimeTag dateTimeTag = new DateTimeTag(); + dateTimeTag.setDateTime(LocalDateTime.now()); + + tagList.put(DateTimeTag.class.getSimpleName(), dateTimeTag); + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java index 08ed720..5394727 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmBaseTag.java @@ -13,4 +13,8 @@ public String toString() { return "[name: " + getClass().getSimpleName() + "][oid: " + oid + "][hex: " + valueStr + "]"; } + + public String toProtocolString() { + return null; + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java index b246fb9..ef031b8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmFrameBuilderFactory.java @@ -24,4 +24,23 @@ return null; } + public static BirmmBaseFrame createBirmmReplyFrame(String deviceType, String operaType) { + BirmmDeviceTypeEnums type = BirmmDeviceTypeEnums.toType(deviceType); + if (type != null) { + switch (type) { + case METHANE: + return MethaneFrameBuilderFactory.createMethaneReplyFrameByOperation(operaType); + + case WELL: + return null; + + default: + return null; + } + + } + + return null; + } + } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java index 86c936b..1d7763e 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/BirmmTagBuilderFactory.java @@ -1,12 +1,12 @@ package com.casic.missiles.frame; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.commanTag.*; public class BirmmTagBuilderFactory { public static BirmmBaseTag createTagByOid(String oid) { - BirmmTagAttributeEnums tag = BirmmTagAttributeEnums.toType(oid); + BirmmTagTypeEnums tag = BirmmTagTypeEnums.toType(oid); if (null != tag) { switch (tag) { case RETRY_TIMES_TAG: diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java index 8cf6d81..d460142 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/commanTag/DateTimeTag.java @@ -1,5 +1,6 @@ package com.casic.missiles.frame.commanTag; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.util.BytesUtil; import lombok.Data; @@ -22,6 +23,29 @@ } @Override + public String toProtocolString() { + String result = ""; + result += BirmmTagTypeEnums.DATETIME_TAG.getName(); // OID + result += String.format("%04d", BirmmTagTypeEnums.DATETIME_TAG.getLength()); // 长度 + + int year = dateTime.getYear() - 2000; + int month = dateTime.getMonthValue(); + int day = dateTime.getDayOfMonth(); + int hour = dateTime.getHour(); + int minute = dateTime.getMinute(); + int second = dateTime.getSecond(); + + result += String.format("%02x", year); + result += String.format("%02x", month); + result += String.format("%02x", day); + result += String.format("%02x", hour); + result += String.format("%02x", minute); + result += String.format("%02x", second); + + return result; + } + + @Override public void setValueStr(String valueStr) { super.setValueStr(valueStr); String hexY = valueStr.substring(0, 2); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java index 76cfe45..ede070a 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneFrameBuilderFactory.java @@ -25,4 +25,20 @@ return null; } } + + public static BirmmBaseFrame createMethaneReplyFrameByOperation(String uploadOperationType) { + BirmmOperationTypeEnums operation = BirmmOperationTypeEnums.toType(uploadOperationType); + if (operation != null) { + switch (operation) { + case UP_TRAP_REQUEST: + // TRAP_REQUEST消息回复TRAP_RESPONSE + return new MethaneTrapResponseFrame(); + + default: + return null; + } + } else { + return null; + } + } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java index 5160fc2..cc5fa90 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapRequestFrame.java @@ -2,16 +2,14 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; -import com.casic.missiles.enums.BirmmTagAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.commanTag.*; import com.casic.missiles.model.DeviceBizData; import com.casic.missiles.util.BytesUtil; -import javafx.scene.control.Cell; import lombok.extern.slf4j.Slf4j; import java.time.LocalDateTime; -import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -52,11 +50,14 @@ body.put("snr", snrTag.getSnr()); } - JSONArray datas = new JSONArray(); - for (MethaneBizData bizData : bizDataList) { - datas.add(bizData.toJSON()); + // 业务数据 + if (bizDataList != null) { + JSONArray datas = new JSONArray(); + for (MethaneBizData bizData : bizDataList) { + datas.add(bizData.toJSON()); + } + body.put("datas", datas); } - body.put("datas", datas); json.put("mBody", body); @@ -71,33 +72,35 @@ @Override public List convertToBizDataList() { List resultList = new ArrayList<>(); - for (MethaneBizData data : this.bizDataList) { - DeviceBizData bizData = new DeviceBizData(); - bizData.setBizType(String.valueOf(data.getBizType())); - bizData.setValue(String.format("%.3f", data.getValue())); - bizData.setUptime(data.getUptime()); + if (bizDataList != null) { + for (MethaneBizData data : bizDataList) { + DeviceBizData bizData = new DeviceBizData(); + bizData.setBizType(String.valueOf(data.getBizType())); + bizData.setValue(String.format("%.3f", data.getValue())); + bizData.setUptime(data.getUptime()); - // 电量 - if (getTagList().containsKey(CellTag.class.getSimpleName())) { - CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); - bizData.setCell(cellTag.getCellVal()); - } + // 电量 + if (getTagList().containsKey(CellTag.class.getSimpleName())) { + CellTag cellTag = (CellTag) getTagList().get(CellTag.class.getSimpleName()); + bizData.setCell(cellTag.getCellVal()); + } - // 信号质量 - if (getTagList().containsKey(PCITag.class.getSimpleName())) { - PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); - bizData.setPci(pciTag.getPci()); - } - if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { - RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); - bizData.setRsrp(rsrpTag.getRsrp()); - } - if (getTagList().containsKey(SNRTag.class.getSimpleName())) { - SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); - bizData.setSnr(snrTag.getSnr()); - } + // 信号质量 + if (getTagList().containsKey(PCITag.class.getSimpleName())) { + PCITag pciTag = (PCITag) getTagList().get(PCITag.class.getSimpleName()); + bizData.setPci(pciTag.getPci()); + } + if (getTagList().containsKey(RSRPTag.class.getSimpleName())) { + RSRPTag rsrpTag = (RSRPTag) getTagList().get(RSRPTag.class.getSimpleName()); + bizData.setRsrp(rsrpTag.getRsrp()); + } + if (getTagList().containsKey(SNRTag.class.getSimpleName())) { + SNRTag snrTag = (SNRTag) getTagList().get(SNRTag.class.getSimpleName()); + bizData.setSnr(snrTag.getSnr()); + } - resultList.add(bizData); + resultList.add(bizData); + } } return resultList; @@ -142,7 +145,7 @@ private void handleSensorStateTag() { SensorStateTag sensorStateTag = (SensorStateTag) getTagList().get(SensorStateTag.class.getSimpleName()); - if (sensorStateTag.getOid().equals(BirmmTagAttributeEnums.SENSOR_STATE_1_TAG.getName())) { + if (sensorStateTag.getOid().equals(BirmmTagTypeEnums.SENSOR_STATE_1_TAG.getName())) { // 甲烷传感器状态 log.info("甲烷传感器状态:{}", sensorStateTag.getValueStr().equals("00") ? "正常" : "异常"); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java new file mode 100644 index 0000000..aeefccc --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/frame/methane/MethaneTrapResponseFrame.java @@ -0,0 +1,20 @@ +package com.casic.missiles.frame.methane; + +import com.casic.missiles.enums.BirmmOperationTypeEnums; +import com.casic.missiles.frame.BirmmBaseFrame; + +public class MethaneTrapResponseFrame extends BirmmBaseFrame { + + @Override + public void replyPduType() { + StringBuilder pduType; + + int pduValue = Integer.parseInt(BirmmOperationTypeEnums.DOWN_TRAP_RESPONSE.getValue()) * 256 + 128 + Integer.parseInt(getDeviceType(), 16); + pduType = new StringBuilder(Integer.toHexString(pduValue)); + while (pduType.length() != 4) { + pduType.insert(0, "0"); + } + + this.setPduType(pduType.toString()); + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java index a7daf4d..2f90c5f 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/BirmmProtocolParser.java @@ -14,6 +14,7 @@ boolean preCheckFrame(byte[] frameBytes); boolean validateCRC(byte[] frameBytes); + String calculateCRC(String toBeVerified); boolean validateLength(byte[] tagBytes, int length); @@ -37,6 +38,8 @@ String getTagListString(byte[] frameBytes); Map getTagList(byte[] tagBytes); + String buildTagListStr(Map tagList); + String getCRC(byte[] frameBytes); String getToBeVerifiedCRCBytes(byte[] frameBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java index 1abff43..8f0bd17 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/impl/BirmmProtocolParserImpl.java @@ -7,6 +7,7 @@ import com.casic.missiles.parser.crc.CRCUtil; import com.casic.missiles.util.BytesUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -49,6 +50,19 @@ } @Override + public String calculateCRC(String toBeVerified) { + byte[] bytes = HexUtils.fromHexString(toBeVerified); + + // 计算CRC值 + CRCUtil crcUtil = new CRCUtil(CRCUtil.Parameters.CRC16MODBUS); + long crcVal = crcUtil.calculateCRC(bytes); + // 格式化输出 + String crcStr = String.format("%0" + BirmmFrameAttributeEnums.CRC.getLength() * 2 + "X", crcVal); + + return crcStr.toUpperCase(); + } + + @Override public boolean validateLength(byte[] tagBytes, int length) { return false; } @@ -135,7 +149,7 @@ log.debug("解析Tag:{}", tagBase); - tagList.put(tagBase.getClass().getSimpleName() ,tagBase); + tagList.put(tagBase.getClass().getSimpleName(), tagBase); } } idx += tagLen; @@ -144,6 +158,17 @@ return tagList; } + @Override + public String buildTagListStr(Map tagList) { + StringBuilder result = new StringBuilder(); + + for (BirmmBaseTag tag : tagList.values()) { + result.append(tag.toProtocolString()); + } + + return result.toString().toUpperCase(); + } + private boolean checkPreCodeAndVersion(byte[] frameBytes) { String headerStr = getFrameHeader(frameBytes); return headerStr.equalsIgnoreCase(BirmmFrameAttributeEnums.HEADER.getDefaultStr()); diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java index d7ea4ea..75e7ca8 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/SafeStrategy.java @@ -4,7 +4,9 @@ public interface SafeStrategy { byte[] decryption(String cipher); + byte[] decryption(String cipher, byte[] keyBytes); byte[] encryption(String lightText); + byte[] encryption(String lightText, byte[] keyBytes); } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java index db2c2d4..4401a83 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/Sm4.java @@ -29,8 +29,13 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] plainBuf = EcbDecrypt(in, keyBytes); - return plainBuf; + return EcbDecrypt(in, keyBytes); + } + + @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + byte[] in = Hex.decode(cipher); + return EcbDecrypt(in, keyBytes); } @Override @@ -42,8 +47,14 @@ key.writeBytes(keyByte); byte[] in = Hex.decode(cipher); byte[] keyBytes = Hex.decode(ByteBufUtil.hexDump(key)); - byte[] ciphertext = EcbEncrypt(in, keyBytes); - return ciphertext; + return EcbEncrypt(in, keyBytes); + } + + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + lightText = fillFrameStructZero(lightText, 16); + byte[] in = Hex.decode(lightText); + return EcbEncrypt(in, keyBytes); } @@ -108,6 +119,13 @@ return out; } + private String fillFrameStructZero(String replyMsgStr, Integer safeLength) { + while (replyMsgStr.length() % (safeLength * 2) != 0) { + replyMsgStr += "00"; + } + return replyMsgStr; + } + /** * 主函数 diff --git a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java index 1f78eca..e45e9ce 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/parser/safe/impl/TeaUtilsX.java @@ -39,6 +39,20 @@ } @Override + public byte[] decryption(String cipher, byte[] keyBytes) { + TeaUtilsX teaUtilsX = new TeaUtilsX(); + teaUtilsX.setKey(keyBytes); + System.out.println(cipher); + byte[] dec = teaUtilsX.decrypt(reverseBytesBy8(Hex.decode(cipher)));//解密 + byte[] reverse_dec = reverseBytesBy8(dec); + System.out.println(ByteBufUtil.hexDump(reverse_dec)); + + byte[] reverse = reverseBytesBy8(Hex.decode(cipher)); + dec = teaUtilsX.decrypt(reverse);//解密 + return reverseBytesBy8(dec); + } + + @Override public byte[] encryption(String lightText) { byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); TeaUtilsX t = new TeaUtilsX(); @@ -53,6 +67,15 @@ return reverseBytesBy8(enc); } + @Override + public byte[] encryption(String lightText, byte[] keyBytes) { + byte[] reverse = reverseBytesBy8(Hex.decode(lightText)); + TeaUtilsX t = new TeaUtilsX(); + t.setKey(keyBytes); + byte[] enc = t.encrypt(reverse);//加密 + return reverseBytesBy8(enc); + } + private static long UINT32_MAX = 0xFFFFFFFFL; private static long BYTE_1 = 0xFFL; private static long BYTE_2 = 0xFF00L; diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java new file mode 100644 index 0000000..d728e30 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/AEPCommandServiceImpl.java @@ -0,0 +1,86 @@ +package com.casic.missiles.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.casic.missiles.util.BytesUtil; +import com.ctg.ag.sdk.biz.AepDeviceCommandLwmProfileClient; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileRequest; +import com.ctg.ag.sdk.biz.aep_device_command_lwm_profile.CreateCommandLwm2mProfileResponse; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Configuration +@Slf4j +@Data +public class AEPCommandServiceImpl implements IAEPCommandService { + + @Value("${sensorhub.aep.key}") + private String key; + + @Value("${sensorhub.aep.secret}") + private String secret; + + @Value("${sensorhub.aep.ttl}") + private Integer ttl = 7200; + private Integer level = 1; + + @Value("${sensorhub.aep.operator}") + private String operator = "birmm"; + + private String masterApiKey; + + private String deviceId; + private String productId; + + @Override + public int handleSendCommand(String command) { + return 0; + } + + @Override + public int handleSendCommandWithProfile(String command) { + AepDeviceCommandLwmProfileClient client = AepDeviceCommandLwmProfileClient.newClient().appKey(key).appSecret(secret).build(); + + JSONObject body = new JSONObject(); + JSONObject cmd = new JSONObject(); + JSONObject paras = new JSONObject(); + + int retCode = -1; + + try { + //组装请求返回的参数 + CreateCommandLwm2mProfileRequest request = new CreateCommandLwm2mProfileRequest(); + request.setParamMasterKey(masterApiKey); + + paras.put("Value", BytesUtil.hexStringToBytes(command)); + cmd.put("paras", paras); + cmd.put("serviceId", "Config"); + cmd.put("method", "Config"); + + body.put("command", cmd); + body.put("deviceId", deviceId); + body.put("operator", operator); + body.put("productId", productId); + + request.setBody(body.toJSONString().getBytes()); + log.info("向AEP平台发送指令:{}", body.toJSONString()); + + //调用电信平台的客服端发送报文回复 + CreateCommandLwm2mProfileResponse msgResponse = client.CreateCommandLwm2mProfile(request); + JSONObject retObj = JSON.parseObject(new String(msgResponse.getBody(), StandardCharsets.UTF_8)); + retCode = (int) retObj.get("code"); + + log.info("AEP平台返回消息:{}", retObj.toJSONString()); + } catch (Exception ex) { + log.error("电信平台发送失败,异常信息{}", ex.getMessage()); + } finally { + client.shutdown(); + } + return retCode; + } +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java index 4b2c6be..d8593c5 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/GeneralServiceImpl.java @@ -1,5 +1,7 @@ package com.casic.missiles.service; +import com.casic.missiles.enums.BirmmFrameAttributeEnums; +import com.casic.missiles.enums.BirmmTagTypeEnums; import com.casic.missiles.frame.BirmmBaseFrame; import com.casic.missiles.frame.BirmmBaseTag; import com.casic.missiles.frame.BirmmFrameBuilderFactory; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Map; import javax.annotation.Resource; @@ -51,14 +54,14 @@ // 加密后的业务字段 String tagListStr = protocol.getTagListString(frame); - log.info("帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); + log.info("上行帧结构字段解析结果:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", length, devCode, commType, destAddr, pduType, seq); // 解密 SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); byte[] plainBytes = safeStrategy.decryption(tagListStr); String plainTagListStr = HexUtils.toHexString(plainBytes).toUpperCase(); - log.info("业务字段:{}", plainTagListStr); + log.info("上行业务字段:{}", plainTagListStr); // 获得业务字段tagList Map tagList = protocol.getTagList(plainBytes); @@ -68,7 +71,11 @@ if (birmmFrame != null) { birmmFrame.setLogTime(LocalDateTime.now()); // 记录日志时间 取服务器本地时间 birmmFrame.setDevCode(devCode); + birmmFrame.setCommunicationType(commType); + birmmFrame.setDestinationAddr(destAddr); + birmmFrame.setSequence(seq); birmmFrame.setDeviceType(deviceType); + birmmFrame.setOperationType(operaType); birmmFrame.setRawBizFrameString(plainTagListStr); birmmFrame.setTagList(tagList); @@ -80,13 +87,68 @@ } @Override - public String replyMessage(BirmmBaseFrame frameObj) { - // 从数据库中查询需要下发配置项 + public BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame) { + BirmmBaseFrame configFrame = BirmmFrameBuilderFactory.createBirmmReplyFrame(uploadFrame.getDeviceType(), uploadFrame.getOperationType()); - // 设置校时Tag + if (null != configFrame) { + configFrame.setDevCode(uploadFrame.getDevCode()); + configFrame.setCommunicationType(uploadFrame.getCommunicationType()); + configFrame.setDestinationAddr(uploadFrame.getDestinationAddr()); + configFrame.setSequence(uploadFrame.getSequence()); - // 调用协议组装 + configFrame.setDeviceType(uploadFrame.getDeviceType()); + configFrame.replyPduType(); - return null; + configFrame.replyBizTag(); + } + + return configFrame; + } + + @Override + public String replyMessage(BirmmBaseFrame configFrame) { + StringBuilder frame = new StringBuilder(); + + // A320 + frame.append(configFrame.getPRE_CODE()); + frame.append(configFrame.getVERSION()); + + // 处理tag + String plainTagListStr = protocol.buildTagListStr(configFrame.getTagList()); + log.info("下行业务字段:{}", plainTagListStr); + + // 计算长度 + int length = BirmmFrameAttributeEnums.DEVICE_CODE.getLength() + + BirmmFrameAttributeEnums.COMM_TYPE.getLength() + + BirmmFrameAttributeEnums.DEST_ADDR.getLength() + + BirmmFrameAttributeEnums.PDU_TYPE.getLength() + + BirmmFrameAttributeEnums.SEQ.getLength() + + plainTagListStr.length() / 2; + // 两个字节的长度 + frame.append(String.format("%04x", length)); + + log.info("下行帧结构字段:[长度:{}],[设备编号:{}],[通信方式:{}],[目标节点地址:{}],[PDUType:{}],[序号:{}]", + length, configFrame.getDevCode(), configFrame.getCommunicationType(), + configFrame.getDestinationAddr(), configFrame.getPduType(), configFrame.getSequence()); + + // 设备编号 - PDUType字段 + frame.append(configFrame.getDevCode()); + frame.append(configFrame.getCommunicationType()); + frame.append(configFrame.getDestinationAddr()); + frame.append(configFrame.getPduType()); + frame.append(configFrame.getSequence()); + + // 加密 + byte[] keyByte = { + 0x24, (byte) 0xad, 0x18, 0x25, 0x07, 0x47, (byte) 0x9a, 0x5d, (byte) 0xa3, (byte) 0xad, (byte) 0x94, (byte) 0xd9, (byte) 0xd7, (byte) 0x8e, (byte) 0xa2, 0x03 + }; + SafeStrategy safeStrategy = SpringContextUtil.getBean(Sm4.class); + byte[] tagBytes = safeStrategy.encryption(plainTagListStr, keyByte); + frame.append(HexUtils.toHexString(tagBytes).toUpperCase()); + + // 计算CRC校验码 + frame.append(protocol.calculateCRC(frame.toString())); + + return frame.toString(); } } diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java new file mode 100644 index 0000000..14736e1 --- /dev/null +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IAEPCommandService.java @@ -0,0 +1,12 @@ +package com.casic.missiles.service; + +public interface IAEPCommandService { + + int handleSendCommand(String command); + + int handleSendCommandWithProfile(String command); + + void setMasterApiKey(String key); + void setDeviceId(String deviceId); + void setProductId(String productId); +} diff --git a/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java b/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java index 6c876a7..06df723 100644 --- a/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java +++ b/sensorhub-core/src/main/java/com/casic/missiles/service/IGeneralService.java @@ -12,6 +12,13 @@ BirmmBaseFrame doFrameParse(byte[] frame); /** + * 创建配置帧 + * @param uploadFrame 收到的消息帧 + * @return + */ + BirmmBaseFrame buildReplyFrame(BirmmBaseFrame uploadFrame); + + /** * 查找需要下发的配置 * 组装下发消息帧 * @return diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagAttributeEnums.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagAttributeEnums.java deleted file mode 100644 index abc6e56..0000000 --- a/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagAttributeEnums.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.casic.missiles.enums; - -import lombok.Getter; - -import java.util.stream.Stream; - -/** - * 帧结构属性枚举 - */ -@Getter -public enum BirmmTagAttributeEnums { - RETRY_TIMES_TAG("1000000A", 1), - DESTINATION_IP_TAG("10000022", -1), - DESTINATION_PORT_TAG("10000023", -1), - DATE_TAG("10000050", 3), - DATETIME_TAG("10000051", 6), - UPLOAD_INTERVAL_TAG("10000062", 2), - START_TIME_TAG("10000104", 2), - COLLECT_INTERVAL_TAG("10000105", 2), - COLLECT_COUNT_TAG("10000106", 2), - LOWER_LIMIT_TAG("10000900", 4), - UPPER_LIMIT_TAG("10000901", 4), - SENSOR_STATE_1_TAG("60000009", 1), - SENSOR_STATE_2_TAG("6000000A", 1), - SENSOR_STATE_3_TAG("6000000B", 1), - SENSOR_STATE_4_TAG("6000000C", 1), - SENSOR_STATE_5_TAG("6000000D", 1), - CELL_TAG("60000020", 1), - SOFTWARE_VERSION_TAG("60000500", -1), - PCI_TAG("60000511", 2), - RSRP_TAG("60000513", 2), - SNR_TAG("60000516", 2); - - - /** - * 名称 - */ - private final String name; - - /** - * 属性字节长度 - */ - private final int length; - - BirmmTagAttributeEnums(String name, int length) { - this.name = name; - this.length = length; - } - - public static BirmmTagAttributeEnums toType(String oid) { - return Stream.of(BirmmTagAttributeEnums.values()).filter(p -> p.name.equalsIgnoreCase(oid)).findAny().orElse(null); - } -} diff --git a/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagTypeEnums.java b/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagTypeEnums.java new file mode 100644 index 0000000..195ce6d --- /dev/null +++ b/sensorhub-support/src/main/java/com/casic/missiles/enums/BirmmTagTypeEnums.java @@ -0,0 +1,53 @@ +package com.casic.missiles.enums; + +import lombok.Getter; + +import java.util.stream.Stream; + +/** + * 帧结构属性枚举 + */ +@Getter +public enum BirmmTagTypeEnums { + RETRY_TIMES_TAG("1000000A", 1), + DESTINATION_IP_TAG("10000022", -1), + DESTINATION_PORT_TAG("10000023", -1), + DATE_TAG("10000050", 3), + DATETIME_TAG("10000051", 6), + UPLOAD_INTERVAL_TAG("10000062", 2), + START_TIME_TAG("10000104", 2), + COLLECT_INTERVAL_TAG("10000105", 2), + COLLECT_COUNT_TAG("10000106", 2), + LOWER_LIMIT_TAG("10000900", 4), + UPPER_LIMIT_TAG("10000901", 4), + SENSOR_STATE_1_TAG("60000009", 1), + SENSOR_STATE_2_TAG("6000000A", 1), + SENSOR_STATE_3_TAG("6000000B", 1), + SENSOR_STATE_4_TAG("6000000C", 1), + SENSOR_STATE_5_TAG("6000000D", 1), + CELL_TAG("60000020", 1), + SOFTWARE_VERSION_TAG("60000500", -1), + PCI_TAG("60000511", 2), + RSRP_TAG("60000513", 2), + SNR_TAG("60000516", 2); + + + /** + * 名称 + */ + private final String name; + + /** + * 属性字节长度 + */ + private final int length; + + BirmmTagTypeEnums(String name, int length) { + this.name = name; + this.length = length; + } + + public static BirmmTagTypeEnums toType(String oid) { + return Stream.of(BirmmTagTypeEnums.values()).filter(p -> p.name.equalsIgnoreCase(oid)).findAny().orElse(null); + } +}