更新消息回复\校验码生成

main
小鱼干 4 weeks ago
parent 54a4c84eb8
commit d6d31aee87

@ -94,5 +94,8 @@ public class BeeHive implements Serializable {
* *
*/ */
private LocalDateTime dateUploadTime; private LocalDateTime dateUploadTime;
/**
*
*/
private String dateUploadTimeHex;
} }

@ -116,6 +116,7 @@ public class HandlerDateProcessing {
// return null; // return null;
// } // }
beeHive.setDateUploadTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneId.systemDefault())); beeHive.setDateUploadTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneId.systemDefault()));
beeHive.setDateUploadTimeHex(getSubData(data, startIndex, endIndex));
break; break;
case 2: case 2:
//当前温度值2 //当前温度值2

@ -12,6 +12,7 @@ import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -20,6 +21,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.*; import java.util.concurrent.*;
import static com.hive.communication.util.CheckCode.*;
import static com.hive.util.DateConvetUtil.getCurrentSeconds; import static com.hive.util.DateConvetUtil.getCurrentSeconds;
@Slf4j @Slf4j
@ -46,21 +48,43 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
public static void sendActive(ChannelHandlerContext ctx, boolean flag, BeeHive beeHive, boolean notice) { public static void sendActive(ChannelHandlerContext ctx, boolean flag, BeeHive beeHive, boolean notice) {
if (flag) { if (flag) {
try { try {
String start="99";
String end ="AA";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(start);
stringBuilder.append("8561");
stringBuilder.append(beeHive.getDateUploadTimeHex());
stringBuilder.append("0b01");
// String paddedString = String.format("%4s", code).replace(' ', '0'); // String paddedString = String.format("%4s", code).replace(' ', '0');
String codes = "注册完回复"; //获取十分钟后的时间秒数,
//获取十分钟后的时间秒数需要转换为16进制 // 转换为16进制
getCurrentSeconds(); String hexSeconds = Long.toHexString(getCurrentSeconds()).toUpperCase();
log.info("当前时间: {}, 消息: {}", LocalDateTime.now(), codes); stringBuilder.append(hexSeconds);
stringBuilder.append("0000ff000000");
byte[] dataSum = hexStringToByteArray(stringBuilder.toString());
// 计算校验码1
byte checksum1 = calculateChecksum1(dataSum);
// 计算校验码2
byte checksum2 = calculateChecksum2(dataSum);
String checksum1Hex = String.format("%02X", checksum1);
String checksum2Hex = String.format("%02X", checksum2);
stringBuilder.append(checksum1Hex);
stringBuilder.append(checksum2Hex);
stringBuilder.append(end);
log.info("当前时间: {}, 消息: {}", LocalDateTime.now(), stringBuilder);
// 先将十六进制字符串转换为字节数组 // 先将十六进制字符串转换为字节数组
byte[] messageBytes = HexConversion.hexStringToByteArray(codes); byte[] messageBytes = HexConversion.hexStringToByteArray(stringBuilder.toString());
// 将字节数组封装到ByteBuf中 // 将字节数组封装到ByteBuf中
ByteBuf messageBuffer = Unpooled.wrappedBuffer(messageBytes); ByteBuf messageBuffer = Unpooled.wrappedBuffer(messageBytes);
// 通过ChannelHandlerContext发送ByteBuf // 通过ChannelHandlerContext发送ByteBuf
// 关联设备编号与Channel // 关联设备编号与Channel
// sendRequest(ctx.channel(),messageBuffer,devicePointsSensor.getId()); // sendRequest(ctx.channel(),messageBuffer,devicePointsSensor.getId());
retrySend(ctx, messageBuffer) retrySend(ctx, messageBuffer)
.whenComplete((result,error) -> { .whenComplete((result, error) -> {
log.info("发送状态: {},当前时间: {}, 消息: {},名称:{}蜂箱id{}", result,LocalDateTime.now(), codes,beeHive.getBeeHiveName(),beeHive.getId()); log.info("发送状态: {},当前时间: {}, 消息: {},名称:{}蜂箱id{}", result, LocalDateTime.now(), stringBuilder, beeHive.getBeeHiveName(), beeHive.getId());
/* if (result) { /* if (result) {
// 发送成功 // 发送成功
} else { } else {
@ -92,6 +116,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
} }
return future; return future;
} }
/** /**
* *
*/ */
@ -108,7 +133,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
// 发送失败,但还有剩余重试次数 // 发送失败,但还有剩余重试次数
if (messageBuffer.isReadable()) { if (messageBuffer.isReadable()) {
// 如果messageBuffer仍然可读重新使用它进行重试 // 如果messageBuffer仍然可读重新使用它进行重试
retrySendAsync(ctx,messageBuffer, remainingRetries - 1, future); retrySendAsync(ctx, messageBuffer, remainingRetries - 1, future);
} else { } else {
// messageBuffer不可读需要重新创建或复制一个新的messageBuffer // messageBuffer不可读需要重新创建或复制一个新的messageBuffer
@ -124,6 +149,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
} }
}); });
} }
/** /**
* pendingRequests * pendingRequests
*/ */
@ -142,6 +168,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
return promise; return promise;
} }
/** /**
* *
*/ */
@ -200,7 +227,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
// System.out.println("接收到的数据sb" + sb.toString()); // System.out.println("接收到的数据sb" + sb.toString());
// 检查消息是否是心跳请求 // 检查消息是否是心跳请求
if (sb.toString().equalsIgnoreCase(HEARTBEAT_REQUEST)) { if (sb.toString().equalsIgnoreCase(HEARTBEAT_REQUEST)) {
handleHeartbeat(ctx,msg); handleHeartbeat(ctx, msg);
} else { } else {
// 如果不是心跳请求调用ChannelInboundHandler的下一个处理器 // 如果不是心跳请求调用ChannelInboundHandler的下一个处理器
ctx.fireChannelRead(msg); ctx.fireChannelRead(msg);

@ -1,35 +1,36 @@
package com.hive.communication.util; package com.hive.communication.util;
public class CheckCode { public class CheckCode {
// 计算字符串的校验码(异位校验)
public static int calculateParity(String input, boolean oddParity) { // 计算校验码1按位异或操作
int parity = 0; public static byte calculateChecksum1(byte[] data) {
for (char ch : input.toCharArray()) { byte checksum = 0x00;
parity ^= ch; for (byte b : data) {
} checksum ^= b;
// 根据需要调整奇偶校验位
int parityBit = Integer.bitCount(parity) % 2;
if (oddParity) {
parityBit = parityBit == 0 ? 1 : 0; // 奇校验如果0变成1如果1变成0
} }
return parityBit; return checksum;
} }
// 计算16进制字符串的校验码
public static int calculateChecksum(String hexString) {
int sum = 0;
// 每两个字符作为一个16进制数进行解析 // 计算校验码2加法操作
for (int i = 0; i < hexString.length(); i += 2) { public static byte calculateChecksum2(byte[] data) {
String hexPair = hexString.substring(i, i + 2); int sum = 0;
int hexValue = Integer.parseInt(hexPair, 16); for (byte b : data) {
sum += hexValue; sum += b & 0xFF; // & 0xFF 保证每个 byte 被当作无符号处理
} }
return (byte) (sum & 0xFF); // 取最后8位
// 保留最后8位
int checksum = sum & 0xFF; // 0xFF表示8位全1的掩码
return checksum;
} }
// 将十六进制字符串转换为字节数组
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
} }

Loading…
Cancel
Save