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