diff --git a/server.test/UDPServerTest.cs b/server.test/UDPServerTest.cs index 0b04b97..11c4aad 100644 --- a/server.test/UDPServerTest.cs +++ b/server.test/UDPServerTest.cs @@ -111,12 +111,12 @@ public class UDPServerTest foreach (var number in bytesArray) { - Assert.True(await UDPClientPool.SendBytesAsync(serverEP, NumberProcessor.NumberToBytes(number, 4).Value)); + Assert.True(await UDPClientPool.SendBytesAsync(serverEP, Number.NumberToBytes(number, 4).Value)); var ret = await udpServer.FindDataAsync(address); Assert.True(ret.HasValue); var data = ret.Value; Assert.Equal(address, data.Address); - Assert.Equal(number, NumberProcessor.BytesToNumber(data.Data)); + Assert.Equal(number, Number.BytesToNumber(data.Data)); } } @@ -130,13 +130,13 @@ public class UDPServerTest foreach (var number in bytesArray) { - Assert.True(await UDPClientPool.SendBytesAsync(serverEP, NumberProcessor.NumberToBytes(number, 4).Value)); + Assert.True(await UDPClientPool.SendBytesAsync(serverEP, Number.NumberToBytes(number, 4).Value)); var ret = await udpServer.WaitForAckAsync(address); Assert.True(ret.IsSuccessful); var data = ret.Value; Assert.True(data.IsSuccessful); - Assert.Equal(number, NumberProcessor.BytesToNumber(data.ToBytes())); + Assert.Equal(number, Number.BytesToNumber(data.ToBytes())); } } @@ -150,13 +150,13 @@ public class UDPServerTest foreach (var number in bytesArray) { - Assert.True(await UDPClientPool.SendBytesAsync(serverEP, NumberProcessor.NumberToBytes(number, 8).Value)); + Assert.True(await UDPClientPool.SendBytesAsync(serverEP, Number.NumberToBytes(number, 8).Value)); var ret = await udpServer.WaitForDataAsync(address); Assert.True(ret.IsSuccessful); var data = ret.Value; Assert.True(data.IsSuccessful); - Assert.Equal(number, NumberProcessor.BytesToNumber(data.ToBytes())); + Assert.Equal(number, Number.BytesToNumber(data.ToBytes())); } } } diff --git a/server/src/Common.cs b/server/src/Common.cs index b3fbc25..ab3d0e2 100644 --- a/server/src/Common.cs +++ b/server/src/Common.cs @@ -2,8 +2,18 @@ using DotNext; namespace Common { - public class NumberProcessor + /// + /// 数字处理工具 + /// + public class Number { + /// + /// 整数转成二进制字节数组 + /// + /// 整数 + /// 整数长度 + /// 是否高位在右边 + /// 二进制字节数组 public static Result NumberToBytes(ulong num, uint length, bool isRightHigh = false) { if (length > 8) @@ -33,6 +43,12 @@ namespace Common return arr; } + /// + /// 二进制字节数组转成整数 + /// + /// 二进制字节数组 + /// 是否高位在右边 + /// 整数 public static Result BytesToNumber(byte[] bytes, bool isRightHigh = false) { if (bytes.Length > 8) @@ -66,12 +82,28 @@ namespace Common + /// + /// 比特合并成二进制字节 + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] public static Result MultiBitsToBytes(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len) { return NumberToBytes(MultiBitsToNumber(bits1, bits1Len, bits2, bits2Len).Value, (bits1Len + bits2Len) % 8 != 0 ? (bits1Len + bits2Len) / 8 + 1 : (bits1Len + bits2Len) / 8); } + /// + /// 比特合并成整型 + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] public static Result MultiBitsToNumber(ulong bits1, uint bits1Len, ulong bits2, uint bits2Len) { if (bits1Len + bits2Len > 64) throw new ArgumentException("Two Bits is more than 64 bits"); @@ -80,6 +112,14 @@ namespace Common return num; } + /// + /// 比特合并成整型 + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] public static Result MultiBitsToNumber(uint bits1, uint bits1Len, uint bits2, uint bits2Len) { if (bits1Len + bits2Len > 64) throw new ArgumentException("Two Bits is more than 64 bits"); @@ -88,17 +128,37 @@ namespace Common return num; } + /// + /// 比特位检查 + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] public static bool BitsCheck(ulong srcBits, ulong dstBits, ulong mask = 0xFFFF_FFFF_FFFF_FFFF) { return (srcBits & mask) == dstBits; } + /// + /// 比特位检查 + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] public static bool BitsCheck(uint srcBits, uint dstBits, uint mask = 0xFFFF_FFFF) { return (srcBits & mask) == dstBits; } + /// + /// 字符串转二进制字节数组 + /// + /// [TODO:parameter] + /// [TODO:parameter] + /// [TODO:return] public static byte[] StringToBytes(string str, int numBase = 16) { var len = str.Length; diff --git a/server/src/JtagController.cs b/server/src/JtagController.cs index 2502824..3146ef1 100644 --- a/server/src/JtagController.cs +++ b/server/src/JtagController.cs @@ -261,7 +261,7 @@ class Jtag if (retPackLen != 4) throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); - return Convert.ToUInt32(NumberProcessor.BytesToNumber(retPackOpts.Data).Value); + return Convert.ToUInt32(Number.BytesToNumber(retPackOpts.Data).Value); } public async ValueTask> RunCommand(uint devAddr, uint command) @@ -281,7 +281,7 @@ class Jtag if (!ret) throw new Exception("Send 1st address package failed!"); // Send Data Package ret = await UDPClientPool.SendDataPackAsync(ep, - new SendDataPackage(NumberProcessor.NumberToBytes(command, 4).Value)); + new SendDataPackage(Number.NumberToBytes(command, 4).Value)); if (!ret) throw new Exception("Send data package failed!"); // Check Msg Bus @@ -322,52 +322,52 @@ class Jtag if (retPackLen != 4) throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); - if (NumberProcessor.BitsCheck( - NumberProcessor.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) + if (Number.BitsCheck( + Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) ret = true; return ret; } - public async ValueTask> ClearAllRegisters() + async ValueTask> ClearAllRegisters() { return await RunCommand(JtagAddr.STATE, 0xFF_FF_FF_FF, 0x01_02_02_02, JtagState.ALL_REG); } - public async ValueTask> ClearWriteDataReg() + async ValueTask> ClearWriteDataReg() { return await RunCommand(JtagAddr.STATE, 0x00_00_11_00, 0x01_00_02_00, JtagState.WRITE_DATA_FIFO | JtagState.CMD_EXEC_FINISH); } - public async ValueTask> RunTest() + async ValueTask> RunTest() { return await RunCommand( JtagAddr.WRITE_CMD, - NumberProcessor.MultiBitsToNumber(JtagCmd.CMD_JTAG_RUN_TEST, JtagCmd.LEN_CMD_JTAG, 0, 28).Value, + Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_RUN_TEST, JtagCmd.LEN_CMD_JTAG, 0, 28).Value, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); } - public async ValueTask> DRIDcode() + async ValueTask> DRIDcode() { return await RunCommand( JtagAddr.WRITE_DATA, - NumberProcessor.MultiBitsToNumber(0, 22, JtagCmd.JTAG_DR_IDCODE, JtagCmd.LEN_JTAG_DR).Value, 0, 0); + Number.MultiBitsToNumber(0, 22, JtagCmd.JTAG_DR_IDCODE, JtagCmd.LEN_JTAG_DR).Value, 0, 0); } - public async ValueTask> LoadIR() + async ValueTask> LoadIR() { return await RunCommand( JtagAddr.WRITE_CMD, - NumberProcessor.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value, + Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value, 0x01_00_00_00); } - public async ValueTask> LoadDRCareo() + async ValueTask> LoadDRCareo() { var ret = await RunCommand( JtagAddr.WRITE_CMD, - NumberProcessor.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREO, JtagCmd.LEN_CMD_JTAG, 32, 28).Value, + Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREO, JtagCmd.LEN_CMD_JTAG, 32, 28).Value, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); if (ret.Value) @@ -380,6 +380,9 @@ class Jtag { var ret = false; + // Clear Data + await MsgBus.UDPServer.ClearUDPData(this.address); + ret = (await ClearAllRegisters()).Value; ret = (await RunTest()).Value; ret = (await DRIDcode()).Value; diff --git a/server/src/Router.cs b/server/src/Router.cs index f6f6569..34d92ac 100644 --- a/server/src/Router.cs +++ b/server/src/Router.cs @@ -70,7 +70,7 @@ namespace Router public static async ValueTask SendBytes(string address, int port, string bytes) { var endPoint = new IPEndPoint(IPAddress.Parse(address), port); - var ret = await UDPClientPool.SendBytesAsync(endPoint, NumberProcessor.StringToBytes(bytes)); + var ret = await UDPClientPool.SendBytesAsync(endPoint, Number.StringToBytes(bytes)); if (ret) { return TypedResults.Ok(); } else { return TypedResults.InternalServerError(); } @@ -105,7 +105,7 @@ namespace Router { var endPoint = new IPEndPoint(IPAddress.Parse(address), port); var ret = await UDPClientPool.SendDataPackAsync(endPoint, - new WebProtocol.SendDataPackage(NumberProcessor.StringToBytes(data))); + new WebProtocol.SendDataPackage(Number.StringToBytes(data))); if (ret) { return TypedResults.Ok(); } else { return TypedResults.InternalServerError(); } diff --git a/server/src/UdpClientPool.cs b/server/src/UdpClientPool.cs index 0d1815a..c86aab2 100644 --- a/server/src/UdpClientPool.cs +++ b/server/src/UdpClientPool.cs @@ -2,28 +2,54 @@ using System.Net; using System.Net.Sockets; using System.Text; +/// +/// UDP客户端发送池 +/// public class UDPClientPool { private static IPAddress localhost = IPAddress.Parse("127.0.0.1"); + /// + /// 发送字符串 + /// + /// IP端点(IP地址与端口) + /// 字符串数组 + /// 是否成功 public static bool SendString(IPEndPoint endPoint, string[] stringArray) { + var isSuccessful = true; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]); + foreach (var str in stringArray) + { + byte[] sendbuf = Encoding.ASCII.GetBytes(str); + var sendLen = socket.SendTo(sendbuf, endPoint); + if (str.Length != sendLen) isSuccessful = false; + } - var sendLen = socket.SendTo(sendbuf, endPoint); socket.Close(); - if (sendLen == stringArray[0].Length) { return true; } + if (isSuccessful) { return true; } else { return false; } } + /// + /// 异步发送字符串 + /// + /// IP端点(IP地址与端口) + /// 字符串数组 + /// 是否成功 public async static ValueTask SendStringAsync(IPEndPoint endPoint, string[] stringArray) { return await Task.Run(() => { return SendString(endPoint, stringArray); }); } + /// + /// 发送二进制字节 + /// + /// IP端点(IP地址与端口) + /// 二进制字节 + /// 是否成功 public static bool SendBytes(IPEndPoint endPoint, byte[] buf) { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); @@ -34,11 +60,23 @@ public class UDPClientPool else { return false; } } + /// + /// 异步发送二进制字节 + /// + /// IP端点(IP地址与端口) + /// 二进制字节 + /// 是否成功 public async static ValueTask SendBytesAsync(IPEndPoint endPoint, byte[] buf) { return await Task.Run(() => { return SendBytes(endPoint, buf); }); } + /// + /// 发送地址包 + /// + /// IP端点(IP地址与端口) + /// 地址包 + /// 是否成功 public static bool SendAddrPack(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg) { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); @@ -50,11 +88,24 @@ public class UDPClientPool else { return false; } } + /// + /// 异步发送地址包 + /// + /// IP端点(IP地址与端口) + /// 地址包 + /// 是否成功 public async static ValueTask SendAddrPackAsync(IPEndPoint endPoint, WebProtocol.SendAddrPackage pkg) { return await Task.Run(() => { return SendAddrPack(endPoint, pkg); }); } + + /// + /// 发送数据包 + /// + /// IP端点(IP地址与端口) + /// 数据包 + /// 是否成功 public static bool SendDataPack(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg) { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); @@ -66,38 +117,48 @@ public class UDPClientPool else { return false; } } + /// + /// 异步发送数据包 + /// + /// IP端点(IP地址与端口) + /// 数据包 + /// 是否成功 public async static ValueTask SendDataPackAsync(IPEndPoint endPoint, WebProtocol.SendDataPackage pkg) { return await Task.Run(() => { return SendDataPack(endPoint, pkg); }); } - public static bool SendLocalHost(int port, string[] stringArray) + /// + /// 发送字符串到本地 + /// + /// 端口 + /// 字符串数组 + /// 是否成功 + public static bool SendStringLocalHost(int port, string[] stringArray) { - Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - - byte[] sendBytes = Encoding.ASCII.GetBytes(stringArray[0]); - IPEndPoint ep = new IPEndPoint(localhost, port); - - var sendLen = socket.SendTo(sendBytes, ep); - socket.Close(); - - if (sendLen == sendBytes.Length) { return true; } - else { return false; } + return SendString(new IPEndPoint(localhost, port), stringArray); } - public static void CycleSendLocalHost(int times, int sleepMilliSeconds, int port, string[] stringArray) + /// + /// 循环发送字符串到本地 + /// + /// 发送总次数 + /// 间隔时间 + /// 端口 + /// 字符串数组 + /// 是否成功 + public static bool CycleSendStringLocalHost(int times, int sleepMilliSeconds, int port, string[] stringArray) { - Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - byte[] sendbuf = Encoding.ASCII.GetBytes(stringArray[0]); - IPEndPoint ep = new IPEndPoint(localhost, port); + var isSuccessful = true; while (times-- >= 0) { - socket.SendTo(sendbuf, ep); + isSuccessful = SendStringLocalHost(port, stringArray); + if (!isSuccessful) break; Thread.Sleep(sleepMilliSeconds); } - socket.Close(); + return isSuccessful; } } diff --git a/server/src/UdpServer.cs b/server/src/UdpServer.cs index 65a2d82..e4eb4ff 100644 --- a/server/src/UdpServer.cs +++ b/server/src/UdpServer.cs @@ -2,6 +2,7 @@ using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Text; +using System.Threading.Tasks; using DotNext; using DotNext.Threading; using Newtonsoft.Json; @@ -392,6 +393,23 @@ public class UDPServer } } + /// + /// 清空指定IP地址的数据 + /// + /// IP地址 + /// + public async Task ClearUDPData(string ipAddr) + { + using (await udpData.AcquireWriteLockAsync()) + { + if (udpData.TryGetValue(ipAddr, out var dataQueue) && dataQueue.Count > 0) + { + dataQueue.Clear(); + } + } + } + + /// /// Start UDP Server /// diff --git a/server/src/WebProtocol.cs b/server/src/WebProtocol.cs index 639b05b..ed6d94d 100644 --- a/server/src/WebProtocol.cs +++ b/server/src/WebProtocol.cs @@ -202,7 +202,7 @@ namespace WebProtocol arr[2] = burstLength; arr[3] = _reserved; - var bytesAddr = Common.NumberProcessor.NumberToBytes(address, 4).Value; + var bytesAddr = Common.Number.NumberToBytes(address, 4).Value; Array.Copy(bytesAddr, 0, arr, 4, bytesAddr.Length); return arr; @@ -248,7 +248,7 @@ namespace WebProtocol ); } - var address = Common.NumberProcessor.BytesToNumber(bytes[4..]).Value; + var address = Common.Number.BytesToNumber(bytes[4..]).Value; return new SendAddrPackage(bytes[1], bytes[2], Convert.ToUInt32(address)); } }