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 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")); }*/ }