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