826220679@qq.com
昨天 1bda9524add969e315d870f284046ecf1097f956
src/dell55AAData/Dell55AA01Parser.java
@@ -1,84 +1,153 @@
package dell55AAData;
import java.util.Arrays;
import dell_system.MessageViewPanel;
import dell_targets.Dell_BaseStation;
import dell_targets.Dell_tag;
import publicsWay.EfficientTimeFormatter;
public class Dell55AA01Parser {
    // 协议常量
    private static final String EXPECTED_HEADER = "55AA01"; // 协议头
    private static final int MIN_LENGTH = 42; // 最小长度(21字节*2字符)
    private static final ThreadLocal<ParseResult> RESULT_CACHE =
        ThreadLocal.withInitial(ParseResult::new);
   // 常量定义
   private static final String EXPECTED_HEADER = "55AA01"; // 协议头
   private static final int MIN_LENGTH = 42; // 最小长度(21字节*2字符)
   private static final ThreadLocal<ParseResult> RESULT_CACHE =
         ThreadLocal.withInitial(ParseResult::new);
    // 解析结果类
    public static class ParseResult {
        public int sequenceNum;   // 序列号
        public String tagId;      // 标签ID(4字节十六进制)
        public String anchorId;   // 锚点ID(4字节十六进制)
        public int distance;      // 距离(毫米)
        public int power;         // 电量(0-100)
        public boolean buttonPressed; // 按钮状态
        public void reset() {
            sequenceNum = 0;
            tagId = "";
            anchorId = "";
            distance = 0;
            power = 0;
            buttonPressed = false;
        }
    }
   // 解析结果类
   public static class ParseResult {
      public int sequenceNum;   // 序列号
      public String tagId;      // 标签ID(4字节小端序)
      public String anchorId;   // 锚点ID(4字节小端序)
      public int distance;      // 距离(毫米)
      public int power;         // 电量(0-100)
      public int buttonPressed; // 按钮状态
      public boolean buttonPressed2;
      public void reset() {
         sequenceNum = 0;
         tagId = "";
         anchorId = "";
         distance = 0;
         power = 0;
         buttonPressed = 0;
         buttonPressed2=false;
      }
   }
    /**
     * 解析55AA01协议数据
     * @param message 十六进制字符串
     * @return 解析结果(失败返回null)
     */
    public static ParseResult parse(String message) {
        // 参数检查
        if (message == null || message.length() < MIN_LENGTH) {
            return null;
        }
        // 协议头验证 (55AA01)
        for (int i = 0; i < 6; i++) {
            if (message.charAt(i) != EXPECTED_HEADER.charAt(i)) {
                return null;
            }
        }
        // 获取线程本地资源
        ParseResult result = RESULT_CACHE.get();
        result.reset();
        char[] chars = HexUtils.getThreadLocalBuffer();
        message.getChars(0, Math.min(message.length(), chars.length), chars, 0);
        // 解析序列号 (位置8-9)
        result.sequenceNum = HexUtils.fastHexToByte(chars[8], chars[9]);
        // 解析标签ID (位置10-13, 小端序)
        result.tagId = new String(new char[] {
            chars[12], chars[13], // 高位
            chars[10], chars[11]   // 低位
        });
        // 解析锚点ID (位置14-17, 小端序)
        result.anchorId = new String(new char[] {
            chars[16], chars[17], // 高位
            chars[14], chars[15]   // 低位
        });
        // 解析距离 (位置18-25, 4字节小端序整数)
        int b0 = HexUtils.fastHexToByte(chars[18], chars[19]); // 最低位
        int b1 = HexUtils.fastHexToByte(chars[20], chars[21]);
        int b2 = HexUtils.fastHexToByte(chars[22], chars[23]);
        int b3 = HexUtils.fastHexToByte(chars[24], chars[25]); // 最高位
        int raw = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
        result.distance = raw; // 保持原始整数值
        // 解析电量 (位置26-27)
        result.power = HexUtils.fastHexToByte(chars[26], chars[27]);
        // 解析按钮状态 (位置28-29)
        result.buttonPressed = HexUtils.fastHexToByte(chars[28], chars[29]) == 1;
        return result;
    }
   /**
    * 解析55AA01协议数据
    * @param message 十六进制字符串
    * @return 解析结果(错误时返回null)
    */
   public static ParseResult parse(String message, String ip, int port) {
      if (message == null || message.isEmpty()) {
         return null;
      }
      // 清洗数据:移除所有非十六进制字符
      char[] cleanedMessage = cleanMessage(message);
      // 数据校验
      if (cleanedMessage == null || cleanedMessage.length < MIN_LENGTH) {
         return null;
      }
      // 协议头校验 (55AA01)
      if (!new String(cleanedMessage, 0, 6).equals(EXPECTED_HEADER)) {
         return null;
      }
      ParseResult result = RESULT_CACHE.get();
      result.reset();
      try {
         if (cleanedMessage.length < 30) { // 确保有足够长度访问charAt(28)
            return null;
         }
         // 解析序列号 (位置8-9)
         result.sequenceNum = HexUtils.fastHexToByte(cleanedMessage[8], cleanedMessage[9]);
         // 解析标签ID (位置10-13, 小端序)
         result.tagId = new String(new char[]{
               cleanedMessage[12], cleanedMessage[13], // 高位
               cleanedMessage[10], cleanedMessage[11]  // 低位
         });
         // 解析锚点ID (位置14-17, 小端序)
         result.anchorId = new String(new char[]{
               cleanedMessage[16], cleanedMessage[17], // 高位
               cleanedMessage[14], cleanedMessage[15]  // 低位
         });
         // 解析距离 (位置18-25, 4字节小端整数)
         int b0 = HexUtils.fastHexToByte(cleanedMessage[18], cleanedMessage[19]); // 最低位
         int b1 = HexUtils.fastHexToByte(cleanedMessage[20], cleanedMessage[21]);
         int b2 = HexUtils.fastHexToByte(cleanedMessage[22], cleanedMessage[23]);
         int b3 = HexUtils.fastHexToByte(cleanedMessage[24], cleanedMessage[25]); // 最高位
         int raw = (b3 << 24) | (b2 << 16) | (b1 << 8) | b0;
         result.distance = raw; // 保持原始整数值
         // 解析电量 (位置26-27)
         result.power = HexUtils.fastHexToByte(cleanedMessage[26], cleanedMessage[27]);
         // 解析按钮状态 (位置28-29)
         result.buttonPressed = HexUtils.fastHexToByte(cleanedMessage[28], cleanedMessage[29]);
         result.buttonPressed2 =result.buttonPressed==1;
         // 日志和更新操作可以考虑优化或减少调用频率
         if (MessageViewPanel.isWindowVisible) {
             StringBuilder sb = new StringBuilder();
             sb.append("55AA01 Seq:")
               .append(result.sequenceNum)
               .append(",Tagid:")
               .append(result.tagId)
               .append(",Anchorid:")
               .append(result.anchorId)
               .append(",Distance:")
               .append(result.distance)
               .append(",Power:")
               .append(result.power)
               .append(",Button:")
               .append(result.buttonPressed);
             MessageViewPanel.showData(sb.toString(), ip, port, 0, "UDPA", "55AA01", "ALL");
         }
         String time = EfficientTimeFormatter.getCurrentTimeFormatted();
         Dell_BaseStation.updateBaseStationProperty(result.anchorId, "ipAddress", ip);
         Dell_BaseStation.updateBaseStationProperty(result.anchorId, "port", port + "");
         Dell_BaseStation.updateBaseStationProperty(result.anchorId, "status", "1");
         Dell_BaseStation.updateBaseStationProperty(result.anchorId, "onlineTime", time);
         Dell_tag.updateLocationTagProperty(result.tagId, "sosStatus", result.buttonPressed + "");
         Dell_tag.updateLocationTagProperty(result.tagId, "onlineStatus", "1");
         Dell_tag.updateLocationTagProperty(result.tagId, "lastUwbSignalTime", time);
         Dell_tag.updateLocationTagProperty(result.tagId, "latestRangingSeq", result.sequenceNum + "");
         Dell_tag.updateLocationTagProperty(result.tagId, "latestRangingBaseId", result.anchorId);
         Dell_tag.updateLocationTagProperty(result.tagId, "latestRangingDistance", result.distance + "");
         Dell_tag.updateLocationTagProperty(result.tagId, "latestRangingBaseCount", "1");
      } catch (IndexOutOfBoundsException | NumberFormatException e) {
         System.err.println("Parsing error in packet from " + ip + ":" + port);
         return null;
      }
      return result;
   }
   private static char[] cleanMessage(String message) {
      char[] cleaned = new char[message.length()];
      int j = 0;
      for (char c : message.toCharArray()) {
         if (Character.isDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
            cleaned[j++] = Character.toUpperCase(c);
         }
      }
      if (j == 0) return null;
      return Arrays.copyOf(cleaned, j);
   }
   public static void updateBase(String baseStationId, String propertyName, String value) {
      Dell_BaseStation.updateBaseStationProperty(baseStationId, propertyName, value);
      Dell_BaseStation.updateBaseStationProperty(baseStationId, propertyName, value);
   }
}