package jiexi; public class Dell55AA12HighPerf { // 协议常量 @SuppressWarnings("unused") private static final String HEADER = "55AA12"; // 协议头 private static final int MIN_LENGTH = 34; // 最小数据长度 private static final ThreadLocal RESULT_CACHE = // 解析结果缓存 ThreadLocal.withInitial(ParseResult::new); // 重用StringBuilder减少内存分配 private static final ThreadLocal hexDataBuilder = ThreadLocal.withInitial(() -> new StringBuilder(64)); // 解析结果类 public static class ParseResult { public String tagId; // 标签ID public int sequenceNum; // 序列号 public int power; // 电量 public int vibrationState; // 振动状态 public boolean tagRemoved; // 标签移除状态 public boolean isSleeping; // 休眠状态 public boolean isStatic; // 静止状态 public boolean sosButtonPressed; // SOS按钮状态 public int tagHeight; // 标签高度 public int anchorCount; // 锚点数量 public String[] anchorIds = new String[0]; // 锚点ID数组 public int[] distances = new int[0]; // 距离数组 public int[] anchorPowers = new int[0]; // 锚点电量数组 public int[] signalStrengths1 = new int[0]; // 信号强度1 public int[] signalStrengths2 = new int[0]; // 信号强度2 // 重置方法 public void reset() { tagId = ""; sequenceNum = 0; power = 0; vibrationState = 0; tagRemoved = false; isSleeping = false; isStatic = false; sosButtonPressed = false; tagHeight = 0; anchorCount = 0; // 数组保持长度,只重置计数 } } /** * 解析协议数据 * @param message 原始16进制字符串 * @return 解析结果对象(线程安全) */ public static ParseResult parse(String message,String ip,int port) { // 长度校验 if (message == null || message.length() < MIN_LENGTH) { return null; } // 协议头校验 if (!(message.charAt(0) == '5' && message.charAt(1) == '5' && message.charAt(2) == 'A' && message.charAt(3) == 'A' && message.charAt(4) == '1' && message.charAt(5) == '2')) { return null; } // 获取线程本地结果对象 ParseResult result = RESULT_CACHE.get(); result.reset(); // 获取字符缓冲区 char[] chars = HexUtils.getThreadLocalBuffer(); message.getChars(0, Math.min(message.length(), chars.length), chars, 0); // 解析数据长度 int dataLength = (HexUtils.fastHexToByte(chars[6], chars[7]) * 2) + 8; if (message.length() != dataLength) { return null; } // 解析标签信息 parseTagInfo(chars, result); // 解析锚点信息 parseAnchorInfo(chars, result); /* if (MessageViewPanel.isWindowVisible) { // 组装基站信息 StringBuilder ids = new StringBuilder(); StringBuilder dists = new StringBuilder(); StringBuilder powers = new StringBuilder(); for (int i = 0; i < result.anchorCount; i++) { if (i > 0) { ids.append(','); dists.append(','); powers.append(','); } ids.append(result.anchorIds[i]); dists.append(result.distances[i]); powers.append(result.anchorPowers[i]); } StringBuilder sb = hexDataBuilder.get(); sb.append("55AA12 ,Seq:").append(result.sequenceNum) .append(",Tagid:").append(result.tagId) .append(",Power: ").append(result.power).append("%") .append(",button:").append(result.sosButtonPressed) .append(",Static:").append(result.isStatic ) .append(",Sleep:").append(result.isSleeping ) .append(",State:").append(result.vibrationState ) .append(",TagRemoved:").append(result.tagRemoved) .append(",TagHeight:").append(result.tagHeight) .append(",AncNum:").append(result.anchorCount) .append(",AncIds:[").append(ids) .append("],Dis:[").append(dists) .append("],AncPowers:[").append(powers).append("]").append('\n'); MessageViewPanel.showData(sb.toString(), ip, port, 0, "UDPA", "55AA12",result.tagId); }*/ return result; } /** * 解析标签信息 */ private static void parseTagInfo(char[] chars, ParseResult result) { // 标签ID(小端序) result.tagId = new String(new char[] { chars[10], chars[11], // 高字节 chars[8], chars[9] // 低字节 }); // 序列号(小端序) result.sequenceNum = (HexUtils.fastHexToByte(chars[14], chars[15]) << 8 | HexUtils.fastHexToByte(chars[12], chars[13])); // 电量 result.power = HexUtils.fastHexToByte(chars[16], chars[17]); // 状态标志 int buttonState = HexUtils.fastHexToByte(chars[18], chars[19]); result.vibrationState = (buttonState >> 5) & 1; result.tagRemoved = ((buttonState >> 3) & 1) == 1; result.isSleeping = ((buttonState >> 2) & 1) == 1; result.isStatic = ((buttonState >> 1) & 1) == 1; result.sosButtonPressed = (buttonState & 1) == 1; // 标签高度(小端序) result.tagHeight = (HexUtils.fastHexToByte(chars[22], chars[23]) << 8 | HexUtils.fastHexToByte(chars[20], chars[21])); } /** * 解析锚点信息 */ private static void parseAnchorInfo(char[] chars, ParseResult result) { // 锚点数量 result.anchorCount = HexUtils.fastHexToByte(chars[32], chars[33]); if (result.anchorCount == 0) return; // 动态扩展数组 if (result.anchorIds.length < result.anchorCount) { result.anchorIds = new String[result.anchorCount]; result.distances = new int[result.anchorCount]; result.anchorPowers = new int[result.anchorCount]; result.signalStrengths1 = new int[result.anchorCount]; result.signalStrengths2 = new int[result.anchorCount]; } int baseIndex = 34; // 锚点ID起始位置 int distanceStart = baseIndex + result.anchorCount * 4; // 距离起始位置 int powerStart = distanceStart + result.anchorCount * 4; // 电量起始位置 // 解析锚点ID(小端序) for (int i = 0; i < result.anchorCount; i++) { int idOffset = baseIndex + i * 4; result.anchorIds[i] = new String(new char[]{ chars[idOffset + 2], // 高字节1 chars[idOffset + 3], // 高字节2 chars[idOffset], // 低字节1 chars[idOffset + 1] // 低字节2 }); } // 解析距离(有符号整数处理) for (int i = 0; i < result.anchorCount; i++) { int distOffset = distanceStart + i * 4; int distLow = HexUtils.fastHexToByte(chars[distOffset], chars[distOffset + 1]); int distHigh = HexUtils.fastHexToByte(chars[distOffset + 2], chars[distOffset + 3]); int rawDistance = (distHigh << 8) | distLow; result.distances[i] = (rawDistance > 0x7FFF) ? (rawDistance - 0x10000) : rawDistance; } // 解析锚点电量 for (int i = 0; i < result.anchorCount; i++) { int powerOffset = powerStart + i * 2; result.anchorPowers[i] = HexUtils.fastHexToByte(chars[powerOffset], chars[powerOffset + 1]); } } }