zsh_root
2025-12-10 8d662de2fd262b3a485f16e197cb4d0ca2a61cdf
src/jiexi/Dell55AA1BParser.java
@@ -2,26 +2,26 @@
import java.util.Arrays;
public class Dell55AA1BParser {
    // 常量定义
    private static final String EXPECTED_HEADER = "55AA1B"; // 协议头
    private static final int MIN_PACKET_LENGTH = 36; // 最小包长度(字符数): 固定字段18字节=36字符
    private static final int FIXED_FIELDS_LENGTH = 11; // 从标签ID到保留字段的固定长度(字节)
    // 常量定义
    private static final String EXPECTED_HEADER = "55AA1B"; // 协议头
    private static final int MIN_PACKET_LENGTH = 36; // 最小包长度(字符数): 固定字段18字节=36字符
    private static final int FIXED_FIELDS_LENGTH = 11; // 从标签ID到保留字段的固定长度(字节)
    private static final ThreadLocal<ParseResult> RESULT_CACHE = 
            ThreadLocal.withInitial(ParseResult::new);
    // 解析结果类
    // 解析结果类
    public static class ParseResult {
        public int dataLength;    // 数据长度
        public int messageType;    // 消息类型
        public String tagId;       // 标签ID(2字节)
        public int distance;       // 距离(厘米)
        public int angle;          // 角度(度)
        public int signalQuality;  // 信号质量(0-255)
        public int buttonPressed;  // 按钮状态
        public int power;          // 电量
        public String reserved;    // 保留字段
        public String userData;    // 用户数据
        public String checksum;    // 校验和
        public int dataLength;    // 数据长度
        public int messageType;    // 消息类型
        public String tagId;       // 标签ID(2字节)
        public int distance;       // 距离(厘米)
        public int angle;          // 角度(度)
        public int signalQuality;  // 信号质量(0-255)
        public int buttonPressed;  // 按钮状态
        public int power;          // 电量
        public String reserved;    // 保留字段
        public String userData;    // 用户数据
        public String checksum;    // 校验和
        
