package jiexi;
|
|
import java.nio.ByteBuffer;
|
import java.nio.ByteOrder;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
public class DeviceConfigParser {
|
|
public static DeviceConfig parseDeviceConfig(String hexData) {
|
DeviceConfig config = new DeviceConfig();
|
byte[] data = hexStringToByteArray(hexData);
|
ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN);
|
|
// 解析第一部分数据
|
parseFirstPart(buffer, config);
|
|
// 解析第二部分数据
|
parseSecondPart(buffer, config);
|
|
return config;
|
}
|
|
private static void parseFirstPart(ByteBuffer buffer, DeviceConfig config) {
|
// ucSequenceNum (1字节)
|
config.setSequenceNum(String.format("%02X", buffer.get()));
|
|
// ucCRC (1字节)
|
config.setCrc(String.format("%02X", buffer.get()));
|
|
// ucVersion (1字节)
|
config.setCrc(String.format("%02X", buffer.get()));
|
|
// ucFlags (1字节) - 需要按位解析
|
byte ucFlags = buffer.get();
|
config.setFlags(String.format("%02X", ucFlags));
|
config.setIpType(((ucFlags & 0x80)!=0?0:1));//IP类型
|
config.setConnectionType((ucFlags & 0x40));//连接类型
|
config.setCacheClear((ucFlags & 0x20) != 0 ? true : false);//是否清理缓存
|
|
// usLocationURLPort (2字节) - 预留
|
String usLocationURLPort = String.format("%04X", buffer.getShort());
|
|
// usHTTPServerPort (2字节) - HTTP服务端口
|
int usHTTPServerPort = Short.reverseBytes(buffer.getShort()) & 0xFFFF;
|
config.setHttpServerPort(usHTTPServerPort);
|
|
// ucUserFlag (1字节) - 预留
|
String ucUserFlag = String.format("%02X", buffer.get());
|
|
// IP地址字段需要按照小端序解析
|
// ulStaticIP (4字节) - 静态IP地址
|
byte[] ipBytes = new byte[4];
|
buffer.get(ipBytes);
|
String staticIp = bytesToIpLittleEndian(ipBytes);
|
config.setStaticIp(staticIp);
|
|
// ulGatewayIP (4字节) - 网关
|
buffer.get(ipBytes);
|
String ulGatewayIP = bytesToIpLittleEndian(ipBytes);
|
config.setGatewayIp(ulGatewayIP);
|
|
// ulSubnetMask (4字节) - 子网掩码
|
buffer.get(ipBytes);
|
String ulSubnetMask = bytesToIpLittleEndian(ipBytes);
|
config.setSubnetMask(ulSubnetMask);
|
|
// ucModName (14字节) - 模块名称
|
byte[] nameBytes = new byte[14];
|
buffer.get(nameBytes);
|
String ucModName = new String(nameBytes).trim();
|
config.setModuleName(ucModName);
|
|
// 协议预留 (2字节)
|
String baoLiu = String.format("%04X", buffer.getShort());
|
|
// username (6字节) - 用户名
|
byte[] userBytes = new byte[6];
|
buffer.get(userBytes);
|
config.setUsername(new String(userBytes).trim());
|
|
// password (6字节) - 密码
|
byte[] pwdBytes = new byte[6];
|
buffer.get(pwdBytes);
|
config.setPassword(new String(pwdBytes).trim());
|
|
// ucNetSendTime (1字节) - 预留
|
String.format("%02X", buffer.get());
|
|
// ulid (2字节) - 设备ID
|
int ulidValue1 = Short.reverseBytes(buffer.getShort()) & 0xFFFF;
|
config.setDeviceId(ulidValue1);
|
|
// ucIdType(1字节) 标志位
|
byte ulidValue = buffer.get();
|
config.setRfc2217((ulidValue & 0x80) != 0);
|
config.setIndex((ulidValue & 0x40) != 0);
|
config.setLink((ulidValue & 0x20) != 0);
|
config.setReset((ulidValue & 0x10) != 0);
|
config.setSendDataWithId((ulidValue & 0x04) != 0);
|
config.setSendIdOnConnect((ulidValue & 0x02) != 0);
|
|
// mac_addrs (6字节) - MAC地址
|
byte[] macBytes = new byte[6];
|
buffer.get(macBytes);
|
config.setMacAddress(bytesToMac(macBytes));
|
|
// DNSGatewayIP (4字节) - DNS服务器地址
|
buffer.get(ipBytes);
|
config.setDnsServer(bytesToIpLittleEndian(ipBytes));
|
|
// TC_sh_time (1字节) - 短连接断开时间
|
config.setShortConnectionTime(buffer.get() & 0xFF);
|
|
// ucReserved (3字节) - 预留
|
byte[] reserved = new byte[3];
|
buffer.get(reserved);
|
String s = bytesToHex(reserved);
|
}
|
|
private static void parseSecondPart(ByteBuffer buffer, DeviceConfig config) {
|
// uIBaudRate (4字节) - 串口波特率 (小端序)
|
byte[] baudBytes = new byte[4];
|
buffer.get(baudBytes);
|
int baudRate = byteArrayToIntLittleEndian(baudBytes);
|
config.setBaudRate(baudRate);
|
|
// ucDataSize (1字节) - 串口数据位
|
byte dataSize = buffer.get();
|
config.setDataBits(dataSize & 0xFF);
|
config.setDataBitsDesc(getDataSizeDesc(dataSize));
|
|
// ucParity (1字节) - 串口校验位
|
byte parity = buffer.get();
|
config.setParity(parity & 0xFF);
|
config.setParityDesc(getParityDesc(parity));
|
|
// ucStopBits (1字节) - 串口停止位
|
byte stopBits = buffer.get();
|
config.setStopBits(stopBits & 0xFF);
|
config.setStopBitsDesc(getStopBitsDesc(stopBits));
|
|
// ucFlowControl (1字节) - 预留
|
String ucFlowControl = String.format("%02X", buffer.get());
|
|
// uITelnetTimeout (4字节) - 预留
|
buffer.getInt(); // 跳过4字节
|
|
// usTelnetLocalPort (2字节) - 本地端口
|
int usTelnetLocalPort = Short.reverseBytes(buffer.getShort()) & 0xFFFF;
|
config.setLocalPort(usTelnetLocalPort);
|
|
// usTelnetRemotePort (2字节) - 远程端口(小端序)
|
int usTelnetRemotePort = Short.reverseBytes(buffer.getShort()) & 0xFFFF;
|
config.setRemotePort(usTelnetRemotePort);
|
|
// uITelnetURL (30字节) - IP地址或域名
|
byte[] urlBytes = new byte[30];
|
buffer.get(urlBytes);
|
String url = new String(urlBytes).trim();
|
config.setTargetUrl(url);
|
|
// uITelnetIPAddr (4字节) - 目标IP设置
|
byte[] ipBytes = new byte[4];
|
buffer.get(ipBytes);
|
config.setTargetIp(bytesToIpLittleEndian(ipBytes));
|
|
// ucFlags (1字节) - 标志位
|
byte ucFlags2 = buffer.get();
|
String StrUcFlags2 = String.format("%02X", ucFlags2);
|
// 根据文档说明,第5位为通信云,第6位为TCP Server跳回连接,第7位为MAC注册包
|
config.setCommunicationCloud((ucFlags2 & 0x10) != 0);
|
config.setTcpServerFallback((ucFlags2 & 0x20) != 0);
|
config.setMacRegistration((ucFlags2 & 0x40) != 0);
|
|
// ucWorkMode (1字节) - 工作方式
|
byte workMode = buffer.get();
|
config.setWorkMode(workMode & 0xFF);
|
config.setWorkModeDesc(getWorkModeDesc(workMode));
|
|
// HTTPucFlags (1字节) - HTTP模式
|
byte httpFlags = buffer.get();
|
config.setHttpMode(httpFlags == 0 ? "HTTPD GET" : "HTTPD POST");
|
|
// tc_number (1字节) - TCP Server可连接的Client数量
|
config.setTcpClientCount(buffer.get() & 0xFF);
|
|
// Timeout_restart (2字节) - 超时重启时间
|
int Timeout_restart = Short.reverseBytes(buffer.getShort()) & 0xFFFF;
|
config.setTimeoutRestart(Timeout_restart);
|
|
// cos_register_flag (1字节) - 自定义注册包
|
String cos_register_flag = String.format("%02X", buffer.get());
|
|
// ucTimeCount (1字节) - 时间计数
|
String ucTimeCount = String.format("%02X", buffer.get());
|
|
// uiPackLen (2字节) - 包长度
|
int uiPackLen = buffer.getShort() & 0xFFFF;
|
|
// ucReserved2 (3字节) - 预留
|
byte[] reserved2 = new byte[3];
|
buffer.get(reserved2);
|
String ucReserved2 = bytesToHex(reserved2);
|
}
|
|
// 辅助方法
|
private static byte[] hexStringToByteArray(String s) {
|
int len = s.length();
|
byte[] data = new byte[len / 2];
|
for (int i = 0; i < len; i += 2) {
|
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
|
+ Character.digit(s.charAt(i + 1), 16));
|
}
|
return data;
|
}
|
|
// IP地址按照小端序解析
|
private static String bytesToIpLittleEndian(byte[] bytes) {
|
return String.format("%d.%d.%d.%d",
|
bytes[3] & 0xFF, bytes[2] & 0xFF, bytes[1] & 0xFF, bytes[0] & 0xFF);
|
}
|
|
// 整数按照小端序解析
|
private static int byteArrayToIntLittleEndian(byte[] bytes) {
|
return ((bytes[3] & 0xFF) << 24) |
|
((bytes[2] & 0xFF) << 16) |
|
((bytes[1] & 0xFF) << 8) |
|
(bytes[0] & 0xFF);
|
}
|
|
private static String bytesToMac(byte[] bytes) {
|
StringBuilder sb = new StringBuilder();
|
for (int i = 0; i < bytes.length; i++) {
|
sb.append(String.format("%02X", bytes[i]));
|
if (i < bytes.length - 1) {
|
sb.append(":");
|
}
|
}
|
return sb.toString();
|
}
|
|
private static String bytesToHex(byte[] bytes) {
|
StringBuilder sb = new StringBuilder();
|
for (byte b : bytes) {
|
sb.append(String.format("%02X", b));
|
}
|
return sb.toString();
|
}
|
|
private static String getDataSizeDesc(byte dataSize) {
|
switch (dataSize) {
|
case 0x05:
|
return "5位";
|
case 0x06:
|
return "6位";
|
case 0x07:
|
return "7位";
|
case 0x08:
|
return "8位";
|
default:
|
return "未知: " + (dataSize & 0xFF);
|
}
|
}
|
|
private static String getParityDesc(byte parity) {
|
switch (parity) {
|
case 1:
|
return "无校验";
|
case 2:
|
return "奇校验";
|
case 3:
|
return "偶校验";
|
case 4:
|
return "标记校验";
|
case 5:
|
return "空格校验";
|
default:
|
return "未知: " + (parity & 0xFF);
|
}
|
}
|
|
private static String getStopBitsDesc(byte stopBits) {
|
switch (stopBits) {
|
case 0x01:
|
return "1位";
|
case 0x02:
|
return "2位";
|
default:
|
return "未知: " + (stopBits & 0xFF);
|
}
|
}
|
|
private static String getWorkModeDesc(byte workMode) {
|
switch (workMode) {
|
case 0:
|
return "UDP";
|
case 1:
|
return "TCP Client";
|
case 2:
|
return "UDP Server";
|
case 3:
|
return "TCP Server";
|
case 4:
|
return "HTTPD Client";
|
default:
|
return "未知: " + (workMode & 0xFF);
|
}
|
}
|
|
// 测试方法
|
/*public static void main(String[] args) {
|
String hexData = "9563038000005000000700A8C00100A8C000FFFFFF5553522D5443503233322D533200000061646D696E0061646D696E0000010080D4AD20CDB9FBDEDE43D00300000000100E0008010101000000008C4ED2043139322E3136382E302E3230310000000000000000000000000000000000C900A8C020000004100E00000000000000";
|
|
Map<String, Object> config = parseDeviceConfig(hexData);
|
|
// 打印解析结果
|
System.out.println("=== 设备配置解析结果 ===");
|
System.out.println("基础配置:");
|
System.out.printf(" %-25s: %s%n", "序列号", config.get("ucSequenceNum"));
|
System.out.printf(" %-25s: %s%n", "CRC", config.get("ucCRC"));
|
System.out.printf(" %-25s: %s%n", "版本", config.get("ucVersion"));
|
System.out.printf(" %-25s: %s%n", "标志位", config.get("ucFlags"));
|
System.out.printf(" %-25s: %s%n", "IP类型", config.get("IP类型"));
|
System.out.printf(" %-25s: %s%n", "连接类型", config.get("连接类型"));
|
System.out.printf(" %-25s: %s%n", "缓存清理", config.get("缓存清理"));
|
System.out.printf(" %-25s: %s%n", "HTTP服务端口", config.get("usHTTPServerPort"));
|
|
System.out.println("\n网络配置:");
|
System.out.printf(" %-25s: %s%n", "静态IP", config.get("ulStaticIP"));
|
System.out.printf(" %-25s: %s%n", "网关", config.get("ulGatewayIP"));
|
System.out.printf(" %-25s: %s%n", "子网掩码", config.get("ulSubnetMask"));
|
System.out.printf(" %-25s: %s%n", "DNS服务器", config.get("DNSGatewayIP"));
|
System.out.printf(" %-25s: %s%n", "MAC地址", config.get("mac_addrs"));
|
|
System.out.println("\n设备信息:");
|
System.out.printf(" %-25s: %s%n", "模块名称", config.get("ucModName"));
|
System.out.printf(" %-25s: %s%n", "用户名", config.get("username"));
|
System.out.printf(" %-25s: %s%n", "密码", config.get("password"));
|
System.out.printf(" %-25s: %s%n", "设备ID", config.get("ulid"));
|
System.out.printf(" %-25s: %s%n", "短连接断开时间", config.get("TC_sh_time"));
|
|
System.out.println("\n设备功能:");
|
System.out.printf(" %-25s: %s%n", "RFC2217", config.get("RFC2217"));
|
System.out.printf(" %-25s: %s%n", "index功能", config.get("index功能"));
|
System.out.printf(" %-25s: %s%n", "link功能", config.get("link功能"));
|
System.out.printf(" %-25s: %s%n", "reset功能", config.get("reset功能"));
|
System.out.printf(" %-25s: %s%n", "发送数据带ID", config.get("发送数据带ID"));
|
System.out.printf(" %-25s: %s%n", "建立连接发送ID", config.get("建立连接发送ID"));
|
|
System.out.println("\n串口配置:");
|
System.out.printf(" %-25s: %s%n", "波特率", config.get("uIBaudRate"));
|
System.out.printf(" %-25s: %s%n", "数据位", config.get("数据位"));
|
System.out.printf(" %-25s: %s%n", "校验位", config.get("校验位"));
|
System.out.printf(" %-25s: %s%n", "停止位", config.get("停止位"));
|
|
System.out.println("\n通信配置:");
|
System.out.printf(" %-25s: %s%n", "本地端口", config.get("usTelnetLocalPort"));
|
System.out.printf(" %-25s: %s%n", "远程端口", config.get("usTelnetRemotePort"));
|
System.out.printf(" %-25s: %s%n", "目标URL", config.get("uITelnetURL"));
|
System.out.printf(" %-25s: %s%n", "目标IP", config.get("uITelnetIPAddr"));
|
System.out.printf(" %-25s: %s%n", "工作方式", config.get("工作方式"));
|
System.out.printf(" %-25s: %s%n", "HTTP模式", config.get("HTTP模式"));
|
System.out.printf(" %-25s: %s%n", "TCP Client数量", config.get("tc_number"));
|
System.out.printf(" %-25s: %s%n", "通信云", config.get("通信云"));
|
System.out.printf(" %-25s: %s%n", "TCP Server跳回连接", config.get("TCP Server跳回连接"));
|
System.out.printf(" %-25s: %s%n", "MAC注册包", config.get("MAC注册包"));
|
|
System.out.println("\n其他配置:");
|
System.out.printf(" %-25s: %s%n", "超时重启时间", config.get("Timeout_restart"));
|
System.out.printf(" %-25s: %s%n", "自定义注册包", config.get("cos_register_flag"));
|
System.out.printf(" %-25s: %s%n", "时间计数", config.get("ucTimeCount"));
|
System.out.printf(" %-25s: %s%n", "包长度", config.get("uiPackLen"));
|
}*/
|
}
|