package jiexi;
|
|
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);
|
// 重用StringBuilder减少内存分配
|
private static final ThreadLocal<StringBuilder> 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]);
|
}
|
}
|
}
|