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.WriteFIFO(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); } } /// /// 通过Jtag下载比特流文件 /// /// 设备地址 /// 设备端口 /// 比特流文件(最大32MB) [HttpGet("DownloadBitstream")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async ValueTask DownloadBitstream(string address, int port, IFormFile file) { // 检查文件 if (file is null || file.Length <= 0) throw new ArgumentException("Empty file", nameof(file)); // 定义缓冲区大小(例如:1MB) const int bufferSize = 1024 * 1024; // 1MB byte[] buffer = new byte[bufferSize]; long totalBytesRead = 0; // 使用异步流读取文件 using (var memoryStream = new MemoryStream()) { using (var stream = file.OpenReadStream()) { int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await memoryStream.WriteAsync(buffer, 0, bytesRead); totalBytesRead += bytesRead; } } // 将所有数据转换为字节数组(注意:如果文件非常大,可能不适合完全加载到内存) byte[] fileBytes = memoryStream.ToArray(); // 下载比特流 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); } } } }