|
@@ -16,6 +16,9 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.Arrays;
|
|
|
|
|
+
|
|
|
@ChannelHandler.Sharable
|
|
@ChannelHandler.Sharable
|
|
|
@Slf4j
|
|
@Slf4j
|
|
|
@Component
|
|
@Component
|
|
@@ -46,15 +49,48 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
|
|
|
msgByteBuf.readBytes(msgBytes);
|
|
msgByteBuf.readBytes(msgBytes);
|
|
|
logger.info("接收到 {} 字节的数据: {}, 来自: {}",
|
|
logger.info("接收到 {} 字节的数据: {}, 来自: {}",
|
|
|
readable, ProtocolUtils.bytesToHex(msgBytes), ctx.channel().remoteAddress());
|
|
readable, ProtocolUtils.bytesToHex(msgBytes), ctx.channel().remoteAddress());
|
|
|
- //计算校验和
|
|
|
|
|
- int check = DataCheckUtil.calcChecksum(msgBytes, 2, msgBytes.length - 3);
|
|
|
|
|
- int checksum = msgBytes[msgBytes.length - 2] & 0xFF;
|
|
|
|
|
|
|
|
|
|
- if (check != checksum) {
|
|
|
|
|
- throw new InvalidMessageException("数据校验失败,本地计算=" + check + ",报文携带=" + checksum);
|
|
|
|
|
|
|
+ int checksumTotalLength = 2; // 末尾2字节校验码(如ED34)
|
|
|
|
|
+ int bodyStartOffset = 16; // 校验和07的主体起始索引
|
|
|
|
|
+ int fullDataStartOffset = 3; // 校验和16的完整数据起始索引
|
|
|
|
|
+
|
|
|
|
|
+ // 校验报文长度合法性
|
|
|
|
|
+ if (readable < fullDataStartOffset + checksumTotalLength) {
|
|
|
|
|
+ throw new InvalidMessageException("报文长度不足,无法完成校验");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ int bodyEndOffset = msgBytes.length - checksumTotalLength; // 避开末尾2字节校验码
|
|
|
|
|
+ int bodyLength = bodyEndOffset - bodyStartOffset;
|
|
|
|
|
+ if (bodyLength <= 0) {
|
|
|
|
|
+ throw new InvalidMessageException("主体数据长度无效,无法计算校验和07");
|
|
|
|
|
+ }
|
|
|
|
|
+ int checksum07 = DataCheckUtil.calcSumOnly(msgBytes, bodyStartOffset, bodyLength);
|
|
|
|
|
+
|
|
|
|
|
+ int fullDataEndOffset = msgBytes.length - 1; // 包含倒数第二个字节
|
|
|
|
|
+ int fullDataLength = fullDataEndOffset - fullDataStartOffset;
|
|
|
|
|
+ if (fullDataLength <= 0) {
|
|
|
|
|
+ throw new InvalidMessageException("完整数据长度无效,无法计算校验和16");
|
|
|
}
|
|
}
|
|
|
- GasMonitorData resultData = DataParser.parseMessage(msgBytes);
|
|
|
|
|
- resultData.setId(UUID.randomUUID().toString());
|
|
|
|
|
|
|
+ int checksum16 = DataCheckUtil.calcChecksum(msgBytes, fullDataStartOffset, fullDataLength);
|
|
|
|
|
+
|
|
|
|
|
+ int calculatedChecksum = (checksum07 << 8) | checksum16;
|
|
|
|
|
+ int receivedChecksum = ((msgBytes[msgBytes.length - 2] & 0xFF) << 8)
|
|
|
|
|
+ | (msgBytes[msgBytes.length - 1] & 0xFF);
|
|
|
|
|
+
|
|
|
|
|
+ // 打印调试信息,确认拼接结果
|
|
|
|
|
+ logger.debug("校验和07(高8位,仅求和): {}", Integer.toHexString(checksum07).toUpperCase());
|
|
|
|
|
+ logger.debug("校验和16(低8位,FF-求和): {}", Integer.toHexString(checksum16).toUpperCase());
|
|
|
|
|
+ logger.debug("修改后拼接校验码: {}", Integer.toHexString(calculatedChecksum).toUpperCase());
|
|
|
|
|
+ logger.debug("报文携带校验码: {}", Integer.toHexString(receivedChecksum).toUpperCase());
|
|
|
|
|
+
|
|
|
|
|
+ if (calculatedChecksum != receivedChecksum) {
|
|
|
|
|
+ throw new InvalidMessageException(
|
|
|
|
|
+ String.format("数据校验失败:本地计算(07+16)=%04X(07=%02X, 16=%02X),报文携带=%04X",
|
|
|
|
|
+ calculatedChecksum, checksum07, checksum16, receivedChecksum));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ com.zksy.gas.domain.GasMonitorData resultData = DataParser.parseMessage(msgBytes);
|
|
|
|
|
+ resultData.setId(java.util.UUID.randomUUID().toString());
|
|
|
service.save(resultData);
|
|
service.save(resultData);
|
|
|
logger.info("数据解析入库成功: {}", resultData);
|
|
logger.info("数据解析入库成功: {}", resultData);
|
|
|
} catch (InvalidMessageException e) {
|
|
} catch (InvalidMessageException e) {
|
|
@@ -68,7 +104,6 @@ public class MessageHandler extends ChannelInboundHandlerAdapter {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
private String printHexBinary(byte[] bytes) {
|
|
private String printHexBinary(byte[] bytes) {
|
|
|
StringBuilder sb = new StringBuilder();
|
|
StringBuilder sb = new StringBuilder();
|
|
|
for (byte b : bytes) {
|
|
for (byte b : bytes) {
|