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;
|
}
|
|
|
}
|