package dell55AAData; 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); // ½âÎö½á¹ûÀà 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); 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]); } } }