|
|
|
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
|
|
|
|
}
|