2024-07-15 16:05:15 +08:00
|
|
|
package com.jsowell.netty.domain;
|
|
|
|
|
|
2024-08-15 08:56:59 +08:00
|
|
|
import com.jsowell.common.YouDianUtils;
|
2024-08-03 16:59:31 +08:00
|
|
|
import com.jsowell.common.util.BytesUtil;
|
|
|
|
|
import lombok.AllArgsConstructor;
|
|
|
|
|
import lombok.Builder;
|
|
|
|
|
import lombok.Data;
|
|
|
|
|
import lombok.NoArgsConstructor;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
2024-08-05 16:37:35 +08:00
|
|
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
|
|
|
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
2024-07-15 17:10:48 +08:00
|
|
|
|
2024-08-05 10:35:19 +08:00
|
|
|
import java.nio.charset.StandardCharsets;
|
2024-08-03 16:59:31 +08:00
|
|
|
import java.util.Arrays;
|
2024-07-15 16:05:15 +08:00
|
|
|
|
2024-08-03 16:59:31 +08:00
|
|
|
@Slf4j
|
|
|
|
|
@Data
|
|
|
|
|
@NoArgsConstructor
|
|
|
|
|
@AllArgsConstructor
|
|
|
|
|
@Builder
|
2024-08-15 11:25:47 +08:00
|
|
|
public class EBikeMessage {
|
2024-08-03 16:59:31 +08:00
|
|
|
private String header; // 包头 (3字节)
|
|
|
|
|
private int length; // 长度 (2字节)
|
|
|
|
|
private int physicalId; // 物理ID (4字节)
|
|
|
|
|
private int messageId; // 消息ID (2字节)
|
2024-08-14 16:36:51 +08:00
|
|
|
private String command; // 命令 (1字节)
|
2024-08-03 16:59:31 +08:00
|
|
|
private byte[] data; // 数据 (n字节)
|
|
|
|
|
private int checksum; // 校验 (2字节)
|
2024-07-15 17:10:48 +08:00
|
|
|
|
2024-08-05 16:37:35 +08:00
|
|
|
@Override
|
|
|
|
|
public String toString() {
|
|
|
|
|
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)
|
|
|
|
|
.append("header", header)
|
|
|
|
|
.append("length", length)
|
|
|
|
|
.append("physicalId", physicalId)
|
|
|
|
|
.append("messageId", messageId)
|
|
|
|
|
.append("command", command)
|
|
|
|
|
.append("data", data)
|
|
|
|
|
.append("checksum", checksum)
|
|
|
|
|
.toString();
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-15 11:25:47 +08:00
|
|
|
public static EBikeMessage parseMessage(byte[] messageBytes) {
|
2024-08-15 08:56:59 +08:00
|
|
|
if (messageBytes == null || messageBytes.length < 14 || messageBytes.length > 256) {
|
|
|
|
|
throw new IllegalArgumentException("Invalid message bytes");
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-15 11:25:47 +08:00
|
|
|
EBikeMessage message = new EBikeMessage();
|
2024-08-15 08:56:59 +08:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 读取包头
|
|
|
|
|
byte[] headerBytes = Arrays.copyOfRange(messageBytes, 0, 3);
|
|
|
|
|
String header = new String(headerBytes, StandardCharsets.UTF_8);
|
|
|
|
|
message.setHeader(header);
|
|
|
|
|
|
|
|
|
|
// 读取长度
|
|
|
|
|
byte[] lengthBytes = Arrays.copyOfRange(messageBytes, 3, 5);
|
|
|
|
|
int length = BytesUtil.bytesToIntLittle(lengthBytes);
|
|
|
|
|
message.setLength(length);
|
|
|
|
|
|
|
|
|
|
// 验证长度
|
|
|
|
|
if (length != (messageBytes.length - 5)) {
|
|
|
|
|
throw new IllegalArgumentException("Invalid message length");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 读取物理ID
|
|
|
|
|
byte[] physicalIdBytes = Arrays.copyOfRange(messageBytes, 5, 9);
|
|
|
|
|
int physicalId = BytesUtil.bytesToIntLittle(physicalIdBytes);
|
|
|
|
|
message.setPhysicalId(physicalId);
|
|
|
|
|
|
|
|
|
|
// 读取消息ID
|
|
|
|
|
byte[] messageIdBytes = Arrays.copyOfRange(messageBytes, 9, 11);
|
|
|
|
|
int messageId = BytesUtil.bytesToIntLittle(messageIdBytes);
|
|
|
|
|
message.setMessageId(messageId);
|
|
|
|
|
|
|
|
|
|
// 读取命令
|
|
|
|
|
byte commandByte = messageBytes[11];
|
|
|
|
|
String command = BytesUtil.bcd2StrLittle(new byte[]{commandByte});
|
|
|
|
|
message.setCommand(command);
|
|
|
|
|
|
|
|
|
|
// 读取数据
|
|
|
|
|
byte[] dataBytes = Arrays.copyOfRange(messageBytes, 12, messageBytes.length - 2);
|
|
|
|
|
message.setData(dataBytes);
|
|
|
|
|
String data = BytesUtil.bcd2StrLittle(dataBytes);
|
|
|
|
|
|
|
|
|
|
// 读取校验
|
|
|
|
|
byte[] checksumBytes = Arrays.copyOfRange(messageBytes, messageBytes.length - 2, messageBytes.length);
|
|
|
|
|
int checksum = BytesUtil.bytesToIntLittle(checksumBytes);
|
|
|
|
|
message.setChecksum(checksum);
|
|
|
|
|
|
|
|
|
|
// 校验码验证
|
|
|
|
|
if (!YouDianUtils.validateChecksum(messageBytes)) {
|
|
|
|
|
throw new IllegalArgumentException("Checksum validation failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
log.info("报文:{}, parseMessage:{}", BytesUtil.binary(messageBytes, 16), message.toString());
|
|
|
|
|
return message;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("Error parsing message", e);
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
2024-07-15 17:10:48 +08:00
|
|
|
}
|
2024-08-15 08:56:59 +08:00
|
|
|
|
2024-08-03 16:59:31 +08:00
|
|
|
}
|