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<String, Byte[]> 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);
|
}
|
|
}
|