package com.hdl.sdk.link.core.utils; import com.hdl.sdk.link.common.utils.LogUtils; import com.hdl.sdk.link.core.bean.BusProRequest; import java.util.HashMap; import java.util.Map; /** * buspro协议工具类 * Created by hxb on 2024/3/25. */ public class BusProUtils { //HDLMIRACLE的值 static final byte[] matchHdlBytes = new byte[]{'H','D','L','M','I','R','A','C','L','E'}; /** * 操作码对应匹配回复数据的索引,主要为了实现数据发送后能正常回调,Byte[]是附加数据的偏移量 */ private static final HashMap matchIndex = new HashMap(); static final String TAG = "BusProUtils"; /** * 本设备子网号,默认值99 */ private static byte sourceSubnetId = 99; /** * 本设备设备号,默认值99 */ private static byte sourceDeviceId = 99; /** * 本设备设备类型,默认0xFEFE */ private static byte[] deviceType = new byte[]{(byte) 0xFE, (byte) 0xFE}; /** * 获取本地设备Id * * @return */ public static byte getSourceSubnetId() { return sourceSubnetId; } /** * 设置本地设备Id */ public static void setSourceSubnetId(byte sourceSubnetId) { BusProUtils.sourceSubnetId = sourceSubnetId; } /** * 获取本地设备Id */ public static byte getSourceDeviceId() { return sourceDeviceId; } /** * 设置本地设备Id */ public static void setSourceDeviceId(byte sourceDeviceId) { BusProUtils.sourceDeviceId = sourceDeviceId; } /** * 获取设备类型 */ public static byte[] getDeviceType() { return deviceType; } /** * 设置设备类型 * * @param deviceType */ public static void setDeviceType(byte[] deviceType) { BusProUtils.deviceType = deviceType; } /** * 是否buspro数据格式 * * @param bytes bus协议每条数据 * @return true表示是bus协议数据,false表示不是 */ public static boolean isBusProBytes(byte[] bytes) { //类似接收到以下数据 C0 A8 01 66 48 44 4C 4D 49 52 41 43 4C 45 AA AA 0B FD FE FF FE 00 0E FF FF A0 0D if (bytes == null || bytes.length < 27) {//最小的buspro数据包大小为27个byte return false; } for (int i = 0; i < matchHdlBytes.length; i++) { //HDLMIRACLE是从接收数据的索引4开始,前面4位是IP地址 if (matchHdlBytes[i] != bytes[4 + i]) { return false; } } return true; } /** * 通过请求对象获取发送数据 * * @param busProRequest bus协议的封装数据 * @return 最终发出去的bus数据 */ public static byte[] getBusBytes(BusProRequest busProRequest) { if (busProRequest == null) { return null; } byte[] extraBytes = busProRequest.getExtraBytes(); if (extraBytes == null) { LogUtils.i(TAG, "附加数据为null"); } // 要计算CRC的数据和CRC两个字节 byte[] crcBytes = new byte[9 + extraBytes.length + 2]; // 发送出去的数据 byte[] sendBytes = new byte[16 + crcBytes.length]; // String[] ip = Net.CurrentNet.getPsdnIp().split("\\."); // // IP地址 // sendBytes[0] = (byte) Global.GetStringToInteger(ip[0]); // sendBytes[1] = (byte) Global.GetStringToInteger(ip[1]); // sendBytes[2] = (byte) Global.GetStringToInteger(ip[2]); // sendBytes[3] = (byte) Global.GetStringToInteger(ip[3]); // HDLMIRACLE sendBytes[4] = (byte) 'H'; sendBytes[5] = (byte) 'D'; sendBytes[6] = (byte) 'L'; sendBytes[7] = (byte) 'M'; sendBytes[8] = (byte) 'I'; sendBytes[9] = (byte) 'R'; sendBytes[10] = (byte) 'A'; sendBytes[11] = (byte) 'C'; sendBytes[12] = (byte) 'L'; sendBytes[13] = (byte) 'E'; // 引导码 sendBytes[14] = (byte) 0xAA; sendBytes[15] = (byte) 0xAA; // 16 数据包长度 11-78 crcBytes[0] = (byte) crcBytes.length; // 17 源子网地址 0-254 crcBytes[1] = sourceSubnetId; // 18 源设备地址 0-254 crcBytes[2] = sourceDeviceId; byte[] deviceType = getDeviceType(); if (deviceType == null || deviceType.length < 2) { LogUtils.i(TAG, "设备类型为null或者长度小于2"); } // 19 源设备类型高位 crcBytes[3] = deviceType[0]; // 20 源设备类型低位 crcBytes[4] = deviceType[1]; byte[] command = busProRequest.getCommand(); if (command == null || command.length < 2) { LogUtils.i(TAG, "操作码为null或者长度小于2"); } // 21 操作码高位 crcBytes[5] = busProRequest.getCommand()[0]; // 22 操作码低位 crcBytes[6] = busProRequest.getCommand()[1]; // 23 目标子网地址 0-254 crcBytes[7] = busProRequest.getDesSubnetId(); // 24 目标设备地址 0-254 crcBytes[8] = busProRequest.getDesDeviceId(); // 25~n附加数据 System.arraycopy(extraBytes, 0, crcBytes, 9, extraBytes.length); // CRC校验 CRCUtil.ConCRC(crcBytes, crcBytes.length - 2); // 复制CRC数据到发送数据里面 System.arraycopy(crcBytes, 0, sendBytes, 16, crcBytes.length); return sendBytes; } /** * 根据操作码动态获取匹配数据 * @param subnetId 子网号 * @param deviceId 设备号 * @param command 操作码 * @param extraBytes 发送或者接收到的附加数据 * @return */ public static String getMatchString(byte subnetId, byte deviceId, byte[] command, byte[] extraBytes) { String commandString=ByteUtils.encodeHexString(command); String result = String.format("BusPro_%s%s%s", ByteUtils.encodeHexString(subnetId), ByteUtils.encodeHexString(deviceId), commandString); Byte[] value = matchIndex.get(commandString); if (value != null) { //value[i]是附加数据偏移量,从0开始 for (int i = 0; i < value.length; i++) { result += String.format("%s", ByteUtils.encodeHexString(extraBytes[value[i]])); } } return result; } public static void setMatchIndex(String key,Byte []value) { matchIndex.put(key,value); } }