package jiexi; import java.util.Arrays; public class Dell55AA01Parser { // 常量定义 private static final String EXPECTED_HEADER = "55AA01"; // 协议头 private static final int MIN_LENGTH = 42; // 最小长度(21字节*2字符) private static final ThreadLocal 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 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, 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; } 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); } }