        public void reset() {
            dataLength = 0;
@@ -39,9 +39,9 @@
    }
    /**
     * 解析55AA1F协议数据
     * @param message 十六进制字符串
     * @return 解析结果(错误时返回null)
     * 解析55AA1F协议数据
     * @param message 十六进制字符串
     * @return 解析结果(错误时返回null)
     */
    public static ParseResult parse(String message, String ip, int port) {
        if (message == null || message.isEmpty()) {
@@ -49,7 +49,7 @@
            return null;
        }
        // 清洗数据:移除所有非十六进制字符
        // 清洗数据:移除所有非十六进制字符
        char[] cleanedMessage = cleanMessage(message);
        if (cleanedMessage == null) {
@@ -57,7 +57,7 @@
            return null;
        }
        // 检查最小长度
        // 检查最小长度
        if (cleanedMessage.length < MIN_PACKET_LENGTH) {
            System.err.println("Message too short from " + ip + ":" + port + 
                             ". Expected at least " + MIN_PACKET_LENGTH + 
@@ -65,7 +65,7 @@
            return null;
        }
        // 协议头校验 (55AA1B)
        // 协议头校验 (55AA1B)
        if (cleanedMessage.length < 6 || 
            !new String(cleanedMessage, 0, 6).equals(EXPECTED_HEADER)) {
            System.err.println("Invalid header in message from " + ip + ":" + port);
@@ -76,11 +76,11 @@
        result.reset();
        try {
            // 解析数据长度 (位置6-7)
            // 解析数据长度 (位置6-7)
            result.dataLength = HexUtils.fastHexToByte(cleanedMessage[6], cleanedMessage[7]);
            
            // 计算期望的总字符长度
            int expectedCharLength = 14 + result.dataLength * 2; // 14=包头6+消息类型2+数据长度2+校验和4
            // 计算期望的总字符长度
            int expectedCharLength = 14 + result.dataLength * 2; // 14=包头6+消息类型2+数据长度2+校验和4
//            if (cleanedMessage.length < expectedCharLength) {
//                System.err.println("Incomplete message from " + ip + ":" + port + 
@@ -89,42 +89,42 @@
//                return null;
//            }
            // 解析消息类型 (位置4-5)
            // 解析消息类型 (位置4-5)
            result.messageType = HexUtils.fastHexToByte(cleanedMessage[4], cleanedMessage[5]);
            // 解析标签ID (位置8-11),直接取字符串
            // 解析标签ID (位置8-11),直接取字符串
            result.tagId = new String(cleanedMessage, 8, 4);
            // 检查是否有足够长度解析固定字段
            if (cleanedMessage.length < 30) { // 需要至少15字节=30字符
            // 检查是否有足够长度解析固定字段
            if (cleanedMessage.length < 30) { // 需要至少15字节=30字符
                System.err.println("Message too short for fixed fields from " + ip + ":" + port);
                return null;
            }
            // 解析距离 (位置12-15, 2字节小端整数)
            // 解析距离 (位置12-15, 2字节小端整数)
            int distLow = HexUtils.fastHexToByte(cleanedMessage[12], cleanedMessage[13]);
            int distHigh = HexUtils.fastHexToByte(cleanedMessage[14], cleanedMessage[15]);
            result.distance = (distHigh << 8) | distLow;
            // 解析角度 (位置16-19, 2字节小端有符号整数)
            // 解析角度 (位置16-19, 2字节小端有符号整数)
            int angleLow = HexUtils.fastHexToByte(cleanedMessage[16], cleanedMessage[17]);
            int angleHigh = HexUtils.fastHexToByte(cleanedMessage[18], cleanedMessage[19]);
            short angleShort = (short) ((angleHigh << 8) | angleLow);
            result.angle = angleShort;
            // 解析信号质量 (位置20-21)
            // 解析信号质量 (位置20-21)
            result.signalQuality = HexUtils.fastHexToByte(cleanedMessage[20], cleanedMessage[21]);
            // 解析按钮状态 (位置22-23)
            // 解析按钮状态 (位置22-23)
            result.buttonPressed = HexUtils.fastHexToByte(cleanedMessage[22], cleanedMessage[23]);
            // 解析电量 (位置24-25)
            // 解析电量 (位置24-25)
            result.power = HexUtils.fastHexToByte(cleanedMessage[24], cleanedMessage[25]);
            // 解析保留字段 (位置26-29)
            // 解析保留字段 (位置26-29)
            result.reserved = new String(cleanedMessage, 26, 4);
            // 解析用户数据
            // 解析用户数据
//            int userDataStart = 30;
//            int userDataCharLength = (result.dataLength - FIXED_FIELDS_LENGTH) * 2;
//            if (userDataCharLength > 0) {
@@ -138,10 +138,10 @@
//                result.userData = "";
//            }
            // 解析校验和 (最后4个字符)
            // 解析校验和 (最后4个字符)
            result.checksum = new String(cleanedMessage, cleanedMessage.length - 4, 4);
            // 验证校验和
            // 验证校验和
//            byte[] packetBytes = hexStringToByteArray(new String(cleanedMessage));
//            if (!verifyChecksum(packetBytes)) {
//                System.err.println("Checksum verification failed for packet from " + ip + ":" + port);
@@ -158,7 +158,7 @@
    }
    /**
     * 将十六进制字符串转换为字节数组
     * 将十六进制字符串转换为字节数组
     */
    private static byte[] hexStringToByteArray(String s) {
        int len = s.length();
@@ -171,21 +171,21 @@
    }
    /**
     * 校验数据包
     * 去掉包头求和取反,校验码为小端模式
     * 校验数据包
     * 去掉包头求和取反,校验码为小端模式
     */
    private static boolean verifyChecksum(byte[] packet) {
        int len = packet.length;
        if (len < 4) return false;
        int sum = 0;
        // 从消息类型开始到校验码前结束 (跳过包头2字节)
        // 从消息类型开始到校验码前结束 (跳过包头2字节)
        for (int i = 2; i < len - 2; i++) {
            sum += packet[i] & 0xFF;
        }
        sum = ~sum & 0xFFFF; // 取反并保留16位
        sum = ~sum & 0xFFFF; // 取反并保留16位
        // 获取包中的校验码 (小端模式)
        // 获取包中的校验码 (小端模式)
        int receivedChecksum = ((packet[len - 2] & 0xFF) << 8) | (packet[len - 1] & 0xFF);
        return sum == receivedChecksum;