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

653 lines
23 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UPPLibs
{
/*
*struReadData
*
*2010-10-30
*
*/
struct struReadData
{
//终端类型
public byte flagDTN;
//逻辑编号
public byte[] addrDNL;
//主站地址
public byte flagMSTA;
//帧序号
public byte flagFSEQ;
//功能标志
public byte flagCtrlF;
//测量点标志
public byte flagPoint;
//数据项编号
public byte[] numPairs;
}
/*
*struWriteData
*
*2010-10-30
*
*/
struct struWriteData
{
//终端类型
public byte flagDTN;
//逻辑编号
public byte[] addrDNL;
//主站地址
public byte flagMSTA;
//帧序号
public byte flagFSEQ;
//功能标志
public byte flagCtrlF;
//测量点标志
public byte flagPoint;
//权限标志
public byte flagAUT;
//密码
public byte[] passwd;
//数据项编号
public byte[] numPairs;
//对时处理标志
public bool isTimeCorrecting;
}
/*
*struFrame
*
*2010-10-30
*
*/
struct struFrame
{
//终端类型
public byte flagDTN;
//逻辑编号
public byte[] addrDNL;
//主站地址
public byte flagMSTA;
//帧内序号
public byte flagISEQ;
//帧序号
public byte flagFSEQ;
//控制码
public byte flagCtrl;
//传送方向
public byte flagCtrlD;
//异常标志
public byte flagCtrlE;
//功能标志
public byte flagCtrlF;
//数据长度
public int lenData;
//数据字符串
public byte[] strData;
public object userData;
public string tName;
public object userData2;
//public bool isCtrl;
//public bool isData;
public bool isTimeCorrectting;
};
/*
*struRequestInQueue
*
*2010-10-30
*
*/
struct struRequestInQueue
{
//帧信息
public struFrame frameInfo;
//帧字节串
public byte[] frameBytes;
//是否匹配
public bool bMatchOK;
};
/*
*UPPHandler
*
*2010-10-30
*
*/
class UPPHandler
{
/*
*countCS
*
*2010-10-30
*byte[] bytes ,
*int start ,
*int len
*int CS
*CS
*/
public static int countCS(byte[] bytes, int start, int len)
{
if (len > bytes.Length || len <= 0)
{
return -1;
}
int sum = 0;
for (int i = start; i < (len + start); i++)
{
sum += bytes[i];
}
return sum % 0x100;
}
/*
*PreframePacking
*
*2010-10-30
*byte flagCtrlF ,
*object obj ,
*ref struFrame sFrame
*bool true false
*
*/
public static bool PreframePacking(byte flagCtrlF, object obj, ref struFrame sFrame)
{
bool res = true;
sFrame.addrDNL = new byte[2];
sFrame.flagCtrlE = 0;
sFrame.flagCtrlD = 0;
sFrame.flagCtrlF = flagCtrlF;
switch (flagCtrlF)
{
case 0x00:
//strComment += "中继";
break;
//"读当前数据"
case 0x01:
struReadData rdData = (struReadData)obj;
sFrame.flagDTN = rdData.flagDTN;
sFrame.addrDNL[0] = rdData.addrDNL[0];
sFrame.addrDNL[1] = rdData.addrDNL[1];
sFrame.flagMSTA = rdData.flagMSTA;
sFrame.flagISEQ = (byte)0;
sFrame.flagFSEQ = rdData.flagFSEQ;
sFrame.lenData = 1 + rdData.numPairs.Length;
sFrame.strData = new byte[sFrame.lenData];
sFrame.strData[0] = rdData.flagPoint;
for (int i = 0; i < rdData.numPairs.Length; i++)
{
sFrame.strData[i + 1] = rdData.numPairs[i];
}
break;
case 0x02:
//strComment += "读任务数据";
break;
case 0x04:
//strComment += "读编程日志";
break;
case 0x07:
//strComment += "实时写对象参数";
break;
case 0x08:
//strComment += "写对象参数";
struWriteData wrData = (struWriteData)obj;
sFrame.flagDTN = wrData.flagDTN;
sFrame.addrDNL[0] = wrData.addrDNL[0];
sFrame.addrDNL[1] = wrData.addrDNL[1];
sFrame.flagMSTA = wrData.flagMSTA;
sFrame.flagISEQ = (byte)0;
sFrame.flagFSEQ = wrData.flagFSEQ;
sFrame.lenData = wrData.numPairs.Length;
sFrame.strData = new byte[sFrame.lenData];
//sFrame.strData[0] = wrData.flagPoint;
//sFrame.strData[1] = wrData.flagAUT;
//if (wrData.passwd.Length == 3)
//{
// sFrame.strData[2] = wrData.passwd[0];
// sFrame.strData[3] = wrData.passwd[1];
// sFrame.strData[4] = wrData.passwd[2];
//}
for (int i = 0; i < wrData.numPairs.Length; i++)
{
sFrame.strData[i] = wrData.numPairs[i];
}
sFrame.isTimeCorrectting = wrData.isTimeCorrecting;
break;
case 0x09:
//strComment += "异常告警";
break;
case 0x0a:
//strComment += "告警确认";
break;
case 0x0f:
//strComment += "用户自定义数据";
break;
case 0x21:
//strComment += "登录";
break;
case 0x22:
//strComment += "登录退出";
break;
case 0x24:
//strComment += "心跳检验";
break;
default:
res = false;
//strComment += "未知";
break;
}
return res;
}
/*
*frameParsing
*
*2010-10-30
*string pack ,
* ref struFrame sFrame
*true false
*
*/
public static bool frameParsing(byte[] pack, ref struFrame sFrame)
{
sFrame.flagDTN = (byte)pack[1];
sFrame.addrDNL = new byte[2];
sFrame.addrDNL[0] = (byte)pack[2];
sFrame.addrDNL[1] = (byte)pack[3];
sFrame.flagMSTA = (byte)((byte)0x3f & (byte)pack[4]);
sFrame.flagISEQ = (byte)((byte)pack[5] >> 5);
sFrame.flagFSEQ = (byte)(((byte)pack[4] >> 6) | (byte)((((byte)pack[5] & 0x1f)) << 2));
sFrame.flagCtrl = (byte)pack[7];
sFrame.flagCtrlD = (byte)(pack[7] >> 7);
sFrame.flagCtrlE = (byte)(pack[7] >> 6 & 1);
sFrame.flagCtrlF = (byte)(pack[7] & 0x3f);
sFrame.lenData = 256 * Convert.ToInt32(pack[8]) + Convert.ToInt32(pack[9]);
//sFrame.strData = pack.Substring(10, sFrame.lenData);
sFrame.strData = new byte[sFrame.lenData];
for (int i = 0; i < sFrame.lenData; i++)
{
sFrame.strData[i] = pack[10 + i];
}
return true;
}
/*
*frameCommenting
*
*2010-10-30
*ref struFrame sFrame ,
* ref string strComment
*void
*
*/
public static void frameCommenting(ref struFrame sFrame, ref string strComment)
{
strComment = "";
switch (sFrame.flagCtrlF)
{
case 0x00:
strComment += "中继";
break;
case 0x01:
strComment += "读当前数据";
break;
case 0x02:
strComment += "读任务数据";
break;
case 0x03:
strComment += "主动上传数据";
break;
case 0x04:
strComment += "读编程日志";
break;
case 0x07:
strComment += "实时写对象参数";
break;
case 0x08:
strComment += "写对象参数";
break;
case 0x09:
strComment += "异常告警";
break;
case 0x0a:
strComment += "告警确认";
break;
case 0x0f:
strComment += "用户自定义数据";
break;
case 0x21:
strComment += "登录";
break;
case 0x22:
strComment += "登录退出";
break;
case 0x24:
strComment += "心跳检验";
break;
default:
strComment += "未知类型";
break;
}
switch (sFrame.flagCtrlD)
{
case 1:
strComment += "应答帧";
break;
case 0:
strComment += "请求帧";
break;
default:
break;
}
strComment += " ";
}
/*
*frameChecking
*
*2010-10-30
*ref struFrame sFrame
*true false
*
*/
public static bool frameChecking(ref struFrame sFrame)
{
bool res = false;
//业务包
if (sFrame.tName.Length == 5)
{
//检查编号一致
if (sFrame.tName[0] == sFrame.flagDTN
&& sFrame.tName.Substring(1, 4)
== (sFrame.addrDNL[0] * 0x100 + sFrame.addrDNL[1]).ToString("X4")
)
res = true;
}
//登录包
else if (sFrame.tName.Length != 5 && sFrame.flagCtrlF == 0x21)
{
res = true;
}
return res;
}
/*
*frameRespPacking
*
*2010-10-30
*ref struFrame sFrame
* ref string strRespFramePack
*true false
*
*/
public static bool framePacking(ref struFrame sFrame, ref byte[] strRespFramePack)//????????????????????????
{
bool res = false;
//request resp
strRespFramePack = new byte[12 + sFrame.lenData];
//string strResp = "";
strRespFramePack[0] = 0x68;
strRespFramePack[1] = sFrame.flagDTN;
strRespFramePack[2] = sFrame.addrDNL[0];
strRespFramePack[3] = sFrame.addrDNL[1];
//strRespFramePack[3] = Convert.ToByte(((int)(sFrame.addrDNL[1])).ToString(),16);
strRespFramePack[4] = (byte)(sFrame.flagMSTA | (sFrame.flagFSEQ & 0x3) << 6);
strRespFramePack[5] = (byte)(sFrame.flagFSEQ >> 2 | (sFrame.flagISEQ << 5));
strRespFramePack[6] = 0x68;
//临时措施有功16进制数据
if (sFrame.flagCtrl == 0x03/*sFrame.flagCtrl == 0xaa || sFrame.flagCtrl == 0x84 || sFrame.flagCtrl == 0x85*/)
{
strRespFramePack[7] = sFrame.flagCtrl;
}
else
{
strRespFramePack[7] = (byte)(sFrame.flagCtrlF
| (sFrame.flagCtrlE << 6)
| (sFrame.flagCtrlD << 7));
}
if (sFrame.lenData <= 0xffff && sFrame.lenData >= 0)
{
if (sFrame.lenData == sFrame.strData.Length)
{
strRespFramePack[8] = (byte)(sFrame.lenData / 0x100);
strRespFramePack[9] = (byte)(sFrame.lenData % 0x100);
for (int j = 0; j < sFrame.strData.Length; j++)
{
strRespFramePack[10 + j] = (byte)sFrame.strData[j];
}
//int sum = 0;
//for (int i = 0; i < strRespFramePack.Length - 2; i++)
//{
// sum += (byte)strRespFramePack[i];
//}
//byte CS = (byte)(sum % 0x100);
byte CS = (byte)countCS(strRespFramePack, 0, strRespFramePack.Length - 2);
strRespFramePack[strRespFramePack.Length - 2] = CS;
strRespFramePack[strRespFramePack.Length - 1] = 0x16;
res = true;
}
}
//frame self
return res;
}
/*
*frameCopy
*9
*2010-10-30
*ref struFrame sFrame
* ref struFrame sRespFrame
*void
*
*/
public static void frameCopy(ref struFrame sFrame, ref struFrame sRespFrame)
//public static void frameCopy(struFrame sFrame, struFrame sRespFrame)
{
//request resp
sRespFrame.flagDTN = sFrame.flagDTN;
if (sRespFrame.addrDNL == null)
{
sRespFrame.addrDNL = new byte[2];
}
sRespFrame.addrDNL[0] = sFrame.addrDNL[0];
sRespFrame.addrDNL[1] = sFrame.addrDNL[1];
sRespFrame.flagMSTA = sFrame.flagMSTA;
sRespFrame.flagISEQ = sFrame.flagISEQ;
sRespFrame.flagFSEQ = sFrame.flagFSEQ;
sRespFrame.flagCtrl = sFrame.flagCtrl;
sRespFrame.flagCtrlD = sFrame.flagCtrlD;
sRespFrame.flagCtrlE = sFrame.flagCtrlE;
sRespFrame.flagCtrlF = sFrame.flagCtrlF;
sRespFrame.lenData = sFrame.lenData;
sRespFrame.strData = new byte[sFrame.strData.Length];
for (int i = 0; i < sFrame.strData.Length; i++)
{
sRespFrame.strData[i] = sFrame.strData[i];
}
}
/*
*FindPackFromBuff
*
*2010-10-30
*ref string buff
*
*
*/
public static byte[] FindPackFromBuff(ref byte[] buff)
{
byte[] res = { };
int ind = -1;
for (int i = 0; i < buff.Length; i++)
{
if (buff[i] == 0x68)
{
ind = i;
break;
}
}
if (ind == -1)
{
buff = new byte[0];
return res;
}
//字符串字符位置
//第一个68H位置
int indF68H1 = ind;
//第二个68H位置
int indF68H2 = indF68H1 + 6;
//长度位置
int indLEN = indF68H1 + 8;
//CS位置
int indCS = 0;
//16H位置
int indF16H = 0;
//帧长度
int lenPack = 0;
while (buff.Length >= 12 && indF68H2 < buff.Length)
{
res = new byte[0];
if (buff[indF68H1] == 0x68 && buff[indF68H2] == 0x68)
{
//get length
if ((indLEN + 2) < buff.Length)
{
int len = 256 * Convert.ToInt32(buff[indLEN]) + Convert.ToInt32(buff[indLEN + 1]);
//计算 结束符 0x16 位置
indF16H = indF68H1 + 11 + len;
//计算 校验和位置
indCS = indF16H - 1;
//get end flag
if (indF16H < buff.Length)
{
if (buff[indF16H] == 0x16)
{
//CS 检查
int CSValue = Convert.ToInt32((byte)buff[indCS]);
lenPack = indF16H + 1 - indF68H1;
//int sum = 0;
//for (int i = 0; i < lenPack - 2; i++)//////////////////////
//{
// sum += Convert.ToInt32(buff[indF68H1 + i]);
//}
//sum %= 0x100;
int sum = countCS(buff, indF68H1, lenPack - 2);
if (sum == CSValue)
{
res = new byte[lenPack];
for (int j = 0; j < lenPack; j++)
{
res[j] = buff[indF68H1 + j];
}
//buff.CopyTo(Substring(indF68H1, lenPack);
//buff.Remove(0, indF68H1 + lenPack);
int newPosition = indF68H1 + lenPack;
byte[] tmp = new byte[buff.Length - newPosition];
for (int n = 0; n < buff.Length - newPosition; n++)
{
tmp[n] = buff[n + newPosition];
}
buff = tmp;//.Substring(newPosition, buff.Length - newPosition);
return res;
}
else
{
//ind++, continue
}
}
else
{
//ind++, continue
}
}
else
{
break;
}
}
else
{
break;
}
}
else
{
//ind++, continue
}
ind++;
indF68H1 = ind;
indF68H2 = indF68H1 + 6;
indLEN = indF68H1 + 8;
indCS = 0;
indF16H = 0;
lenPack = 0;
}
return res;
}
}
}