You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
5.8 KiB

namespace JiLinApp.Docking.FenceAlarm;
public class AlarmEncode
{
#region Fields
public static readonly byte Version = 0x12;
public static readonly byte[] Head = new byte[] { 0xF0, 0xFA };
public static readonly byte End = 0x0D;
public static readonly byte[] TEA_key = new byte[16] {
0x08,0x01,0x08,0x06,0x07,0x08,0x07,0x08,
0x08,0x90,0xC5,0x04,0x0D,0x0E,0x0F,0x10
};
#endregion Fields
public static byte[] EncodeMessage(byte[] msg)
{
if (!CheckMessage(msg)) return Array.Empty<byte>();
return GetMessage(msg[0], BteaEncrypt(GetContent(msg, msg[0] - 1)));
}
public static byte[] DecodeMessage(byte[] msg)
{
if (!CheckMessage(msg)) return Array.Empty<byte>();
return GetMessage(msg[0], BteaDecrpyt(GetContent(msg, msg[0] - 1)));
}
private static bool CheckMessage(byte[] msg)
{
if (msg == null) return false;
if (msg[0] > msg.Length) return false;
return true;
}
private static byte[] GetMessage(byte msgLen, byte[] msg)
{
byte[] outMsg = new byte[msg.Length + 1];
outMsg[0] = msgLen;
for (int i = 0; i < msg.Length; i++)
{
outMsg[i + 1] = msg[i];
}
return outMsg;
}
private static byte[] GetContent(byte[] msg, int len)
{
byte[] bytes = new byte[len];
for (int i = 0; i < len; i++)
{
bytes[i] = msg[i + 1];
}
return bytes;
}
public static byte[] GetSendMessage(byte command, byte[] data)
{
byte[] msg = data != null ? new byte[data.Length + 8] : new byte[8];
msg[0] = (byte)msg.Length;
msg[1] = Version;
msg[2] = Head[0];
msg[3] = Head[1];
msg[4] = command;
if (data != null)
{
for (int i = 0; i < data.Length; i++)
{
msg[i + 5] = data[i];
}
}
byte[] subMsg = data != null ? new byte[data.Length + 4] : new byte[4];
for (int i = 0; i < subMsg.Length; i++)
{
subMsg[i] = msg[i + 1];
}
byte[] crc = CRC16(subMsg);
msg[^3] = crc[1];
msg[^2] = crc[0];
msg[^1] = End;
return msg;
}
public static byte[] CRC16(byte[] data)
{
int len = data.Length;
if (len > 0)
{
ushort crc = 0xFFFF;
for (int i = 0; i < len; i++)
{
crc = (ushort)(crc ^ (data[i]));
for (int j = 0; j < 8; j++)
{
crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8); //高位置
byte lo = (byte)(crc & 0x00FF); //低位置
return new byte[] { hi, lo };
}
return new byte[] { 0, 0 };
}
private static byte[] BteaEncrypt(byte[] bytes)
{
byte[] output = new byte[bytes.Length];
for (int i = 0; i < bytes.Length; i++)
{
byte abyte = (byte)(bytes[i] ^ TEA_key[i % 16]);
output[i] = (byte)(((byte)(abyte >> 3)) | ((byte)(abyte << 5)));
}
return output;
}
private static byte[] BteaDecrpyt(byte[] bytes)
{
byte[] output = new byte[bytes.Length];
for (int i = 0; i < bytes.Length; i++)
{
byte abyte = (byte)(((byte)(bytes[i] << 3)) | ((byte)(bytes[i] >> 5)));
output[i] = (byte)(abyte ^ TEA_key[i % 16]);
}
return output;
}
}
public enum DeviceCmd : byte
{
/// <summary>
/// 心跳
/// </summary>
HeartBeatCmd = 0x01,
/// <summary>
/// 报警
/// </summary>
AlarmCmd = 0x02,
/// <summary>
/// 所有防区状态
/// </summary>
AllSectorStateCmd = 0x03,
/// <summary>
/// 实时防区状态
/// </summary>
RtSectorStateCmd = 0x04,
/// <summary>
/// 最大防区号
/// </summary>
MaxSectorTotalCmd = 0x05,
/// <summary>
/// 报警主机设置参数返回服务器
/// </summary>
BackSettingsCmd = 0x08,
/// <summary>
/// 布防指令
/// </summary>
DefenceCmd = 0x80,
/// <summary>
/// 校对时间指令
/// </summary>
CheckTimeCmd = 0x8D,
/// <summary>
/// 正确应答指令
/// </summary>
OkCmd = 0x8F,
/// <summary>
/// 主机重启指令
/// </summary>
RebootCmd = 0xA0,
}
public enum DeviceSectorType : byte
{
/// <summary>
/// 防区未使用
/// </summary>
NotUsed = 0x00,
/// <summary>
/// 防区撤防
/// </summary>
Withdraw = 0x01,
/// <summary>
/// 防区布防
/// </summary>
Deploy = 0x02,
/// <summary>
/// 防区旁路
/// </summary>
Byway = 0x03,
/// <summary>
/// 防区报警
/// </summary>
Alarm = 0x04,
/// <summary>
/// 无线防区欠压
/// </summary>
Undervoltage = 0x05,
/// <summary>
/// 防区掉线(与主线总线脱离)
/// </summary>
OffBus = 0x06,
/// <summary>
/// 未准备就绪
/// </summary>
Unprepared = 0x07,
}
public enum DeviceDefenceState : byte
{
/// <summary>
/// 撤防状态
/// </summary>
Withdraw = 0x00,
/// <summary>
/// 外出布防(普通布防最常用)
/// </summary>
GoOut = 0x01,
/// <summary>
/// 即时布防(所有防区没有延时)
/// </summary>
Immediately = 0x02,
/// <summary>
/// 在家布防(留守布防有些防区可能是在旁路状态)
/// </summary>
Home = 0x04,
/// <summary>
/// 即时留守布防(有些防区可能旁路,但是没有旁路防区没有延时)
/// </summary>
HomeImmediately = 0x08,
/// <summary>
/// 部分防区布防部分防区撤防
/// </summary>
Part = 0x09
}