package dell55AAData;
|
|
public class Dell55AA12HighPerf {
|
|
// ÐÒé³£Á¿
|
@SuppressWarnings("unused")
|
private static final String HEADER = "55AA12"; // ÐÒéÍ·
|
private static final int MIN_LENGTH = 34; // ×îСÊý¾Ý³¤¶È
|
private static final ThreadLocal<ParseResult> 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]);
|
}
|
}
|
}
|