张世豪
昨天 8f8eed75beb5bb9b66f2a87de856f2dbf11e6ffe
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
package publicway;
/**
 * ½âÎö¹¦ÄÜÂëΪ 0x51 µÄЭÒ黨¸´£¨»ùÓÚ¹¤³ÌÖРDebugActivity µÄ±¨Îĸñʽ£©¡£
 *
 * Ð­Ò鹿Ôò£¨ÒÑÔÚ¹¤³ÌÖжദʹÓã©£º
 * - ±¨ÎĽṹ£º [0xDD][0xCC][len_H][len_L][cmd][doorNo][func][payload...][CRC_H][CRC_L]
 * - len ÊÇ´Ó cmd£¨index 4£©¿ªÊ¼µ½ payload Ä©Î²µÄ×Ö½ÚÊý£¨´ó¶Ë£©¡£
 * - CRC Ê¹ÓàModbus CRC16£¨¶àÏîʽ 0xA001£¬³õʼֵ 0xFFFF£©£¬Õ¼×îºóÁ½×Ö½Ú£¬Hex ¸ñʽΪ 4 ¸ö hex ×Ö·û¡£
 *
 * ±¾½âÎöÆ÷£º
 * - ÊäÈ룺ʮÁù½øÖÆ×Ö·û´®£¨ÔÊÐí´ø»ò²»´ø¿Õ¸ñ£¬´óСд²»Ãô¸Ð£©
 * - Êä³ö£ºint£¬1 ±íʾÃüÁîÕýÈ·Ö´ÐУ¬0 ±íʾÃüÁîδÕýÈ·Ö´Ðлò±¨ÎIJ»ºÏ·¨
 *
 * ¹æÔò˵Ã÷£¨»ùÓÚÑùÀý£©£º
 * - µ± func==0x51 Ê±£¬È¡ÓÐЧ¸ºÔصÄ×îºóÒ»¸ö×Ö½Ú×÷Ϊ״̬Â룻ʾÀýÖР0x11 ±íʾ³É¹¦¡£
 */
public class ProtocolParser51 {
 
    /**
     * ½âÎöÊäÈ뱨ÎIJ¢·µ»ØÖ´Ðнá¹û£¨1 ³É¹¦£¬0 Ê§°Ü»ò±¨ÎIJ»ºÏ·¨£©
     *
     * @param hexString ±¨ÎÄÊ®Áù½øÖÆ×Ö·û´®£¬ÀýÈç "DD CC 00 08 F0 01 51 5A A5 5A A5 11 1C 77"
     * @return 1 ±íʾÃüÁîÕýÈ·Ö´ÐУ¬0 ±íʾʧ°Ü»ò²»ºÏ·¨
     */
    public static int parse(String hexString) {
        if (hexString == null) return 0;
        String s = hexString.replaceAll("\\s+", "").toLowerCase();
        if (s.length() < 12) { // ×î¶ÌÒ²ÒªÓРheader(4hex) + len(4hex) + cmd(2hex) + CRC(4hex)
            return 0;
        }
 
        // ³¤¶È±ØÐëΪżÊý
        if (s.length() % 2 != 0) {
            s = "0" + s;
        }
 
        // ×îºóÁ½×Ö½ÚΪ CRC£¨4 hex chars£©
        if (s.length() < 6) return 0;
        String crcHex = s.substring(s.length() - 4);
        String withoutCrc = s.substring(0, s.length() - 4);
 
        // Ð£Ñé CRC
//        String calcCrc = CRC16Modbus.calculate(withoutCrc);
//        if (!calcCrc.equals(crcHex)) {
//            System.out.println("calcCrc:"+calcCrc);
//            System.out.println("crcHex:"+crcHex);
//            return 0;
//        }
 
        // ×ª»»Îª×Ö½ÚÊý×é
        byte[] data = hexStringToBytes(s);
        if (data.length < 6) return 0;
 
        // ¼ì²é°üÍ·
        if ((data[0] & 0xFF) != 0xDD || (data[1] & 0xFF) != 0xCC) {
            return 0;
        }
 
        // len ×Ö½Ú£¨2¡¢3£©Îª´ó¶Ë
        int len = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
        // ×ܳ¤¶ÈӦΪ 4 (header+len) + len + 2 (crc)
        int expectedTotal = 4 + len + 2;
        if (expectedTotal != data.length) {
            return 0;
        }
 
        // func ÔÚµÚ 6 ¸ö×Ö½Ú£¨index=6£©£¬°´Ê¾Àý
        if (data.length <= 6) return 0;
        int func = data[6] & 0xFF;
        if (func != 0x51) {
            return 0; // ²»ÊÇ 0x51 ¹¦ÄÜÂë
        }
 
        // ÓÐÐ§ÔØºÉ´Ó index 4 µ½ index 4+len-1
        int payloadStart = 4;
        int payloadEnd = 4 + len - 1; // inclusive
        if (payloadEnd < payloadStart) return 0;
 
        // ×´Ì¬×Ö½ÚÈ¡ÓÐÐ§ÔØºÉ×îºóÒ»¸ö×Ö½Ú£¨Ê¾ÀýÖÐΪ 0x11 ±íʾ³É¹¦£©
        int status = data[payloadEnd] & 0xFF;
 
        // Ô¼¶¨£ºµ±×´Ì¬µÈÓÚ 0x11 ·µ»Ø³É¹¦£»ÆäËü·µ»ØÊ§°Ü
        return (status == 0x11) ? 1 : 0;
    }
 
    // ±¾ÀàÄÚ¸´ÓõĠhex->bytes ×ª»»
    private static byte[] hexStringToBytes(String hex) {
        String s = hex.replaceAll("\\s+", "");
        if (s.length() % 2 != 0) s = "0" + s;
        int len = s.length() / 2;
        byte[] data = new byte[len];
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            data[i] = (byte) Integer.parseInt(s.substring(pos, pos + 2), 16);
        }
        return data;
    }
    
 
}