HONGRI_uds_tools/CAN_Tool/UDS.cs

426 lines
12 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UDS
{
public enum UDSFrameType
{
SingleFrame = 0,
FirstFrame = 1,
ConsecutiveFrames = 2,
FlowControlFrame = 3,
};
public delegate void ReceivePackageEventHandler(byte[] data, int len);
public delegate void SendMessageEventHandler(UInt32 id, byte[] data, int len);
public class UDSBase
{
public UInt32 CANPhyDevRxId;
public UInt32 CANPhyDevTxId;
public UInt32 CANFuncDevRxId;
//是否是功能寻址
protected bool IsFunc;
protected int CANDL;
//发送的数据
protected byte[] SendData;
//发送包的大小
protected int SendPackageSize;
protected int NowSendDataIndex;
//用于判断接收到流控后 是否需要发送连续帧
protected bool IsSendFirstFrame;
//接收到的数据
protected byte[] ReceiveData;
//接收到包的大小
protected int ReceivePackageSize;
//当前接收到数据的在整个接收包的下标
protected int NowReceiveDataIndex;
protected byte ConsecutiveFramesHead;
//发送和接受事件
public event ReceivePackageEventHandler ReceivedPackage;
public event SendMessageEventHandler SendMessage;
//设置ID
public void SetId(UInt32 phyDevRxId, UInt32 phyDevTxId, UInt32 funcDevRxId)
{
this.CANPhyDevRxId = phyDevRxId;
this.CANPhyDevTxId = phyDevTxId;
this.CANFuncDevRxId = funcDevRxId;
}
public void SetCANDL(int canDL)
{
this.CANDL = canDL;
}
//触发发送报文事件
protected void SendMessageInvoke(byte[] data, int len)
{
UInt32 id;
if (this.IsFunc)
{
id = this.CANFuncDevRxId;
}
else
{
id = this.CANPhyDevRxId;
}
if (null != this.SendMessage)
{
this.SendMessage.Invoke(id, data, len);
}
}
//触发事件
protected void ReceivedPackageInvoke()
{
if (null != this.ReceivedPackage)
{
this.ReceivedPackage.Invoke(this.ReceiveData, this.ReceivePackageSize);
}
}
//发送一个包
virtual public void SendPackage(byte[] data, int len, bool isFunc)
{
}
//将数据插入接受缓存中
virtual public int InsertReceiveData(UInt32 id, byte[] data)
{
return 1;
}
//注册发送报文的事件
public void RegisterSendMessageEvent(SendMessageEventHandler func)
{
this.SendMessage += func;
}
//删除发送报文的事件
public void UnregisterSendMessageEvent(SendMessageEventHandler func)
{
this.SendMessage -= func;
}
//删除所有发送报文的事件
public void UnregisterSendMessageEventAll()
{
this.SendMessage = null;
}
//注册接收完成一个包的事件
public void RegisterReceivedPackageEvent(ReceivePackageEventHandler func)
{
this.ReceivedPackage += func;
}
//删除接收完成一个包的事件
public void UnregisterReceivedPackageEvent(ReceivePackageEventHandler func)
{
this.ReceivedPackage -= func;
}
//删除所有接收完成一个包的事件
public void UnregisterReceivedPackageEventAll()
{
this.ReceivedPackage = null;
}
}
public class UDSInfo : UDSBase
{
public UDSInfo(UInt32 phyDevRxId = 0, UInt32 phyDevTxId = 0, UInt32 funcDevRxId = 0, int canDL = 8)
{
//设置ID
this.SetId(phyDevRxId, phyDevTxId, funcDevRxId);
this.CANDL = canDL;
IsFunc = false;
IsSendFirstFrame = false;
//加一帧数据的大小 防止填充溢出
this.SendData = new byte[65535 + 64];
this.ReceiveData = new byte[65535 + 64];
}
//发送一个包 需要多帧则发送首帧后等待流控
override public void SendPackage(byte[] data, int len, bool isFunc)
{
byte[] dataFrame = new byte[8];
//byte[] dataFrame_64 = new byte[64];
this.SendPackageSize = len;
//是否发送首帧 先置false
IsSendFirstFrame = false;
//拷贝数据到缓存中
Array.Copy(data, 0, this.SendData, 0, len);
/*************************ISO15765-2******************************/
//8字节内单帧
//if ((this.CANDL <= 8)&& (len <= (this.CANDL - 1)))
if (len > 7)
{
//填充
for (int i = len; i < len + (7 - (len - 6 % 7)); i++)
{
this.SendData[i] = 0xAA;
}
//设置头数据
dataFrame[0] = (byte)(0x10 | ((len >> 8) & 0x0f));
dataFrame[1] = (byte)(len & 0xff);
Array.Copy(this.SendData, 0, dataFrame, 2, 6);
//发送了首帧
IsSendFirstFrame = true;
NowSendDataIndex = 6;
}
else
{
//填充
for (int i = len; i < 8; i++)
{
this.SendData[i] = 0xAA;
}
//设置头数据
dataFrame[0] = (byte)(len & 0xff);
Array.Copy(this.SendData, 0, dataFrame, 1, 7);
}
this.IsFunc = isFunc;
SendMessageInvoke(dataFrame, 8/*this.CANDL*/);
}
//发送连续帧
//内部调用
private void SendConsecutiveFrames()
{
byte[] dataFrame = new byte[this.CANDL];
int frameHead = 0x21;
//计算需要发送的连续帧数量
int framesNum = (this.SendPackageSize - this.NowSendDataIndex) / (this.CANDL - 1) + 1;
//未发送首帧 不应发送连续帧
if (!this.IsSendFirstFrame)
{
return;
}
//发送连续帧
for (int i = 0; i < framesNum; i++)
{
dataFrame[0] = (byte)frameHead;
Array.Copy(SendData, this.NowSendDataIndex, dataFrame, 1, this.CANDL - 1);
frameHead++;
if (0x30 == frameHead)
{
frameHead = 0x20;
}
this.NowSendDataIndex += this.CANDL - 1;
SendMessageInvoke(dataFrame, this.CANDL);
}
//发送完成后 将发送首帧标志置0
this.IsSendFirstFrame = false;
}
//发送流控帧
private void SendFlowControlFrame()
{
byte[] data = new byte[8] { 0x30, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00 };
this.IsFunc = false;
SendMessageInvoke(data, 8);
}
//插入单帧
//内部调用
private void InsertSingleFrameData(byte[] data)
{
//获取大小
this.ReceivePackageSize = data[1];
//判断单帧格式
if (0 != data[0])
{
this.ReceivePackageSize = data[0];
//拷贝数据
Array.Copy(data, 1, this.ReceiveData, 0, this.ReceivePackageSize);
}
else
{
this.ReceivePackageSize = data[1];
//拷贝数据
Array.Copy(data, 2, this.ReceiveData, 0, this.ReceivePackageSize);
}
//方便字符串截取
this.ReceiveData[this.ReceivePackageSize] = 0;
//触发事件
this.ReceivedPackageInvoke();
}
//插入首帧
//内部调用
private void InsertFirstFrameData(byte[] data)
{
//获取大小
this.ReceivePackageSize = (((int)data[0] & 0x0f) << 8) | (int)data[1];
if (0 != ReceivePackageSize)
{
//拷贝首帧数据
Array.Copy(data, 2, this.ReceiveData, 0, this.CANDL - 2);
NowReceiveDataIndex = this.CANDL - 2;
}
else
{
//拷贝首帧数据
Array.Copy(data, 6, this.ReceiveData, 0, this.CANDL - 6);
NowReceiveDataIndex = this.CANDL - 6;
}
//连续帧头设置为0x20方便后面累加计算
ConsecutiveFramesHead = 0x20;
//发送流控帧
this.SendFlowControlFrame();
}
//插入的是连续帧
//内部调用
private int InsertConsecutiveFramesData(byte[] data)
{
int ret = 0;
int readDataLen;
//对上一次的头累加
ConsecutiveFramesHead++;
if (0x30 == ConsecutiveFramesHead)
{
ConsecutiveFramesHead = 0x20;
}
//判断是否连续
if (data[0] == ConsecutiveFramesHead)
{
//判断需要读取的长度
if ((this.NowReceiveDataIndex + this.CANDL - 1) > this.ReceivePackageSize)
{
readDataLen = this.ReceivePackageSize - this.NowReceiveDataIndex;
}
else
{
readDataLen = this.CANDL - 1;
}
Array.Copy(data, 1, this.ReceiveData, this.NowReceiveDataIndex, readDataLen);
this.NowReceiveDataIndex += readDataLen;
//判断接收一个包是否完成
if (this.NowReceiveDataIndex == this.ReceivePackageSize)
{
//方便字符串截取
this.ReceiveData[this.ReceivePackageSize] = 0;
//触发事件
this.ReceivedPackageInvoke();
}
ret = 0;
}
else
{
ret = 1;
}
return ret;
}
//插入接收数据解析
//在接收到数据时使用 传入一帧的数据 完成一包的接收后触发事件
override public int InsertReceiveData(UInt32 id, byte[] data)
{
int ret = 0;
if (id != this.CANPhyDevTxId)
{
return 1;
}
//取出帧类型
UDSFrameType frameType = (UDSFrameType)((uint)data[0] >> 4);
//判断帧类型
switch (frameType)
{
case UDSFrameType.SingleFrame://收到单帧
InsertSingleFrameData(data);
break;
case UDSFrameType.FirstFrame://收到首帧
InsertFirstFrameData(data);
break;
case UDSFrameType.ConsecutiveFrames://收到连续帧
ret = InsertConsecutiveFramesData(data);
break;
case UDSFrameType.FlowControlFrame://收到流控帧
//发送连续帧
this.SendConsecutiveFrames();
break;
default:
ret = 1;
break;
}
return ret;
}
}
}