diff --git a/.justfile b/.justfile index 5d979fb..551a2f3 100644 --- a/.justfile +++ b/.justfile @@ -3,6 +3,12 @@ pwd echo +clean: + rm -rf "server/bin" + rm -rf "server/obj" + rm -rf "server.test/bin" + rm -rf "server.test/obj" + [working-directory: "server"] publish: _show-dir dotnet publish --self-contained false -t:PublishAllRids diff --git a/server/src/Common.cs b/server/src/Common.cs index ab3d0e2..bc126ef 100644 --- a/server/src/Common.cs +++ b/server/src/Common.cs @@ -18,10 +18,10 @@ namespace Common { if (length > 8) { - throw new ArgumentException( + return new(new ArgumentException( "Unsigned long number can't over 8 bytes(64 bits).", nameof(length) - ); + )); } var arr = new byte[length]; @@ -53,10 +53,10 @@ namespace Common { if (bytes.Length > 8) { - throw new ArgumentException( + return new(new ArgumentException( "Unsigned long number can't over 8 bytes(64 bits).", nameof(bytes) - ); + )); } ulong num = 0; @@ -106,7 +106,7 @@ namespace Common /// [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"); + if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits")); ulong num = (bits1 << Convert.ToInt32(bits2Len)) | bits2; return num; @@ -122,7 +122,7 @@ namespace Common /// [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"); + if (bits1Len + bits2Len > 64) return new(new ArgumentException("Two Bits is more than 64 bits")); uint num = (bits1 << Convert.ToInt32(bits2Len)) | bits2; return num; diff --git a/server/src/Controllers.cs b/server/src/Controllers.cs index 399e7c6..e76db1a 100644 --- a/server/src/Controllers.cs +++ b/server/src/Controllers.cs @@ -1,5 +1,6 @@ using System.Net; using Common; +using DotNext; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using WebProtocol; @@ -149,6 +150,7 @@ public class JtagController : ControllerBase { return "This is Jtag Controller"; } + /// /// 执行一个Jtag命令 /// @@ -182,8 +184,16 @@ public class JtagController : ControllerBase var jtagCtrl = new JtagClient.Jtag(address, port); var ret = await jtagCtrl.ReadIDCode(); - if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); } - else { return TypedResults.InternalServerError(ret.Error); } + if (ret.IsSuccessful) + { + logger.Info($"Get device {address} ID code: 0x{ret.Value:X4}"); + return TypedResults.Ok(ret.Value); + } + else + { + logger.Error(ret.Error); + return TypedResults.InternalServerError(ret.Error); + } } /// @@ -217,7 +227,8 @@ public class JtagController : ControllerBase await file.CopyToAsync(stream); } - return TypedResults.Ok("文件上传成功"); + logger.Info($"Device {address} Upload Bitstream Successfully"); + return TypedResults.Ok("Bitstream Upload Successfully"); } /// @@ -265,8 +276,16 @@ public class JtagController : ControllerBase var jtagCtrl = new JtagClient.Jtag(address, port); var ret = await jtagCtrl.DownloadBitstream(fileBytes); - if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); } - else { return TypedResults.InternalServerError(ret.Error); } + if (ret.IsSuccessful) + { + logger.Info($"Device {address} dowload bitstream successfully"); + return TypedResults.Ok(ret.Value); + } + else + { + logger.Error(ret.Error); + return TypedResults.InternalServerError(ret.Error); + } } } catch (Exception error) diff --git a/server/src/JtagClient.cs b/server/src/JtagClient.cs index a724b18..6c5791e 100644 --- a/server/src/JtagClient.cs +++ b/server/src/JtagClient.cs @@ -213,23 +213,34 @@ public static class JtagCmd public const UInt32 CMD_JTAG_IDLE_DELAY = 0b0101; } -class Jtag +/// +/// Jtag控制器 +/// +public class Jtag { + private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); + readonly int timeout; readonly int port; readonly string address; private IPEndPoint ep; - public Jtag(string address, int port, int outTime = 2000) + /// + /// Jtag构造函数 + /// + /// 目标IP地址 + /// 目标UDP端口 + /// 超时时间 + public Jtag(string address, int port, int timeout = 2000) { this.address = address; this.port = port; this.ep = new IPEndPoint(IPAddress.Parse(address), port); - this.timeout = outTime; + this.timeout = timeout; } - public async ValueTask> ReadFIFO(uint devAddr) + async ValueTask> ReadFIFO(uint devAddr) { var ret = false; var opts = new SendAddrPackOptions(); @@ -242,23 +253,23 @@ class Jtag // Read Jtag State Register opts.IsWrite = false; ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); - if (!ret) throw new Exception("Send Address Package Failed!"); + if (!ret) return new(new Exception("Send Address Package Failed!")); // Wait for Read Ack if (!MsgBus.IsRunning) - throw new Exception("Message Bus not Working!"); + return new(new Exception("Message Bus not Working!")); var retPack = await MsgBus.UDPServer.WaitForDataAsync(address, port); if (!retPack.IsSuccessful || !retPack.Value.IsSuccessful) - throw new Exception("Send address package failed"); + return new(new Exception("Send address package failed")); var retPackOpts = retPack.Value.Options; if (retPackOpts.Data is null) - throw new Exception($"Data is Null, package: {retPackOpts.ToString()}"); + return new(new Exception($"Data is Null, package: {retPackOpts.ToString()}")); var retPackLen = retPackOpts.Data.Length; if (retPackLen != 4) - throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); + return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes")); return Convert.ToUInt32(Common.Number.BytesToNumber(retPackOpts.Data).Value); } @@ -277,36 +288,36 @@ class Jtag // Write Jtag State Register opts.IsWrite = true; ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); - if (!ret) throw new Exception("Send 1st address package failed!"); + if (!ret) return new(new Exception("Send 1st address package failed!")); // Send Data Package ret = await UDPClientPool.SendDataPackAsync(ep, new SendDataPackage(Common.Number.NumberToBytes(data, 4).Value)); - if (!ret) throw new Exception("Send data package failed!"); + if (!ret) return new(new Exception("Send data package failed!")); // Check Msg Bus if (!MsgBus.IsRunning) - throw new Exception("Message bus not working!"); + return new(new Exception("Message bus not working!")); // Wait for Write Ack var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port); - if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error; + if (!udpWriteAck.IsSuccessful) return new(udpWriteAck.Error); else if (!udpWriteAck.Value.IsSuccessful) - throw new Exception("Send address package failed"); + return new(new Exception("Send address package failed")); // Read Jtag State Register opts.IsWrite = false; opts.Address = JtagAddr.STATE; ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); - if (!ret) throw new Exception("Send 2rd Address Package Failed!"); + if (!ret) return new(new Exception("Send 2rd Address Package Failed!")); // Wait for Read Data var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); - if (!udpDataResp.IsSuccessful) throw udpDataResp.Error; + if (!udpDataResp.IsSuccessful) return new(udpDataResp.Error); else if (!udpDataResp.Value.IsSuccessful) - throw new Exception("Send address package failed"); + return new(new Exception("Send address package failed")); return udpDataResp.Value; } - public async ValueTask> WriteFIFO(UInt32 devAddr, byte[] dataArray) + async ValueTask> WriteFIFO(UInt32 devAddr, byte[] dataArray) { var ret = false; var opts = new SendAddrPackOptions(); @@ -318,7 +329,7 @@ class Jtag // Check Msg Bus if (!MsgBus.IsRunning) - throw new Exception("Message bus not working!"); + return new(new Exception("Message bus not working!")); var writeTimes = dataArray.Length / (256 * (32 / 8)) + 1; for (var i = 0; i < writeTimes; i++) @@ -328,7 +339,7 @@ class Jtag opts.IsWrite = true; opts.BurstLength = isLastData ? (byte)(dataArray.Length - i * (256 * (32 / 8)) - 1) : (byte)255; ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); - if (!ret) throw new Exception("Send 1st address package failed!"); + if (!ret) return new(new Exception("Send 1st address package failed!")); // Send Data Package ret = await UDPClientPool.SendDataPackAsync(ep, new SendDataPackage( @@ -337,13 +348,13 @@ class Jtag dataArray[(i * (256 * (32 / 8)))..((i + 1) * (256 * (32 / 8)) - 1)] ) ); - if (!ret) throw new Exception("Send data package failed!"); + if (!ret) return new(new Exception("Send data package failed!")); // Wait for Write Ack var udpWriteAck = await MsgBus.UDPServer.WaitForAckAsync(address, port); - if (!udpWriteAck.IsSuccessful) throw udpWriteAck.Error; + if (!udpWriteAck.IsSuccessful) return new(udpWriteAck.Error); else if (!udpWriteAck.Value.IsSuccessful) - throw new Exception("Send address package failed"); + return new(new Exception("Send address package failed")); } // Read Jtag State Register @@ -351,29 +362,29 @@ class Jtag opts.BurstLength = 0; opts.Address = JtagAddr.STATE; ret = await UDPClientPool.SendAddrPackAsync(ep, new SendAddrPackage(opts)); - if (!ret) throw new Exception("Send 2rd Address Package Failed!"); + if (!ret) return new(new Exception("Send 2rd Address Package Failed!")); // Wait for Read Data var udpDataResp = await MsgBus.UDPServer.WaitForDataAsync(address, port); - if (!udpDataResp.IsSuccessful) throw udpDataResp.Error; + if (!udpDataResp.IsSuccessful) return new(udpDataResp.Error); else if (!udpDataResp.Value.IsSuccessful) - throw new Exception("Send address package failed"); + return new(new Exception("Send address package failed")); return udpDataResp.Value; } - public async ValueTask> WriteFIFO + async ValueTask> WriteFIFO (UInt32 devAddr, UInt32 data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF) { var ret = false; var retPack = await WriteFIFO(devAddr, data); - if (!retPack.IsSuccessful) throw retPack.Error; + if (!retPack.IsSuccessful) return new(retPack.Error); if (retPack.Value.Options.Data is null) - throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); + return new(new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}")); var retPackLen = retPack.Value.Options.Data.Length; if (retPackLen != 4) - throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); + return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes")); if (Common.Number.BitsCheck( Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) @@ -382,18 +393,18 @@ class Jtag return ret; } - public async ValueTask> WriteFIFO + async ValueTask> WriteFIFO (UInt32 devAddr, byte[] data, UInt32 result, UInt32 resultMask = 0xFF_FF_FF_FF) { var ret = false; var retPack = await WriteFIFO(devAddr, data); if (retPack.Value.Options.Data is null) - throw new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}"); + return new(new Exception($"Data is Null, package: {retPack.Value.Options.ToString()}")); var retPackLen = retPack.Value.Options.Data.Length; if (retPackLen != 4) - throw new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes"); + return new(new Exception($"RecvDataPackage BodyData Length not Equal to 4: Total {retPackLen} bytes")); if (Common.Number.BitsCheck( Common.Number.BytesToNumber(retPack.Value.Options.Data).Value, result, resultMask)) @@ -431,7 +442,7 @@ class Jtag async ValueTask> IdleDelay(UInt32 milliseconds) { - if (milliseconds > Math.Pow(2, 28)) throw new Exception("Timespan is over 2^28 milliseconds"); + if (milliseconds > Math.Pow(2, 28)) return new(new Exception("Timespan is over 2^28 milliseconds")); return await WriteFIFO( JtagAddr.WRITE_CMD, @@ -446,8 +457,8 @@ class Jtag JtagAddr.WRITE_DATA, Common.Number.MultiBitsToNumber(0, 22, command, JtagCmd.LEN_JTAG_DR).Value, 0, 0); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Write JTAG_DR_IDCODE Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Write JTAG_DR_IDCODE Failed")); } { var ret = await WriteFIFO( @@ -455,8 +466,8 @@ class Jtag Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_IR, JtagCmd.LEN_CMD_JTAG, 10, 28).Value, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_IR Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Write CMD_JTAG_LOAD_IR Failed")); } return await ClearWriteDataReg(); } @@ -464,7 +475,7 @@ class Jtag async ValueTask> LoadDRCareInput(byte[] bytesArray) { var bytesLen = ((uint)(bytesArray.Length * 8)); - if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)"); + if (bytesLen > Math.Pow(2, 28)) return new(new Exception("Length is over 2^(28 - 3)")); { var ret = await WriteFIFO( @@ -472,21 +483,21 @@ class Jtag Common.Number.MultiBitsToNumber(JtagCmd.CMD_JTAG_LOAD_DR_CAREI, JtagCmd.LEN_CMD_JTAG, bytesLen, 28).Value, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Write CMD_JTAG_LOAD_DR_CAREI Failed")); } { var ret = await WriteFIFO(JtagAddr.WRITE_DATA, bytesArray, 0x01_00_00_00, JtagState.CMD_EXEC_FINISH); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Write Data Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Write Data Failed")); } return true; } async ValueTask> LoadDRCareOutput(UInt32 bytesLen) { - if (bytesLen > Math.Pow(2, 28)) throw new Exception("Length is over 2^(28 - 3)"); + if (bytesLen > Math.Pow(2, 28)) return new(new Exception("Length is over 2^(28 - 3)")); var ret = await WriteFIFO( JtagAddr.WRITE_CMD, @@ -496,7 +507,7 @@ class Jtag if (ret.Value) return await ReadFIFO(JtagAddr.READ_DATA); else - throw new Exception("LoadDRCareo Failed!"); + return new(new Exception("LoadDRCareo Failed!")); } public async ValueTask> ReadIDCode() @@ -504,28 +515,30 @@ class Jtag // Clear Data await MsgBus.UDPServer.ClearUDPData(this.address); + logger.Trace($"Clear up udp server {this.address} receive data"); + Result ret; ret = await ClearAllRegisters(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Clear All Registers Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Clear All Registers Failed")); ret = await RunTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Run Test Failed")); ret = await ExecRDCmd(JtagCmd.JTAG_DR_IDCODE); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_IDCODE Failed")); ret = await ClearWriteDataReg(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Clear Write Registers Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Clear Write Registers Failed")); var retData = await LoadDRCareOutput(4); if (!retData.IsSuccessful) { - throw new Exception("Get ID Code Failed"); + return new(new Exception("Get ID Code Failed")); } return retData.Value; @@ -536,66 +549,66 @@ class Jtag // Clear Data await MsgBus.UDPServer.ClearUDPData(this.address); + logger.Trace($"Clear up udp server {this.address} receive data"); + Result ret; ret = await CloseTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Close Test Failed")); ret = await RunTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Run Test Failed")); + logger.Trace("Jtag initialize"); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JRST); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JRST Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_JRST Failed")); ret = await RunTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Run Test Failed")); ret = await ExecRDCmd(JtagCmd.JTAG_DR_CFGI); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_CFGI Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_CFGI Failed")); + logger.Trace("Jtag ready to write bitstream"); ret = await IdleDelay(75000); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed")); ret = await LoadDRCareInput(bitstream); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Load Data Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Load Data Failed")); + logger.Trace("Jtag write bitstream"); ret = await CloseTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Close Test Failed")); ret = await RunTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Run Test Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Run Test Failed")); ret = await ExecRDCmd(JtagCmd.JTAG_DR_JWAKEUP); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Execute Command JTAG_DR_JWAKEUP Failed")); + logger.Trace("Jtag reset device"); ret = await IdleDelay(1000); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag IDLE Delay Failed"); - + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag IDLE Delay Failed")); ret = await CloseTest(); - if (!ret.IsSuccessful) throw ret.Error; - else if (!ret.Value) throw new Exception("Jtag Close Test Failed"); + if (!ret.IsSuccessful) return new(ret.Error); + else if (!ret.Value) return new(new Exception("Jtag Close Test Failed")); + logger.Trace("Jtag download bitstream successfully"); return true; } diff --git a/server/src/UdpServer.cs b/server/src/UdpServer.cs index e5f15f2..b17937b 100644 --- a/server/src/UdpServer.cs +++ b/server/src/UdpServer.cs @@ -5,6 +5,7 @@ using System.Text; using DotNext; using DotNext.Threading; using Newtonsoft.Json; +using WebProtocol; /// UDP接受数据包格式 public class UDPData @@ -58,9 +59,6 @@ public class UDPData } } -/// -/// UDP Server -/// /// /// UDP 服务器 /// @@ -80,6 +78,15 @@ public class UDPServer /// public bool IsRunning { get { return isRunning; } } + /// UDP 服务器的错误代码 + public enum ErrorCode + { + Success = 0, + GetNoneAfterTimeout, + ResponseWrong, + NotRecvDataPackage, + } + /// /// Construct a udp server with fixed port /// @@ -132,8 +139,9 @@ public class UDPServer { var elapsed = DateTime.Now - startTime; isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout); - timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; + if (isTimeout) break; + timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; using (await udpData.AcquireWriteLockAsync(timeleft)) { if (udpData.ContainsKey(ipAddr) && @@ -150,11 +158,11 @@ public class UDPServer if (data is null) { logger.Trace("Get nothing even after time out"); - return Optional.None; + return new(null); } else { - return Optional.Some((UDPData)data.DeepClone()); + return new(data.DeepClone()); } } @@ -175,8 +183,9 @@ public class UDPServer { var elapsed = DateTime.Now - startTime; isTimeout = elapsed >= TimeSpan.FromMilliseconds(timeout); - timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; + if (isTimeout) break; + timeleft = TimeSpan.FromMilliseconds(timeout) - elapsed; using (await udpData.AcquireReadLockAsync(timeleft)) { if (udpData.ContainsKey(ipAddr) && @@ -193,11 +202,11 @@ public class UDPServer if (data is null) { logger.Trace("Get nothing even after time out"); - return Optional>.None; + return new(null); } else { - return Optional.Some((List)data); + return new(data); } } @@ -213,15 +222,15 @@ public class UDPServer { var data = await FindDataAsync(address, timeout); if (!data.HasValue) - throw new Exception("Get None even after time out!"); + return new(new Exception("Get None even after time out!")); var recvData = data.Value; if (recvData.Address != address || (port > 0 && recvData.Port != port)) - throw new Exception("Receive Data From Wrong Board!"); + return new(new Exception("Receive Data From Wrong Board!")); var retPack = WebProtocol.RecvRespPackage.FromBytes(recvData.Data); if (!retPack.IsSuccessful) - throw new Exception("Not RecvDataPackage!", retPack.Error); + return new(new Exception("Not RecvDataPackage!", retPack.Error)); return retPack.Value; } @@ -233,20 +242,20 @@ public class UDPServer /// UDP 端口 /// 超时时间范围 /// 接收数据包 - public async ValueTask> WaitForDataAsync + public async ValueTask> WaitForDataAsync (string address, int port = -1, int timeout = 1000) { var data = await FindDataAsync(address, timeout); if (!data.HasValue) - throw new Exception("Get None even after time out!"); + return new(new Exception("Get None even after time out!")); var recvData = data.Value; if (recvData.Address != address || (port >= 0 && recvData.Port != port)) - throw new Exception("Receive Data From Wrong Board!"); + return new(new Exception("Receive Data From Wrong Board!")); var retPack = WebProtocol.RecvDataPackage.FromBytes(recvData.Data); if (!retPack.IsSuccessful) - throw new Exception("Not RecvDataPackage!", retPack.Error); + return new(new Exception("Not RecvDataPackage!", retPack.Error)); return retPack.Value; } diff --git a/server/src/WebProtocol.cs b/server/src/WebProtocol.cs index bbd71ba..88a99df 100644 --- a/server/src/WebProtocol.cs +++ b/server/src/WebProtocol.cs @@ -234,18 +234,18 @@ namespace WebProtocol { if (bytes.Length != 8) { - throw new ArgumentException( + return new(new ArgumentException( "Bytes are not equal to 8 bytes.", nameof(bytes) - ); + )); } if (checkSign && bytes[0] != (byte)PackSign.SendAddr) { - throw new ArgumentException( - "The sign of bytes is not SendAddr Package, but you can disable it by set checkSign false.", - nameof(bytes) - ); + return new(new ArgumentException( + "The sign of bytes is not SendAddr Package, but you can disable it by set checkSign false.", + nameof(bytes) + )); } var address = Common.Number.BytesToNumber(bytes[4..]).Value; @@ -377,10 +377,10 @@ namespace WebProtocol public static Result FromBytes(byte[] bytes) { if (bytes[0] != (byte)PackSign.RecvData) - throw new ArgumentException( + return new(new ArgumentException( $"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}", nameof(bytes) - ); + )); return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]); } @@ -480,10 +480,10 @@ namespace WebProtocol public static Result FromBytes(byte[] bytes) { if (bytes[0] != (byte)PackSign.RecvResp) - throw new ArgumentException( + return new(new ArgumentException( $"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}", nameof(bytes) - ); + )); return new RecvRespPackage(bytes[1], bytes[2]); }