feat: 更新网络配置后端及其api
This commit is contained in:
		@@ -222,7 +222,7 @@ public class DataController : ControllerBase
 | 
			
		||||
 | 
			
		||||
            var user = userRet.Value.Value;
 | 
			
		||||
            var expireTime = DateTime.UtcNow.AddHours(durationHours);
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            var boardOpt = db.GetAvailableBoard(user.ID, expireTime);
 | 
			
		||||
            if (!boardOpt.HasValue)
 | 
			
		||||
                return NotFound("没有可用的实验板");
 | 
			
		||||
@@ -303,21 +303,17 @@ public class DataController : ControllerBase
 | 
			
		||||
    [Authorize("Admin")]
 | 
			
		||||
    [HttpPost("AddBoard")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(int), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(typeof(Guid), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public IActionResult AddBoard(string name, string ipAddr, int port)
 | 
			
		||||
    public IActionResult AddBoard(string name)
 | 
			
		||||
    {
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(name))
 | 
			
		||||
            return BadRequest("板子名称不能为空");
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(ipAddr))
 | 
			
		||||
            return BadRequest("IP地址不能为空");
 | 
			
		||||
        if (port <= 0 || port > 65535)
 | 
			
		||||
            return BadRequest("端口号不合法");
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            using var db = new Database.AppDataConnection();
 | 
			
		||||
            var ret = db.AddBoard(name, ipAddr, port);
 | 
			
		||||
            var ret = db.AddBoard(name);
 | 
			
		||||
            return Ok(ret);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
 
 | 
			
		||||
@@ -15,11 +15,206 @@ namespace server.Controllers;
 | 
			
		||||
public class NetConfigController : ControllerBase
 | 
			
		||||
{
 | 
			
		||||
    private static readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // 固定的实验板IP和端口
 | 
			
		||||
    private const string BOARD_IP = "169.254.109.0";
 | 
			
		||||
    private const int BOARD_PORT = 1234;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取主机IP地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>主机IP地址</returns>
 | 
			
		||||
    [HttpGet("GetHostIP")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public async Task<IActionResult> GetHostIP()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
 | 
			
		||||
            var result = await netConfig.GetHostIP();
 | 
			
		||||
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"获取主机IP失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, $"获取失败: {result.Error}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取主机IP时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取板卡IP地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>板卡IP地址</returns>
 | 
			
		||||
    [HttpGet("GetBoardIP")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public async Task<IActionResult> GetBoardIP()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
 | 
			
		||||
            var result = await netConfig.GetBoardIP();
 | 
			
		||||
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"获取板卡IP失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, $"获取失败: {result.Error}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取板卡IP时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取主机MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>主机MAC地址</returns>
 | 
			
		||||
    [HttpGet("GetHostMAC")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public async Task<IActionResult> GetHostMAC()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
 | 
			
		||||
            var result = await netConfig.GetHostMAC();
 | 
			
		||||
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"获取主机MAC地址失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, $"获取失败: {result.Error}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取主机MAC地址时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取板卡MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>板卡MAC地址</returns>
 | 
			
		||||
    [HttpGet("GetBoardMAC")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public async Task<IActionResult> GetBoardMAC()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
 | 
			
		||||
            var result = await netConfig.GetBoardMAC();
 | 
			
		||||
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"获取板卡MAC地址失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, $"获取失败: {result.Error}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取板卡MAC地址时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取所有网络配置信息
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>网络配置信息</returns>
 | 
			
		||||
    [HttpGet("GetNetworkConfig")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(NetworkConfigDto), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public async Task<IActionResult> GetNetworkConfig()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
 | 
			
		||||
            
 | 
			
		||||
            var hostIPResult = await netConfig.GetHostIP();
 | 
			
		||||
            var boardIPResult = await netConfig.GetBoardIP();
 | 
			
		||||
            var hostMACResult = await netConfig.GetHostMAC();
 | 
			
		||||
            var boardMACResult = await netConfig.GetBoardMAC();
 | 
			
		||||
 | 
			
		||||
            var config = new NetworkConfigDto
 | 
			
		||||
            {
 | 
			
		||||
                HostIP = hostIPResult.IsSuccessful ? hostIPResult.Value : "获取失败",
 | 
			
		||||
                BoardIP = boardIPResult.IsSuccessful ? boardIPResult.Value : "获取失败",
 | 
			
		||||
                HostMAC = hostMACResult.IsSuccessful ? hostMACResult.Value : "获取失败",
 | 
			
		||||
                BoardMAC = boardMACResult.IsSuccessful ? boardMACResult.Value : "获取失败"
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            return Ok(config);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取网络配置信息时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 获取本机所有网络接口信息
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>网络接口信息列表</returns>
 | 
			
		||||
    [HttpGet("GetLocalNetworkInterfaces")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(List<NetworkInterfaceDto>), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public IActionResult GetLocalNetworkInterfaces()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            var interfaces = System.Net.NetworkInformation.NetworkInterface
 | 
			
		||||
                .GetAllNetworkInterfaces()
 | 
			
		||||
                .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
 | 
			
		||||
                              && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
 | 
			
		||||
                .Select(nic => new NetworkInterfaceDto
 | 
			
		||||
                {
 | 
			
		||||
                    Name = nic.Name,
 | 
			
		||||
                    Description = nic.Description,
 | 
			
		||||
                    Type = nic.NetworkInterfaceType.ToString(),
 | 
			
		||||
                    Status = nic.OperationalStatus.ToString(),
 | 
			
		||||
                    IPAddresses = nic.GetIPProperties().UnicastAddresses
 | 
			
		||||
                        .Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
 | 
			
		||||
                        .Select(addr => addr.Address.ToString())
 | 
			
		||||
                        .ToList(),
 | 
			
		||||
                    MACAddress = nic.GetPhysicalAddress().ToString()
 | 
			
		||||
                })
 | 
			
		||||
                .ToList();
 | 
			
		||||
 | 
			
		||||
            return Ok(interfaces);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "获取本机网络接口信息时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "获取失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 设置主机IP地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -138,6 +333,49 @@ public class NetConfigController : ControllerBase
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 自动获取本机IP地址并设置为实验板主机IP
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>操作结果</returns>
 | 
			
		||||
    [HttpPost("UpdateHostIP")]
 | 
			
		||||
    [EnableCors("Users")]
 | 
			
		||||
    [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
 | 
			
		||||
    [ProducesResponseType(StatusCodes.Status500InternalServerError)]
 | 
			
		||||
    public async Task<IActionResult> UpdateHostIP()
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            // 获取本机第一个有效的IPv4地址
 | 
			
		||||
            var ip = System.Net.NetworkInformation.NetworkInterface
 | 
			
		||||
                .GetAllNetworkInterfaces()
 | 
			
		||||
                .Where(nic => nic.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up
 | 
			
		||||
                              && nic.NetworkInterfaceType != System.Net.NetworkInformation.NetworkInterfaceType.Loopback)
 | 
			
		||||
                .SelectMany(nic => nic.GetIPProperties().UnicastAddresses)
 | 
			
		||||
                .Where(addr => addr.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
 | 
			
		||||
                .Select(addr => addr.Address)
 | 
			
		||||
                .FirstOrDefault();
 | 
			
		||||
 | 
			
		||||
            if (ip == null)
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, "无法获取本机IP地址");
 | 
			
		||||
 | 
			
		||||
            var netConfig = new NetConfig(BOARD_IP, BOARD_PORT, 0);
 | 
			
		||||
            var result = await netConfig.SetHostIP(ip);
 | 
			
		||||
 | 
			
		||||
            if (!result.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"自动设置主机IP失败: {result.Error}");
 | 
			
		||||
                return StatusCode(StatusCodes.Status500InternalServerError, $"设置失败: {result.Error}");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return Ok(result.Value);
 | 
			
		||||
        }
 | 
			
		||||
        catch (Exception ex)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error(ex, "自动设置主机IP时发生异常");
 | 
			
		||||
            return StatusCode(StatusCodes.Status500InternalServerError, "设置失败,请稍后重试");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 更新主机MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@@ -262,3 +500,111 @@ public class NetConfigController : ControllerBase
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// 网络配置数据传输对象
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class NetworkConfigDto
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 主机IP地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? HostIP { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 板卡IP地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? BoardIP { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 主机MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? HostMAC { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 板卡MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? BoardMAC { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// 网络配置操作结果
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class NetworkConfigResult
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 主机IP设置结果
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public bool? HostIPResult { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 主机IP设置错误信息
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? HostIPError { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 板卡IP设置结果
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public bool? BoardIPResult { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 板卡IP设置错误信息
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? BoardIPError { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 主机MAC设置结果
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public bool? HostMACResult { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 主机MAC设置错误信息
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? HostMACError { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 板卡MAC设置结果
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public bool? BoardMACResult { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 板卡MAC设置错误信息
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string? BoardMACError { get; set; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// 网络接口信息数据传输对象
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class NetworkInterfaceDto
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 网络接口名称
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string Name { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 网络接口描述
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string Description { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 网络接口类型
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string Type { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 网络接口状态
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string Status { get; set; } = string.Empty;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// IP地址列表
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public List<string> IPAddresses { get; set; } = new();
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public string MACAddress { get; set; } = string.Empty;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -92,11 +92,17 @@ public class Board
 | 
			
		||||
    [NotNull]
 | 
			
		||||
    public required string IpAddr { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// FPGA 板子的MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [NotNull]
 | 
			
		||||
    public required string MacAddr { get; set; }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// FPGA 板子的通信端口
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    [NotNull]
 | 
			
		||||
    public required int Port { get; set; }
 | 
			
		||||
    public int Port { get; set; } = 1234;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// FPGA 板子的当前状态
 | 
			
		||||
@@ -127,6 +133,11 @@ public class Board
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum BoardStatus
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary> 
 | 
			
		||||
        /// 未启用状态,无法被使用
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        Disabled,
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 繁忙状态,正在被用户使用
 | 
			
		||||
        /// </summary>
 | 
			
		||||
@@ -371,25 +382,61 @@ public class AppDataConnection : DataConnection
 | 
			
		||||
        return userResult + boardResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 自动分配一个未被占用的IP地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>分配的IP地址字符串</returns>
 | 
			
		||||
    public string AllocateIpAddr()
 | 
			
		||||
    {
 | 
			
		||||
        var usedIps = this.BoardTable.Select(b => b.IpAddr).ToArray();
 | 
			
		||||
        for (int i = 1; i <= 254; i++)
 | 
			
		||||
        {
 | 
			
		||||
            string ip = $"169.254.109.{i}";
 | 
			
		||||
            if (!usedIps.Contains(ip))
 | 
			
		||||
                return ip;
 | 
			
		||||
        }
 | 
			
		||||
        throw new Exception("没有可用的IP地址");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 自动分配一个未被占用的MAC地址
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>分配的MAC地址字符串</returns>
 | 
			
		||||
    public string AllocateMacAddr()
 | 
			
		||||
    {
 | 
			
		||||
        var usedMacs = this.BoardTable.Select(b => b.MacAddr).ToArray();
 | 
			
		||||
        // 以 02-00-00-xx-xx-xx 格式分配,02 表示本地管理地址
 | 
			
		||||
        for (int i = 1; i <= 0xFFFFFF; i++)
 | 
			
		||||
        {
 | 
			
		||||
            string mac = $"02-00-00-{(i >> 16) & 0xFF:X2}-{(i >> 8) & 0xFF:X2}-{i & 0xFF:X2}";
 | 
			
		||||
            if (!usedMacs.Contains(mac))
 | 
			
		||||
                return mac;
 | 
			
		||||
        }
 | 
			
		||||
        throw new Exception("没有可用的MAC地址");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 添加一块新的 FPGA 板子到数据库
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="name">FPGA 板子的名称</param>
 | 
			
		||||
    /// <param name="ipAddr">FPGA 板子的IP地址</param>
 | 
			
		||||
    /// <param name="port">FPGA 板子的通信端口</param>
 | 
			
		||||
    /// <returns>插入的记录数</returns>
 | 
			
		||||
    public int AddBoard(string name, string ipAddr, int port)
 | 
			
		||||
    public Guid AddBoard(string name)
 | 
			
		||||
    {
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(name) || name.Contains('\'') || name.Contains(';'))
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error("实验板名称非法,包含不允许的字符");
 | 
			
		||||
            throw new ArgumentException("实验板名称非法");
 | 
			
		||||
        }
 | 
			
		||||
        var board = new Board()
 | 
			
		||||
        {
 | 
			
		||||
            BoardName = name,
 | 
			
		||||
            IpAddr = ipAddr,
 | 
			
		||||
            Port = port,
 | 
			
		||||
            Status = Database.Board.BoardStatus.Available,
 | 
			
		||||
            IpAddr = AllocateIpAddr(),
 | 
			
		||||
            MacAddr = AllocateMacAddr(),
 | 
			
		||||
            Status = Database.Board.BoardStatus.Disabled,
 | 
			
		||||
        };
 | 
			
		||||
        var result = this.Insert(board);
 | 
			
		||||
        logger.Info($"新实验板已添加: {name} ({ipAddr}:{port})");
 | 
			
		||||
        return result;
 | 
			
		||||
        logger.Info($"新实验板已添加: {name} ({board.IpAddr}:{board.MacAddr})");
 | 
			
		||||
        return board.ID;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
@@ -543,18 +590,39 @@ public class AppDataConnection : DataConnection
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 更新实验板的IP地址
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="boardId">实验板的唯一标识符</param>
 | 
			
		||||
    /// <param name="newIpAddr">新的IP地址</param>
 | 
			
		||||
    /// <returns>更新的记录数</returns>
 | 
			
		||||
    public int UpdateBoardIpAddr(Guid boardId, string newIpAddr)
 | 
			
		||||
    /// <param name="boardId">[TODO:parameter]</param>
 | 
			
		||||
    /// <param name="newName">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    public int UpdateBoardName(Guid boardId, string newName)
 | 
			
		||||
    {
 | 
			
		||||
        if (string.IsNullOrWhiteSpace(newName) || newName.Contains('\'') || newName.Contains(';'))
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error("实验板名称非法,包含不允许的字符");
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
        var result = this.BoardTable
 | 
			
		||||
            .Where(b => b.ID == boardId)
 | 
			
		||||
            .Set(b => b.BoardName, newName)
 | 
			
		||||
            .Update();
 | 
			
		||||
        logger.Info($"实验板名称已更新: {boardId} -> {newName}");
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="boardId">[TODO:parameter]</param>
 | 
			
		||||
    /// <param name="newStatus">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    public int UpdateBoardStatus(Guid boardId, Board.BoardStatus newStatus)
 | 
			
		||||
    {
 | 
			
		||||
        var result = this.BoardTable
 | 
			
		||||
            .Where(b => b.ID == boardId)
 | 
			
		||||
            .Set(b => b.IpAddr, newIpAddr)
 | 
			
		||||
            .Set(b => b.Status, newStatus)
 | 
			
		||||
            .Update();
 | 
			
		||||
        logger.Info($"实验板 {boardId} 的IP地址已更新为 {newIpAddr},更新记录数: {result}");
 | 
			
		||||
        logger.Info($"TODO");
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -13,9 +13,8 @@ static class NetConfigAddr
 | 
			
		||||
    public static readonly UInt32[] BOARD_MAC = { BASE + 14, BASE + 15, BASE + 16, BASE + 17, BASE + 18, BASE + 19 };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// [TODO:description]
 | 
			
		||||
/// Network configuration client for FPGA board communication
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class NetConfig
 | 
			
		||||
{
 | 
			
		||||
@@ -28,13 +27,12 @@ public class NetConfig
 | 
			
		||||
    private IPEndPoint ep;
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// Initialize NetConfig client
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="address">[TODO:parameter]</param>
 | 
			
		||||
    /// <param name="port">[TODO:parameter]</param>
 | 
			
		||||
    /// <param name="taskID">[TODO:parameter]</param>
 | 
			
		||||
    /// <param name="timeout">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    /// <param name="address">Target board address</param>
 | 
			
		||||
    /// <param name="port">Target board port</param>
 | 
			
		||||
    /// <param name="taskID">Task identifier</param>
 | 
			
		||||
    /// <param name="timeout">Timeout in milliseconds</param>
 | 
			
		||||
    public NetConfig(string address, int port, int taskID, int timeout = 2000)
 | 
			
		||||
    {
 | 
			
		||||
        if (timeout < 0)
 | 
			
		||||
@@ -47,10 +45,10 @@ public class NetConfig
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// Set host IP address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="ip">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    /// <param name="ip">IP address to set</param>
 | 
			
		||||
    /// <returns>Result indicating success or failure</returns>
 | 
			
		||||
    public async ValueTask<Result<bool>> SetHostIP(IPAddress ip)
 | 
			
		||||
    {
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
@@ -58,29 +56,43 @@ public class NetConfig
 | 
			
		||||
 | 
			
		||||
        var ipBytes = ip.GetAddressBytes();
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_IP, ipBytes, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_IP, ipBytes, this.timeout);
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set host IP: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set host IP: operation returned false");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            logger.Error($"Failed to set host IP: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!ret.Value)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to set host IP: operation returned false");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 验证设置结果
 | 
			
		||||
        var verifyResult = await GetHostIP();
 | 
			
		||||
        if (!verifyResult.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to verify host IP after setting: {verifyResult.Error}");
 | 
			
		||||
            return new(verifyResult.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var expectedIP = ip.ToString();
 | 
			
		||||
        if (verifyResult.Value != expectedIP)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Host IP verification failed: expected {expectedIP}, got {verifyResult.Value}");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        logger.Info($"Successfully set and verified host IP: {expectedIP}");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// Set board IP address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="ip">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    /// <param name="ip">IP address to set</param>
 | 
			
		||||
    /// <returns>Result indicating success or failure</returns>
 | 
			
		||||
    public async ValueTask<Result<bool>> SetBoardIP(IPAddress ip)
 | 
			
		||||
    {
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
@@ -88,29 +100,43 @@ public class NetConfig
 | 
			
		||||
 | 
			
		||||
        var ipBytes = ip.GetAddressBytes();
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_IP, ipBytes, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_IP, ipBytes, this.timeout);
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set board IP: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set board IP: operation returned false");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            logger.Error($"Failed to set board IP: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!ret.Value)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to set board IP: operation returned false");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 验证设置结果
 | 
			
		||||
        var verifyResult = await GetBoardIP();
 | 
			
		||||
        if (!verifyResult.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to verify board IP after setting: {verifyResult.Error}");
 | 
			
		||||
            return new(verifyResult.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var expectedIP = ip.ToString();
 | 
			
		||||
        if (verifyResult.Value != expectedIP)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Board IP verification failed: expected {expectedIP}, got {verifyResult.Value}");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        logger.Info($"Successfully set and verified board IP: {expectedIP}");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// Set host MAC address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="macAddress">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    /// <param name="macAddress">MAC address bytes (6 bytes)</param>
 | 
			
		||||
    /// <returns>Result indicating success or failure</returns>
 | 
			
		||||
    public async ValueTask<Result<bool>> SetHostMAC(byte[] macAddress)
 | 
			
		||||
    {
 | 
			
		||||
        if (macAddress == null)
 | 
			
		||||
@@ -121,29 +147,43 @@ public class NetConfig
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
        MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_MAC, macAddress, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_MAC, macAddress, this.timeout);
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set host MAC address: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set host MAC address: operation returned false");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            logger.Error($"Failed to set host MAC address: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!ret.Value)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to set host MAC address: operation returned false");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 验证设置结果
 | 
			
		||||
        var verifyResult = await GetHostMAC();
 | 
			
		||||
        if (!verifyResult.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to verify host MAC after setting: {verifyResult.Error}");
 | 
			
		||||
            return new(verifyResult.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var expectedMAC = string.Join(":", macAddress.Select(b => $"{b:X2}"));
 | 
			
		||||
        if (verifyResult.Value != expectedMAC)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Host MAC verification failed: expected {expectedMAC}, got {verifyResult.Value}");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        logger.Info($"Successfully set and verified host MAC: {expectedMAC}");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// [TODO:description]
 | 
			
		||||
    /// Set board MAC address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="macAddress">[TODO:parameter]</param>
 | 
			
		||||
    /// <returns>[TODO:return]</returns>
 | 
			
		||||
    /// <param name="macAddress">MAC address bytes (6 bytes)</param>
 | 
			
		||||
    /// <returns>Result indicating success or failure</returns>
 | 
			
		||||
    public async ValueTask<Result<bool>> SetBoardMAC(byte[] macAddress)
 | 
			
		||||
    {
 | 
			
		||||
        if (macAddress == null)
 | 
			
		||||
@@ -154,21 +194,143 @@ public class NetConfig
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
        MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_MAC, macAddress, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await UDPClientPool.WriteAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_MAC, macAddress, this.timeout);
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set board MAC address: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!ret.Value)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"Failed to set board MAC address: operation returned false");
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            logger.Error($"Failed to set board MAC address: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!ret.Value)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to set board MAC address: operation returned false");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 验证设置结果
 | 
			
		||||
        var verifyResult = await GetBoardMAC();
 | 
			
		||||
        if (!verifyResult.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to verify board MAC after setting: {verifyResult.Error}");
 | 
			
		||||
            return new(verifyResult.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var expectedMAC = string.Join(":", macAddress.Select(b => $"{b:X2}"));
 | 
			
		||||
        if (verifyResult.Value != expectedMAC)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Board MAC verification failed: expected {expectedMAC}, got {verifyResult.Value}");
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        logger.Info($"Successfully set and verified board MAC: {expectedMAC}");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Get host IP address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>Host IP address as string</returns>
 | 
			
		||||
    public async ValueTask<Result<string>> GetHostIP()
 | 
			
		||||
    {
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
        MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_IP, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to get host IP: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var ip = "";
 | 
			
		||||
        for (int i = 0; i < NetConfigAddr.HOST_IP.Length; i++)
 | 
			
		||||
        {
 | 
			
		||||
            ip += $"{ret.Value[i * 4 + 3]}";
 | 
			
		||||
            if (i != NetConfigAddr.HOST_IP.Length - 1)
 | 
			
		||||
                ip += ".";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ip;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Get board IP address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>Board IP address as string</returns>
 | 
			
		||||
    public async ValueTask<Result<string>> GetBoardIP()
 | 
			
		||||
    {
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
        MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_IP, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to get board IP: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var ip = "";
 | 
			
		||||
        for (int i = 0; i < NetConfigAddr.BOARD_IP.Length; i++)
 | 
			
		||||
        {
 | 
			
		||||
            ip += $"{ret.Value[i * 4 + 3]}";
 | 
			
		||||
            if (i != NetConfigAddr.BOARD_IP.Length - 1)
 | 
			
		||||
                ip += ".";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return ip;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Get host MAC address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>Host MAC address as formatted string (XX:XX:XX:XX:XX:XX)</returns>
 | 
			
		||||
    public async ValueTask<Result<string>> GetHostMAC()
 | 
			
		||||
    {
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
        MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.HOST_MAC, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to get host MAC address: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var mac = "";
 | 
			
		||||
        for (int i = 0; i < NetConfigAddr.HOST_MAC.Length; i++)
 | 
			
		||||
        {
 | 
			
		||||
            mac += $"{ret.Value[i * 4 + 3]:X2}";
 | 
			
		||||
            if (i != NetConfigAddr.HOST_MAC.Length - 1)
 | 
			
		||||
                mac += ":";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mac;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Get board MAC address
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <returns>Board MAC address as formatted string (XX:XX:XX:XX:XX:XX)</returns>
 | 
			
		||||
    public async ValueTask<Result<string>> GetBoardMAC()
 | 
			
		||||
    {
 | 
			
		||||
        // 清除UDP服务器接收缓冲区
 | 
			
		||||
        MsgBus.UDPServer.ClearUDPData(this.address, this.taskID);
 | 
			
		||||
 | 
			
		||||
        var ret = await UDPClientPool.ReadAddrSeq(this.ep, this.taskID, NetConfigAddr.BOARD_MAC, this.timeout);
 | 
			
		||||
        if (!ret.IsSuccessful)
 | 
			
		||||
        {
 | 
			
		||||
            logger.Error($"Failed to get board MAC address: {ret.Error}");
 | 
			
		||||
            return new(ret.Error);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var mac = "";
 | 
			
		||||
        for (int i = 0; i < NetConfigAddr.BOARD_MAC.Length; i++)
 | 
			
		||||
        {
 | 
			
		||||
            mac += $"{ret.Value[i * 4 + 3]:X2}";
 | 
			
		||||
            if (i != NetConfigAddr.BOARD_MAC.Length - 1)
 | 
			
		||||
                mac += ":";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mac;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -537,6 +537,42 @@ public class UDPClientPool
 | 
			
		||||
        return resultData.ToArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 顺序读取多个地址的数据,并合并BodyData后返回
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="endPoint">IP端点(IP地址与端口)</param>
 | 
			
		||||
    /// <param name="taskID">任务ID</param>
 | 
			
		||||
    /// <param name="addr">地址数组</param>
 | 
			
		||||
    /// <param name="timeout">超时时间(毫秒)</param>
 | 
			
		||||
    /// <returns>合并后的BodyData字节数组</returns>
 | 
			
		||||
    public static async ValueTask<Result<byte[]>> ReadAddrSeq(IPEndPoint endPoint, int taskID, UInt32[] addr, int timeout = 1000)
 | 
			
		||||
    {
 | 
			
		||||
        var length = addr.Length;
 | 
			
		||||
        var resultData = new List<byte>();
 | 
			
		||||
        for (int i = 0; i < length; i++)
 | 
			
		||||
        {
 | 
			
		||||
            var ret = await ReadAddr(endPoint, taskID, addr[i], timeout);
 | 
			
		||||
            if (!ret.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"ReadAddrSeq failed at index {i}: {ret.Error}");
 | 
			
		||||
                return new(ret.Error);
 | 
			
		||||
            }
 | 
			
		||||
            if (!ret.Value.IsSuccessful)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"ReadAddrSeq failed at index {i}: Read not successful");
 | 
			
		||||
                return new(new Exception($"ReadAddrSeq failed at index {i}"));
 | 
			
		||||
            }
 | 
			
		||||
            var data = ret.Value.Options.Data;
 | 
			
		||||
            if (data is null)
 | 
			
		||||
            {
 | 
			
		||||
                logger.Error($"ReadAddrSeq got null data at index {i}");
 | 
			
		||||
                return new(new Exception($"ReadAddrSeq got null data at index {i}"));
 | 
			
		||||
            }
 | 
			
		||||
            resultData.AddRange(data);
 | 
			
		||||
        }
 | 
			
		||||
        return resultData.ToArray();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 向设备地址写入32位数据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										472
									
								
								src/APIClient.ts
									
									
									
									
									
								
							
							
						
						
									
										472
									
								
								src/APIClient.ts
									
									
									
									
									
								
							@@ -1126,23 +1126,13 @@ export class DataClient {
 | 
			
		||||
    /**
 | 
			
		||||
     * 新增板子(管理员权限)
 | 
			
		||||
     * @param name (optional) 
 | 
			
		||||
     * @param ipAddr (optional) 
 | 
			
		||||
     * @param port (optional) 
 | 
			
		||||
     */
 | 
			
		||||
    addBoard(name: string | undefined, ipAddr: string | undefined, port: number | undefined): Promise<number> {
 | 
			
		||||
    addBoard(name: string | undefined): Promise<string> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/Data/AddBoard?";
 | 
			
		||||
        if (name === null)
 | 
			
		||||
            throw new Error("The parameter 'name' cannot be null.");
 | 
			
		||||
        else if (name !== undefined)
 | 
			
		||||
            url_ += "name=" + encodeURIComponent("" + name) + "&";
 | 
			
		||||
        if (ipAddr === null)
 | 
			
		||||
            throw new Error("The parameter 'ipAddr' cannot be null.");
 | 
			
		||||
        else if (ipAddr !== undefined)
 | 
			
		||||
            url_ += "ipAddr=" + encodeURIComponent("" + ipAddr) + "&";
 | 
			
		||||
        if (port === null)
 | 
			
		||||
            throw new Error("The parameter 'port' cannot be null.");
 | 
			
		||||
        else if (port !== undefined)
 | 
			
		||||
            url_ += "port=" + encodeURIComponent("" + port) + "&";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
@@ -1157,7 +1147,7 @@ export class DataClient {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processAddBoard(response: Response): Promise<number> {
 | 
			
		||||
    protected processAddBoard(response: Response): Promise<string> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
@@ -1184,7 +1174,7 @@ export class DataClient {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<number>(null as any);
 | 
			
		||||
        return Promise.resolve<string>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -2689,6 +2679,269 @@ export class NetConfigClient {
 | 
			
		||||
        this.baseUrl = baseUrl ?? "http://localhost:5000";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取主机IP地址
 | 
			
		||||
     * @return 主机IP地址
 | 
			
		||||
     */
 | 
			
		||||
    getHostIP(): Promise<string> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/GetHostIP";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processGetHostIP(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processGetHostIP(response: Response): Promise<string> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<string>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取板卡IP地址
 | 
			
		||||
     * @return 板卡IP地址
 | 
			
		||||
     */
 | 
			
		||||
    getBoardIP(): Promise<string> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/GetBoardIP";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processGetBoardIP(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processGetBoardIP(response: Response): Promise<string> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<string>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取主机MAC地址
 | 
			
		||||
     * @return 主机MAC地址
 | 
			
		||||
     */
 | 
			
		||||
    getHostMAC(): Promise<string> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/GetHostMAC";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processGetHostMAC(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processGetHostMAC(response: Response): Promise<string> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<string>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取板卡MAC地址
 | 
			
		||||
     * @return 板卡MAC地址
 | 
			
		||||
     */
 | 
			
		||||
    getBoardMAC(): Promise<string> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/GetBoardMAC";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processGetBoardMAC(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processGetBoardMAC(response: Response): Promise<string> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<string>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取所有网络配置信息
 | 
			
		||||
     * @return 网络配置信息
 | 
			
		||||
     */
 | 
			
		||||
    getNetworkConfig(): Promise<NetworkConfigDto> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/GetNetworkConfig";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processGetNetworkConfig(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processGetNetworkConfig(response: Response): Promise<NetworkConfigDto> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            result200 = NetworkConfigDto.fromJS(resultData200);
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<NetworkConfigDto>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取本机所有网络接口信息
 | 
			
		||||
     * @return 网络接口信息列表
 | 
			
		||||
     */
 | 
			
		||||
    getLocalNetworkInterfaces(): Promise<NetworkInterfaceDto[]> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/GetLocalNetworkInterfaces";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processGetLocalNetworkInterfaces(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processGetLocalNetworkInterfaces(response: Response): Promise<NetworkInterfaceDto[]> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
            if (Array.isArray(resultData200)) {
 | 
			
		||||
                result200 = [] as any;
 | 
			
		||||
                for (let item of resultData200)
 | 
			
		||||
                    result200!.push(NetworkInterfaceDto.fromJS(item));
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                result200 = <any>null;
 | 
			
		||||
            }
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<NetworkInterfaceDto[]>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 设置主机IP地址
 | 
			
		||||
     * @param hostIp (optional) 主机IP地址
 | 
			
		||||
@@ -2854,6 +3107,49 @@ export class NetConfigClient {
 | 
			
		||||
        return Promise.resolve<boolean>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 自动获取本机IP地址并设置为实验板主机IP
 | 
			
		||||
     * @return 操作结果
 | 
			
		||||
     */
 | 
			
		||||
    updateHostIP(): Promise<boolean> {
 | 
			
		||||
        let url_ = this.baseUrl + "/api/NetConfig/UpdateHostIP";
 | 
			
		||||
        url_ = url_.replace(/[?&]$/, "");
 | 
			
		||||
 | 
			
		||||
        let options_: RequestInit = {
 | 
			
		||||
            method: "POST",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json"
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return this.http.fetch(url_, options_).then((_response: Response) => {
 | 
			
		||||
            return this.processUpdateHostIP(_response);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected processUpdateHostIP(response: Response): Promise<boolean> {
 | 
			
		||||
        const status = response.status;
 | 
			
		||||
        let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
 | 
			
		||||
        if (status === 200) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            let result200: any = null;
 | 
			
		||||
            let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
 | 
			
		||||
                result200 = resultData200 !== undefined ? resultData200 : <any>null;
 | 
			
		||||
    
 | 
			
		||||
            return result200;
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status === 500) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("A server side error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        } else if (status !== 200 && status !== 204) {
 | 
			
		||||
            return response.text().then((_responseText) => {
 | 
			
		||||
            return throwException("An unexpected server error occurred.", status, _responseText, _headers);
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
        return Promise.resolve<boolean>(null as any);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新主机MAC地址
 | 
			
		||||
     * @return 操作结果
 | 
			
		||||
@@ -4033,6 +4329,8 @@ export class Board implements IBoard {
 | 
			
		||||
    boardName!: string;
 | 
			
		||||
    /** FPGA 板子的IP地址 */
 | 
			
		||||
    ipAddr!: string;
 | 
			
		||||
    /** FPGA 板子的MAC地址 */
 | 
			
		||||
    macAddr!: string;
 | 
			
		||||
    /** FPGA 板子的通信端口 */
 | 
			
		||||
    port!: number;
 | 
			
		||||
    /** FPGA 板子的当前状态 */
 | 
			
		||||
@@ -4058,6 +4356,7 @@ export class Board implements IBoard {
 | 
			
		||||
            this.id = _data["id"];
 | 
			
		||||
            this.boardName = _data["boardName"];
 | 
			
		||||
            this.ipAddr = _data["ipAddr"];
 | 
			
		||||
            this.macAddr = _data["macAddr"];
 | 
			
		||||
            this.port = _data["port"];
 | 
			
		||||
            this.status = _data["status"];
 | 
			
		||||
            this.occupiedUserID = _data["occupiedUserID"];
 | 
			
		||||
@@ -4078,6 +4377,7 @@ export class Board implements IBoard {
 | 
			
		||||
        data["id"] = this.id;
 | 
			
		||||
        data["boardName"] = this.boardName;
 | 
			
		||||
        data["ipAddr"] = this.ipAddr;
 | 
			
		||||
        data["macAddr"] = this.macAddr;
 | 
			
		||||
        data["port"] = this.port;
 | 
			
		||||
        data["status"] = this.status;
 | 
			
		||||
        data["occupiedUserID"] = this.occupiedUserID;
 | 
			
		||||
@@ -4095,6 +4395,8 @@ export interface IBoard {
 | 
			
		||||
    boardName: string;
 | 
			
		||||
    /** FPGA 板子的IP地址 */
 | 
			
		||||
    ipAddr: string;
 | 
			
		||||
    /** FPGA 板子的MAC地址 */
 | 
			
		||||
    macAddr: string;
 | 
			
		||||
    /** FPGA 板子的通信端口 */
 | 
			
		||||
    port: number;
 | 
			
		||||
    /** FPGA 板子的当前状态 */
 | 
			
		||||
@@ -4109,8 +4411,9 @@ export interface IBoard {
 | 
			
		||||
 | 
			
		||||
/** FPGA 板子状态枚举 */
 | 
			
		||||
export enum BoardStatus {
 | 
			
		||||
    Busy = 0,
 | 
			
		||||
    Available = 1,
 | 
			
		||||
    Disabled = 0,
 | 
			
		||||
    Busy = 1,
 | 
			
		||||
    Available = 2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class SystemException extends Exception implements ISystemException {
 | 
			
		||||
@@ -4325,6 +4628,145 @@ export interface ISignalTriggerConfig {
 | 
			
		||||
    value: SignalValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 网络配置数据传输对象 */
 | 
			
		||||
export class NetworkConfigDto implements INetworkConfigDto {
 | 
			
		||||
    /** 主机IP地址 */
 | 
			
		||||
    hostIP?: string | undefined;
 | 
			
		||||
    /** 板卡IP地址 */
 | 
			
		||||
    boardIP?: string | undefined;
 | 
			
		||||
    /** 主机MAC地址 */
 | 
			
		||||
    hostMAC?: string | undefined;
 | 
			
		||||
    /** 板卡MAC地址 */
 | 
			
		||||
    boardMAC?: string | undefined;
 | 
			
		||||
 | 
			
		||||
    constructor(data?: INetworkConfigDto) {
 | 
			
		||||
        if (data) {
 | 
			
		||||
            for (var property in data) {
 | 
			
		||||
                if (data.hasOwnProperty(property))
 | 
			
		||||
                    (<any>this)[property] = (<any>data)[property];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init(_data?: any) {
 | 
			
		||||
        if (_data) {
 | 
			
		||||
            this.hostIP = _data["hostIP"];
 | 
			
		||||
            this.boardIP = _data["boardIP"];
 | 
			
		||||
            this.hostMAC = _data["hostMAC"];
 | 
			
		||||
            this.boardMAC = _data["boardMAC"];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static fromJS(data: any): NetworkConfigDto {
 | 
			
		||||
        data = typeof data === 'object' ? data : {};
 | 
			
		||||
        let result = new NetworkConfigDto();
 | 
			
		||||
        result.init(data);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    toJSON(data?: any) {
 | 
			
		||||
        data = typeof data === 'object' ? data : {};
 | 
			
		||||
        data["hostIP"] = this.hostIP;
 | 
			
		||||
        data["boardIP"] = this.boardIP;
 | 
			
		||||
        data["hostMAC"] = this.hostMAC;
 | 
			
		||||
        data["boardMAC"] = this.boardMAC;
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 网络配置数据传输对象 */
 | 
			
		||||
export interface INetworkConfigDto {
 | 
			
		||||
    /** 主机IP地址 */
 | 
			
		||||
    hostIP?: string | undefined;
 | 
			
		||||
    /** 板卡IP地址 */
 | 
			
		||||
    boardIP?: string | undefined;
 | 
			
		||||
    /** 主机MAC地址 */
 | 
			
		||||
    hostMAC?: string | undefined;
 | 
			
		||||
    /** 板卡MAC地址 */
 | 
			
		||||
    boardMAC?: string | undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 网络接口信息数据传输对象 */
 | 
			
		||||
export class NetworkInterfaceDto implements INetworkInterfaceDto {
 | 
			
		||||
    /** 网络接口名称 */
 | 
			
		||||
    name!: string;
 | 
			
		||||
    /** 网络接口描述 */
 | 
			
		||||
    description!: string;
 | 
			
		||||
    /** 网络接口类型 */
 | 
			
		||||
    type!: string;
 | 
			
		||||
    /** 网络接口状态 */
 | 
			
		||||
    status!: string;
 | 
			
		||||
    /** IP地址列表 */
 | 
			
		||||
    ipAddresses!: string[];
 | 
			
		||||
    /** MAC地址 */
 | 
			
		||||
    macAddress!: string;
 | 
			
		||||
 | 
			
		||||
    constructor(data?: INetworkInterfaceDto) {
 | 
			
		||||
        if (data) {
 | 
			
		||||
            for (var property in data) {
 | 
			
		||||
                if (data.hasOwnProperty(property))
 | 
			
		||||
                    (<any>this)[property] = (<any>data)[property];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!data) {
 | 
			
		||||
            this.ipAddresses = [];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    init(_data?: any) {
 | 
			
		||||
        if (_data) {
 | 
			
		||||
            this.name = _data["name"];
 | 
			
		||||
            this.description = _data["description"];
 | 
			
		||||
            this.type = _data["type"];
 | 
			
		||||
            this.status = _data["status"];
 | 
			
		||||
            if (Array.isArray(_data["ipAddresses"])) {
 | 
			
		||||
                this.ipAddresses = [] as any;
 | 
			
		||||
                for (let item of _data["ipAddresses"])
 | 
			
		||||
                    this.ipAddresses!.push(item);
 | 
			
		||||
            }
 | 
			
		||||
            this.macAddress = _data["macAddress"];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static fromJS(data: any): NetworkInterfaceDto {
 | 
			
		||||
        data = typeof data === 'object' ? data : {};
 | 
			
		||||
        let result = new NetworkInterfaceDto();
 | 
			
		||||
        result.init(data);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    toJSON(data?: any) {
 | 
			
		||||
        data = typeof data === 'object' ? data : {};
 | 
			
		||||
        data["name"] = this.name;
 | 
			
		||||
        data["description"] = this.description;
 | 
			
		||||
        data["type"] = this.type;
 | 
			
		||||
        data["status"] = this.status;
 | 
			
		||||
        if (Array.isArray(this.ipAddresses)) {
 | 
			
		||||
            data["ipAddresses"] = [];
 | 
			
		||||
            for (let item of this.ipAddresses)
 | 
			
		||||
                data["ipAddresses"].push(item);
 | 
			
		||||
        }
 | 
			
		||||
        data["macAddress"] = this.macAddress;
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 网络接口信息数据传输对象 */
 | 
			
		||||
export interface INetworkInterfaceDto {
 | 
			
		||||
    /** 网络接口名称 */
 | 
			
		||||
    name: string;
 | 
			
		||||
    /** 网络接口描述 */
 | 
			
		||||
    description: string;
 | 
			
		||||
    /** 网络接口类型 */
 | 
			
		||||
    type: string;
 | 
			
		||||
    /** 网络接口状态 */
 | 
			
		||||
    status: string;
 | 
			
		||||
    /** IP地址列表 */
 | 
			
		||||
    ipAddresses: string[];
 | 
			
		||||
    /** MAC地址 */
 | 
			
		||||
    macAddress: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Package options which to send address to read or write */
 | 
			
		||||
export class SendAddrPackOptions implements ISendAddrPackOptions {
 | 
			
		||||
    /** 突发类型 */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user