diff --git a/server/Program.cs b/server/Program.cs
index 80f8ebb..1c4b39c 100644
--- a/server/Program.cs
+++ b/server/Program.cs
@@ -1,5 +1,3 @@
-using System.Reflection;
-using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using NLog;
using NLog.Web;
@@ -15,6 +13,7 @@ try
{
var builder = WebApplication.CreateBuilder(args);
+ // Services Settings
// Add services to the container.
builder.Services.AddControllersWithViews();
@@ -32,27 +31,32 @@ try
});
// Add Swagger
- builder.Services.AddSwaggerGen(options =>
+ builder.Services.AddControllers();
+ builder.Services.AddOpenApiDocument(options =>
{
- options.SwaggerDoc("v1", new OpenApiInfo
+ options.PostProcess = document =>
{
- Title = "FPGA Web Lab API",
- Description = "Use FPGA in the cloud",
- Version = "v1"
- });
- // Generate Doc and Example
- options.IncludeXmlComments(Assembly.GetExecutingAssembly());
- // var executingAssembly = Assembly.GetExecutingAssembly();
- // var xmlFilename = $"{executingAssembly.GetName().Name}.xml";
- // options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
- // var referencedProjectsXmlDocPaths =
- // executingAssembly.GetReferencedAssemblies()
- // .Where(assembly => assembly.Name != null && assembly.Name.StartsWith("server", StringComparison.InvariantCultureIgnoreCase))
- // .Select(assembly => Path.Combine(AppContext.BaseDirectory, $"{assembly.Name}.xml"))
- // .Where(path => File.Exists(path));
- // foreach (var xmlDocPath in referencedProjectsXmlDocPaths) options.IncludeXmlComments(xmlDocPath);
+ document.Info = new NSwag.OpenApiInfo
+ {
+ Version = "v1",
+ Title = "FPGA Web Lab API",
+ Description = "Use FPGA in the cloud",
+ // TermsOfService = "https://example.com/terms",
+ // Contact = new NSwag.OpenApiContact
+ // {
+ // Name = "Example Contact",
+ // Url = "https://example.com/contact"
+ // },
+ // License = new NSwag.OpenApiLicense
+ // {
+ // Name = "Example License",
+ // Url = "https://example.com/license"
+ // }
+ };
+ };
});
+ // Application Settings
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseExceptionHandler("/Home/Error");
@@ -61,20 +65,12 @@ try
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
-
app.UseAuthorization();
- app.MapControllerRoute(
- name: "default",
- pattern: "{controller=Home}/{action=Index}/{id?}");
-
// if (app.Environment.IsDevelopment())
// {
- app.UseSwagger();
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint("/swagger/v1/swagger.json", "FPAG WebLab API V1");
- });
+ app.UseOpenApi();
+ app.UseSwaggerUi();
// }
// Setup Program
@@ -83,15 +79,7 @@ try
// Router
// API Get
app.MapGet("/", () => Results.Redirect("/swagger"));
- app.MapGet("/api/GetRecvDataArray", Router.API.GetRecvDataArray);
- // API Post
- app.MapPost("/api/SendString", Router.API.SendString);
- app.MapPost("/api/SendBytes", Router.API.SendBytes);
- app.MapPost("/api/SendAddrPackage", Router.API.SendAddrPackage);
- app.MapPost("/api/SendDataPackage", Router.API.SendDataPackage);
- // API Jtag
- app.MapPost("/api/jtag/RunCommand", Router.API.Jtag.RunCommand);
- app.MapGet("/api/jtag/GetIDCode", Router.API.Jtag.GetDeviceIDCode);
+ app.MapControllers();
app.Run("http://localhost:5000");
}
diff --git a/server/server.csproj b/server/server.csproj
index a903e41..dca031e 100644
--- a/server/server.csproj
+++ b/server/server.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/server/src/Controllers.cs b/server/src/Controllers.cs
new file mode 100644
index 0000000..d563152
--- /dev/null
+++ b/server/src/Controllers.cs
@@ -0,0 +1,186 @@
+using System.Net;
+using Common;
+using Microsoft.AspNetCore.Mvc;
+using Newtonsoft.Json;
+using WebProtocol;
+
+namespace server.Controllers;
+
+///
+/// UDP API
+///
+[ApiController]
+[Route("api/[controller]")]
+public class UDPController : ControllerBase
+{
+ private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
+
+ private const string LOCALHOST = "127.0.0.1";
+
+ ///
+ /// 页面
+ ///
+ [HttpGet]
+ public string Index()
+ {
+ return "This is UDP Controller";
+ }
+
+ ///
+ /// 发送字符串
+ ///
+ /// IPV4 或者 IPV6 地址
+ /// 设备端口号
+ /// 发送的文本
+ /// 发送成功
+ /// 发送失败
+ [HttpPost("SendString")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask SendString(string address = LOCALHOST, int port = 1234, string text = "Hello Server!")
+ {
+ var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
+ var ret = await UDPClientPool.SendStringAsync(endPoint, [text]);
+
+ if (ret) { return TypedResults.Ok(); }
+ else { return TypedResults.InternalServerError(); }
+ }
+
+ ///
+ /// 发送二进制数据
+ ///
+ /// IPV4 或者 IPV6 地址
+ /// 设备端口号
+ /// 16进制文本
+ [HttpPost("SendBytes")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask SendBytes(string address, int port, string bytes)
+ {
+ var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
+ var ret = await UDPClientPool.SendBytesAsync(endPoint, Number.StringToBytes(bytes));
+
+ if (ret) { return TypedResults.Ok(); }
+ else { return TypedResults.InternalServerError(); }
+ }
+
+
+ ///
+ /// 发送地址包
+ ///
+ /// IP地址
+ /// UDP 端口号
+ /// 地址包选项
+ [HttpPost("SendAddrPackage")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask SendAddrPackage(
+ string address,
+ int port,
+ [FromBody] SendAddrPackOptions opts)
+ {
+ var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
+ var ret = await UDPClientPool.SendAddrPackAsync(endPoint, new WebProtocol.SendAddrPackage(opts));
+
+ if (ret) { return TypedResults.Ok(); }
+ else { return TypedResults.InternalServerError(); }
+ }
+
+ ///
+ /// 发送数据包
+ ///
+ /// IP地址
+ /// UDP 端口号
+ /// 16进制数据
+ [HttpPost("SendDataPackage")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask SendDataPackage(string address, int port, string data)
+ {
+ var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
+ var ret = await UDPClientPool.SendDataPackAsync(endPoint,
+ new WebProtocol.SendDataPackage(Number.StringToBytes(data)));
+
+ if (ret) { return TypedResults.Ok(); }
+ else { return TypedResults.InternalServerError(); }
+ }
+
+ ///
+ /// 获取指定IP地址接受的数据列表
+ ///
+ /// IP地址
+ [HttpGet("GetRecvDataArray")]
+ [ProducesResponseType(typeof(List), StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask GetRecvDataArray(string address)
+ {
+ var ret = await MsgBus.UDPServer.GetDataArrayAsync(address);
+
+ if (ret.HasValue)
+ {
+ var dataJson = JsonConvert.SerializeObject(ret.Value);
+ logger.Debug($"Get Receive Successfully: {dataJson}");
+
+ return TypedResults.Ok(ret.Value);
+ }
+ else
+ {
+ logger.Debug("Get Receive Failed");
+ return TypedResults.InternalServerError();
+ }
+ }
+
+}
+
+///
+/// Jtag API
+///
+[ApiController]
+[Route("api/[controller]")]
+public class JtagController : ControllerBase
+{
+ ///
+ /// 页面
+ ///
+ [HttpGet]
+ public string Index()
+ {
+ return "This is Jtag Controller";
+ }
+ ///
+ /// 执行一个Jtag命令
+ ///
+ /// 设备地址
+ /// 设备端口
+ /// 16进制设备目的地址(Jtag)
+ /// 16进制命令
+ [HttpPost("RunCommand")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask RunCommand(string address, int port, string hexDevAddr, string hexCmd)
+ {
+ var jtagCtrl = new JtagClient.Jtag(address, port);
+ var ret = await jtagCtrl.RunCommand(Convert.ToUInt32(hexDevAddr, 16), Convert.ToUInt32(hexCmd, 16));
+
+ if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); }
+ else { return TypedResults.InternalServerError(ret.Error); }
+ }
+
+
+ ///
+ /// 获取Jtag ID Code
+ ///
+ /// 设备地址
+ /// 设备端口
+ [HttpGet("GetDeviceIDCode")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError)]
+ public async ValueTask GetDeviceIDCode(string address, int port)
+ {
+ 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); }
+ }
+}
diff --git a/server/src/JtagController.cs b/server/src/JtagClient.cs
similarity index 99%
rename from server/src/JtagController.cs
rename to server/src/JtagClient.cs
index 3146ef1..5fb6e4e 100644
--- a/server/src/JtagController.cs
+++ b/server/src/JtagClient.cs
@@ -3,7 +3,7 @@ using Common;
using DotNext;
using WebProtocol;
-namespace JtagController;
+namespace JtagClient;
///
/// Global Constant Jtag Address
diff --git a/server/src/Router.cs b/server/src/Router.cs
deleted file mode 100644
index 34d92ac..0000000
--- a/server/src/Router.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-using System.Net;
-using Common;
-using Microsoft.AspNetCore.Mvc;
-using Newtonsoft.Json;
-using WebProtocol;
-
-namespace Router
-{
- ///
- /// Custom Web Http Response
- ///
- public class Response
- {
- ///
- /// 是否成功执行
- ///
- public bool IsSuccess { get; set; }
-
- ///
- /// 数据
- ///
- public object? Data { get; set; }
-
- ///
- /// 转换为Json格式的字符串
- ///
- /// Json字符串
- public override string ToString()
- {
- return JsonConvert.SerializeObject(this);
- }
- }
-
- ///
- /// Web API
- ///
- class API
- {
- private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
-
- private const string LOCALHOST = "127.0.0.1";
-
- ///
- /// 发送字符串
- ///
- /// IPV4 或者 IPV6 地址
- /// 设备端口号
- /// Text for send
- [HttpPost("{address}/{port}")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public static async ValueTask SendString(string address, int port, string text)
- {
- var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
- var ret = await UDPClientPool.SendStringAsync(endPoint, [text]);
-
- if (ret) { return TypedResults.Ok(); }
- else { return TypedResults.InternalServerError(); }
- }
-
- ///
- /// 发送二进制数据
- ///
- /// IPV4 或者 IPV6 地址
- /// 设备端口号
- /// 16进制文本
- [HttpPost("{address}/{port}")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- 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, Number.StringToBytes(bytes));
-
- if (ret) { return TypedResults.Ok(); }
- else { return TypedResults.InternalServerError(); }
- }
-
-
- ///
- /// 发送地址包
- ///
- /// IP地址
- /// UDP 端口号
- /// 地址包选项
- [HttpPost("{address}/{port}")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public static async ValueTask SendAddrPackage(
- string address,
- int port,
- [FromBody] SendAddrPackOptions opts)
- {
- var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
- var ret = await UDPClientPool.SendAddrPackAsync(endPoint, new WebProtocol.SendAddrPackage(opts));
-
- if (ret) { return TypedResults.Ok(); }
- else { return TypedResults.InternalServerError(); }
- }
-
- [HttpPost("{address}/{port}")]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public static async ValueTask SendDataPackage(string address, int port, string data)
- {
- var endPoint = new IPEndPoint(IPAddress.Parse(address), port);
- var ret = await UDPClientPool.SendDataPackAsync(endPoint,
- new WebProtocol.SendDataPackage(Number.StringToBytes(data)));
-
- if (ret) { return TypedResults.Ok(); }
- else { return TypedResults.InternalServerError(); }
- }
-
- [HttpGet("{address}")]
- [ProducesResponseType(typeof(List), StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public static async ValueTask GetRecvDataArray(string address)
- {
- var ret = await MsgBus.UDPServer.GetDataArrayAsync(address);
-
- if (ret.HasValue)
- {
- var dataJson = JsonConvert.SerializeObject(ret.Value);
- logger.Debug($"Get Receive Successfully: {dataJson}");
-
- return TypedResults.Ok(ret.Value);
- }
- else
- {
- logger.Debug("Get Receive Failed");
- return TypedResults.InternalServerError();
- }
- }
-
- public class Jtag
- {
- private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
-
- ///
- /// 执行一个Jtag命令
- ///
- /// 设备地址
- /// 设备端口
- /// 16进制设备目的地址(Jtag)
- /// 16进制命令
- [HttpPost]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public static async ValueTask RunCommand(string address, int port, string hexDevAddr, string hexCmd)
- {
- var jtagCtrl = new JtagController.Jtag(address, port);
- var ret = await jtagCtrl.RunCommand(Convert.ToUInt32(hexDevAddr, 16), Convert.ToUInt32(hexCmd, 16));
-
- if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); }
- else { return TypedResults.InternalServerError(ret.Error); }
- }
-
-
- ///
- /// 获取Jtag ID Code
- ///
- /// 设备地址
- /// 设备端口
- [HttpGet]
- [ProducesResponseType(StatusCodes.Status200OK)]
- [ProducesResponseType(StatusCodes.Status500InternalServerError)]
- public static async ValueTask GetDeviceIDCode(string address, int port)
- {
- var jtagCtrl = new JtagController.Jtag(address, port);
- var ret = await jtagCtrl.ReadIDCode();
-
- if (ret.IsSuccessful) { return TypedResults.Ok(ret.Value); }
- else { return TypedResults.InternalServerError(ret.Error); }
- }
-
-
- }
- }
-}
diff --git a/server/src/UdpServer.cs b/server/src/UdpServer.cs
index e4eb4ff..1295bbe 100644
--- a/server/src/UdpServer.cs
+++ b/server/src/UdpServer.cs
@@ -2,7 +2,6 @@ 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;