You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
8.2 KiB
240 lines
8.2 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace AIK.Common.AIKProtocol
|
|
{
|
|
public class AIKCommunication
|
|
{
|
|
/// <summary>
|
|
/// 数据包总包数
|
|
/// </summary>
|
|
public int TotalPackets { get; set; } = 0;
|
|
/// <summary>
|
|
/// 发送的文件数据(bin文件)
|
|
/// </summary>
|
|
public byte[] FileData { get; set; }
|
|
/// <summary>
|
|
/// 当前正在发送包的索引
|
|
/// </summary>
|
|
public int CurrentIndex { get; set; } = 0;
|
|
|
|
private readonly object _sendLock = new object();
|
|
private bool _isSending = false;
|
|
/// <summary>
|
|
/// 所有数据包是否完成发送
|
|
/// </summary>
|
|
private bool _isAllSendSuccess = false;
|
|
#region 数据包发送
|
|
/// <summary>
|
|
/// 发送起始码,建立连接使用
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public byte[] GetStartFrame()
|
|
{
|
|
var buf = new byte[8] { 0XA5, 0X5E, 0XAA, 0XBB, 0XCC, 0XDD, 0X00, 0X00 };
|
|
return buf;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送头帧
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task SendHeader(string sourceitem)
|
|
{
|
|
List<byte> bytes = new List<byte>();
|
|
bytes.Add(0x01);
|
|
bytes.Add(0x00);
|
|
bytes.Add(0xFF);
|
|
int lastSlashIndex = sourceitem.LastIndexOf('/');
|
|
string fileName = lastSlashIndex >= 0 ? sourceitem.Substring(lastSlashIndex + 1) : sourceitem;
|
|
byte[] filenamedata = Encoding.Default.GetBytes(fileName);
|
|
bytes.AddRange(filenamedata);
|
|
bytes.Add(0x00);
|
|
//string sourceitem = "/keys/bin/1.bin";
|
|
//string sourceitem = "/keys/bin/(7926)AiLiSheng47DaiA_DaiZuoYouCeHuaMen13NianHou.bin";
|
|
//FileData = await WebHelper.GetVehKeyBin(sourceitem);
|
|
if (FileData == null)
|
|
{
|
|
return;
|
|
}
|
|
TotalPackets = FileData.Length / 1024;
|
|
byte[] DataBuffdata = Encoding.Default.GetBytes(FileData.Length.ToString());
|
|
bytes.AddRange(DataBuffdata);
|
|
bytes.Add(0x00);
|
|
if (bytes.Count < 128)
|
|
{
|
|
int copi = 128 + 3 - bytes.Count;
|
|
for (int i = 0; i < copi; i++)
|
|
{
|
|
bytes.Add(0x00);
|
|
}
|
|
}
|
|
var cdata = new byte[128];
|
|
Array.Copy(bytes.ToArray(), 3, cdata, 0, 128);
|
|
var crc = ProtocolHelper.CalculateCRC16(cdata);
|
|
var CRCHigh = (byte)((crc >> 8) & 0xFF);
|
|
var CRCLow = (byte)(crc & 0xFF);
|
|
bytes.Add((byte)CRCHigh);
|
|
bytes.Add((byte)CRCLow);
|
|
|
|
var rdata = bytes.ToArray();
|
|
await WriteLargeDataFrame(rdata, 100);
|
|
}
|
|
/// <summary>
|
|
/// 发送数据帧
|
|
/// </summary>
|
|
/// <param name="page"></param>
|
|
/// <returns></returns>
|
|
public async Task<bool> SendDataFrame(int page)
|
|
{
|
|
bool flag = false;
|
|
var rdata = GetSendDataFrame(page, FileData);
|
|
bool success = await WriteLargeDataFrame(rdata.ToArray(), 100);
|
|
if (success)
|
|
{
|
|
flag = true;
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine("TestData发送失败");
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 发送结束帧
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public async Task SendEOTFrame()
|
|
{
|
|
var rdata = new byte[133];
|
|
rdata[0] = 0x01;
|
|
rdata[1] = 0x00;
|
|
rdata[2] = 0xFF;
|
|
await WriteLargeDataFrame(rdata, 100);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据包页及文件数据获取数据帧
|
|
/// </summary>
|
|
/// <param name="page"></param>
|
|
/// <param name="filedata"></param>
|
|
/// <returns></returns>
|
|
private List<byte> GetSendDataFrame(int page, byte[] filedata)
|
|
{
|
|
try
|
|
{
|
|
var bytes = new List<byte>();
|
|
if (page == filedata.Length / 1024 && filedata.Length % 1024 == 0)
|
|
{
|
|
return bytes;
|
|
}
|
|
bytes.Add(0x02);
|
|
bytes.Add((byte)(page));
|
|
bytes.Add((byte)~(page));
|
|
if (page == filedata.Length / 1024 - 1 && filedata.Length % 1024 <= 128 && filedata.Length % 1024 > 0)
|
|
{
|
|
var cdata = new byte[128];
|
|
Array.Copy(filedata, page * 1024, cdata, 0, filedata.Length - page * 1024);
|
|
var crc = ProtocolHelper.CalculateCRC16(cdata);
|
|
var CRCHigh = (byte)((crc >> 8) & 0xFF);
|
|
var CRCLow = (byte)(crc & 0xFF);
|
|
bytes.AddRange(cdata);
|
|
bytes.Add((byte)CRCHigh);
|
|
bytes.Add((byte)CRCLow);
|
|
}
|
|
else
|
|
{
|
|
var cdata = new byte[1024];
|
|
var arrarycount = 1024;
|
|
if (filedata.Length - page * 1024 > 0 && filedata.Length - page * 1024 < 1024)
|
|
{
|
|
arrarycount = filedata.Length - page * 1024;
|
|
}
|
|
Array.Copy(filedata, page * 1024, cdata, 0, arrarycount);
|
|
var crc = ProtocolHelper.CalculateCRC16(cdata);
|
|
var CRCHigh = (byte)((crc >> 8) & 0xFF);
|
|
var CRCLow = (byte)(crc & 0xFF);
|
|
bytes.AddRange(cdata);
|
|
bytes.Add((byte)CRCHigh);
|
|
bytes.Add((byte)CRCLow);
|
|
}
|
|
return bytes;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw;
|
|
}
|
|
|
|
}
|
|
#endregion
|
|
|
|
#region 写入数据帧
|
|
/// <summary>
|
|
/// 分包发送大数据
|
|
/// </summary>
|
|
public async Task<bool> WriteLargeDataFrame(byte[] data, int maxPacketSize = 100)
|
|
{
|
|
try
|
|
{
|
|
Debug.WriteLine($"开始发送数据,总长度: {data.Length} 字节,分包大小: {maxPacketSize} 字节");
|
|
|
|
int totalPackets = (int)Math.Ceiling((double)data.Length / maxPacketSize);
|
|
int successfulPackets = 0;
|
|
|
|
for (int i = 0; i < totalPackets; i++)
|
|
{
|
|
int offset = i * maxPacketSize;
|
|
int length = Math.Min(maxPacketSize, data.Length - offset);
|
|
byte[] packet = new byte[length];
|
|
Array.Copy(data, offset, packet, 0, length);
|
|
|
|
bool packetSuccess = await WritePacketDataFrame(packet, i + 1, totalPackets);
|
|
if (packetSuccess)
|
|
{
|
|
successfulPackets++;
|
|
}
|
|
else
|
|
{
|
|
Debug.WriteLine($"第 {i + 1} 包发送失败");
|
|
// 可以选择重试或直接失败
|
|
// return false;
|
|
}
|
|
|
|
// 添加小延迟,避免发送过快
|
|
await Task.Delay(30);
|
|
}
|
|
|
|
bool overallSuccess = successfulPackets == totalPackets;
|
|
Debug.WriteLine($"数据发送完成: {successfulPackets}/{totalPackets} 包成功");
|
|
return overallSuccess;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"发送大数据异常: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 发送单个数据包
|
|
/// </summary>
|
|
private async Task<bool> WritePacketDataFrame(byte[] packet, int packetNumber, int totalPackets)
|
|
{
|
|
try
|
|
{
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.WriteLine($"发送第 {packetNumber} 包异常: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|
|
|