zsh_root
2025-12-10 8d662de2fd262b3a485f16e197cb4d0ca2a61cdf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
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]);
        }
    }
}